q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=88083b0f14ad887d37cac49d66376ffab86e7431

commit 88083b0f14ad887d37cac49d66376ffab86e7431
Author: Daniel Kolesa <[email protected]>
Date:   Tue Oct 24 23:39:14 2017 +0200

    eolian: check for inheritance tree function conflicts
    
    Now a class cannot define a method/property of some name if there
    already is something of the same name within the inheritance tree.
---
 src/lib/eolian/database_validate.c | 62 +++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 21 deletions(-)

diff --git a/src/lib/eolian/database_validate.c 
b/src/lib/eolian/database_validate.c
index edd5d2c4c6..36b8c1c476 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -96,10 +96,9 @@ _ef_map_cb(const Eina_Hash *hash EINA_UNUSED, const void 
*key EINA_UNUSED,
 }
 
 static Eina_Bool
-_type_error(const Eolian_Type *tp, const char *msg)
+_obj_error(const Eolian_Object *o, const char *msg)
 {
-   fprintf(stderr, "eolian:%s:%d:%d: %s\n", tp->base.file, tp->base.line,
-           tp->base.column, msg);
+   fprintf(stderr, "eolian:%s:%d:%d: %s\n", o->file, o->line, o->column, msg);
    return EINA_FALSE;
 }
 
@@ -172,7 +171,7 @@ _validate_type(Eolian_Type *tp)
    if (tp->owned && !database_type_is_ownable(tp))
      {
         snprintf(buf, sizeof(buf), "type '%s' is not ownable", tp->full_name);
-        return _type_error(tp, buf);
+        return _obj_error(&tp->base, buf);
      }
 
    switch (tp->type)
@@ -231,7 +230,7 @@ _validate_type(Eolian_Type *tp)
            if (!tpp)
              {
                 snprintf(buf, sizeof(buf), "undefined type %s", tp->full_name);
-                return _type_error(tp, buf);
+                return _obj_error(&tp->base, buf);
              }
            if (!_validate_typedecl(tpp))
              return EINA_FALSE;
@@ -246,7 +245,7 @@ _validate_type(Eolian_Type *tp)
              {
                 snprintf(buf, sizeof(buf), "undefined class %s "
                          "(likely wrong namespacing)", tp->full_name);
-                return _type_error(tp, buf);
+                return _obj_error(&tp->base, buf);
              }
            if (!tp->freefunc)
              tp->freefunc = eina_stringshare_add(eo_obj_free);
@@ -288,14 +287,25 @@ _validate_param(Eolian_Function_Parameter *param)
 }
 
 static Eina_Bool
-_validate_function(Eolian_Function *func)
+_validate_function(Eolian_Function *func, Eina_Hash *nhash)
 {
    Eina_List *l;
    Eolian_Function_Parameter *param;
+   char buf[512];
 
    if (func->base.validated)
      return EINA_TRUE;
 
+   const Eolian_Function *ofunc = eina_hash_find(nhash, func->name);
+   if (ofunc)
+     {
+        snprintf(buf, sizeof(buf),
+                 "function '%s' redefined (originally at %s:%d:%d)",
+                 func->name, ofunc->base.file,
+                 ofunc->base.line, ofunc->base.column);
+        return _obj_error(&func->base, buf);
+     }
+
    if (func->get_ret_type && !_validate_type(func->get_ret_type))
      return EINA_FALSE;
 
@@ -364,13 +374,14 @@ _validate_implement(Eolian_Implement *impl)
 }
 
 static Eina_Bool
-_validate_class(Eolian_Class *cl)
+_validate_class(Eolian_Class *cl, Eina_Hash *nhash)
 {
    Eina_List *l;
    Eolian_Function *func;
    Eolian_Event *event;
    Eolian_Implement *impl;
    const char *iname;
+   Eina_Bool res = EINA_TRUE;
 
    if (!cl)
      return EINA_FALSE; /* if this happens something is very wrong though */
@@ -378,31 +389,40 @@ _validate_class(Eolian_Class *cl)
    if (cl->base.validated)
      return EINA_TRUE;
 
+   Eina_Bool ahash = (nhash == NULL);
+   if (ahash)
+     nhash = eina_hash_string_small_new(NULL);
+
    EINA_LIST_FOREACH(cl->inherits, l, iname)
      {
-        if (!_validate_class(eina_hash_find(_classes, iname)))
-          return EINA_FALSE;
+        if (!(res = _validate_class(eina_hash_find(_classes, iname), nhash)))
+          goto freehash;
      }
 
    EINA_LIST_FOREACH(cl->properties, l, func)
-     if (!_validate_function(func))
-       return EINA_FALSE;
+     if (!(res = _validate_function(func, nhash)))
+       goto freehash;
 
    EINA_LIST_FOREACH(cl->methods, l, func)
-     if (!_validate_function(func))
-       return EINA_FALSE;
+     if (!(res = _validate_function(func, nhash)))
+       goto freehash;
 
    EINA_LIST_FOREACH(cl->events, l, event)
-     if (!_validate_event(event))
-       return EINA_FALSE;
+     if (!(res = _validate_event(event)))
+       goto freehash;
 
    EINA_LIST_FOREACH(cl->implements, l, impl)
-     if (!_validate_implement(impl))
-       return EINA_FALSE;
+     if (!(res = _validate_implement(impl)))
+       goto freehash;
 
-   if (!_validate_doc(cl->doc))
-     return EINA_FALSE;
+   if (!(res = _validate_doc(cl->doc)))
+     goto freehash;
 
+freehash:
+   if (ahash)
+     eina_hash_free(nhash);
+   if (!res)
+     return EINA_FALSE;
    return _validate(&cl->base);
 }
 
@@ -446,7 +466,7 @@ database_validate()
    /* FIXME: pass unit properly */
    Eina_Iterator *iter = eolian_all_classes_get(NULL);
    EINA_ITERATOR_FOREACH(iter, cl)
-     if (cl->toplevel && !_validate_class(cl))
+     if (cl->toplevel && !_validate_class(cl, NULL))
        {
           eina_iterator_free(iter);
           return EINA_FALSE;

-- 


Reply via email to