Eolian: modify 'implement' API parameters.

The function eolian_implement_information_get was returning strings for
the class and the function. It was written in this way at the beginning
because it was not needed to verify the correctness of the class and
the function.
Now that we have the namespace feature, this function must check it,
meaning that the class and the function are now known.
So we can return them instead of returning the strings.

The generators had to find the class from the classname. It is no more
needed.

The C++ generator has been adapted to this new API.
This commit is contained in:
Daniel Zaoui 2014-05-29 14:42:16 +03:00
parent f4a0c8054f
commit dc3178404f
6 changed files with 103 additions and 122 deletions

View File

@ -51,9 +51,6 @@ static const Eo_Class_Description _@#class_class_desc = {\n\
EO_DEFINE_CLASS(@#eoprefix_class_get, &_@#class_class_desc, @#list_inheritNULL);\
";
static const char
tmpl_eo_func_desc[] = "\n EO_OP_FUNC_OVERRIDE(@#eoprefix_@#func, _@#class_@#func),";
static const char
tmpl_eo_op_desc[] = "\n EO_OP_FUNC(@#eoprefix_@#func, _@#class_@#func, \"@#desc\"),";
@ -590,7 +587,6 @@ eo_source_end_generate(const Eolian_Class class, Eina_Strbuf *buf)
Eina_Strbuf *str_func = eina_strbuf_new();
Eina_Strbuf *str_bodyf = eina_strbuf_new();
Eina_Strbuf *str_ev = eina_strbuf_new();
Eina_Strbuf *tmpl_impl = eina_strbuf_new();
_template_fill(str_end, tmpl_eo_src, class, NULL, NULL, EINA_TRUE);
@ -628,80 +624,51 @@ eo_source_end_generate(const Eolian_Class class, Eina_Strbuf *buf)
Eolian_Implement impl_desc;
EINA_LIST_FOREACH(eolian_class_implements_list_get(class), itr, impl_desc)
{
const char *funcname;
const char *impl_classname;
Eolian_Class impl_class;
Eolian_Function_Type ftype;
eolian_implement_information_get(impl_desc, &impl_classname, &funcname, &ftype);
Eolian_Class impl_class = eolian_class_find_by_name(impl_classname);
_eolian_class_vars impl_env;
_class_env_create(impl_class, NULL, &impl_env);
Eolian_Function fnid;
const char *funcname;
eina_strbuf_reset(tmpl_impl);
eina_strbuf_append(tmpl_impl, tmpl_eo_func_desc);
eina_strbuf_replace_all(tmpl_impl, "@#eoprefix", impl_env.lower_eo_prefix);
eolian_implement_information_get(impl_desc, &impl_class, &fnid, &ftype);
_class_env_create(impl_class, NULL, &impl_env);
funcname = eolian_function_name_get(fnid);
char implname[0xFF];
char *tp = implname;
sprintf(implname, "%s_%s", class_env.full_classname, impl_env.full_classname);
eina_str_tolower(&tp);
eina_strbuf_replace_all(tmpl_impl, "@#class", implname);
const char *tmpl_impl_str = eina_strbuf_string_get(tmpl_impl);
Eolian_Function in_meth = NULL;
Eolian_Function in_prop = NULL;
const Eina_List *itr2;
Eolian_Function fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get(impl_class, EOLIAN_CTOR), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get(impl_class, EOLIAN_METHOD), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get(impl_class, EOLIAN_PROPERTY), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_prop = fnid;
if (!in_meth && !in_prop)
if (!fnid)
{
ERR ("Failed to generate implementation of %s:%s - missing form super class", impl_classname, funcname);
ERR ("Failed to generate implementation of %s - missing form super class",
eolian_implement_full_name_get(impl_desc));
goto end;
}
/* e.g event_freeze can be a property or a method. If a type is explicit (property EOLIAN_PROP_SET/EOLIAN_PROP_GET),
* we assume it can't be a method.
*/
if ((in_meth && in_prop) && (ftype == EOLIAN_PROP_SET || ftype == EOLIAN_PROP_GET)) in_meth = NULL;
if (in_meth)
switch (ftype)
{
_template_fill(str_op, tmpl_impl_str, impl_class, NULL, funcname, EINA_FALSE);
eo_bind_func_generate(class, in_meth, EOLIAN_UNRESOLVED, str_bodyf, &impl_env);
continue;
case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY:
if (ftype != EOLIAN_PROP_GET)
{
eina_strbuf_append_printf(str_op, "\n EO_OP_FUNC_OVERRIDE(%s_%s_set, _%s_%s_set),",
impl_env.lower_eo_prefix, funcname, implname, funcname);
eo_bind_func_generate(class, fnid, EOLIAN_PROP_SET, str_bodyf, &impl_env);
}
if (ftype != EOLIAN_PROP_SET)
{
eina_strbuf_append_printf(str_op, "\n EO_OP_FUNC_OVERRIDE(%s_%s_get, _%s_%s_get),",
impl_env.lower_eo_prefix, funcname, implname, funcname);
eo_bind_func_generate(class, fnid, EOLIAN_PROP_GET, str_bodyf, &impl_env);
}
break;
default:
eina_strbuf_append_printf(str_op, "\n EO_OP_FUNC_OVERRIDE(%s_%s, _%s_%s),",
impl_env.lower_eo_prefix, funcname, implname, funcname);
eo_bind_func_generate(class, fnid, ftype, str_bodyf, &impl_env);
break;
}
if (in_prop)
{
char tmpstr[0xFF];
if ((ftype != EOLIAN_PROP_GET) && (ftype != EOLIAN_PROP_SET)) ftype = eolian_function_type_get(in_prop);
Eina_Bool prop_read = ( ftype == EOLIAN_PROP_SET ) ? EINA_FALSE : EINA_TRUE;
Eina_Bool prop_write = ( ftype == EOLIAN_PROP_GET ) ? EINA_FALSE : EINA_TRUE;
if (prop_write)
{
sprintf(tmpstr, "%s_set", funcname);
_template_fill(str_op, tmpl_impl_str, impl_class, NULL, tmpstr, EINA_FALSE);
eo_bind_func_generate(class, in_prop, EOLIAN_PROP_SET, str_bodyf, &impl_env);
}
if (prop_read)
{
sprintf(tmpstr, "%s_get", funcname);
_template_fill(str_op, tmpl_impl_str, impl_class, NULL, tmpstr, EINA_FALSE);
eo_bind_func_generate(class, in_prop, EOLIAN_PROP_GET, str_bodyf, &impl_env);
}
}
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
}
//Constructors
@ -864,7 +831,6 @@ end:
eina_strbuf_free(str_bodyf);
eina_strbuf_free(str_end);
eina_strbuf_free(str_ev);
eina_strbuf_free(tmpl_impl);
return ret;
}

View File

@ -119,15 +119,14 @@ _prototype_generate(Eolian_Function foo, Eolian_Function_Type ftype, Eina_Strbuf
super_invok = eina_strbuf_new();
if (impl_desc)
{
const char *impl_classname;
Eolian_Class impl_class;
eolian_implement_information_get(impl_desc, &impl_class, NULL, NULL);
eolian_implement_information_get(impl_desc, &impl_classname, NULL, NULL);
_class_env_create(impl_class, NULL, &impl_env);
char *tmp = impl_name;
sprintf(impl_name, "%s_%s", class_env.full_classname, impl_classname);
sprintf(impl_name, "%s_%s", class_env.full_classname, impl_env.full_classname);
eina_str_tolower(&tmp);
_class_env_create(eolian_class_find_by_name(impl_classname), NULL, &impl_env);
}
sprintf(func_name, "_%s_%s%s",
@ -256,17 +255,15 @@ impl_source_generate(const Eolian_Class class, Eina_Strbuf *buffer)
Eolian_Implement impl_desc;
EINA_LIST_FOREACH(eolian_class_implements_list_get(class), itr_funcs, impl_desc)
{
const char *func_name;
const char *impl_classname;
Eolian_Class impl_class = NULL;
Eolian_Function_Type ftype;
eolian_implement_information_get(impl_desc, &impl_classname, &func_name, &ftype);
Eolian_Class impl_class = eolian_class_find_by_name(impl_classname);
foo = eolian_class_function_find_by_name(impl_class, func_name, ftype);
foo = NULL;
eolian_implement_information_get(impl_desc, &impl_class, &foo, &ftype);
if (!foo)
{
ERR ("Failed to generate implementation of %s:%s - missing form super class", impl_classname, func_name);
ERR ("Failed to generate implementation of %s - missing form super class",
eolian_implement_full_name_get(impl_desc));
goto end;
}
switch (ftype)

View File

@ -182,25 +182,22 @@ convert_eolian_implements(efl::eolian::eo_class& cls, const Eolian_Class klass)
EINA_LIST_FOREACH(eolian_class_implements_list_get(klass), it, impl_desc_)
{
Eolian_Implement impl_desc = static_cast<Eolian_Implement>(impl_desc_);
const char *impl_classname;
const char *func_name;
Eolian_Function_Type func_type;
Eolian_Class impl_class;
Eolian_Function impl_func;
Eolian_Function_Type impl_type;
eolian_implement_information_get
(impl_desc, &impl_classname, &func_name, &func_type);
if (func_type == EOLIAN_CTOR)
(impl_desc, &impl_class, &impl_func, &impl_type);
if (impl_type == EOLIAN_CTOR)
{
efl::eolian::eo_constructor constructor;
Eolian_Class impl_class = eolian_class_find_by_name(impl_classname);
Eolian_Function eolian_constructor =
eolian_class_function_find_by_name(impl_class, func_name, func_type);
std::string parent = safe_str(impl_classname);
std::string parent = safe_str(eolian_class_full_name_get(impl_class));
if(parent == "Eo_Base") parent = "eo";
else std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
constructor.name = parent + "_" + safe_str(func_name);
constructor.name = parent + "_" + safe_str(eolian_function_name_get(impl_func));
constructor.params = _get_params
(eolian_parameters_list_get(eolian_constructor));
(eolian_parameters_list_get(impl_func));
constructor.comment = detail::eolian_constructor_comment
(eolian_constructor);
(impl_func);
cls.constructors.push_back(constructor);
}
}

View File

@ -595,19 +595,27 @@ EAPI Eina_Bool eolian_function_return_is_warn_unused(Eolian_Function foo_id, Eol
*/
EAPI Eina_Bool eolian_function_object_is_const(Eolian_Function function_id);
/*
* @brief Get full string of an overriding function (implement).
*
* @param[in] impl handle of the implement
* @return the full string.
*/
EAPI Eina_Stringshare * eolian_implement_full_name_get(const Eolian_Implement impl);
/*
* @brief Get information about an overriding function (implement).
*
* @param[in] impl handle of the implement
* @param[out] class_name name of the class to override
* @param[out] func_name name of the function to override
* @param[out] type type of the function to override
* @param[out] class overridden class
* @param[out] func overridden function
* @param[out] type type of the overridden function
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_implement_information_get(Eolian_Implement impl,
const char **class_name, const char **func_name, Eolian_Function_Type *type);
EAPI Eina_Bool eolian_implement_information_get(const Eolian_Implement impl,
Eolian_Class *klass, Eolian_Function *function, Eolian_Function_Type *type);
/*
* @brief Get the list of overriding functions defined in a class.

View File

@ -564,15 +564,23 @@ database_class_implement_add(Eolian_Class class, Eolian_Implement impl_desc)
return EINA_TRUE;
}
EAPI Eina_Stringshare *
eolian_implement_full_name_get(const Eolian_Implement impl)
{
_Implement_Desc *_impl = (_Implement_Desc *)impl;
EINA_SAFETY_ON_NULL_RETURN_VAL(_impl, NULL);
return _impl->full_name;
}
EAPI Eina_Bool
eolian_implement_information_get(Eolian_Implement impl, const char **class_name_out, const char **func_name_out, Eolian_Function_Type *type_out)
eolian_implement_information_get(const Eolian_Implement impl, Eolian_Class *class_out, Eolian_Function *func_out, Eolian_Function_Type *type_out)
{
_Implement_Desc *_impl = (_Implement_Desc *)impl;
EINA_SAFETY_ON_NULL_RETURN_VAL(_impl, EINA_FALSE);
Eolian_Class class;
if (!database_class_name_validate(_impl->full_name, &class) || !class) return EINA_FALSE;
const char *class_name = ((_Class_Desc *)class)->full_name;
if (class_name_out) *class_name_out = class_name;
if (class_out) *class_out = class;
char *func_name = strdup(_impl->full_name + strlen(class_name) + 2);
char *colon = strstr(func_name, "::");
@ -585,7 +593,7 @@ eolian_implement_information_get(Eolian_Implement impl, const char **class_name_
}
Eolian_Function fid = eolian_class_function_find_by_name(class, func_name, type);
if (func_name_out) *func_name_out = eolian_function_name_get(fid);
if (func_out) *func_out = fid;
if (type == EOLIAN_UNRESOLVED) type = eolian_function_type_get(fid);
if (type_out) *type_out = type;
free(func_name);
@ -1116,10 +1124,12 @@ eolian_class_dtor_enable_get(const Eolian_Class class)
static void
_implements_print(Eolian_Implement impl, int nb_spaces)
{
const char *t, *cl, *fn;
Eolian_Class class;
Eolian_Function func;
const char *t;
Eolian_Function_Type ft;
eolian_implement_information_get(impl, &cl, &fn, &ft);
eolian_implement_information_get(impl, &class, &func, &ft);
switch (ft)
{
case EOLIAN_PROP_SET: t = "SET"; break;
@ -1133,7 +1143,7 @@ _implements_print(Eolian_Implement impl, int nb_spaces)
default:
return;
}
printf("%*s <%s :: %s> <%s>\n", nb_spaces + 5, "", cl, fn, t);
printf("%*s <%s> <%s>\n", nb_spaces + 5, "", eolian_implement_full_name_get(impl), t);
}
static void
@ -1413,14 +1423,13 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
}
EINA_LIST_FOREACH(eolian_class_implements_list_get(class), itr, impl)
{
const char *impl_classname = NULL, *impl_func = NULL;
Eolian_Class impl_class;
Eolian_Function impl_func;
Eolian_Function_Type impl_type = EOLIAN_UNRESOLVED;
eolian_implement_information_get(impl, &impl_classname, &impl_func, &impl_type);
Eolian_Class impl_class = eolian_class_find_by_name(impl_classname);
Eolian_Function foo = eolian_class_function_find_by_name(impl_class, impl_func, impl_type);
if (!foo)
eolian_implement_information_get(impl, &impl_class, &impl_func, &impl_type);
if (!impl_func)
{
ERR("Unable to find function %s in class %s", impl_func, impl_classname);
ERR("Unable to find function %s", eolian_implement_full_name_get(impl));
return EINA_FALSE;
}
}

View File

@ -11,11 +11,11 @@
START_TEST(eolian_namespaces)
{
Eolian_Class class11, class112, class21, class_no;
Eolian_Class class11, class112, class21, class_no, impl_class;
Eolian_Function fid;
const Eina_List *list = NULL;
const char *class_name, *func_name;
Eolian_Function_Type func_type;
const char *class_name;
eolian_init();
/* Parsing */
@ -60,17 +60,19 @@ START_TEST(eolian_namespaces)
/* Implements */
fail_if(!(list = eolian_class_implements_list_get(class11)));
fail_if(eina_list_count(list) != 3);
fail_if(!eolian_implement_information_get(eina_list_nth(list, 0),
&class_name, &func_name, &func_type));
fail_if(eolian_class_find_by_name(class_name) != class112);
fail_if(strcmp(func_name, "a"));
&impl_class, &fid, &func_type));
fail_if(impl_class != class112);
fail_if(strcmp(eolian_function_name_get(fid), "a"));
fail_if(func_type != EOLIAN_PROP_SET);
fail_if(eolian_implement_information_get(eina_list_nth(list, 1),
&class_name, &func_name, &func_type));
&impl_class, &fid, &func_type));
fail_if(!eolian_implement_information_get(eina_list_nth(list, 2),
&class_name, &func_name, &func_type));
fail_if(eolian_class_find_by_name(class_name) != class_no);
fail_if(strcmp(func_name, "foo"));
&impl_class, &fid, &func_type));
fail_if(impl_class != class_no);
fail_if(strcmp(eolian_function_name_get(fid), "foo"));
fail_if(func_type != EOLIAN_METHOD);
/* Virtual regression */
@ -116,7 +118,8 @@ START_TEST(eolian_override)
{
Eolian_Function fid = NULL;
const Eina_List *impls = NULL;
const char *impl_class = NULL, *impl_func = NULL;
Eolian_Class impl_class = NULL;
Eolian_Function impl_func = NULL;
Eolian_Class class, base;
eolian_init();
@ -133,8 +136,8 @@ START_TEST(eolian_override)
fail_if(!eolian_function_is_virtual_pure(fid, EOLIAN_UNRESOLVED));
fail_if(!(impls = eolian_class_implements_list_get(class)));
fail_if(!eolian_implement_information_get(eina_list_nth(impls, 0), &impl_class, &impl_func, NULL));
fail_if(strcmp(impl_class, "Base"));
fail_if(strcmp(impl_func, "constructor"));
fail_if(impl_class != base);
fail_if(strcmp(eolian_function_name_get(impl_func), "constructor"));
/* Property */
fail_if(!(fid = eolian_class_function_find_by_name(class, "a", EOLIAN_PROPERTY)));
@ -177,7 +180,8 @@ END_TEST
START_TEST(eolian_ctor_dtor)
{
const Eina_List *impls = NULL;
const char *impl_class = NULL, *impl_func = NULL;
Eolian_Class impl_class = NULL;
Eolian_Function impl_func = NULL;
Eolian_Class class, base;
eolian_init();
@ -195,11 +199,11 @@ START_TEST(eolian_ctor_dtor)
fail_if(!(impls = eolian_class_implements_list_get(class)));
fail_if(eina_list_count(impls) != 2);
fail_if(!eolian_implement_information_get(eina_list_nth(impls, 0), &impl_class, &impl_func, NULL));
fail_if(strcmp(impl_class, "Base"));
fail_if(strcmp(impl_func, "constructor"));
fail_if(impl_class != base);
fail_if(strcmp(eolian_function_name_get(impl_func), "constructor"));
fail_if(!eolian_implement_information_get(eina_list_nth(impls, 1), &impl_class, &impl_func, NULL));
fail_if(strcmp(impl_class, "Base"));
fail_if(strcmp(impl_func, "destructor"));
fail_if(impl_class != base);
fail_if(strcmp(eolian_function_name_get(impl_func), "destructor"));
/* Custom ctors/dtors */
fail_if(!eolian_class_function_find_by_name(base, "constructor", EOLIAN_CTOR));