forked from enlightenment/efl
Merge branch 'master' of ssh://git.enlightenment.org/core/efl
This commit is contained in:
commit
e56199b626
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
@ -101,4 +101,8 @@ class Ecore.Timer (Eo.Base)
|
|||
* @see ecore_timer_freeze()
|
||||
*/
|
||||
}
|
||||
constructors {
|
||||
.constructor;
|
||||
.loop_constructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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,9 +361,10 @@ _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_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_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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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), \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Base {
|
||||
methods {
|
||||
constructor @constructor {
|
||||
constructor {
|
||||
}
|
||||
destructor {
|
||||
}
|
||||
|
@ -8,4 +8,7 @@ class Base {
|
|||
implements {
|
||||
@virtual .constructor;
|
||||
}
|
||||
constructors {
|
||||
.constructor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue