eo: more information when we cannot resolve method.
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Fri, 2 Dec 2016 23:35:18 +0000 (21:35 -0200)
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Fri, 2 Dec 2016 23:44:23 +0000 (21:44 -0200)
_efl_object_api_op_id_get() will query a hash for the given pointer,
however if it wasn't populated, it will return "NOOP" and we're
hopeless while debugging on what happened.

Common case is to use the incorrect method, like:

        obj = efl_add(CLS1, ...);
        cls2_method(obj);

Since we did not create CLS2, it won't populate its methods on the
hash, thus the lookup will return NOOP.

With this change the function now gets the target object and function
name so reports an insightful message such as:

        ERR:eo file.c:123 cls2_method() Unable to resolve op for api func 0x7ff492ddea00 for obj=0x400000007e8ee1df (CLS1)

src/lib/eo/Eo.h
src/lib/eo/eo.c

index 8ad780b..0fc48d9 100644 (file)
@@ -827,7 +827,7 @@ typedef struct _Efl_Object_Call_Cache
 // hits.
 #define EFL_FUNC_COMMON_OP_END(Obj, Name, DefRet) \
 __##Name##_op_create: \
-   ___cache.op = _efl_object_api_op_id_get(EFL_FUNC_COMMON_OP_FUNC(Name)); \
+   ___cache.op = _efl_object_op_api_id_get(EFL_FUNC_COMMON_OP_FUNC(Name), Obj, #Name, __FILE__, __LINE__); \
    if (___cache.op == EFL_NOOP) return DefRet; \
    ___cache.generation = _efl_object_init_generation; \
    goto __##Name##_op_create_done;
@@ -914,7 +914,8 @@ __##Name##_op_create: \
 #define EFL_OBJECT_OP_FUNC(_api, _private) { _EFL_OBJECT_OP_API_ENTRY(_api), (void*)_private }
 
 // returns the OP id corresponding to the given api_func
-EAPI Efl_Object_Op _efl_object_api_op_id_get(const void *api_func);
+EAPI Efl_Object_Op _efl_object_api_op_id_get(const void *api_func) EINA_DEPRECATED;
+EAPI Efl_Object_Op _efl_object_op_api_id_get(const void *api_func, const Eo *obj, const char *api_func_name, const char *file, int line) EINA_ARG_NONNULL(1, 2, 3, 4) EINA_WARN_UNUSED_RESULT;
 
 // gets the real function pointer and the object data
 EAPI Eina_Bool _efl_object_call_resolve(Eo *obj, const char *func_name, Efl_Object_Op_Call_Data *call, Efl_Object_Call_Cache *callcache, const char *file, int line);
index 6430df8..d57c31c 100644 (file)
@@ -638,6 +638,7 @@ _efl_object_api_op_id_get_internal(const void *api_func)
    return op;
 }
 
+/* LEGACY, should be removed before next release */
 EAPI Efl_Object_Op
 _efl_object_api_op_id_get(const void *api_func)
 {
@@ -651,6 +652,21 @@ _efl_object_api_op_id_get(const void *api_func)
    return op;
 }
 
+EAPI Efl_Object_Op
+_efl_object_op_api_id_get(const void *api_func, const Eo *obj, const char *api_func_name, const char *file, int line)
+{
+   Efl_Object_Op op = _efl_object_api_op_id_get_internal(api_func);
+
+   if (op == EFL_NOOP)
+     {
+        eina_log_print(_eo_log_dom, EINA_LOG_LEVEL_ERR,
+                       file, api_func_name, line,
+                       "Unable to resolve op for api func %p for obj=%p (%s)", api_func, obj, efl_class_name_get(obj));
+     }
+
+   return op;
+}
+
 /* klass is the klass we are working on. hierarchy_klass is the class whe should
  * use when validating. */
 static Eina_Bool