jackdanielz pushed a commit to branch master.

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

commit b191379d1db3b90ae8c0150117035b4c5d318f2b
Author: Daniel Zaoui <[email protected]>
Date:   Tue Mar 17 13:11:41 2015 +0200

    Eolian: add API to determine if a function is implemented.
    
    This is needed in Erigo to determine if a virtual pure function can be
    invoked via eo_do, as we don't want error messages to be displayed in
    case of a non implementation in the Eo object.
    This function works with non virtual functions too.
    
    Tests have been provided.
    
    @feature
---
 src/lib/eolian/Eolian.h                | 13 +++++++
 src/lib/eolian/database_function_api.c | 63 ++++++++++++++++++++++++++++++++++
 src/tests/eolian/eolian_parsing.c      | 12 +++++++
 3 files changed, 88 insertions(+)

diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index bb13a31..d231782 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -1108,6 +1108,19 @@ EAPI Eina_Bool eolian_function_object_is_const(const 
Eolian_Function *function_i
 EAPI const Eolian_Class *eolian_function_class_get(const Eolian_Function 
*function_id);
 
 /*
+ * @brief Determine if a function is implemented in the inheritance of the 
given class
+ *
+ * @param[in] function_id id of the function
+ * @param[in] func_type type requested
+ * @param[in] klass the top class to begin with
+ * @return EINA_TRUE if found, EINA_FALSE otherwise
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Bool eolian_function_is_implemented(const Eolian_Function 
*function_id,
+      Eolian_Function_Type func_type, const Eolian_Class *klass);
+
+/*
  * @brief Get full string of an overriding function (implement).
  *
  * @param[in] impl the handle of the implement
diff --git a/src/lib/eolian/database_function_api.c 
b/src/lib/eolian/database_function_api.c
index 69b9668..fbe1e1c 100644
--- a/src/lib/eolian/database_function_api.c
+++ b/src/lib/eolian/database_function_api.c
@@ -263,3 +263,66 @@ eolian_function_is_c_only(const Eolian_Function *fid)
    EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE);
    return fid->is_c_only;
 }
+
+EAPI Eina_Bool eolian_function_is_implemented(
+      const Eolian_Function *function_id, Eolian_Function_Type func_type,
+      const Eolian_Class *klass)
+{
+   Eina_Iterator *impl_itr = NULL;
+   Eolian_Function_Type found_type = EOLIAN_UNRESOLVED;
+   Eina_Bool found = EINA_TRUE;
+   if (!function_id || !klass) return EINA_FALSE;
+   Eina_List *list = eina_list_append(NULL, klass), *list2, *itr;
+   EINA_LIST_FOREACH(list, itr, klass)
+     {
+        const char *inherit_name;
+        const Eolian_Implement *impl;
+        if (eolian_class_type_get(klass) == EOLIAN_CLASS_INTERFACE) continue;
+        impl_itr = eolian_class_implements_get(klass);
+        EINA_ITERATOR_FOREACH(impl_itr, impl)
+          {
+             if (eolian_implement_is_virtual(impl)) continue;
+             Eolian_Function_Type impl_type = EOLIAN_UNRESOLVED;
+             const Eolian_Function *impl_func = 
eolian_implement_function_get(impl, &impl_type);
+             if (impl_func == function_id)
+               {
+                  /* The type matches the requested or is not important for 
the caller */
+                  if (func_type == EOLIAN_UNRESOLVED || impl_type == 
func_type) goto end;
+                  if (impl_type == EOLIAN_METHOD) continue;
+                  /* In case we search for a property type */
+                  if (impl_type == EOLIAN_PROPERTY &&
+                        (func_type == EOLIAN_PROP_GET || func_type == 
EOLIAN_PROP_SET))
+                     goto end;
+                  /* Property may be splitted on multiple implements */
+                  if (func_type == EOLIAN_PROPERTY)
+                    {
+                       if (found_type == EOLIAN_UNRESOLVED) found_type = 
impl_type;
+                       if ((found_type == EOLIAN_PROP_SET && impl_type == 
EOLIAN_PROP_GET) ||
+                             (found_type == EOLIAN_PROP_GET && impl_type == 
EOLIAN_PROP_SET))
+                          goto end;
+                    }
+               }
+          }
+        eina_iterator_free(impl_itr);
+        impl_itr = NULL;
+
+        Eina_Iterator *inherits_itr = eolian_class_inherits_get(klass);
+        EINA_ITERATOR_FOREACH(inherits_itr, inherit_name)
+          {
+             const Eolian_Class *inherit = 
eolian_class_get_by_name(inherit_name);
+             /* Avoid duplicates. */
+             if (!eina_list_data_find(list, inherit))
+               {
+                  list2 = eina_list_append(list, inherit);
+               }
+          }
+        eina_iterator_free(inherits_itr);
+     }
+   (void) list2;
+   found = EINA_FALSE;
+end:
+   if (impl_itr) eina_iterator_free(impl_itr);
+   eina_list_free(list);
+   return found;
+}
+
diff --git a/src/tests/eolian/eolian_parsing.c 
b/src/tests/eolian/eolian_parsing.c
index 3c623e1..f614346 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -155,15 +155,27 @@ START_TEST(eolian_override)
    /* Base ctor */
    fail_if(!(fid = eolian_class_function_get_by_name(base, "constructor", 
EOLIAN_UNRESOLVED)));
    fail_if(!eolian_function_is_virtual_pure(fid, EOLIAN_UNRESOLVED));
+   fail_if(!eolian_function_is_implemented(fid, EOLIAN_UNRESOLVED, class));
+   fail_if(!eolian_function_is_implemented(fid, EOLIAN_METHOD, class));
+   fail_if(eolian_function_is_implemented(fid, EOLIAN_PROP_GET, class));
 
    /* Property */
    fail_if(!(fid = eolian_class_function_get_by_name(class, "a", 
EOLIAN_PROPERTY)));
    fail_if(!eolian_function_is_virtual_pure(fid, EOLIAN_PROP_SET));
    fail_if(eolian_function_is_virtual_pure(fid, EOLIAN_PROP_GET));
+   fail_if(eolian_function_is_implemented(fid, EOLIAN_PROP_SET, class));
+   fail_if(!eolian_function_is_implemented(fid, EOLIAN_PROP_GET, class));
+   fail_if(eolian_function_is_implemented(fid, EOLIAN_PROPERTY, class));
 
    /* Method */
    fail_if(!(fid = eolian_class_function_get_by_name(class, "foo", 
EOLIAN_METHOD)));
    fail_if(!eolian_function_is_virtual_pure(fid, EOLIAN_METHOD));
+   fail_if(eolian_function_is_implemented(fid, EOLIAN_UNRESOLVED, class));
+   fail_if(eolian_function_is_implemented(fid, EOLIAN_UNRESOLVED, base));
+
+   fail_if(!(fid = eolian_class_function_get_by_name(base, "z", 
EOLIAN_PROPERTY)));
+   fail_if(!eolian_function_is_implemented(fid, EOLIAN_PROPERTY, class));
+   fail_if(!eolian_function_is_implemented(fid, EOLIAN_PROP_SET, class));
 
    /* Implements */
    fail_if(!(iter = eolian_class_implements_get(class)));

-- 


Reply via email to