summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2018-01-30 14:01:40 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2018-01-30 17:08:44 +0100
commit7b643f6919529f24d1094d3484a44cc197603b33 (patch)
treebdba505b0463b0cd107a8754f2d9fd0952295ca7
parentc950b17a57f5bc59ad6e27fbc98f63759b81e25f (diff)
downloadefl-7b643f6919529f24d1094d3484a44cc197603b33.tar.gz
eolian: move impl/ctor fill to validation stage
-rw-r--r--src/lib/eolian/database_validate.c218
-rw-r--r--src/lib/eolian/eo_parser.c217
2 files changed, 218 insertions, 217 deletions
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index 1ba1dfd638..2f316fc653 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -433,6 +433,217 @@ _validate_event(const Eolian_Unit *src, Eolian_Event *event)
return _validate(&event->base);
}
+const Eolian_Class *
+_get_impl_class(const Eolian_Class *cl, const char *cln)
+{
+ if (!cl || !strcmp(cl->full_name, cln))
+ return cl;
+ Eina_List *l;
+ Eolian_Class *icl;
+ EINA_LIST_FOREACH(cl->inherits, l, icl)
+ {
+ /* we can do a depth first search, it's easier and doesn't matter
+ * which part of the inheritance tree we find the class in
+ */
+ const Eolian_Class *fcl = _get_impl_class(icl, cln);
+ if (fcl)
+ return fcl;
+ }
+ return NULL;
+}
+
+#define _eo_parser_log(_base, ...) \
+ _eolian_log_line((_base)->file, (_base)->line, (_base)->column, __VA_ARGS__)
+
+static Eina_Bool
+_db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
+{
+ Eolian_Function_Type ftype = EOLIAN_METHOD;
+
+ if (impl->is_prop_get && impl->is_prop_set)
+ ftype = EOLIAN_PROPERTY;
+ else if (impl->is_prop_get)
+ ftype = EOLIAN_PROP_GET;
+ else if (impl->is_prop_set)
+ ftype = EOLIAN_PROP_SET;
+
+ size_t imlen = strlen(impl->full_name);
+ char *clbuf = alloca(imlen + 1);
+ memcpy(clbuf, impl->full_name, imlen + 1);
+
+ char *ldot = strrchr(clbuf, '.');
+ if (!ldot)
+ return EINA_FALSE; /* unreachable in practice, for static analysis */
+
+ *ldot = '\0'; /* split between class name and func name */
+ const char *clname = clbuf;
+ const char *fnname = ldot + 1;
+
+ const Eolian_Class *tcl = _get_impl_class(cl, clname);
+ if (!tcl)
+ {
+ _eo_parser_log(&impl->base, "class '%s' not found within the inheritance tree of '%s'",
+ clname, cl->full_name);
+ return EINA_FALSE;
+ }
+
+ impl->klass = tcl;
+
+ const Eolian_Function *fid = eolian_class_function_get_by_name(tcl, fnname, EOLIAN_UNRESOLVED);
+ if (!fid)
+ {
+ _eo_parser_log(&impl->base, "function '%s' not known in class '%s'", fnname, clname);
+ return EINA_FALSE;
+ }
+
+ Eolian_Function_Type aftype = eolian_function_type_get(fid);
+
+ Eina_Bool auto_empty = (impl->get_auto || impl->get_empty);
+
+ /* match implement type against function type */
+ if (ftype == EOLIAN_PROPERTY)
+ {
+ /* property */
+ if (aftype != EOLIAN_PROPERTY)
+ {
+ _eo_parser_log(&impl->base, "function '%s' is not a complete property", fnname);
+ return EINA_FALSE;
+ }
+ auto_empty = auto_empty && (impl->set_auto || impl->set_empty);
+ }
+ else if (ftype == EOLIAN_PROP_SET)
+ {
+ /* setter */
+ if ((aftype != EOLIAN_PROP_SET) && (aftype != EOLIAN_PROPERTY))
+ {
+ _eo_parser_log(&impl->base, "function '%s' doesn't have a setter", fnname);
+ return EINA_FALSE;
+ }
+ auto_empty = (impl->set_auto || impl->set_empty);
+ }
+ else if (ftype == EOLIAN_PROP_GET)
+ {
+ /* getter */
+ if ((aftype != EOLIAN_PROP_GET) && (aftype != EOLIAN_PROPERTY))
+ {
+ _eo_parser_log(&impl->base, "function '%s' doesn't have a getter", fnname);
+ return EINA_FALSE;
+ }
+ }
+ else if (aftype != EOLIAN_METHOD)
+ {
+ _eo_parser_log(&impl->base, "function '%s' is not a method", fnname);
+ return EINA_FALSE;
+ }
+
+ if ((fid->klass == cl) && !auto_empty)
+ {
+ /* only allow explicit implements from other classes, besides auto and
+ * empty... also prevents pure virtuals from being implemented
+ */
+ _eo_parser_log(&impl->base, "invalid implement '%s'", impl->full_name);
+ return EINA_FALSE;
+ }
+
+ impl->foo_id = fid;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_db_fill_implements(Eolian_Class *cl)
+{
+ Eolian_Implement *impl;
+ Eina_List *l;
+
+ Eina_Bool ret = EINA_TRUE;
+
+ Eina_Hash *th = eina_hash_string_small_new(NULL),
+ *pth = eina_hash_string_small_new(NULL);
+ EINA_LIST_FOREACH(cl->implements, l, impl)
+ {
+ Eina_Bool prop = (impl->is_prop_get || impl->is_prop_set);
+ if (eina_hash_find(prop ? pth : th, impl->full_name))
+ {
+ _eo_parser_log(&impl->base, "duplicate implement '%s'", impl->full_name);
+ ret = EINA_FALSE;
+ goto end;
+ }
+ if (impl->klass != cl)
+ {
+ if (!_db_fill_implement(cl, impl))
+ {
+ ret = EINA_FALSE;
+ goto end;
+ }
+ if (eolian_function_is_constructor(impl->foo_id, impl->klass))
+ database_function_constructor_add((Eolian_Function *)impl->foo_id, cl);
+ }
+ if ((impl->klass != cl) && !_db_fill_implement(cl, impl))
+ {
+ ret = EINA_FALSE;
+ goto end;
+ }
+ eina_hash_add(prop ? pth : th, impl->full_name, impl->full_name);
+ }
+
+end:
+ eina_hash_free(th);
+ eina_hash_free(pth);
+ return ret;
+}
+
+static Eina_Bool
+_db_fill_ctors(Eolian_Class *cl)
+{
+ Eolian_Constructor *ctor;
+ Eina_List *l;
+
+ Eina_Bool ret = EINA_TRUE;
+
+ Eina_Hash *th = eina_hash_string_small_new(NULL);
+ EINA_LIST_FOREACH(cl->constructors, l, ctor)
+ {
+ if (eina_hash_find(th, ctor->full_name))
+ {
+ _eo_parser_log(&ctor->base, "duplicate ctor '%s'", ctor->full_name);
+ ret = EINA_FALSE;
+ goto end;
+ }
+ const char *ldot = strrchr(ctor->full_name, '.');
+ if (!ldot)
+ {
+ ret = EINA_FALSE;
+ goto end;
+ }
+ char *cnbuf = alloca(ldot - ctor->full_name + 1);
+ memcpy(cnbuf, ctor->full_name, ldot - ctor->full_name);
+ cnbuf[ldot - ctor->full_name] = '\0';
+ const Eolian_Class *tcl = _get_impl_class(cl, cnbuf);
+ if (!tcl)
+ {
+ _eo_parser_log(&ctor->base, "class '%s' not found within the inheritance tree of '%s'",
+ cnbuf, cl->full_name);
+ ret = EINA_FALSE;
+ goto end;
+ }
+ ctor->klass = tcl;
+ const Eolian_Function *cfunc = eolian_constructor_function_get(ctor);
+ if (!cfunc)
+ {
+ _eo_parser_log(&ctor->base, "unable to find function '%s'", ctor->full_name);
+ ret = EINA_FALSE;
+ goto end;
+ }
+ database_function_constructor_add((Eolian_Function *)cfunc, tcl);
+ eina_hash_add(th, ctor->full_name, ctor->full_name);
+ }
+
+end:
+ eina_hash_free(th);
+ return ret;
+}
+
static Eina_Bool
_validate_implement(const Eolian_Unit *src, Eolian_Implement *impl)
{
@@ -464,6 +675,13 @@ _validate_class(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *nhash)
Eina_Bool valid = cl->base.validated;
+ /* make sure impls/ctors are filled first, but do it only once */
+ if (!valid && !_db_fill_implements(cl))
+ return EINA_FALSE;
+
+ if (!valid && !_db_fill_ctors(cl))
+ return EINA_FALSE;
+
EINA_LIST_FOREACH(cl->inherits, l, icl)
{
/* first inherit needs some checking done on it */
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 08b8900016..309b2df39d 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -2255,217 +2255,6 @@ parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
eot = EINA_TRUE;
}
-const Eolian_Class *
-_get_impl_class(const Eolian_Class *cl, const char *cln)
-{
- if (!cl || !strcmp(cl->full_name, cln))
- return cl;
- Eina_List *l;
- Eolian_Class *icl;
- EINA_LIST_FOREACH(cl->inherits, l, icl)
- {
- /* we can do a depth first search, it's easier and doesn't matter
- * which part of the inheritance tree we find the class in
- */
- const Eolian_Class *fcl = _get_impl_class(icl, cln);
- if (fcl)
- return fcl;
- }
- return NULL;
-}
-
-#define _eo_parser_log(_base, ...) \
- _eolian_log_line((_base)->file, (_base)->line, (_base)->column, __VA_ARGS__)
-
-static Eina_Bool
-_db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
-{
- Eolian_Function_Type ftype = EOLIAN_METHOD;
-
- if (impl->is_prop_get && impl->is_prop_set)
- ftype = EOLIAN_PROPERTY;
- else if (impl->is_prop_get)
- ftype = EOLIAN_PROP_GET;
- else if (impl->is_prop_set)
- ftype = EOLIAN_PROP_SET;
-
- size_t imlen = strlen(impl->full_name);
- char *clbuf = alloca(imlen + 1);
- memcpy(clbuf, impl->full_name, imlen + 1);
-
- char *ldot = strrchr(clbuf, '.');
- if (!ldot)
- return EINA_FALSE; /* unreachable in practice, for static analysis */
-
- *ldot = '\0'; /* split between class name and func name */
- const char *clname = clbuf;
- const char *fnname = ldot + 1;
-
- const Eolian_Class *tcl = _get_impl_class(cl, clname);
- if (!tcl)
- {
- _eo_parser_log(&impl->base, "class '%s' not found within the inheritance tree of '%s'",
- clname, cl->full_name);
- return EINA_FALSE;
- }
-
- impl->klass = tcl;
-
- const Eolian_Function *fid = eolian_class_function_get_by_name(tcl, fnname, EOLIAN_UNRESOLVED);
- if (!fid)
- {
- _eo_parser_log(&impl->base, "function '%s' not known in class '%s'", fnname, clname);
- return EINA_FALSE;
- }
-
- Eolian_Function_Type aftype = eolian_function_type_get(fid);
-
- Eina_Bool auto_empty = (impl->get_auto || impl->get_empty);
-
- /* match implement type against function type */
- if (ftype == EOLIAN_PROPERTY)
- {
- /* property */
- if (aftype != EOLIAN_PROPERTY)
- {
- _eo_parser_log(&impl->base, "function '%s' is not a complete property", fnname);
- return EINA_FALSE;
- }
- auto_empty = auto_empty && (impl->set_auto || impl->set_empty);
- }
- else if (ftype == EOLIAN_PROP_SET)
- {
- /* setter */
- if ((aftype != EOLIAN_PROP_SET) && (aftype != EOLIAN_PROPERTY))
- {
- _eo_parser_log(&impl->base, "function '%s' doesn't have a setter", fnname);
- return EINA_FALSE;
- }
- auto_empty = (impl->set_auto || impl->set_empty);
- }
- else if (ftype == EOLIAN_PROP_GET)
- {
- /* getter */
- if ((aftype != EOLIAN_PROP_GET) && (aftype != EOLIAN_PROPERTY))
- {
- _eo_parser_log(&impl->base, "function '%s' doesn't have a getter", fnname);
- return EINA_FALSE;
- }
- }
- else if (aftype != EOLIAN_METHOD)
- {
- _eo_parser_log(&impl->base, "function '%s' is not a method", fnname);
- return EINA_FALSE;
- }
-
- if ((fid->klass == cl) && !auto_empty)
- {
- /* only allow explicit implements from other classes, besides auto and
- * empty... also prevents pure virtuals from being implemented
- */
- _eo_parser_log(&impl->base, "invalid implement '%s'", impl->full_name);
- return EINA_FALSE;
- }
-
- impl->foo_id = fid;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_db_fill_implements(Eolian_Class *cl)
-{
- Eolian_Implement *impl;
- Eina_List *l;
-
- Eina_Bool ret = EINA_TRUE;
-
- Eina_Hash *th = eina_hash_string_small_new(NULL),
- *pth = eina_hash_string_small_new(NULL);
- EINA_LIST_FOREACH(cl->implements, l, impl)
- {
- Eina_Bool prop = (impl->is_prop_get || impl->is_prop_set);
- if (eina_hash_find(prop ? pth : th, impl->full_name))
- {
- _eo_parser_log(&impl->base, "duplicate implement '%s'", impl->full_name);
- ret = EINA_FALSE;
- goto end;
- }
- if (impl->klass != cl)
- {
- if (!_db_fill_implement(cl, impl))
- {
- ret = EINA_FALSE;
- goto end;
- }
- if (eolian_function_is_constructor(impl->foo_id, impl->klass))
- database_function_constructor_add((Eolian_Function *)impl->foo_id, cl);
- }
- if ((impl->klass != cl) && !_db_fill_implement(cl, impl))
- {
- ret = EINA_FALSE;
- goto end;
- }
- eina_hash_add(prop ? pth : th, impl->full_name, impl->full_name);
- }
-
-end:
- eina_hash_free(th);
- eina_hash_free(pth);
- return ret;
-}
-
-static Eina_Bool
-_db_fill_ctors(Eolian_Class *cl)
-{
- Eolian_Constructor *ctor;
- Eina_List *l;
-
- Eina_Bool ret = EINA_TRUE;
-
- Eina_Hash *th = eina_hash_string_small_new(NULL);
- EINA_LIST_FOREACH(cl->constructors, l, ctor)
- {
- if (eina_hash_find(th, ctor->full_name))
- {
- _eo_parser_log(&ctor->base, "duplicate ctor '%s'", ctor->full_name);
- ret = EINA_FALSE;
- goto end;
- }
- const char *ldot = strrchr(ctor->full_name, '.');
- if (!ldot)
- {
- ret = EINA_FALSE;
- goto end;
- }
- char *cnbuf = alloca(ldot - ctor->full_name + 1);
- memcpy(cnbuf, ctor->full_name, ldot - ctor->full_name);
- cnbuf[ldot - ctor->full_name] = '\0';
- const Eolian_Class *tcl = _get_impl_class(cl, cnbuf);
- if (!tcl)
- {
- _eo_parser_log(&ctor->base, "class '%s' not found within the inheritance tree of '%s'",
- cnbuf, cl->full_name);
- ret = EINA_FALSE;
- goto end;
- }
- ctor->klass = tcl;
- const Eolian_Function *cfunc = eolian_constructor_function_get(ctor);
- if (!cfunc)
- {
- _eo_parser_log(&ctor->base, "unable to find function '%s'", ctor->full_name);
- ret = EINA_FALSE;
- goto end;
- }
- database_function_constructor_add((Eolian_Function *)cfunc, tcl);
- eina_hash_add(th, ctor->full_name, ctor->full_name);
- }
-
-end:
- eina_hash_free(th);
- return ret;
-}
-
Eolian_Unit *
eo_parser_database_fill(Eolian_Unit *parent, const char *filename, Eina_Bool eot, Eolian_Class **fcl)
{
@@ -2513,12 +2302,6 @@ eo_parser_database_fill(Eolian_Unit *parent, const char *filename, Eina_Bool eot
}
ls->tmp.kls = NULL;
- if (!_db_fill_implements(cl))
- goto error;
-
- if (!_db_fill_ctors(cl))
- goto error;
-
eina_hash_set(ls->state->unit.classes, cl->full_name, cl);
eina_hash_set(ls->state->classes_f, cl->base.file, cl);
eolian_object_ref(&cl->base);