eolian-cxx: Add property_def

Summary:
While individual getters and setters are added to the list of methods of
a class, property_def will hold them as a pair.

This will help defining accessors like C#'s where they're grouped.

Also update some eolian-cxx tests that were commented out.

Depends: D7262

Test Plan: run eolian-cxx tests

Reviewers: vitor.sousa, felipealmeida

Reviewed By: vitor.sousa

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D7389
This commit is contained in:
Lauro Moura 2018-11-30 19:34:43 -02:00 committed by Christopher Michael
parent db579aad3b
commit 22c8bc2f59
7 changed files with 188 additions and 11 deletions

View File

@ -178,6 +178,7 @@ tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
-I$(top_builddir)/src/tests/eolian_cxx \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
-DEO_SRC_DIR=\"$(top_srcdir)/src/lib\" \
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
-DPACKAGE_DATA_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_cxx\" \

View File

@ -175,7 +175,7 @@ struct documentation_def
std::string since;
std::vector<std::string> desc_paragraphs;
documentation_def() {}
documentation_def() = default;
documentation_def(std::string summary, std::string description, std::string since)
: summary(summary), description(description), since(since)
{}
@ -296,7 +296,7 @@ struct type_def
bool has_own;
bool is_ptr;
type_def() {}
type_def() = default;
type_def(variant_type original_type, std::string c_type, bool has_own)
: original_type(original_type), c_type(c_type), has_own(has_own) {}
@ -798,6 +798,40 @@ struct tuple_element<2ul, function_def>
static type const& get(function_def const& f) { return f.parameters; }
};
struct property_def
{
klass_name klass;
std::string name;
efl::eina::optional<function_def> getter;
efl::eina::optional<function_def> setter;
friend inline bool operator==(property_def const& lhs, property_def const& rhs)
{
return lhs.klass == rhs.klass
&& lhs.name == rhs.name
&& lhs.getter == rhs.getter
&& lhs.setter == rhs.setter;
}
friend inline bool operator!=(property_def const& lhs, property_def const& rhs)
{
return !(lhs == rhs);
}
property_def() = default;
property_def(Eolian_Function const *function, efl::eina::optional<function_def> getter
, efl::eina::optional<function_def> setter, Eolian_Unit const* unit)
: getter(getter), setter(setter)
{
name = ::eolian_function_name_get(function);
const Eolian_Class *eolian_klass = eolian_function_class_get(function);
klass = klass_name(eolian_klass, {attributes::qualifier_info::is_none, std::string()});
}
};
// template <int N>
// struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
// template <int N>
@ -938,6 +972,7 @@ struct klass_def
documentation_def documentation;
std::vector<std::string> namespaces;
std::vector<function_def> functions;
std::vector<property_def> properties;
std::set<klass_name, compare_klass_name_by_name> inherits;
class_type type;
std::vector<event_def> events;
@ -952,6 +987,7 @@ struct klass_def
&& lhs.filename == lhs.filename
&& lhs.namespaces == rhs.namespaces
&& lhs.functions == rhs.functions
&& lhs.properties == rhs.properties
&& lhs.inherits == rhs.inherits
&& lhs.type == rhs.type
&& lhs.events == rhs.events
@ -973,23 +1009,25 @@ struct klass_def
, documentation_def documentation
, std::vector<std::string> namespaces
, std::vector<function_def> functions
, std::vector<property_def> properties
, std::set<klass_name, compare_klass_name_by_name> inherits
, class_type type
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
, documentation(documentation)
, namespaces(namespaces)
, functions(functions), inherits(inherits), type(type)
, functions(functions), properties(properties), inherits(inherits), type(type)
, immediate_inherits(immediate_inherits)
{}
klass_def(std::string _eolian_name, std::string _cxx_name
, std::vector<std::string> _namespaces
, std::vector<function_def> _functions
, std::vector<property_def> _properties
, std::set<klass_name, compare_klass_name_by_name> _inherits
, class_type _type, Eolian_Unit const* unit)
: eolian_name(_eolian_name), cxx_name(_cxx_name)
, namespaces(_namespaces)
, functions(_functions), inherits(_inherits), type(_type), unit(unit)
, functions(_functions), properties(_properties), inherits(_inherits), type(_type), unit(unit)
{}
klass_def(Eolian_Class const* klass, Eolian_Unit const* unit) : unit(unit)
{
@ -1007,22 +1045,45 @@ struct klass_def
Eolian_Function_Type func_type = ::eolian_function_type_get(function);
if(func_type == EOLIAN_PROPERTY)
{
efl::eina::optional<function_def> getter(nullptr);
efl::eina::optional<function_def> setter(nullptr);
try {
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET)
&& ::eolian_function_scope_get(function, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PRIVATE)
functions.push_back({function, EOLIAN_PROP_GET, NULL, unit});
{
function_def f(function, EOLIAN_PROP_GET, NULL, unit);
functions.push_back(f);
getter = efl::eina::optional<function_def>(f);
}
} catch(std::exception const&) {}
try {
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET)
&& ::eolian_function_scope_get(function, EOLIAN_PROP_SET) != EOLIAN_SCOPE_PRIVATE)
functions.push_back({function, EOLIAN_PROP_SET, NULL, unit});
{
function_def f(function, EOLIAN_PROP_SET, NULL, unit);
functions.push_back(f);
setter = efl::eina::optional<function_def>(f);
}
} catch(std::exception const&) {}
if (getter.is_engaged() || setter.is_engaged())
properties.push_back({function, getter, setter, unit});
}
else
try {
if(! ::eolian_function_is_legacy_only(function, func_type)
&& ::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE)
functions.push_back({function, func_type, NULL, unit});
{
efl::eina::optional<function_def> getter(nullptr);
efl::eina::optional<function_def> setter(nullptr);
function_def f(function, func_type, NULL, unit);
if (func_type == EOLIAN_PROP_GET)
getter = efl::eina::optional<function_def>(f);
else if (func_type == EOLIAN_PROP_SET)
setter = efl::eina::optional<function_def>(f);
functions.push_back(f);
if (func_type == EOLIAN_PROP_GET || func_type == EOLIAN_PROP_SET)
properties.push_back({function, getter, setter, unit});
}
} catch(std::exception const&) {}
}
for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD))
@ -1154,7 +1215,7 @@ struct value_def
std::string literal;
type_def type;
value_def() {}
value_def() = default;
value_def(Eolian_Value value_obj)
{
type.set(value_obj.type);

View File

@ -4,7 +4,7 @@ class Complex_Type {
methods {
@property a {
set {
return: list<array<ptr(Eo) @owned> > @owned;
return: list<array<Eo @owned> > @owned;
}
get {
}

View File

@ -4,6 +4,8 @@
#include <Ecore.h>
#include <map>
#include <generic.eo.hh>
#include <generic.eo.impl.hh>
#include <name1_name2_type_generation.eo.hh>
@ -11,6 +13,9 @@
#include "eolian_cxx_suite.h"
#include <Eolian_Cxx.hh>
#include "grammar/klass_def.hpp"
EFL_START_TEST(eolian_cxx_test_binding_constructor_only_required)
{
efl::eo::eo_init init;
@ -223,6 +228,70 @@ EFL_START_TEST(eolian_cxx_test_type_callback)
}
EFL_END_TEST
using efl::eolian::grammar::attributes::klass_def;
using efl::eolian::grammar::attributes::function_def;
using efl::eolian::grammar::attributes::property_def;
using efl::eolian::grammar::attributes::type_def;
// FIXME Unify this definition some so we can share it with documentation tests.
static
klass_def init_test_data(std::string const target_file, std::string const target_klass, efl::eolian::eolian_state const& state)
{
ck_assert(::eolian_state_directory_add(state.value, TESTS_SRC_DIR));
ck_assert(::eolian_state_directory_add(state.value, EO_SRC_DIR));
ck_assert(::eolian_state_all_eot_files_parse(state.value));
std::string filename = TESTS_SRC_DIR;
filename += "/" + target_file;
ck_assert(::eolian_state_file_parse(state.value, filename.c_str()));
const Eolian_Class *c_klass = ::eolian_state_class_by_name_get(state.value, target_klass.c_str());
ck_assert_ptr_ne(c_klass, NULL);
klass_def klass(c_klass, state.as_unit());
return klass;
}
EFL_START_TEST(eolian_cxx_test_properties)
{
efl::eolian::eolian_init eolian_init;
efl::eolian::eolian_state eolian_state;
klass_def cls = init_test_data("property_holder.eo", "Property_Holder", eolian_state);
// FIXME Currently parsing only properties with both get/set values.
auto props = cls.properties;
ck_assert_int_eq(4, cls.properties.size());
ck_assert("prop_simple" == props[0].name);
ck_assert("getter_only" == props[1].name);
ck_assert("setter_only" == props[2].name);
ck_assert("prop_with_key" == props[3].name);
auto property = props[0];
ck_assert(property.getter.is_engaged());
ck_assert(property.setter.is_engaged());
ck_assert(property.getter->name == "prop_simple_get");
ck_assert(property.setter->name == "prop_simple_set");
auto function = std::find_if(cls.functions.cbegin(), cls.functions.cend(), [](const function_def &f) {
return f.name == "prop_simple_get";
});
ck_assert(*property.getter == *function);
property = props[1];
ck_assert(property.getter.is_engaged());
ck_assert(!property.setter.is_engaged());
property = props[2];
ck_assert(!property.getter.is_engaged());
ck_assert(property.setter.is_engaged());
property = props[3];
ck_assert(property.getter.is_engaged());
ck_assert(property.setter.is_engaged());
}
EFL_END_TEST
void
eolian_cxx_test_binding(TCase* tc)
{
@ -233,4 +302,5 @@ eolian_cxx_test_binding(TCase* tc)
tcase_add_test(tc, eolian_cxx_test_type_generation_return);
tcase_add_test(tc, eolian_cxx_test_type_generation_optional);
tcase_add_test(tc, eolian_cxx_test_type_callback);
tcase_add_test(tc, eolian_cxx_test_properties);
}

View File

@ -12,8 +12,10 @@
EFL_START_TEST(eolian_cxx_test_parse_complex_types)
{
efl::eolian::eolian_init init;
// fail_if(!::eolian_state_directory_add(PACKAGE_DATA_DIR"/data"));
// fail_if(!::eolian_state_file_parse(PACKAGE_DATA_DIR"/data/complex_type.eo"));
efl::eolian::eolian_state state;
fail_if(!::eolian_state_directory_add(state.value, EO_SRC_DIR));
fail_if(!::eolian_state_directory_add(state.value, TESTS_SRC_DIR));
fail_if(!::eolian_state_file_parse(state.value, TESTS_SRC_DIR"/complex.eo"));
// TODO finish
}
EFL_END_TEST

View File

@ -65,6 +65,7 @@ eolian_cxx_suite = executable('eolian_cxx_suite',
# package_c_args contains -D definitions for the package
cpp_args : package_c_args +[
'-DTESTS_BUILD_DIR="'+meson.current_build_dir()+'"',
'-DEO_SRC_DIR="'+join_paths(meson.source_root(), 'src', 'lib')+'"',
'-DTESTS_SRC_DIR="'+meson.current_source_dir()+'"']
)

View File

@ -0,0 +1,42 @@
class Property_Holder extends Efl.Object
{
methods {
some_method {
return: int;
}
@property prop_simple {
get {}
set {}
values {
data: int;
}
}
@property getter_only {
get {}
values {
data: int;
}
}
@property setter_only {
set {}
values {
data: int;
}
}
@property prop_with_key {
get {}
set {}
values {
data: int;
}
keys {
key: string;
}
}
}
}