Merge branch 'master' of ssh://git.enlightenment.org/core/efl

This commit is contained in:
ChunEon Park 2014-09-02 10:00:11 +09:00
commit e56199b626
33 changed files with 428 additions and 127 deletions

View File

@ -27,6 +27,8 @@ lib_eolian_libeolian_la_SOURCES = \
lib/eolian/database_type_api.c \
lib/eolian/database_implement.c \
lib/eolian/database_implement_api.c \
lib/eolian/database_constructor.c \
lib/eolian/database_constructor_api.c \
lib/eolian/database_event.c \
lib/eolian/database_event_api.c \
lib/eolian/database_print.c \

View File

@ -4,11 +4,11 @@ class Colourable (Eo.Base)
legacy_prefix: legacy;
data: Colourable_Data;
methods {
constructor @constructor {
constructor {
/*@ Default constructor. */
legacy: null;
}
rgb_composite_constructor @constructor {
rgb_composite_constructor {
/*@ Composite RGB Constructor. */
legacy: null;
params {
@ -17,7 +17,7 @@ class Colourable (Eo.Base)
@in int b; /*@ The blue component. */
}
}
rgb_24bits_constructor @constructor {
rgb_24bits_constructor {
/*@ RGB Constructor. */
legacy: null;
params {
@ -59,6 +59,11 @@ class Colourable (Eo.Base)
}
}
}
constructors {
.constructor;
.rgb_composite_constructor;
.rgb_24bits_constructor;
}
events {
colour_changed: int;
}

View File

@ -3,7 +3,7 @@ class ColourableSquare (Colourable)
legacy_prefix: legacy;
data: ColourableSquare_Data;
properties {
size_constructor @constructor {
size_constructor {
legacy: null;
params {
@in int size;
@ -24,4 +24,7 @@ class ColourableSquare (Colourable)
methods {
size_print { /*@ Show the square. */ }
}
constructors {
.size_constructor;
}
}

View File

@ -2,7 +2,7 @@ class Ecore.Animator (Eo.Base)
{
eo_prefix: ecore_animator;
methods {
timeline_constructor @constructor {
timeline_constructor {
/*@ Constructor. */
legacy: null;
params {
@ -11,7 +11,7 @@ class Ecore.Animator (Eo.Base)
@in const(void)* data;
}
}
constructor @constructor {
constructor {
/*@ Constructor. */
legacy: null;
params {
@ -26,4 +26,8 @@ class Ecore.Animator (Eo.Base)
Eo.Base.event_freeze;
Eo.Base.event_thaw;
}
constructors {
.constructor;
.timeline_constructor;
}
}

View File

@ -2,7 +2,7 @@ class Ecore.Exe (Eo.Base, Efl.Control)
{
eo_prefix: ecore_obj_exe;
properties {
command @constructor {
command {
/*@ Control the command that's executed. FIXME: May need a split/rename. */
set {
legacy: null;
@ -24,6 +24,9 @@ class Ecore.Exe (Eo.Base, Efl.Control)
Eo.Base.finalize;
Efl.Control.suspend.set;
}
constructors {
.command;
}
events {
data,get: Ecore_Exe_Event_Data;
data,error: Ecore_Exe_Event_Data;

View File

@ -2,7 +2,7 @@ class Ecore.Idle.Enterer (Eo.Base)
{
eo_prefix: ecore_idle_enterer;
methods {
before_constructor @constructor {
before_constructor {
/*@ Contructor. Will insert the handler at the beginning of the list. */
legacy: null;
params {
@ -10,7 +10,7 @@ class Ecore.Idle.Enterer (Eo.Base)
@in const(void)* data;
}
}
after_constructor @constructor {
after_constructor {
/*@ Contructor. Will insert the handler at the end of the list. */
legacy: null;
params {
@ -23,4 +23,8 @@ class Ecore.Idle.Enterer (Eo.Base)
Eo.Base.constructor;
Eo.Base.destructor;
}
constructors {
.before_constructor;
.after_constructor;
}
}

View File

@ -2,7 +2,7 @@ class Ecore.Idle.Exiter (Eo.Base)
{
eo_prefix: ecore_idle_exiter;
methods {
constructor @constructor {
constructor {
/*@ Constructor. */
legacy: null;
params {
@ -15,4 +15,7 @@ class Ecore.Idle.Exiter (Eo.Base)
Eo.Base.constructor;
Eo.Base.destructor;
}
constructors {
.constructor;
}
}

View File

@ -2,7 +2,7 @@ class Ecore.Idler (Eo.Base)
{
eo_prefix: ecore_idler;
methods {
constructor @constructor {
constructor {
/*@ Constructor. */
legacy: null;
params {
@ -15,4 +15,7 @@ class Ecore.Idler (Eo.Base)
Eo.Base.constructor;
Eo.Base.destructor;
}
constructors {
.constructor;
}
}

View File

@ -2,7 +2,7 @@ class Ecore.Job (Eo.Base)
{
eo_prefix: ecore_job;
methods {
constructor @constructor {
constructor {
/*@ Constructor. */
legacy: null;
params {
@ -15,4 +15,7 @@ class Ecore.Job (Eo.Base)
Eo.Base.constructor;
Eo.Base.destructor;
}
constructors {
.constructor;
}
}

View File

@ -1,7 +1,7 @@
class Ecore.Poller (Eo.Base)
{
methods {
constructor @constructor {
constructor {
/*@ Constructor with parameters for Ecore Poller. */
legacy: null;
params {
@ -41,4 +41,7 @@ class Ecore.Poller (Eo.Base)
Eo.Base.constructor;
Eo.Base.destructor;
}
constructors {
.constructor;
}
}

View File

@ -30,7 +30,7 @@ class Ecore.Timer (Eo.Base)
}
}
methods {
loop_constructor @constructor {
loop_constructor {
/*@ Create a timer to call in a given time from now */
legacy: null;
params {
@ -39,7 +39,7 @@ class Ecore.Timer (Eo.Base)
@in const(void)* data; /*@ A pointer to pass to the callback function as its data pointer */
}
}
constructor @constructor {
constructor {
/*@ Create a timer to call in a given time from when the mainloop woke up from sleep */
legacy: null;
params {
@ -100,5 +100,9 @@ class Ecore.Timer (Eo.Base)
*
* @see ecore_timer_freeze()
*/
}
}
constructors {
.constructor;
.loop_constructor;
}
}

View File

@ -44,7 +44,7 @@ Return event freeze count. */
}
}
methods {
constructor @constructor {
constructor {
/*@ Call the object's constructor.
Should not be used with #eo_do. Only use it with #eo_do_super. */
legacy: null;
@ -178,6 +178,9 @@ callbacks of the same priority are called in reverse order of creation. */
class.constructor;
class.destructor;
}
constructors {
.constructor;
}
events {
callback,add; /*@ A callback was added. */
callback,del; /*@ A callback was deleted. */

View File

@ -68,6 +68,12 @@ typedef struct _Eolian_Function_Parameter Eolian_Function_Parameter;
*/
typedef struct _Eolian_Implement Eolian_Implement;
/* Class constructor information
*
* @ingroup Eolian
*/
typedef struct _Eolian_Constructor Eolian_Constructor;
/* Event information
*
* @ingroup Eolian
@ -711,16 +717,6 @@ EAPI Eina_Bool eolian_function_is_legacy_only(const Eolian_Function *function_id
*/
EAPI Eina_Bool eolian_function_is_class(const Eolian_Function *function_id);
/*
* @brief Get whether a function is constructing.
*
* @param[in] function_id Id of the function
* @return EINA_TRUE and EINA_FALSE respectively
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_function_is_constructing(const Eolian_Function *function_id);
/*
* @brief Returns a parameter of a function pointed by its id.
*
@ -975,6 +971,46 @@ EAPI Eina_Bool eolian_implement_is_prop_set(const Eolian_Implement *impl);
*/
EAPI Eina_Iterator *eolian_class_implements_get(const Eolian_Class *klass);
/*
* @brief Get full string of a constructing function.
*
* @param[in] ctor the handle of the constructor
* @return the full string.
*
* @ingroup Eolian
*/
EAPI Eina_Stringshare *eolian_constructor_full_name_get(const Eolian_Constructor *ctor);
/*
* @brief Get the class of a constructing function.
*
* @param[in] ctor the handle of the constructor
* @return the class handle or NULL.
*
* @ingroup Eolian
*/
EAPI const Eolian_Class *eolian_constructor_class_get(const Eolian_Constructor *ctor);
/*
* @brief Get the function of a constructing function.
*
* @param[in] ctor the handle of the constructor
* @return the function handle or NULL.
*
* @ingroup Eolian
*/
EAPI const Eolian_Function *eolian_constructor_function_get(const Eolian_Constructor *ctor);
/*
* @brief Get an iterator to the constructing functions defined in a class.
*
* @param[in] klass the class.
* @return the iterator
*
* @ingroup Eolian
*/
EAPI Eina_Iterator *eolian_class_constructors_get(const Eolian_Class *klass);
/*
* @brief Get an iterator to the events defined in a class.
*

View File

@ -23,6 +23,14 @@ database_class_del(Eolian_Class *cl)
free(impl);
}
Eolian_Constructor *ctor;
Eina_List *constructors = cl->constructors;
EINA_LIST_FREE(constructors, ctor)
{
eina_stringshare_del(ctor->full_name);
free(ctor);
}
EINA_LIST_FREE(cl->methods, fid) database_function_del(fid);
EINA_LIST_FREE(cl->properties, fid) database_function_del(fid);
EINA_LIST_FREE(cl->events, ev) database_event_del(ev);

View File

@ -94,13 +94,20 @@ eolian_class_inherits_get(const Eolian_Class *cl)
return (cl->inherits ? eina_list_iterator_new(cl->inherits) : NULL);
}
EAPI Eina_Iterator*
EAPI Eina_Iterator *
eolian_class_implements_get(const Eolian_Class *cl)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
return (cl->implements ? eina_list_iterator_new(cl->implements) : NULL);
}
EAPI Eina_Iterator *
eolian_class_constructors_get(const Eolian_Class *cl)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
return (cl->constructors ? eina_list_iterator_new(cl->constructors) : NULL);
}
EAPI const Eolian_Function *
eolian_class_function_get_by_name(const Eolian_Class *cl, const char *func_name, Eolian_Function_Type f_type)
{

View File

@ -0,0 +1,11 @@
#include <Eina.h>
#include "eolian_database.h"
void
database_constructor_del(Eolian_Constructor *ctor)
{
if (!ctor) return;
if (ctor->base.file) eina_stringshare_del(ctor->base.file);
if (ctor->full_name) eina_stringshare_del(ctor->full_name);
free(ctor);
}

View File

@ -0,0 +1,41 @@
#include <Eina.h>
#include "eolian_database.h"
EAPI Eina_Stringshare *
eolian_constructor_full_name_get(const Eolian_Constructor *ctor)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(ctor, NULL);
return ctor->full_name;
}
static Eina_Bool
_fill_class(Eolian_Constructor *ctor)
{
const Eolian_Class *class = NULL;
if (ctor->klass)
return EINA_TRUE;
if (!database_class_name_validate(ctor->full_name, &class) || !class)
return EINA_FALSE;
ctor->klass = class;
return EINA_TRUE;
}
EAPI const Eolian_Class *
eolian_constructor_class_get(const Eolian_Constructor *ctor)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(ctor, NULL);
if (!_fill_class((Eolian_Constructor*)ctor))
return NULL;
return ctor->klass;
}
EAPI const Eolian_Function *
eolian_constructor_function_get(const Eolian_Constructor *ctor)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(ctor, NULL);
const Eolian_Class *klass = eolian_constructor_class_get(ctor);
if (!klass)
return NULL;
return eolian_class_function_get_by_name(klass,
ctor->full_name + strlen(klass->full_name) + 1, EOLIAN_UNRESOLVED);
}

View File

@ -138,7 +138,6 @@ _db_fill_property(Eolian_Class *cl, Eo_Class_Def *kls, Eo_Property_Def *prop)
foo_id->scope = prop->scope;
foo_id->is_class = prop->is_class;
foo_id->is_constructing = prop->is_constructing;
if (!_db_fill_params (prop->keys , &(foo_id->keys ))) goto failure;
if (!_db_fill_params (prop->values, &(foo_id->params))) goto failure;
@ -197,7 +196,6 @@ _db_fill_method(Eolian_Class *cl, Eo_Class_Def *kls, Eo_Method_Def *meth)
foo_id->get_legacy = eina_stringshare_ref(meth->legacy);
foo_id->obj_is_const = meth->obj_const;
foo_id->is_class = meth->is_class;
foo_id->is_constructing = meth->is_constructing;
if (meth->only_legacy)
foo_id->get_only_legacy = EINA_TRUE;
@ -297,6 +295,35 @@ _db_fill_implements(Eolian_Class *cl, Eo_Class_Def *kls)
return EINA_TRUE;
}
static void
_db_fill_constructor(Eolian_Class *cl, Eolian_Constructor *ctor)
{
const char *ctor_name = ctor->full_name;
if (ctor_name[0] == '.')
{
ctor->full_name = eina_stringshare_printf("%s%s", cl->full_name,
ctor_name);
eina_stringshare_del(ctor_name);
}
cl->constructors = eina_list_append(cl->constructors, ctor);
}
static Eina_Bool
_db_fill_constructors(Eolian_Class *cl, Eo_Class_Def *kls)
{
Eolian_Constructor *ctor;
Eina_List *l;
EINA_LIST_FOREACH(kls->constructors, l, ctor)
{
_db_fill_constructor(cl, ctor);
eina_list_data_set(l, NULL); /* prevent double free */
}
return EINA_TRUE;
}
static Eina_Bool
_db_fill_events(Eolian_Class *cl, Eo_Class_Def *kls)
{
@ -334,10 +361,11 @@ _db_fill_class(Eo_Class_Def *kls)
if (kls->data_type)
cl->data_type = eina_stringshare_ref(kls->data_type);
if (!_db_fill_properties(cl, kls)) return EINA_FALSE;
if (!_db_fill_methods (cl, kls)) return EINA_FALSE;
if (!_db_fill_implements(cl, kls)) return EINA_FALSE;
if (!_db_fill_events (cl, kls)) return EINA_FALSE;
if (!_db_fill_properties (cl, kls)) return EINA_FALSE;
if (!_db_fill_methods (cl, kls)) return EINA_FALSE;
if (!_db_fill_implements (cl, kls)) return EINA_FALSE;
if (!_db_fill_constructors(cl, kls)) return EINA_FALSE;
if (!_db_fill_events (cl, kls)) return EINA_FALSE;
cl->base = kls->base;
kls->base.file = NULL;

View File

@ -111,13 +111,6 @@ eolian_function_is_class(const Eolian_Function *fid)
return fid->is_class;
}
EAPI Eina_Bool
eolian_function_is_constructing(const Eolian_Function *fid)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE);
return fid->is_constructing;
}
EAPI const Eolian_Function_Parameter *
eolian_function_parameter_get_by_name(const Eolian_Function *fid, const char *param_name)
{

View File

@ -8,51 +8,13 @@ eolian_implement_full_name_get(const Eolian_Implement *impl)
return impl->full_name;
}
/*
* ret false -> clash, class = NULL
* ret true && class -> only one class corresponding
* ret true && !class -> no class corresponding
*/
static Eina_Bool
_class_name_validate(const char *class_name, const Eolian_Class **cl)
{
char *name = strdup(class_name);
char *colon = name + 1;
const Eolian_Class *found_class = NULL;
const Eolian_Class *candidate;
if (cl) *cl = NULL;
do
{
colon = strchr(colon, '.');
if (colon) *colon = '\0';
candidate = eolian_class_get_by_name(name);
if (candidate)
{
if (found_class)
{
ERR("Name clash between class %s and class %s",
candidate->full_name,
found_class->full_name);
free(name);
return EINA_FALSE; // Names clash
}
found_class = candidate;
}
if (colon) *colon++ = '.';
}
while(colon);
if (cl) *cl = found_class;
free(name);
return EINA_TRUE;
}
static Eina_Bool
_fill_class(Eolian_Implement *impl)
{
const Eolian_Class *class = NULL;
if (impl->klass)
return EINA_TRUE;
if (!_class_name_validate(impl->full_name, &class) || !class)
if (!database_class_name_validate(impl->full_name, &class) || !class)
return EINA_FALSE;
impl->klass = class;
return EINA_TRUE;

View File

@ -4,26 +4,40 @@
static void
_implements_print(Eolian_Implement *impl, int nb_spaces)
{
Eolian_Function_Type ft;
const char *t;
Eolian_Function_Type ft = EOLIAN_UNRESOLVED;
eolian_implement_function_get(impl, &ft);
switch (ft)
{
case EOLIAN_PROP_SET: t = "SET"; break;
case EOLIAN_PROP_GET: t = "GET"; break;
case EOLIAN_METHOD: t = "METHOD"; break;
case EOLIAN_UNRESOLVED:
{
t = "Type is the same as function being overriden";
break;
}
case EOLIAN_UNRESOLVED: t = ""; break;
default:
return;
}
printf("%*s <%s> <%s>\n", nb_spaces + 5, "", eolian_implement_full_name_get(impl), t);
}
static void
_constructors_print(Eolian_Constructor *ctor, int nb_spaces)
{
const char *t;
const Eolian_Function *func = eolian_constructor_function_get(ctor);
Eolian_Function_Type ft = eolian_function_type_get(func);
switch (ft)
{
case EOLIAN_PROP_SET: t = "SET"; break;
case EOLIAN_PROP_GET: t = "GET"; break;
case EOLIAN_METHOD: t = "METHOD"; break;
case EOLIAN_UNRESOLVED: t = ""; break;
default:
return;
}
printf("%*s <%s> <%s>\n", nb_spaces + 5, "", eolian_constructor_full_name_get(ctor), t);
}
static void
_event_print(Eolian_Event *ev, int nb_spaces)
{
@ -200,6 +214,8 @@ _class_print(const Eolian_Class *cl)
{
_function_print(function, 4);
}
printf("\n");
// Implement
printf(" implements:\n");
Eolian_Implement *impl;
@ -208,6 +224,16 @@ _class_print(const Eolian_Class *cl)
_implements_print(impl, 4);
}
printf("\n");
// Constructor
printf(" constructors:\n");
Eolian_Constructor *ctor;
EINA_LIST_FOREACH(cl->constructors, itr, ctor)
{
_constructors_print(ctor, 4);
}
printf("\n");
// Implement
printf(" events:\n");
Eolian_Event *ev;
@ -216,6 +242,7 @@ _class_print(const Eolian_Class *cl)
_event_print(ev, 4);
}
printf("\n");
return EINA_TRUE;
}

View File

@ -107,6 +107,7 @@ eo_definitions_class_def_free(Eo_Class_Def *kls)
Eo_Method_Def *meth;
Eolian_Event *sgn;
Eolian_Implement *impl;
Eolian_Constructor *ctor;
if (kls->base.file)
eina_stringshare_del(kls->base.file);
@ -128,6 +129,9 @@ eo_definitions_class_def_free(Eo_Class_Def *kls)
EINA_LIST_FREE(kls->implements, impl)
database_implement_del(impl);
EINA_LIST_FREE(kls->constructors, ctor)
database_constructor_del(ctor);
EINA_LIST_FREE(kls->properties, prop)
eo_definitions_property_def_free(prop);
@ -194,6 +198,9 @@ eo_definitions_temps_free(Eo_Lexer_Temps *tmp)
if (tmp->impl)
database_implement_del(tmp->impl);
if (tmp->ctor)
database_constructor_del(tmp->ctor);
EINA_LIST_FREE(tmp->strs, s)
if (s) eina_stringshare_del(s);
}

View File

@ -64,7 +64,6 @@ typedef struct _Eo_Property_Def
Eina_List *accessors;
int scope;
Eina_Bool is_class:1;
Eina_Bool is_constructing:1;
} Eo_Property_Def;
/* METHOD */
@ -80,7 +79,6 @@ typedef struct _Eo_Method_Def
Eina_Bool obj_const;
int scope;
Eina_Bool is_class:1;
Eina_Bool is_constructing:1;
Eina_Bool only_legacy:1;
} Eo_Method_Def;
@ -98,6 +96,7 @@ typedef struct _Eo_Class_Def
Eina_Stringshare *data_type;
Eina_List *inherits;
Eina_List *implements;
Eina_List *constructors;
Eina_List *events;
Eina_List *properties;
Eina_List *methods;
@ -122,6 +121,7 @@ typedef struct _Eo_Lexer_Temps
Eina_List *str_items;
Eolian_Event *event;
Eolian_Implement *impl;
Eolian_Constructor *ctor;
Eina_List *expr_defs;
Eina_List *strs;
} Eo_Lexer_Temps;

View File

@ -23,14 +23,14 @@ enum Tokens
* they just fill in the "kw" field of the token */
#define KEYWORDS KW(class), KW(const), KW(enum), KW(return), KW(struct), \
\
KW(abstract), KW(constructor), KW(data), KW(destructor), KW(eo), \
KW(eo_prefix), KW(events), KW(free), KW(func), KW(get), KW(implements), \
KW(interface), KW(keys), KW(legacy), KW(legacy_prefix), KW(methods), \
KW(mixin), KW(own), KW(params), KW(properties), KW(set), KW(type), \
KW(values), KW(var), KWAT(auto), KWAT(class), KWAT(const), \
KWAT(constructor), KWAT(empty), KWAT(extern), KWAT(free), KWAT(in), \
KWAT(inout), KWAT(nonull), KWAT(out), KWAT(private), KWAT(protected), \
KWAT(virtual), KWAT(warn_unused), \
KW(abstract), KW(constructor), KW(constructors), KW(data), \
KW(destructor), KW(eo), KW(eo_prefix), KW(events), KW(free), KW(func), \
KW(get), KW(implements), KW(interface), KW(keys), KW(legacy), \
KW(legacy_prefix), KW(methods), KW(mixin), KW(own), KW(params), \
KW(properties), KW(set), KW(type), KW(values), KW(var), KWAT(auto), \
KWAT(class), KWAT(const), KWAT(empty), KWAT(extern), KWAT(free), \
KWAT(in), KWAT(inout), KWAT(nonull), KWAT(out), KWAT(private), \
KWAT(protected), KWAT(virtual), KWAT(warn_unused), \
\
KW(byte), KW(ubyte), KW(char), KW(short), KW(ushort), KW(int), KW(uint), \
KW(long), KW(ulong), KW(llong), KW(ullong), \

View File

@ -1296,8 +1296,7 @@ parse_property(Eo_Lexer *ls)
Eo_Property_Def *prop = NULL;
Eina_Bool has_get = EINA_FALSE, has_set = EINA_FALSE,
has_keys = EINA_FALSE, has_values = EINA_FALSE,
has_protected = EINA_FALSE, has_class = EINA_FALSE,
has_constructor = EINA_FALSE;
has_protected = EINA_FALSE, has_class = EINA_FALSE;
prop = calloc(1, sizeof(Eo_Property_Def));
prop->base.file = eina_stringshare_ref(ls->filename);
prop->base.line = ls->line_number;
@ -1318,11 +1317,6 @@ parse_property(Eo_Lexer *ls)
prop->is_class = EINA_TRUE;
eo_lexer_get(ls);
break;
case KW_at_constructor:
CASE_LOCK(ls, constructor, "constructor qualifier");
eo_lexer_get(ls);
prop->is_constructing = EINA_TRUE;
break;
default:
goto body;
}
@ -1378,7 +1372,7 @@ parse_method(Eo_Lexer *ls, Eina_Bool ctor)
Eina_Bool has_const = EINA_FALSE, has_params = EINA_FALSE,
has_return = EINA_FALSE, has_legacy = EINA_FALSE,
has_protected = EINA_FALSE, has_class = EINA_FALSE,
has_constructor = EINA_FALSE, has_eo = EINA_FALSE;
has_eo = EINA_FALSE;
meth = calloc(1, sizeof(Eo_Method_Def));
meth->base.file = eina_stringshare_ref(ls->filename);
meth->base.line = ls->line_number;
@ -1423,11 +1417,6 @@ parse_method(Eo_Lexer *ls, Eina_Bool ctor)
meth->is_class = EINA_TRUE;
eo_lexer_get(ls);
break;
case KW_at_constructor:
CASE_LOCK(ls, constructor, "constructor qualifier");
meth->is_constructing = EINA_TRUE;
eo_lexer_get(ls);
break;
default:
goto body;
}
@ -1529,7 +1518,10 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
check_next(ls, '.');
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
eo_lexer_syntax_error(ls, "name expected");
impl->full_name = eina_stringshare_add(ls->t.value.s);
if (impl->is_virtual)
impl->full_name = eina_stringshare_ref(ls->t.value.s);
else
impl->full_name = eina_stringshare_printf(".%s", ls->t.value.s);
eo_lexer_get(ls);
if (ls->t.token == '.')
{
@ -1598,6 +1590,46 @@ end:
pop_strbuf(ls);
}
static void
parse_constructor(Eo_Lexer *ls)
{
Eina_Strbuf *buf = NULL;
Eolian_Constructor *ctor = NULL;
ctor = calloc(1, sizeof(Eolian_Implement));
ctor->base.file = eina_stringshare_ref(ls->filename);
ctor->base.line = ls->line_number;
ctor->base.column = ls->column;
ls->tmp.ctor = ctor;
if (ls->t.token == '.')
{
check_next(ls, '.');
if (ls->t.token != TOK_VALUE)
eo_lexer_syntax_error(ls, "name expected");
ctor->full_name = eina_stringshare_printf(".%s", ls->t.value.s);
eo_lexer_get(ls);
check_next(ls, ';');
return;
}
check(ls, TOK_VALUE);
buf = push_strbuf(ls);
eina_strbuf_append(buf, ls->t.value.s);
eo_lexer_get(ls);
check_next(ls, '.');
check(ls, TOK_VALUE);
for (;;)
{
eina_strbuf_append_char(buf, '.');
check(ls, TOK_VALUE);
eina_strbuf_append(buf, ls->t.value.s);
eo_lexer_get(ls);
if (ls->t.token != '.') break;
eo_lexer_get(ls);
}
check_next(ls, ';');
ctor->full_name = eina_stringshare_add(eina_strbuf_string_get(buf));
pop_strbuf(ls);
}
static void
parse_event(Eo_Lexer *ls)
{
@ -1684,6 +1716,19 @@ parse_implements(Eo_Lexer *ls, Eina_Bool iface)
check_match(ls, '}', '{', line, col);
}
static void
parse_constructors(Eo_Lexer *ls)
{
PARSE_SECTION
{
parse_constructor(ls);
ls->tmp.kls->constructors = eina_list_append(ls->tmp.kls->constructors,
ls->tmp.ctor);
ls->tmp.ctor = NULL;
}
check_match(ls, '}', '{', line, col);
}
static void
parse_events(Eo_Lexer *ls)
{
@ -1712,6 +1757,7 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
has_properties = EINA_FALSE,
has_methods = EINA_FALSE,
has_implements = EINA_FALSE,
has_constructors = EINA_FALSE,
has_events = EINA_FALSE;
if (ls->t.token == TOK_COMMENT)
{
@ -1764,6 +1810,12 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
CASE_LOCK(ls, implements, "implements definition")
parse_implements(ls, type == EOLIAN_CLASS_INTERFACE);
break;
case KW_constructors:
if (type == EOLIAN_CLASS_INTERFACE || type == EOLIAN_CLASS_MIXIN)
return;
CASE_LOCK(ls, constructors, "constructors definition")
parse_constructors(ls);
break;
case KW_events:
CASE_LOCK(ls, events, "events definition")
parse_events(ls);

View File

@ -160,6 +160,44 @@ database_class_to_filename(const char *cname)
return ret;
}
/*
* ret false -> clash, class = NULL
* ret true && class -> only one class corresponding
* ret true && !class -> no class corresponding
*/
Eina_Bool
database_class_name_validate(const char *class_name, const Eolian_Class **cl)
{
char *name = strdup(class_name);
char *colon = name + 1;
const Eolian_Class *found_class = NULL;
const Eolian_Class *candidate;
if (cl) *cl = NULL;
do
{
colon = strchr(colon, '.');
if (colon) *colon = '\0';
candidate = eolian_class_get_by_name(name);
if (candidate)
{
if (found_class)
{
ERR("Name clash between class %s and class %s",
candidate->full_name,
found_class->full_name);
free(name);
return EINA_FALSE; // Names clash
}
found_class = candidate;
}
if (colon) *colon++ = '.';
}
while(colon);
if (cl) *cl = found_class;
free(name);
return EINA_TRUE;
}
EAPI Eina_Bool
eolian_eot_file_parse(const char *filepath)
{
@ -177,6 +215,7 @@ eolian_eo_file_parse(const char *filepath)
const Eolian_Class *class = eolian_class_get_by_file(bfilename);
const char *inherit_name;
Eolian_Implement *impl;
Eolian_Constructor *ctor;
Eina_Bool failed_dep = EINA_FALSE;
if (!class)
{
@ -249,6 +288,17 @@ inherits:
}
}
eina_iterator_free(itr);
itr = eolian_class_constructors_get(class);
EINA_ITERATOR_FOREACH(itr, ctor)
{
const Eolian_Function *ctor_func = eolian_constructor_function_get(ctor);
if (!ctor_func)
{
ERR("Unable to find function %s", eolian_constructor_full_name_get(ctor));
goto error;
}
}
eina_iterator_free(itr);
return EINA_TRUE;

View File

@ -78,6 +78,7 @@ struct _Eolian_Class
Eina_List *properties; /* List prop_name -> Eolian_Function */
Eina_List *methods; /* List meth_name -> Eolian_Function */
Eina_List *implements; /* List implements name -> Eolian_Implement */
Eina_List *constructors; /* List constructors name -> Eolian_Constructor */
Eina_List *events; /* List event_name -> Eolian_Event */
Eina_Bool class_ctor_enable:1;
Eina_Bool class_dtor_enable:1;
@ -110,7 +111,6 @@ struct _Eolian_Function
Eina_Bool get_only_legacy: 1;
Eina_Bool set_only_legacy: 1;
Eina_Bool is_class :1;
Eina_Bool is_constructing :1;
};
struct _Eolian_Function_Parameter
@ -168,6 +168,13 @@ struct _Eolian_Implement
Eina_Bool is_empty: 1;
};
struct _Eolian_Constructor
{
Eolian_Object base;
const Eolian_Class *klass;
Eina_Stringshare *full_name;
};
struct _Eolian_Event
{
Eolian_Object base;
@ -270,6 +277,7 @@ int database_shutdown();
char *database_class_to_filename(const char *cname);
Eina_Bool database_validate(void);
Eina_Bool database_class_name_validate(const char *class_name, const Eolian_Class **cl);
/* types */
@ -312,6 +320,10 @@ void database_parameter_del(Eolian_Function_Parameter *pdesc);
void database_implement_del(Eolian_Implement *impl);
/* constructors */
void database_constructor_del(Eolian_Constructor *ctor);
/* events */
Eolian_Event *database_event_new(const char *event_name, const char *event_type, const char *event_desc);

View File

@ -3,7 +3,7 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
legacy_prefix: null;
data: Evas_3D_Node_Data;
methods {
constructor @constructor {
constructor {
/*@ Constructor. */
legacy: null;
params {
@ -582,4 +582,7 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
Evas_3D_Object.update_notify;
Evas_3D_Object.change_notify;
}
constructors {
.constructor;
}
}

View File

@ -1,6 +1,6 @@
class Base {
methods {
constructor @constructor {
constructor {
}
destructor {
}
@ -8,4 +8,7 @@ class Base {
implements {
@virtual .constructor;
}
constructors {
.constructor;
}
}

View File

@ -1,12 +1,12 @@
class Ctor_Dtor (Base) {
methods {
custom_constructor_1 @constructor {
custom_constructor_1 {
params {
@in int a;
@in char b;
}
}
custom_constructor_2 @constructor {
custom_constructor_2 {
}
}
implements {
@ -15,4 +15,8 @@ class Ctor_Dtor (Base) {
Base.constructor;
Base.destructor;
}
constructors {
.custom_constructor_1;
.custom_constructor_2;
}
}

View File

@ -26,13 +26,13 @@ class Object_Impl (Base) {
}
}
methods {
constructor_1 @constructor {
constructor_1 {
params {
@in int a;
@in char b;
}
}
constructor_2 @constructor {
constructor_2 {
}
foo1 {
/*@ comment foo */
@ -62,4 +62,8 @@ class Object_Impl (Base) {
@virtual .pure_foo3;
@virtual .b.get;
}
constructors {
.constructor_1;
.constructor_2;
}
}

View File

@ -208,6 +208,7 @@ START_TEST(eolian_ctor_dtor)
const Eolian_Function *impl_func = NULL;
const Eolian_Class *class, *base;
const Eolian_Implement *impl;
const Eolian_Constructor *ctor;
void *dummy;
eolian_init();
@ -237,13 +238,20 @@ START_TEST(eolian_ctor_dtor)
eina_iterator_free(iter);
/* Custom ctors/dtors */
fail_if(!(impl_func = eolian_class_function_get_by_name(base, "constructor", EOLIAN_METHOD)));
fail_if(!eolian_function_is_constructing(impl_func));
fail_if(!eolian_class_function_get_by_name(base, "destructor", EOLIAN_METHOD));
fail_if(!(impl_func = eolian_class_function_get_by_name(class, "custom_constructor_1", EOLIAN_METHOD)));
fail_if(!eolian_function_is_constructing(impl_func));
fail_if(!(impl_func = eolian_class_function_get_by_name(class, "custom_constructor_2", EOLIAN_METHOD)));
fail_if(!eolian_function_is_constructing(impl_func));
fail_if(!(iter = eolian_class_constructors_get(class)));
fail_if(!(eina_iterator_next(iter, (void**)&ctor)));
fail_if(!(impl_class = eolian_constructor_class_get(ctor)));
fail_if(!(impl_func = eolian_constructor_function_get(ctor)));
fail_if(impl_class != class);
fail_if(strcmp(eolian_function_name_get(impl_func), "custom_constructor_1"));
fail_if(!(eina_iterator_next(iter, (void**)&ctor)));
fail_if(!(impl_class = eolian_constructor_class_get(ctor)));
fail_if(!(impl_func = eolian_constructor_function_get(ctor)));
fail_if(impl_class != class);
fail_if(strcmp(eolian_function_name_get(impl_func), "custom_constructor_2"));
fail_if(eina_iterator_next(iter, &dummy));
eina_iterator_free(iter);
eolian_shutdown();
}

View File

@ -3,15 +3,15 @@ class Callback (Eo.Base)
legacy_prefix: null;
data: Callback_Data;
methods {
default_constructor @constructor {
default_constructor {
}
constructor @constructor {
constructor {
params {
@in Ecore_Cb cb;
@in void* data;
}
}
constructor2 @constructor {
constructor2 {
params {
@in Ecore_Cb cb;
@in void* data;
@ -32,6 +32,11 @@ class Callback (Eo.Base)
}
}
}
constructors {
.default_constructor;
.constructor;
.constructor2;
}
events {
call_on_add;
}