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_type_api.c \
lib/eolian/database_implement.c \ lib/eolian/database_implement.c \
lib/eolian/database_implement_api.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.c \
lib/eolian/database_event_api.c \ lib/eolian/database_event_api.c \
lib/eolian/database_print.c \ lib/eolian/database_print.c \

View File

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

View File

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

View File

@ -2,7 +2,7 @@ class Ecore.Animator (Eo.Base)
{ {
eo_prefix: ecore_animator; eo_prefix: ecore_animator;
methods { methods {
timeline_constructor @constructor { timeline_constructor {
/*@ Constructor. */ /*@ Constructor. */
legacy: null; legacy: null;
params { params {
@ -11,7 +11,7 @@ class Ecore.Animator (Eo.Base)
@in const(void)* data; @in const(void)* data;
} }
} }
constructor @constructor { constructor {
/*@ Constructor. */ /*@ Constructor. */
legacy: null; legacy: null;
params { params {
@ -26,4 +26,8 @@ class Ecore.Animator (Eo.Base)
Eo.Base.event_freeze; Eo.Base.event_freeze;
Eo.Base.event_thaw; 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; eo_prefix: ecore_obj_exe;
properties { properties {
command @constructor { command {
/*@ Control the command that's executed. FIXME: May need a split/rename. */ /*@ Control the command that's executed. FIXME: May need a split/rename. */
set { set {
legacy: null; legacy: null;
@ -24,6 +24,9 @@ class Ecore.Exe (Eo.Base, Efl.Control)
Eo.Base.finalize; Eo.Base.finalize;
Efl.Control.suspend.set; Efl.Control.suspend.set;
} }
constructors {
.command;
}
events { events {
data,get: Ecore_Exe_Event_Data; data,get: Ecore_Exe_Event_Data;
data,error: 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; eo_prefix: ecore_idle_enterer;
methods { methods {
before_constructor @constructor { before_constructor {
/*@ Contructor. Will insert the handler at the beginning of the list. */ /*@ Contructor. Will insert the handler at the beginning of the list. */
legacy: null; legacy: null;
params { params {
@ -10,7 +10,7 @@ class Ecore.Idle.Enterer (Eo.Base)
@in const(void)* data; @in const(void)* data;
} }
} }
after_constructor @constructor { after_constructor {
/*@ Contructor. Will insert the handler at the end of the list. */ /*@ Contructor. Will insert the handler at the end of the list. */
legacy: null; legacy: null;
params { params {
@ -23,4 +23,8 @@ class Ecore.Idle.Enterer (Eo.Base)
Eo.Base.constructor; Eo.Base.constructor;
Eo.Base.destructor; 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; eo_prefix: ecore_idle_exiter;
methods { methods {
constructor @constructor { constructor {
/*@ Constructor. */ /*@ Constructor. */
legacy: null; legacy: null;
params { params {
@ -15,4 +15,7 @@ class Ecore.Idle.Exiter (Eo.Base)
Eo.Base.constructor; Eo.Base.constructor;
Eo.Base.destructor; Eo.Base.destructor;
} }
constructors {
.constructor;
}
} }

View File

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

View File

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

View File

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

View File

@ -30,7 +30,7 @@ class Ecore.Timer (Eo.Base)
} }
} }
methods { methods {
loop_constructor @constructor { loop_constructor {
/*@ Create a timer to call in a given time from now */ /*@ Create a timer to call in a given time from now */
legacy: null; legacy: null;
params { 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 */ @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 */ /*@ Create a timer to call in a given time from when the mainloop woke up from sleep */
legacy: null; legacy: null;
params { params {
@ -100,5 +100,9 @@ class Ecore.Timer (Eo.Base)
* *
* @see ecore_timer_freeze() * @see ecore_timer_freeze()
*/ */
} }
constructors {
.constructor;
.loop_constructor;
}
} }

View File

@ -44,7 +44,7 @@ Return event freeze count. */
} }
} }
methods { methods {
constructor @constructor { constructor {
/*@ Call the object's constructor. /*@ Call the object's constructor.
Should not be used with #eo_do. Only use it with #eo_do_super. */ Should not be used with #eo_do. Only use it with #eo_do_super. */
legacy: null; legacy: null;
@ -178,6 +178,9 @@ callbacks of the same priority are called in reverse order of creation. */
class.constructor; class.constructor;
class.destructor; class.destructor;
} }
constructors {
.constructor;
}
events { events {
callback,add; /*@ A callback was added. */ callback,add; /*@ A callback was added. */
callback,del; /*@ A callback was deleted. */ 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; typedef struct _Eolian_Implement Eolian_Implement;
/* Class constructor information
*
* @ingroup Eolian
*/
typedef struct _Eolian_Constructor Eolian_Constructor;
/* Event information /* Event information
* *
* @ingroup Eolian * @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); 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. * @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); 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. * @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); 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->methods, fid) database_function_del(fid);
EINA_LIST_FREE(cl->properties, 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); 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); return (cl->inherits ? eina_list_iterator_new(cl->inherits) : NULL);
} }
EAPI Eina_Iterator* EAPI Eina_Iterator *
eolian_class_implements_get(const Eolian_Class *cl) eolian_class_implements_get(const Eolian_Class *cl)
{ {
EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
return (cl->implements ? eina_list_iterator_new(cl->implements) : 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 * EAPI const Eolian_Function *
eolian_class_function_get_by_name(const Eolian_Class *cl, const char *func_name, Eolian_Function_Type f_type) 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->scope = prop->scope;
foo_id->is_class = prop->is_class; 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->keys , &(foo_id->keys ))) goto failure;
if (!_db_fill_params (prop->values, &(foo_id->params))) 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->get_legacy = eina_stringshare_ref(meth->legacy);
foo_id->obj_is_const = meth->obj_const; foo_id->obj_is_const = meth->obj_const;
foo_id->is_class = meth->is_class; foo_id->is_class = meth->is_class;
foo_id->is_constructing = meth->is_constructing;
if (meth->only_legacy) if (meth->only_legacy)
foo_id->get_only_legacy = EINA_TRUE; foo_id->get_only_legacy = EINA_TRUE;
@ -297,6 +295,35 @@ _db_fill_implements(Eolian_Class *cl, Eo_Class_Def *kls)
return EINA_TRUE; 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 static Eina_Bool
_db_fill_events(Eolian_Class *cl, Eo_Class_Def *kls) _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) if (kls->data_type)
cl->data_type = eina_stringshare_ref(kls->data_type); cl->data_type = eina_stringshare_ref(kls->data_type);
if (!_db_fill_properties(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_methods (cl, kls)) return EINA_FALSE;
if (!_db_fill_implements(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_constructors(cl, kls)) return EINA_FALSE;
if (!_db_fill_events (cl, kls)) return EINA_FALSE;
cl->base = kls->base; cl->base = kls->base;
kls->base.file = NULL; kls->base.file = NULL;

View File

@ -111,13 +111,6 @@ eolian_function_is_class(const Eolian_Function *fid)
return fid->is_class; 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 * EAPI const Eolian_Function_Parameter *
eolian_function_parameter_get_by_name(const Eolian_Function *fid, const char *param_name) 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; 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 static Eina_Bool
_fill_class(Eolian_Implement *impl) _fill_class(Eolian_Implement *impl)
{ {
const Eolian_Class *class = NULL; const Eolian_Class *class = NULL;
if (impl->klass) if (impl->klass)
return EINA_TRUE; 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; return EINA_FALSE;
impl->klass = class; impl->klass = class;
return EINA_TRUE; return EINA_TRUE;

View File

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

View File

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

View File

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

View File

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

View File

@ -1296,8 +1296,7 @@ parse_property(Eo_Lexer *ls)
Eo_Property_Def *prop = NULL; Eo_Property_Def *prop = NULL;
Eina_Bool has_get = EINA_FALSE, has_set = EINA_FALSE, Eina_Bool has_get = EINA_FALSE, has_set = EINA_FALSE,
has_keys = EINA_FALSE, has_values = EINA_FALSE, has_keys = EINA_FALSE, has_values = EINA_FALSE,
has_protected = EINA_FALSE, has_class = EINA_FALSE, has_protected = EINA_FALSE, has_class = EINA_FALSE;
has_constructor = EINA_FALSE;
prop = calloc(1, sizeof(Eo_Property_Def)); prop = calloc(1, sizeof(Eo_Property_Def));
prop->base.file = eina_stringshare_ref(ls->filename); prop->base.file = eina_stringshare_ref(ls->filename);
prop->base.line = ls->line_number; prop->base.line = ls->line_number;
@ -1318,11 +1317,6 @@ parse_property(Eo_Lexer *ls)
prop->is_class = EINA_TRUE; prop->is_class = EINA_TRUE;
eo_lexer_get(ls); eo_lexer_get(ls);
break; break;
case KW_at_constructor:
CASE_LOCK(ls, constructor, "constructor qualifier");
eo_lexer_get(ls);
prop->is_constructing = EINA_TRUE;
break;
default: default:
goto body; goto body;
} }
@ -1378,7 +1372,7 @@ parse_method(Eo_Lexer *ls, Eina_Bool ctor)
Eina_Bool has_const = EINA_FALSE, has_params = EINA_FALSE, Eina_Bool has_const = EINA_FALSE, has_params = EINA_FALSE,
has_return = EINA_FALSE, has_legacy = EINA_FALSE, has_return = EINA_FALSE, has_legacy = EINA_FALSE,
has_protected = EINA_FALSE, has_class = 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 = calloc(1, sizeof(Eo_Method_Def));
meth->base.file = eina_stringshare_ref(ls->filename); meth->base.file = eina_stringshare_ref(ls->filename);
meth->base.line = ls->line_number; meth->base.line = ls->line_number;
@ -1423,11 +1417,6 @@ parse_method(Eo_Lexer *ls, Eina_Bool ctor)
meth->is_class = EINA_TRUE; meth->is_class = EINA_TRUE;
eo_lexer_get(ls); eo_lexer_get(ls);
break; break;
case KW_at_constructor:
CASE_LOCK(ls, constructor, "constructor qualifier");
meth->is_constructing = EINA_TRUE;
eo_lexer_get(ls);
break;
default: default:
goto body; goto body;
} }
@ -1529,7 +1518,10 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
check_next(ls, '.'); check_next(ls, '.');
if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set)) if ((ls->t.token != TOK_VALUE) || (ls->t.kw == KW_get || ls->t.kw == KW_set))
eo_lexer_syntax_error(ls, "name expected"); 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); eo_lexer_get(ls);
if (ls->t.token == '.') if (ls->t.token == '.')
{ {
@ -1598,6 +1590,46 @@ end:
pop_strbuf(ls); 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 static void
parse_event(Eo_Lexer *ls) parse_event(Eo_Lexer *ls)
{ {
@ -1684,6 +1716,19 @@ parse_implements(Eo_Lexer *ls, Eina_Bool iface)
check_match(ls, '}', '{', line, col); 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 static void
parse_events(Eo_Lexer *ls) parse_events(Eo_Lexer *ls)
{ {
@ -1712,6 +1757,7 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
has_properties = EINA_FALSE, has_properties = EINA_FALSE,
has_methods = EINA_FALSE, has_methods = EINA_FALSE,
has_implements = EINA_FALSE, has_implements = EINA_FALSE,
has_constructors = EINA_FALSE,
has_events = EINA_FALSE; has_events = EINA_FALSE;
if (ls->t.token == TOK_COMMENT) 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") CASE_LOCK(ls, implements, "implements definition")
parse_implements(ls, type == EOLIAN_CLASS_INTERFACE); parse_implements(ls, type == EOLIAN_CLASS_INTERFACE);
break; 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 KW_events:
CASE_LOCK(ls, events, "events definition") CASE_LOCK(ls, events, "events definition")
parse_events(ls); parse_events(ls);

View File

@ -160,6 +160,44 @@ database_class_to_filename(const char *cname)
return ret; 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 EAPI Eina_Bool
eolian_eot_file_parse(const char *filepath) 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 Eolian_Class *class = eolian_class_get_by_file(bfilename);
const char *inherit_name; const char *inherit_name;
Eolian_Implement *impl; Eolian_Implement *impl;
Eolian_Constructor *ctor;
Eina_Bool failed_dep = EINA_FALSE; Eina_Bool failed_dep = EINA_FALSE;
if (!class) if (!class)
{ {
@ -249,6 +288,17 @@ inherits:
} }
} }
eina_iterator_free(itr); 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; return EINA_TRUE;

View File

@ -78,6 +78,7 @@ struct _Eolian_Class
Eina_List *properties; /* List prop_name -> Eolian_Function */ Eina_List *properties; /* List prop_name -> Eolian_Function */
Eina_List *methods; /* List meth_name -> Eolian_Function */ Eina_List *methods; /* List meth_name -> Eolian_Function */
Eina_List *implements; /* List implements name -> Eolian_Implement */ 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_List *events; /* List event_name -> Eolian_Event */
Eina_Bool class_ctor_enable:1; Eina_Bool class_ctor_enable:1;
Eina_Bool class_dtor_enable:1; Eina_Bool class_dtor_enable:1;
@ -110,7 +111,6 @@ struct _Eolian_Function
Eina_Bool get_only_legacy: 1; Eina_Bool get_only_legacy: 1;
Eina_Bool set_only_legacy: 1; Eina_Bool set_only_legacy: 1;
Eina_Bool is_class :1; Eina_Bool is_class :1;
Eina_Bool is_constructing :1;
}; };
struct _Eolian_Function_Parameter struct _Eolian_Function_Parameter
@ -168,6 +168,13 @@ struct _Eolian_Implement
Eina_Bool is_empty: 1; Eina_Bool is_empty: 1;
}; };
struct _Eolian_Constructor
{
Eolian_Object base;
const Eolian_Class *klass;
Eina_Stringshare *full_name;
};
struct _Eolian_Event struct _Eolian_Event
{ {
Eolian_Object base; Eolian_Object base;
@ -270,6 +277,7 @@ int database_shutdown();
char *database_class_to_filename(const char *cname); char *database_class_to_filename(const char *cname);
Eina_Bool database_validate(void); Eina_Bool database_validate(void);
Eina_Bool database_class_name_validate(const char *class_name, const Eolian_Class **cl);
/* types */ /* types */
@ -312,6 +320,10 @@ void database_parameter_del(Eolian_Function_Parameter *pdesc);
void database_implement_del(Eolian_Implement *impl); void database_implement_del(Eolian_Implement *impl);
/* constructors */
void database_constructor_del(Eolian_Constructor *ctor);
/* events */ /* events */
Eolian_Event *database_event_new(const char *event_name, const char *event_type, const char *event_desc); 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; legacy_prefix: null;
data: Evas_3D_Node_Data; data: Evas_3D_Node_Data;
methods { methods {
constructor @constructor { constructor {
/*@ Constructor. */ /*@ Constructor. */
legacy: null; legacy: null;
params { params {
@ -582,4 +582,7 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
Evas_3D_Object.update_notify; Evas_3D_Object.update_notify;
Evas_3D_Object.change_notify; Evas_3D_Object.change_notify;
} }
constructors {
.constructor;
}
} }

View File

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

View File

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

View File

@ -26,13 +26,13 @@ class Object_Impl (Base) {
} }
} }
methods { methods {
constructor_1 @constructor { constructor_1 {
params { params {
@in int a; @in int a;
@in char b; @in char b;
} }
} }
constructor_2 @constructor { constructor_2 {
} }
foo1 { foo1 {
/*@ comment foo */ /*@ comment foo */
@ -62,4 +62,8 @@ class Object_Impl (Base) {
@virtual .pure_foo3; @virtual .pure_foo3;
@virtual .b.get; @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_Function *impl_func = NULL;
const Eolian_Class *class, *base; const Eolian_Class *class, *base;
const Eolian_Implement *impl; const Eolian_Implement *impl;
const Eolian_Constructor *ctor;
void *dummy; void *dummy;
eolian_init(); eolian_init();
@ -237,13 +238,20 @@ START_TEST(eolian_ctor_dtor)
eina_iterator_free(iter); eina_iterator_free(iter);
/* Custom ctors/dtors */ /* 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(!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(!(iter = eolian_class_constructors_get(class)));
fail_if(!eolian_function_is_constructing(impl_func)); fail_if(!(eina_iterator_next(iter, (void**)&ctor)));
fail_if(!(impl_func = eolian_class_function_get_by_name(class, "custom_constructor_2", EOLIAN_METHOD))); fail_if(!(impl_class = eolian_constructor_class_get(ctor)));
fail_if(!eolian_function_is_constructing(impl_func)); 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(); eolian_shutdown();
} }

View File

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