From 1933735635aa72cf7be96c47b1e5b8a5ee318323 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Wed, 31 Oct 2018 02:47:58 +0100 Subject: [PATCH] eolian: Add @ctor_param parameter to constructors Summary: This tagging keyword explicitly asks, for bindings that support it, that the constructor's parameters are added to the class constructor. Allowing the user to instantiate the class and call the constructor in a straightforward way. Reviewers: q66, woohyun, bu5hm4n, Jaehyun_Cho, segfaultxavi Reviewed By: q66 Subscribers: cedric, #reviewers, #committers, lauromoura Tags: #efl Differential Revision: https://phab.enlightenment.org/D7221 --- src/lib/eolian/Eolian.h | 10 ++++++++++ src/lib/eolian/database_constructor_api.c | 7 +++++++ src/lib/eolian/eo_lexer.h | 2 +- src/lib/eolian/eo_parser.c | 22 ++++++++++++++++++---- src/lib/eolian/eolian_database.h | 1 + src/tests/eolian/data/ctor_dtor.eo | 6 ++++++ src/tests/eolian/eolian_parsing.c | 9 +++++++++ 7 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index b5241ead86..f626ce82ca 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -1988,6 +1988,16 @@ EAPI const Eolian_Function *eolian_constructor_function_get(const Eolian_Constru */ EAPI Eina_Bool eolian_constructor_is_optional(const Eolian_Constructor *ctor); +/* + * @brief Checks if a constructor is tagged as a constructor parameter. + * + * @param[in] ctor the handle of the constructor + * @return EINA_TRUE if a constructor parameter, EINA_FALSE if not (or if input is NULL). + * + * @ingroup Eolian + */ +EAPI Eina_Bool eolian_constructor_is_ctor_param(const Eolian_Constructor *ctor); + /* * @brief Get an iterator to the constructing functions defined in a class. * diff --git a/src/lib/eolian/database_constructor_api.c b/src/lib/eolian/database_constructor_api.c index bedf9ab7da..63b935cc6c 100644 --- a/src/lib/eolian/database_constructor_api.c +++ b/src/lib/eolian/database_constructor_api.c @@ -29,3 +29,10 @@ eolian_constructor_is_optional(const Eolian_Constructor *ctor) EINA_SAFETY_ON_NULL_RETURN_VAL(ctor, EINA_FALSE); return ctor->is_optional; } + +EAPI Eina_Bool +eolian_constructor_is_ctor_param(const Eolian_Constructor *ctor) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(ctor, EINA_FALSE); + return ctor->is_ctor_param; +} diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index 846123937c..fc70a0c914 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -60,7 +60,7 @@ enum Tokens KW(function), \ KW(__undefined_type), \ \ - KW(true), KW(false), KW(null) + KW(true), KW(false), KW(null), KWAT(ctor_param) /* "regular" keyword and @ prefixed keyword */ #define KW(x) KW_##x diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 90b0db60ae..f55e3e1744 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -1655,10 +1655,17 @@ parse_constructor(Eo_Lexer *ls) ls->klass->base.name, ls->t.value.s); eo_lexer_get(ls); - if (ls->t.kw == KW_at_optional) + while (ls->t.kw == KW_at_optional || ls->t.kw == KW_at_ctor_param) { + if (ls->t.kw == KW_at_optional) + { + ctor->is_optional = EINA_TRUE; + } + if (ls->t.kw == KW_at_ctor_param) + { + ctor->is_ctor_param = EINA_TRUE; + } eo_lexer_get(ls); - ctor->is_optional = EINA_TRUE; } check_next(ls, ';'); return; @@ -1679,10 +1686,17 @@ parse_constructor(Eo_Lexer *ls) if (ls->t.token != '.') break; eo_lexer_get(ls); } - if (ls->t.kw == KW_at_optional) + while (ls->t.kw == KW_at_optional || ls->t.kw == KW_at_ctor_param) { + if (ls->t.kw == KW_at_optional) + { + ctor->is_optional = EINA_TRUE; + } + if (ls->t.kw == KW_at_ctor_param) + { + ctor->is_ctor_param = EINA_TRUE; + } eo_lexer_get(ls); - ctor->is_optional = EINA_TRUE; } check_next(ls, ';'); ctor->base.name = eina_stringshare_add(eina_strbuf_string_get(buf)); diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index dfbad0c304..3f3ab61b18 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -309,6 +309,7 @@ struct _Eolian_Constructor Eolian_Object base; const Eolian_Class *klass; Eina_Bool is_optional: 1; + Eina_Bool is_ctor_param : 1; }; struct _Eolian_Event diff --git a/src/tests/eolian/data/ctor_dtor.eo b/src/tests/eolian/data/ctor_dtor.eo index 0cc36a9f85..98452b1018 100644 --- a/src/tests/eolian/data/ctor_dtor.eo +++ b/src/tests/eolian/data/ctor_dtor.eo @@ -8,6 +8,11 @@ class Ctor_Dtor (Base) { } custom_constructor_2 { } + custom_constructor_3 { + params { + @in z: int; + } + } } implements { class.constructor; @@ -18,5 +23,6 @@ class Ctor_Dtor (Base) { constructors { .custom_constructor_1; .custom_constructor_2 @optional; + .custom_constructor_3 @ctor_param; } } diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index 8f4d015663..f29d5060c0 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -272,6 +272,7 @@ EFL_START_TEST(eolian_ctor_dtor) fail_if(!(eina_iterator_next(iter, (void**)&impl))); fail_if(!(eina_iterator_next(iter, (void**)&impl))); fail_if(!(eina_iterator_next(iter, (void**)&impl))); + fail_if(!(eina_iterator_next(iter, (void**)&impl))); fail_if(!(impl_class = eolian_implement_class_get(impl))); fail_if(!(impl_func = eolian_implement_function_get(impl, NULL))); fail_if(impl_class != base); @@ -306,6 +307,14 @@ EFL_START_TEST(eolian_ctor_dtor) fail_if(strcmp(eolian_function_name_get(impl_func), "custom_constructor_2")); fail_if(!eolian_function_is_constructor(impl_func, class)); fail_if(eolian_function_is_constructor(impl_func, base)); + fail_if(!(eina_iterator_next(iter, (void**)&ctor))); + fail_if(!eolian_constructor_is_ctor_param(ctor)); + fail_if(!(impl_class = eolian_constructor_class_get(ctor))); + fail_if(!(impl_func = eolian_constructor_function_get(ctor))); + fail_if(impl_class != class); + fail_if(strcmp(eolian_function_name_get(impl_func), "custom_constructor_3")); + fail_if(!eolian_function_is_constructor(impl_func, class)); + fail_if(eolian_function_is_constructor(impl_func, base)); fail_if(eina_iterator_next(iter, &dummy)); eina_iterator_free(iter);