forked from enlightenment/efl
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:
parent
6b0c85cb0d
commit
98b716d0fa
|
@ -178,6 +178,7 @@ tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
|
||||||
-I$(top_builddir)/src/tests/eolian_cxx \
|
-I$(top_builddir)/src/tests/eolian_cxx \
|
||||||
-DTESTS_WD=\"`pwd`\" \
|
-DTESTS_WD=\"`pwd`\" \
|
||||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
|
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
|
||||||
|
-DEO_SRC_DIR=\"$(top_srcdir)/src/lib\" \
|
||||||
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
|
-DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)\" \
|
||||||
-DPACKAGE_DATA_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
|
-DPACKAGE_DATA_DIR=\"$(top_srcdir)/src/tests/eolian_cxx\" \
|
||||||
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_cxx\" \
|
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eolian_cxx\" \
|
||||||
|
|
|
@ -175,7 +175,7 @@ struct documentation_def
|
||||||
std::string since;
|
std::string since;
|
||||||
std::vector<std::string> desc_paragraphs;
|
std::vector<std::string> desc_paragraphs;
|
||||||
|
|
||||||
documentation_def() {}
|
documentation_def() = default;
|
||||||
documentation_def(std::string summary, std::string description, std::string since)
|
documentation_def(std::string summary, std::string description, std::string since)
|
||||||
: summary(summary), description(description), since(since)
|
: summary(summary), description(description), since(since)
|
||||||
{}
|
{}
|
||||||
|
@ -296,7 +296,7 @@ struct type_def
|
||||||
bool has_own;
|
bool has_own;
|
||||||
bool is_ptr;
|
bool is_ptr;
|
||||||
|
|
||||||
type_def() {}
|
type_def() = default;
|
||||||
type_def(variant_type original_type, std::string c_type, bool has_own)
|
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) {}
|
: 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; }
|
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>
|
// template <int N>
|
||||||
// struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
|
// struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
|
||||||
// template <int N>
|
// template <int N>
|
||||||
|
@ -938,6 +972,7 @@ struct klass_def
|
||||||
documentation_def documentation;
|
documentation_def documentation;
|
||||||
std::vector<std::string> namespaces;
|
std::vector<std::string> namespaces;
|
||||||
std::vector<function_def> functions;
|
std::vector<function_def> functions;
|
||||||
|
std::vector<property_def> properties;
|
||||||
std::set<klass_name, compare_klass_name_by_name> inherits;
|
std::set<klass_name, compare_klass_name_by_name> inherits;
|
||||||
class_type type;
|
class_type type;
|
||||||
std::vector<event_def> events;
|
std::vector<event_def> events;
|
||||||
|
@ -952,6 +987,7 @@ struct klass_def
|
||||||
&& lhs.filename == lhs.filename
|
&& lhs.filename == lhs.filename
|
||||||
&& lhs.namespaces == rhs.namespaces
|
&& lhs.namespaces == rhs.namespaces
|
||||||
&& lhs.functions == rhs.functions
|
&& lhs.functions == rhs.functions
|
||||||
|
&& lhs.properties == rhs.properties
|
||||||
&& lhs.inherits == rhs.inherits
|
&& lhs.inherits == rhs.inherits
|
||||||
&& lhs.type == rhs.type
|
&& lhs.type == rhs.type
|
||||||
&& lhs.events == rhs.events
|
&& lhs.events == rhs.events
|
||||||
|
@ -973,23 +1009,25 @@ struct klass_def
|
||||||
, documentation_def documentation
|
, documentation_def documentation
|
||||||
, std::vector<std::string> namespaces
|
, std::vector<std::string> namespaces
|
||||||
, std::vector<function_def> functions
|
, std::vector<function_def> functions
|
||||||
|
, std::vector<property_def> properties
|
||||||
, std::set<klass_name, compare_klass_name_by_name> inherits
|
, std::set<klass_name, compare_klass_name_by_name> inherits
|
||||||
, class_type type
|
, class_type type
|
||||||
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
|
, std::set<klass_name, compare_klass_name_by_name> immediate_inherits)
|
||||||
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
|
: eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
|
||||||
, documentation(documentation)
|
, documentation(documentation)
|
||||||
, namespaces(namespaces)
|
, namespaces(namespaces)
|
||||||
, functions(functions), inherits(inherits), type(type)
|
, functions(functions), properties(properties), inherits(inherits), type(type)
|
||||||
, immediate_inherits(immediate_inherits)
|
, immediate_inherits(immediate_inherits)
|
||||||
{}
|
{}
|
||||||
klass_def(std::string _eolian_name, std::string _cxx_name
|
klass_def(std::string _eolian_name, std::string _cxx_name
|
||||||
, std::vector<std::string> _namespaces
|
, std::vector<std::string> _namespaces
|
||||||
, std::vector<function_def> _functions
|
, std::vector<function_def> _functions
|
||||||
|
, std::vector<property_def> _properties
|
||||||
, std::set<klass_name, compare_klass_name_by_name> _inherits
|
, std::set<klass_name, compare_klass_name_by_name> _inherits
|
||||||
, class_type _type, Eolian_Unit const* unit)
|
, class_type _type, Eolian_Unit const* unit)
|
||||||
: eolian_name(_eolian_name), cxx_name(_cxx_name)
|
: eolian_name(_eolian_name), cxx_name(_cxx_name)
|
||||||
, namespaces(_namespaces)
|
, 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)
|
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);
|
Eolian_Function_Type func_type = ::eolian_function_type_get(function);
|
||||||
if(func_type == EOLIAN_PROPERTY)
|
if(func_type == EOLIAN_PROPERTY)
|
||||||
{
|
{
|
||||||
|
efl::eina::optional<function_def> getter(nullptr);
|
||||||
|
efl::eina::optional<function_def> setter(nullptr);
|
||||||
try {
|
try {
|
||||||
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET)
|
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET)
|
||||||
&& ::eolian_function_scope_get(function, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PRIVATE)
|
&& ::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&) {}
|
} catch(std::exception const&) {}
|
||||||
try {
|
try {
|
||||||
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET)
|
if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET)
|
||||||
&& ::eolian_function_scope_get(function, EOLIAN_PROP_SET) != EOLIAN_SCOPE_PRIVATE)
|
&& ::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&) {}
|
} catch(std::exception const&) {}
|
||||||
|
if (getter.is_engaged() || setter.is_engaged())
|
||||||
|
properties.push_back({function, getter, setter, unit});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
try {
|
try {
|
||||||
if(! ::eolian_function_is_legacy_only(function, func_type)
|
if(! ::eolian_function_is_legacy_only(function, func_type)
|
||||||
&& ::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE)
|
&& ::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&) {}
|
} catch(std::exception const&) {}
|
||||||
}
|
}
|
||||||
for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD))
|
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;
|
std::string literal;
|
||||||
type_def type;
|
type_def type;
|
||||||
|
|
||||||
value_def() {}
|
value_def() = default;
|
||||||
value_def(Eolian_Value value_obj)
|
value_def(Eolian_Value value_obj)
|
||||||
{
|
{
|
||||||
type.set(value_obj.type);
|
type.set(value_obj.type);
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Complex_Type {
|
||||||
methods {
|
methods {
|
||||||
@property a {
|
@property a {
|
||||||
set {
|
set {
|
||||||
return: list<array<ptr(Eo) @owned> > @owned;
|
return: list<array<Eo @owned> > @owned;
|
||||||
}
|
}
|
||||||
get {
|
get {
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <Ecore.h>
|
#include <Ecore.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <generic.eo.hh>
|
#include <generic.eo.hh>
|
||||||
#include <generic.eo.impl.hh>
|
#include <generic.eo.impl.hh>
|
||||||
#include <name1_name2_type_generation.eo.hh>
|
#include <name1_name2_type_generation.eo.hh>
|
||||||
|
@ -11,6 +13,9 @@
|
||||||
|
|
||||||
#include "eolian_cxx_suite.h"
|
#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_START_TEST(eolian_cxx_test_binding_constructor_only_required)
|
||||||
{
|
{
|
||||||
efl::eo::eo_init init;
|
efl::eo::eo_init init;
|
||||||
|
@ -223,6 +228,70 @@ EFL_START_TEST(eolian_cxx_test_type_callback)
|
||||||
}
|
}
|
||||||
EFL_END_TEST
|
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
|
void
|
||||||
eolian_cxx_test_binding(TCase* tc)
|
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_return);
|
||||||
tcase_add_test(tc, eolian_cxx_test_type_generation_optional);
|
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_type_callback);
|
||||||
|
tcase_add_test(tc, eolian_cxx_test_properties);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
EFL_START_TEST(eolian_cxx_test_parse_complex_types)
|
EFL_START_TEST(eolian_cxx_test_parse_complex_types)
|
||||||
{
|
{
|
||||||
efl::eolian::eolian_init init;
|
efl::eolian::eolian_init init;
|
||||||
// fail_if(!::eolian_state_directory_add(PACKAGE_DATA_DIR"/data"));
|
efl::eolian::eolian_state state;
|
||||||
// fail_if(!::eolian_state_file_parse(PACKAGE_DATA_DIR"/data/complex_type.eo"));
|
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
|
// TODO finish
|
||||||
}
|
}
|
||||||
EFL_END_TEST
|
EFL_END_TEST
|
||||||
|
|
|
@ -65,6 +65,7 @@ eolian_cxx_suite = executable('eolian_cxx_suite',
|
||||||
# package_c_args contains -D definitions for the package
|
# package_c_args contains -D definitions for the package
|
||||||
cpp_args : package_c_args +[
|
cpp_args : package_c_args +[
|
||||||
'-DTESTS_BUILD_DIR="'+meson.current_build_dir()+'"',
|
'-DTESTS_BUILD_DIR="'+meson.current_build_dir()+'"',
|
||||||
|
'-DEO_SRC_DIR="'+join_paths(meson.source_root(), 'src', 'lib')+'"',
|
||||||
'-DTESTS_SRC_DIR="'+meson.current_source_dir()+'"']
|
'-DTESTS_SRC_DIR="'+meson.current_source_dir()+'"']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue