diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua index 161de2c5bb..1ef6617fd9 100644 --- a/src/bindings/luajit/eolian.lua +++ b/src/bindings/luajit/eolian.lua @@ -363,6 +363,7 @@ ffi.cdef [[ Eina_Bool eolian_function_return_is_warn_unused(const Eolian_Function *foo_id, Eolian_Function_Type ftype); Eina_Bool eolian_function_object_is_const(const Eolian_Function *function_id); const Eolian_Class *eolian_implement_class_get(const Eolian_Implement *impl); + const Eolian_Class *eolian_implement_implementing_class_get(const Eolian_Implement *impl); const Eolian_Function *eolian_implement_function_get(const Eolian_Implement *impl, Eolian_Function_Type *func_type); const Eolian_Documentation *eolian_implement_documentation_get(const Eolian_Implement *impl, Eolian_Function_Type f_type); Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type ftype); @@ -1189,6 +1190,12 @@ ffi.metatype("Eolian_Implement", { return v end, + implementing_class_get = function(self) + local v = eolian.eolian_implement_implementing_class_get(self) + if v == nil then return nil end + return v + end, + function_get = function(self) local tp = ffi.new("Eolian_Function_Type[1]") local v = eolian.eolian_implement_function_get(self, tp) diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index f626ce82ca..516bee088e 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -1840,13 +1840,35 @@ eolian_implement_name_get(const Eolian_Implement *impl) /* * @brief Get the class of an overriding function (implement). * + * This is always the class specified in the implement name, i.e. if a class + * B overrides a method from a class A, the returned class will be A. There + * is another API to get the overriding class. + * * @param[in] impl the handle of the implement * @return the class handle or NULL. * + * @see eolian_implement_implementing_class_get + * * @ingroup Eolian */ EAPI const Eolian_Class *eolian_implement_class_get(const Eolian_Implement *impl); +/* + * @brief Get the implementing class of an overriding function (implement). + * + * This is always the class that is implementing the function, override or + * not. That is, if class B overrides a method from class A, this will return + * the B class. There is another API to get the original class. + * + * @param[in] impl the handle of the implement + * @return the class handle or NULL. + * + * @see eolian_implement_class_get + * + * @ingroup Eolian + */ +EAPI const Eolian_Class *eolian_implement_implementing_class_get(const Eolian_Implement *impl); + /* * @brief Get the function of an implement. * diff --git a/src/lib/eolian/database_implement_api.c b/src/lib/eolian/database_implement_api.c index ff83c9eeb6..a373a77911 100644 --- a/src/lib/eolian/database_implement_api.c +++ b/src/lib/eolian/database_implement_api.c @@ -12,6 +12,13 @@ eolian_implement_class_get(const Eolian_Implement *impl) return impl->klass; } +EAPI const Eolian_Class * +eolian_implement_implementing_class_get(const Eolian_Implement *impl) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(impl, NULL); + return impl->implklass; +} + EAPI const Eolian_Function * eolian_implement_function_get(const Eolian_Implement *impl, Eolian_Function_Type *func_type) diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index 0f7d08e981..8858818dff 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -546,6 +546,7 @@ _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl) } impl->klass = tcl; + impl->implklass = cl; const Eolian_Function *fid = eolian_class_function_by_name_get(tcl, fnname, EOLIAN_UNRESOLVED); if (!fid) diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index f55e3e1744..89263e766e 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -1183,7 +1183,7 @@ parse_property(Eo_Lexer *ls) prop->get_scope = prop->set_scope = EOLIAN_SCOPE_PUBLIC; FILL_BASE(prop->base, ls, ls->line_number, ls->column, FUNCTION); impl = calloc(1, sizeof(Eolian_Implement)); - impl->klass = ls->klass; + impl->klass = impl->implklass = ls->klass; impl->foo_id = prop; FILL_BASE(impl->base, ls, ls->line_number, ls->column, IMPLEMENT); prop->impl = impl; @@ -1347,7 +1347,7 @@ parse_method(Eo_Lexer *ls) meth->get_scope = meth->set_scope = EOLIAN_SCOPE_PUBLIC; FILL_BASE(meth->base, ls, ls->line_number, ls->column, FUNCTION); impl = calloc(1, sizeof(Eolian_Implement)); - impl->klass = ls->klass; + impl->klass = impl->implklass = ls->klass; impl->foo_id = meth; FILL_BASE(impl->base, ls, ls->line_number, ls->column, IMPLEMENT); meth->impl = impl; diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 3f3ab61b18..b0684f0591 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -290,6 +290,7 @@ struct _Eolian_Implement { Eolian_Object base; const Eolian_Class *klass; + const Eolian_Class *implklass; const Eolian_Function *foo_id; Eolian_Documentation *common_doc; Eolian_Documentation *get_doc; diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index f29d5060c0..6cb7bb0e92 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -196,6 +196,7 @@ EFL_START_TEST(eolian_override) fail_if(!(impl_class = eolian_implement_class_get(impl))); fail_if(!(impl_func = eolian_implement_function_get(impl, NULL))); fail_if(impl_class != class); + fail_if(eolian_implement_implementing_class_get(impl) != class); fail_if(strcmp(eolian_function_name_get(impl_func), "b")); fail_if(!(eina_iterator_next(iter, (void**)&impl))); /* skip c */ @@ -208,6 +209,7 @@ EFL_START_TEST(eolian_override) fail_if(!(impl_class = eolian_implement_class_get(impl))); fail_if(!(impl_func = eolian_implement_function_get(impl, NULL))); fail_if(impl_class != class); + fail_if(eolian_implement_implementing_class_get(impl) != class); fail_if(strcmp(eolian_function_name_get(impl_func), "bar")); fail_if(!(eina_iterator_next(iter, (void**)&impl))); @@ -217,6 +219,7 @@ EFL_START_TEST(eolian_override) fail_if(!(impl_class = eolian_implement_class_get(impl))); fail_if(!(impl_func = eolian_implement_function_get(impl, NULL))); fail_if(impl_class != base); + fail_if(eolian_implement_implementing_class_get(impl) != class); fail_if(strcmp(eolian_function_name_get(impl_func), "constructor")); eina_iterator_free(iter);