diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am index 3d77be6a24..be2eb260c7 100644 --- a/src/Makefile_Eolian.am +++ b/src/Makefile_Eolian.am @@ -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 \ diff --git a/src/examples/eolian_cxx/colourable.eo b/src/examples/eolian_cxx/colourable.eo index 342790c9b3..a2623877da 100644 --- a/src/examples/eolian_cxx/colourable.eo +++ b/src/examples/eolian_cxx/colourable.eo @@ -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; } diff --git a/src/examples/eolian_cxx/colourablesquare.eo b/src/examples/eolian_cxx/colourablesquare.eo index 1d12862601..f21f7b43f2 100644 --- a/src/examples/eolian_cxx/colourablesquare.eo +++ b/src/examples/eolian_cxx/colourablesquare.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_animator.eo b/src/lib/ecore/ecore_animator.eo index a0f0cfe637..81ed666ec1 100644 --- a/src/lib/ecore/ecore_animator.eo +++ b/src/lib/ecore/ecore_animator.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_exe.eo b/src/lib/ecore/ecore_exe.eo index dcb624c94c..618595d324 100644 --- a/src/lib/ecore/ecore_exe.eo +++ b/src/lib/ecore/ecore_exe.eo @@ -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; diff --git a/src/lib/ecore/ecore_idle_enterer.eo b/src/lib/ecore/ecore_idle_enterer.eo index 8250d50ad8..f28ca7eba2 100644 --- a/src/lib/ecore/ecore_idle_enterer.eo +++ b/src/lib/ecore/ecore_idle_enterer.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_idle_exiter.eo b/src/lib/ecore/ecore_idle_exiter.eo index 711ece68c2..22602ccaef 100644 --- a/src/lib/ecore/ecore_idle_exiter.eo +++ b/src/lib/ecore/ecore_idle_exiter.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_idler.eo b/src/lib/ecore/ecore_idler.eo index e071567a95..db6927742e 100644 --- a/src/lib/ecore/ecore_idler.eo +++ b/src/lib/ecore/ecore_idler.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_job.eo b/src/lib/ecore/ecore_job.eo index fdd5cb2bac..2bc9d68b5c 100644 --- a/src/lib/ecore/ecore_job.eo +++ b/src/lib/ecore/ecore_job.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_poller.eo b/src/lib/ecore/ecore_poller.eo index 4dcf71454e..c08a6055fd 100644 --- a/src/lib/ecore/ecore_poller.eo +++ b/src/lib/ecore/ecore_poller.eo @@ -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; + } } diff --git a/src/lib/ecore/ecore_timer.eo b/src/lib/ecore/ecore_timer.eo index f83290adce..165487a4ca 100644 --- a/src/lib/ecore/ecore_timer.eo +++ b/src/lib/ecore/ecore_timer.eo @@ -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; + } } diff --git a/src/lib/eo/eo_base.eo b/src/lib/eo/eo_base.eo index 37ba6c73c2..b76b45b89f 100644 --- a/src/lib/eo/eo_base.eo +++ b/src/lib/eo/eo_base.eo @@ -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. */ diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index 4996315186..9cf640a22c 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -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. * diff --git a/src/lib/eolian/database_class.c b/src/lib/eolian/database_class.c index 79999a999f..1c6ff14e63 100644 --- a/src/lib/eolian/database_class.c +++ b/src/lib/eolian/database_class.c @@ -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); diff --git a/src/lib/eolian/database_class_api.c b/src/lib/eolian/database_class_api.c index d624c27231..c48d98fe9e 100644 --- a/src/lib/eolian/database_class_api.c +++ b/src/lib/eolian/database_class_api.c @@ -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) { diff --git a/src/lib/eolian/database_constructor.c b/src/lib/eolian/database_constructor.c new file mode 100644 index 0000000000..dca1b3bea7 --- /dev/null +++ b/src/lib/eolian/database_constructor.c @@ -0,0 +1,11 @@ +#include +#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); +} diff --git a/src/lib/eolian/database_constructor_api.c b/src/lib/eolian/database_constructor_api.c new file mode 100644 index 0000000000..a528bfdd49 --- /dev/null +++ b/src/lib/eolian/database_constructor_api.c @@ -0,0 +1,41 @@ +#include +#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); +} diff --git a/src/lib/eolian/database_fill.c b/src/lib/eolian/database_fill.c index 1d29fa8eea..dbcade782b 100644 --- a/src/lib/eolian/database_fill.c +++ b/src/lib/eolian/database_fill.c @@ -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; diff --git a/src/lib/eolian/database_function_api.c b/src/lib/eolian/database_function_api.c index ecd1853393..d467eaf237 100644 --- a/src/lib/eolian/database_function_api.c +++ b/src/lib/eolian/database_function_api.c @@ -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) { diff --git a/src/lib/eolian/database_implement_api.c b/src/lib/eolian/database_implement_api.c index 38cdd26b2b..b0bdce2b7d 100644 --- a/src/lib/eolian/database_implement_api.c +++ b/src/lib/eolian/database_implement_api.c @@ -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; diff --git a/src/lib/eolian/database_print.c b/src/lib/eolian/database_print.c index ef48abefa2..6a5f0c118b 100644 --- a/src/lib/eolian/database_print.c +++ b/src/lib/eolian/database_print.c @@ -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; } diff --git a/src/lib/eolian/eo_definitions.c b/src/lib/eolian/eo_definitions.c index 34cd5bfbc5..facd8833a7 100644 --- a/src/lib/eolian/eo_definitions.c +++ b/src/lib/eolian/eo_definitions.c @@ -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); } diff --git a/src/lib/eolian/eo_definitions.h b/src/lib/eolian/eo_definitions.h index ad5048475a..533e0bd31a 100644 --- a/src/lib/eolian/eo_definitions.h +++ b/src/lib/eolian/eo_definitions.h @@ -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; diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index 432cef83b0..18b215e36b 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -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), \ diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 350c36054e..370ae25c04 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -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); diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c index 0c4da9c33a..3ef0955efa 100644 --- a/src/lib/eolian/eolian_database.c +++ b/src/lib/eolian/eolian_database.c @@ -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; diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index e72e1352c4..ba4cb7b194 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -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); diff --git a/src/lib/evas/canvas/evas_3d_node.eo b/src/lib/evas/canvas/evas_3d_node.eo index b4c47035a8..ec862e1a6d 100644 --- a/src/lib/evas/canvas/evas_3d_node.eo +++ b/src/lib/evas/canvas/evas_3d_node.eo @@ -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; + } } diff --git a/src/tests/eolian/data/base.eo b/src/tests/eolian/data/base.eo index 4527e83477..59560142c8 100644 --- a/src/tests/eolian/data/base.eo +++ b/src/tests/eolian/data/base.eo @@ -1,6 +1,6 @@ class Base { methods { - constructor @constructor { + constructor { } destructor { } @@ -8,4 +8,7 @@ class Base { implements { @virtual .constructor; } + constructors { + .constructor; + } } diff --git a/src/tests/eolian/data/ctor_dtor.eo b/src/tests/eolian/data/ctor_dtor.eo index 9a1d031e77..e1b6cfc66d 100644 --- a/src/tests/eolian/data/ctor_dtor.eo +++ b/src/tests/eolian/data/ctor_dtor.eo @@ -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; + } } diff --git a/src/tests/eolian/data/object_impl.eo b/src/tests/eolian/data/object_impl.eo index bec9d8f89f..b65efda6d6 100644 --- a/src/tests/eolian/data/object_impl.eo +++ b/src/tests/eolian/data/object_impl.eo @@ -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; + } } diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index a90395a8ba..4010fddf1a 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -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(); } diff --git a/src/tests/eolian_cxx/callback.eo b/src/tests/eolian_cxx/callback.eo index 24cfa729ff..a22885e4d3 100644 --- a/src/tests/eolian_cxx/callback.eo +++ b/src/tests/eolian_cxx/callback.eo @@ -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; }