eolian: add eolian_implement_implementing_class_get

This will make it easier for generators and utilities to retrieve
the class that implemented a method/property/etc rather than the
class the implement was originally defined for. Thanks to this
it will no longer be necessary to carry the class pointer around
the place.
This commit is contained in:
Daniel Kolesa 2018-11-04 16:08:48 +01:00
parent 01c756a851
commit d0c96539f2
7 changed files with 43 additions and 2 deletions

View File

@ -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)

View File

@ -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.
*

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);