From 078a4eef71a97ea869d8dfc8a8e60d90b8e42265 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 12 Jan 2017 16:56:49 +0100 Subject: [PATCH] eolian: strict function type input checks in APIs Strictness of various Eolian APIs has been enhanced, for example eolian_class_function_get_by_name now won't return anything if you request an EOLIAN_PROPERTY and the found func is just an EOLIAN_PROP_GET, and various APIs won't accept arbitrary inputs like EOLIAN_UNRESOLVED or EOLIAN_PROPERTY now, instead you will need to provide EOLIAN_PROP_GET, EOLIAN_PROP_SET or EOLIAN_METHOD explicitly. The purpose of this is to reduce potential bugs and fix ambiguous behavior. Thanks to use of EINA_SAFETY, appropriate errors should be printed into terminal when an API is used incorrectly. --- src/lib/elementary/elm_diskselector.eo | 4 +- src/lib/eolian/Eolian.h | 38 +++++++ src/lib/eolian/database_class_api.c | 2 + src/lib/eolian/database_fill.c | 4 +- src/lib/eolian/database_function.c | 12 ++ src/lib/eolian/database_function_api.c | 193 +++++++++++++++++++++++++++----- src/lib/eolian/database_implement_api.c | 39 +++++-- src/lib/eolian/eolian_database.h | 1 + src/tests/eolian/eolian_parsing.c | 21 ++-- 9 files changed, 262 insertions(+), 52 deletions(-) diff --git a/src/lib/elementary/elm_diskselector.eo b/src/lib/elementary/elm_diskselector.eo index 9a74c00..ae157b1 100644 --- a/src/lib/elementary/elm_diskselector.eo +++ b/src/lib/elementary/elm_diskselector.eo @@ -129,8 +129,8 @@ class Elm.Diskselector (Elm.Widget, Elm.Interface_Scrollable, [[Get the selected item. - The selected item can be unselected with function - @.selected_item.set, and the first item of + The selected item can be unselected with + @Elm.Diskselector.Item.selected.set, and the first item of diskselector will be selected. The selected item always will be centered on diskselector, with diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index 783c5b9..7368921 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -655,6 +655,8 @@ EAPI Eina_Iterator *eolian_class_inherits_get(const Eolian_Class *klass); * @param[in] func_type type of the functions to insert into the list. * @return the iterator * + * Acceptable inputs are EOLIAN_PROPERTY or EOLIAN_METHOD. + * * @ingroup Eolian */ EAPI Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type); @@ -676,6 +678,8 @@ EAPI Eolian_Function_Type eolian_function_type_get(const Eolian_Function *functi * @param[in] ftype The type of function to get the scope for * @return the function scope * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eolian_Object_Scope eolian_function_scope_get(const Eolian_Function *function_id, Eolian_Function_Type ftype); @@ -720,6 +724,10 @@ EAPI Eina_Stringshare *eolian_function_full_c_name_get(const Eolian_Function *fu * @param[in] f_type type of the function * @return the function id if found, NULL otherwise. * + * Providing EOLIAN_UNRESOLVED finds any func, EOLIAN_PROPERTY any property, + * EOLIAN_METHOD any method, EOLIAN_PROP_GET properties with either only a getter + * or full property, EOLIAN_PROP_SET either only a setter or full property. + * * @ingroup Eolian */ EAPI const Eolian_Function *eolian_class_function_get_by_name(const Eolian_Class *klass, const char *func_name, Eolian_Function_Type f_type); @@ -731,6 +739,8 @@ EAPI const Eolian_Function *eolian_class_function_get_by_name(const Eolian_Class * @param[in] f_type The function type, for property get/set distinction. * @return the legacy name or NULL. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Stringshare *eolian_function_legacy_get(const Eolian_Function *function_id, Eolian_Function_Type f_type); @@ -742,6 +752,8 @@ EAPI Eina_Stringshare *eolian_function_legacy_get(const Eolian_Function *functio * @param[in] f_type The function type, for property get/set distinction. * @return the documentation or NULL. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI const Eolian_Documentation *eolian_function_documentation_get(const Eolian_Function *function_id, Eolian_Function_Type f_type); @@ -753,6 +765,8 @@ EAPI const Eolian_Documentation *eolian_function_documentation_get(const Eolian_ * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE if virtual pure, EINA_FALSE othrewise. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_function_is_virtual_pure(const Eolian_Function *function_id, Eolian_Function_Type f_type); @@ -764,6 +778,8 @@ EAPI Eina_Bool eolian_function_is_virtual_pure(const Eolian_Function *function_i * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE if auto, EINA_FALSE othrewise. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_function_is_auto(const Eolian_Function *function_id, Eolian_Function_Type f_type); @@ -775,6 +791,8 @@ EAPI Eina_Bool eolian_function_is_auto(const Eolian_Function *function_id, Eolia * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE if empty, EINA_FALSE othrewise. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_function_is_empty(const Eolian_Function *function_id, Eolian_Function_Type f_type); @@ -786,6 +804,8 @@ EAPI Eina_Bool eolian_function_is_empty(const Eolian_Function *function_id, Eoli * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE if legacy only, EINA_FALSE otherwise. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_function_is_legacy_only(const Eolian_Function *function_id, Eolian_Function_Type ftype); @@ -848,6 +868,8 @@ EAPI Eina_Iterator *eolian_function_parameters_get(const Eolian_Function *functi * @param[in] ftype The function type, for property get/set distinction. * @return the iterator * + * Acceptable input types are PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Iterator *eolian_property_keys_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype); @@ -859,6 +881,8 @@ EAPI Eina_Iterator *eolian_property_keys_get(const Eolian_Function *foo_id, Eoli * @param[in] ftype The function type, for property get/set distinction. * @return the iterator * + * Acceptable input types are PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Iterator *eolian_property_values_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype); @@ -953,6 +977,8 @@ EAPI Eina_Bool eolian_parameter_is_optional(const Eolian_Function_Parameter *par * The type of the function is needed because a given function can represent a * property, that can be set and get functions. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI const Eolian_Type *eolian_function_return_type_get(const Eolian_Function *function_id, Eolian_Function_Type ftype); @@ -968,6 +994,8 @@ EAPI const Eolian_Type *eolian_function_return_type_get(const Eolian_Function *f * value if an error occurs (eo_do failure...). * The default value is not mandatory, so NULL can be returned. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI const Eolian_Expression * @@ -983,6 +1011,8 @@ eolian_function_return_default_value_get(const Eolian_Function *foo_id, Eolian_F * The type of the function is needed because a given function can represent a * property, that can be set and get functions. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI const Eolian_Documentation *eolian_function_return_documentation_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype); @@ -997,6 +1027,8 @@ EAPI const Eolian_Documentation *eolian_function_return_documentation_get(const * The type of the function is needed because a given function can represent a * property, that can be set and get functions. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_function_return_is_warn_unused(const Eolian_Function *foo_id, Eolian_Function_Type ftype); @@ -1059,6 +1091,8 @@ EAPI const Eolian_Function *eolian_implement_function_get(const Eolian_Implement * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE when it is, EINA_FALSE when it's not. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type f_type); @@ -1070,6 +1104,8 @@ EAPI Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Fun * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE when it is, EINA_FALSE when it's not. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Function_Type f_type); @@ -1081,6 +1117,8 @@ EAPI Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Fu * @param[in] f_type The function type, for property get/set distinction. * @return EINA_TRUE when it is, EINA_FALSE when it's not. * + * Acceptable input types are METHOD, PROP_GET and PROP_SET. + * * @ingroup Eolian */ EAPI Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl, Eolian_Function_Type f_type); diff --git a/src/lib/eolian/database_class_api.c b/src/lib/eolian/database_class_api.c index 3086ecf..ebbe5dd 100644 --- a/src/lib/eolian/database_class_api.c +++ b/src/lib/eolian/database_class_api.c @@ -138,6 +138,8 @@ eolian_class_function_get_by_name(const Eolian_Class *cl, const char *func_name, { EINA_LIST_FOREACH(cl->properties, itr, fid) { + if (!database_function_is_type(fid, f_type)) + continue; if (!strcmp(fid->name, func_name)) return fid; } diff --git a/src/lib/eolian/database_fill.c b/src/lib/eolian/database_fill.c index b904a57..2f47145 100644 --- a/src/lib/eolian/database_fill.c +++ b/src/lib/eolian/database_fill.c @@ -129,7 +129,7 @@ static Eina_Bool _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl) { Eolian_Function *foo_id; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; + Eolian_Function_Type ftype = EOLIAN_METHOD; if (impl->is_prop_get && impl->is_prop_set) ftype = EOLIAN_PROPERTY; @@ -147,7 +147,7 @@ _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl) foo_id->set_empty = impl->set_empty; if (foo_id->get_auto || foo_id->get_empty) { - if (ftype == EOLIAN_UNRESOLVED) + if (ftype == EOLIAN_METHOD) foo_id->set_impl = impl; foo_id->get_impl = impl; } diff --git a/src/lib/eolian/database_function.c b/src/lib/eolian/database_function.c index 454c511..0ad9f2f 100644 --- a/src/lib/eolian/database_function.c +++ b/src/lib/eolian/database_function.c @@ -60,3 +60,15 @@ database_function_constructor_add(Eolian_Function *func, const Eolian_Class *cls (func->ctor_of, EINA_COMPARE_CB(strcmp), eina_stringshare_ref(cls->full_name)); } + +Eina_Bool +database_function_is_type(Eolian_Function *fid, Eolian_Function_Type ftype) +{ + if (ftype == EOLIAN_UNRESOLVED) + return EINA_TRUE; + else if (ftype == EOLIAN_PROP_GET) + return (fid->type == EOLIAN_PROP_GET) || (fid->type == EOLIAN_PROPERTY); + else if (ftype == EOLIAN_PROP_SET) + return (fid->type == EOLIAN_PROP_SET) || (fid->type == EOLIAN_PROPERTY); + return (fid->type == ftype); +} \ No newline at end of file diff --git a/src/lib/eolian/database_function_api.c b/src/lib/eolian/database_function_api.c index fd12325..6266ca4 100644 --- a/src/lib/eolian/database_function_api.c +++ b/src/lib/eolian/database_function_api.c @@ -9,11 +9,24 @@ EAPI Eolian_Object_Scope eolian_function_scope_get(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EOLIAN_SCOPE_PUBLIC); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EOLIAN_SCOPE_PUBLIC); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EOLIAN_SCOPE_PUBLIC); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_scope; break; - case EOLIAN_PROP_SET: return fid->set_scope; break; - default: return EOLIAN_SCOPE_PUBLIC; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EOLIAN_SCOPE_PUBLIC; + return fid->get_scope; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EOLIAN_SCOPE_PUBLIC; + return fid->get_scope; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EOLIAN_SCOPE_PUBLIC; + return fid->set_scope; + default: + return EOLIAN_SCOPE_PUBLIC; } } @@ -150,11 +163,24 @@ EAPI Eina_Stringshare * eolian_function_legacy_get(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, NULL); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_legacy; break; - case EOLIAN_PROP_SET: return fid->set_legacy; break; - default: return NULL; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return NULL; + return fid->get_legacy; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->get_legacy; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->set_legacy; + default: + return NULL; } } @@ -174,11 +200,24 @@ EAPI Eina_Bool eolian_function_is_virtual_pure(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_virtual_pure; break; - case EOLIAN_PROP_SET: return fid->set_virtual_pure; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EINA_FALSE; + return fid->get_virtual_pure; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->get_virtual_pure; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->set_virtual_pure; + default: + return EINA_FALSE; } } @@ -186,11 +225,24 @@ EAPI Eina_Bool eolian_function_is_auto(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_auto; break; - case EOLIAN_PROP_SET: return fid->set_auto; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EINA_FALSE; + return fid->get_auto; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->get_auto; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->set_auto; + default: + return EINA_FALSE; } } @@ -198,11 +250,24 @@ EAPI Eina_Bool eolian_function_is_empty(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_empty; break; - case EOLIAN_PROP_SET: return fid->set_empty; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EINA_FALSE; + return fid->get_empty; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->get_empty; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->set_empty; + default: + return EINA_FALSE; } } @@ -210,11 +275,24 @@ EAPI Eina_Bool eolian_function_is_legacy_only(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_only_legacy; break; - case EOLIAN_PROP_SET: return fid->set_only_legacy; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EINA_FALSE; + return fid->get_only_legacy; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->get_only_legacy; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->set_only_legacy; + default: + return EINA_FALSE; } } @@ -288,33 +366,75 @@ eolian_function_parameters_get(const Eolian_Function *fid) EAPI const Eolian_Type * eolian_function_return_type_get(const Eolian_Function *fid, Eolian_Function_Type ftype) { + EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, NULL); switch (ftype) { - case EOLIAN_PROP_SET: return fid->set_ret_type; - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROP_GET: return fid->get_ret_type; - default: return NULL; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return NULL; + return fid->get_ret_type; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->get_ret_type; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->set_ret_type; + default: + return NULL; } } EAPI const Eolian_Expression * eolian_function_return_default_value_get(const Eolian_Function *fid, Eolian_Function_Type ftype) { + EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, NULL); switch (ftype) { - case EOLIAN_PROP_SET: return fid->set_ret_val; - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_ret_val; - default: return NULL; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return NULL; + return fid->get_ret_val; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->get_ret_val; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->set_ret_val; + default: + return NULL; } } EAPI const Eolian_Documentation * eolian_function_return_documentation_get(const Eolian_Function *fid, Eolian_Function_Type ftype) { + EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, NULL); switch (ftype) { - case EOLIAN_PROP_SET: return fid->set_return_doc; break; - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_return_doc; break; - default: return NULL; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return NULL; + return fid->get_return_doc; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->get_return_doc; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return NULL; + return fid->set_return_doc; + default: + return NULL; } } @@ -323,11 +443,24 @@ eolian_function_return_is_warn_unused(const Eolian_Function *fid, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_PROP_SET: return fid->set_return_warn_unused; - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_return_warn_unused; - default: return EINA_FALSE; + case EOLIAN_METHOD: + if (fid->type != EOLIAN_METHOD) + return EINA_FALSE; + return fid->get_return_warn_unused; + case EOLIAN_PROP_GET: + if ((fid->type != EOLIAN_PROP_GET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->get_return_warn_unused; + case EOLIAN_PROP_SET: + if ((fid->type != EOLIAN_PROP_SET) && (fid->type != EOLIAN_PROPERTY)) + return EINA_FALSE; + return fid->set_return_warn_unused; + default: + return EINA_FALSE; } } diff --git a/src/lib/eolian/database_implement_api.c b/src/lib/eolian/database_implement_api.c index 4cd31db..d97e584 100644 --- a/src/lib/eolian/database_implement_api.c +++ b/src/lib/eolian/database_implement_api.c @@ -47,11 +47,18 @@ EAPI Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_auto; break; - case EOLIAN_PROP_SET: return impl->set_auto; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + return impl->get_auto && !impl->is_prop_get && !impl->is_prop_set; + case EOLIAN_PROP_GET: + return impl->get_auto && impl->is_prop_get; + case EOLIAN_PROP_SET: + return impl->set_auto && impl->is_prop_set; + default: + return EINA_FALSE; } } @@ -59,11 +66,18 @@ EAPI Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_empty; break; - case EOLIAN_PROP_SET: return impl->set_empty; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + return impl->get_empty && !impl->is_prop_get && !impl->is_prop_set; + case EOLIAN_PROP_GET: + return impl->get_empty && impl->is_prop_get; + case EOLIAN_PROP_SET: + return impl->set_empty && impl->is_prop_set; + default: + return EINA_FALSE; } } @@ -71,11 +85,18 @@ EAPI Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl, Eolian_Function_Type ftype) { EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_UNRESOLVED, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(ftype != EOLIAN_PROPERTY, EINA_FALSE); switch (ftype) { - case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_virtual; break; - case EOLIAN_PROP_SET: return impl->set_virtual; break; - default: return EINA_FALSE; + case EOLIAN_METHOD: + return impl->get_virtual && !impl->is_prop_get && !impl->is_prop_set; + case EOLIAN_PROP_GET: + return impl->get_virtual && impl->is_prop_get; + case EOLIAN_PROP_SET: + return impl->set_virtual && impl->is_prop_set; + default: + return EINA_FALSE; } } diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 0c8157a..2bb2122 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -325,6 +325,7 @@ void database_class_del(Eolian_Class *cl); /* functions */ void database_function_del(Eolian_Function *fid); void database_function_constructor_add(Eolian_Function *func, const Eolian_Class *klass); +Eina_Bool database_function_is_type(Eolian_Function *fid, Eolian_Function_Type ftype); /* func parameters */ void database_parameter_del(Eolian_Function_Parameter *pdesc); diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index 3e8e4eb..fc94534 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -186,8 +186,8 @@ START_TEST(eolian_override) fail_if(!(base = eolian_class_get_by_name("Base"))); /* 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(!(fid = eolian_class_function_get_by_name(base, "constructor", EOLIAN_METHOD))); + fail_if(!eolian_function_is_virtual_pure(fid, EOLIAN_METHOD)); /* Property */ fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY))); @@ -499,10 +499,11 @@ START_TEST(eolian_scope) fail_if(!(class = eolian_class_get_by_name("Scope"))); /* Property scope */ - fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY))); - fail_if(eolian_function_scope_get(fid, EOLIAN_PROPERTY) != EOLIAN_SCOPE_PROTECTED); - fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROPERTY))); - fail_if(eolian_function_scope_get(fid, EOLIAN_PROPERTY) != EOLIAN_SCOPE_PUBLIC); + fail_if(eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY)); + fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROP_GET))); + fail_if(eolian_function_scope_get(fid, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PROTECTED); + fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROP_GET))); + fail_if(eolian_function_scope_get(fid, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PUBLIC); fail_if(!(fid = eolian_class_function_get_by_name(class, "c", EOLIAN_PROPERTY))); fail_if(eolian_function_scope_get(fid, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PUBLIC); fail_if(eolian_function_scope_get(fid, EOLIAN_PROP_SET) != EOLIAN_SCOPE_PROTECTED); @@ -590,7 +591,8 @@ START_TEST(eolian_simple_parsing) fail_if(v.value.i != 100); /* legacy only + c only */ - fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROPERTY))); + fail_if(eolian_class_function_get_by_name(class, "b", EOLIAN_PROPERTY)); + fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROP_SET))); fail_if(eolian_function_is_legacy_only(fid, EOLIAN_PROP_GET)); fail_if(!eolian_function_is_legacy_only(fid, EOLIAN_PROP_SET)); fail_if(!eolian_function_is_c_only(fid)); @@ -945,9 +947,10 @@ START_TEST(eolian_class_funcs) fail_if(!(class = eolian_class_get_by_name("Class_Funcs"))); /* Class properties */ - fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY))); + fail_if(eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY)); + fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROP_GET))); fail_if(!eolian_function_is_class(fid)); - fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROPERTY))); + fail_if(!(fid = eolian_class_function_get_by_name(class, "b", EOLIAN_PROP_GET))); fail_if(eolian_function_is_class(fid)); /* Class methods */ -- 2.7.4