lauromoura pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=135c69b23c7d091bb114022f3eb0c1788758a67c

commit 135c69b23c7d091bb114022f3eb0c1788758a67c
Author: Lauro Moura <[email protected]>
Date:   Mon Oct 28 20:35:39 2019 -0300

    eolian_cxx: Add key/value to function_def
    
    Summary:
    This commit adds explicit eolian key/value/return info to function_def. The
    original parameter/return types are kept for compatibility.
    
    parameter/return -> Mimics the behavior of the generated C API (i.e.
    single-valued getters have their lone value translated to be their
    return type)
    
    explicit_return -> The actual return value for that block in the EO
    file.
    keys/values -> The values for respectively key and values blocks.
    
    This should help working with properties in the generators instead of
    fumbling with paremeter/return directly
    
    Fixes T8431
    
    Test Plan: extra tests in the diff
    
    Reviewers: felipealmeida, brunobelo, segfaultxavi, YOhoho
    
    Reviewed By: brunobelo
    
    Subscribers: cedric, #reviewers, #committers, woohyun
    
    Tags: #efl
    
    Maniphest Tasks: T8431
    
    Differential Revision: https://phab.enlightenment.org/D10494
---
 src/lib/eolian_cxx/grammar/klass_def.hpp        |  85 ++++++++--------
 src/tests/eolian_cxx/eolian_cxx_test_binding.cc | 126 +++++++++++++++++++++++-
 src/tests/eolian_cxx/property_holder.eo         |  42 ++++++++
 3 files changed, 210 insertions(+), 43 deletions(-)

diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp 
b/src/lib/eolian_cxx/grammar/klass_def.hpp
index 3356a6ff77..d6969315e7 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -778,16 +778,35 @@ enum class member_scope
 
 struct function_def
 {
-  klass_name klass; // Klass information for function_def as method
-  type_def return_type;
+  // Klass information for function_def as method
+  klass_name klass;
+  // Eolian name of the function
   std::string name;
+
+  // Actual return type as expected in the C version of this function.
+  // For property getters, this could be the type of the single
+  // value it holds
+  type_def return_type;
+  // Parameters of this function as the C implementation of it
   std::vector<parameter_def> parameters;
+
+  // Original return type as declared in the Eo.
+  type_def explicit_return_type;
+  // Original Eolian keys of this function. Used only for properties
+  std::vector<parameter_def> keys;
+  // Original Eolian values of this function. Used only for properties
+  std::vector<parameter_def> values;
+
+  // Name of this function in the C api
   std::string c_name;
   std::string filename;
-  std::vector<std::string> namespaces; // Namespaces for top-level function 
pointers
+  // Namespaces for top-level function pointers
+  std::vector<std::string> namespaces;
+
   documentation_def documentation;
   documentation_def return_documentation;
   documentation_def property_documentation;
+
   function_type type;
   member_scope scope;
   bool is_beta;
@@ -801,6 +820,8 @@ struct function_def
       && lhs.return_type == rhs.return_type
       && lhs.name == rhs.name
       && lhs.parameters == rhs.parameters
+      && lhs.keys == rhs.keys
+      && lhs.values == rhs.values
       && lhs.c_name == rhs.c_name
       && lhs.filename == rhs.filename
       && lhs.namespaces == rhs.namespaces
@@ -818,46 +839,25 @@ struct function_def
     return !(lhs == rhs);
   }
   function_def() = default;
-  function_def(klass_name _klass,
-               type_def _return_type, std::string const& _name,
-               std::vector<parameter_def> const& _parameters,
-               std::string const& _c_name,
-               std::string _filename,
-               std::vector<std::string> const& _namespaces,
-               documentation_def _documentation,
-               documentation_def _return_documentation,
-               documentation_def _property_documentation,
-               function_type _type,
-               member_scope _scope,
-               bool _is_beta = false,
-               bool _is_protected = false,
-               bool _is_static = false,
-               Eolian_Unit const* unit = nullptr)
-    : klass(_klass), return_type(_return_type), name(_name),
-      parameters(_parameters), c_name(_c_name), filename(_filename),
-      namespaces(_namespaces),
-      documentation(_documentation),
-      return_documentation(_return_documentation),
-      property_documentation(_property_documentation),
-      type(_type),
-      scope(_scope),
-      is_beta(_is_beta), is_protected(_is_protected),
-      is_static(_is_static),
-      unit(unit) {}
 
   function_def( ::Eolian_Function const* function, Eolian_Function_Type type, 
Eolian_Typedecl const* tp, Eolian_Unit const* unit)
-    : return_type(void_), unit(unit)
+    : return_type(void_), explicit_return_type(void_), unit(unit)
   {
-    Eolian_Type const* r_type = ::eolian_function_return_type_get(function, 
type);
-    name = ::eolian_function_name_get(function);
-    return_documentation = eolian_function_return_documentation_get(function, 
type);
-    scope = static_cast<member_scope>(eolian_function_scope_get(function, 
type));
-    if(r_type)
-      return_type.set(r_type
-                      , unit
-                      , eolian_function_return_c_type_get(function, type)
-                      , eolian_function_return_is_move(function, type)
-                      , eolian_function_return_is_by_ref(function, type));
+     Eolian_Type const* r_type = ::eolian_function_return_type_get(function, 
type);
+     name = ::eolian_function_name_get(function);
+     return_documentation = eolian_function_return_documentation_get(function, 
type);
+     scope = static_cast<member_scope>(eolian_function_scope_get(function, 
type));
+
+     if(r_type)
+       {
+          return_type.set(r_type
+                         , unit
+                         , eolian_function_return_c_type_get(function, type)
+                         , eolian_function_return_is_move(function, type)
+                         , eolian_function_return_is_by_ref(function, type));
+          explicit_return_type = return_type;
+       }
+
      if(type == EOLIAN_METHOD || type == EOLIAN_FUNCTION_POINTER)
        {
           for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( 
::eolian_function_parameters_get(function))
@@ -876,9 +876,10 @@ struct function_def
                ( ::eolian_property_keys_get(function, type))
                , param_last; param_iterator != param_last; ++param_iterator)
            {
-              parameters.push_back({&*param_iterator, unit});
+              parameter_def param = {&*param_iterator, unit};
+              parameters.push_back(param);
+              keys.push_back(param);
            }
-         std::vector<parameter_def> values;
          for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator
                ( ::eolian_property_values_get(function, type))
                , param_last; param_iterator != param_last; ++param_iterator)
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc 
b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
index 498852f28b..c6e0381551 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_binding.cc
@@ -232,12 +232,16 @@ EFL_START_TEST(eolian_cxx_test_properties)
   klass_def cls = init_test_data("property_holder.eo", "Property_Holder", 
eolian_state);
 
   auto props = cls.properties;
-  ck_assert_int_eq(4, cls.properties.size());
+  ck_assert_int_eq(8, 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);
+  ck_assert("multi_value_prop" == props[4].name);
+  ck_assert("setter_with_return" == props[5].name);
+  ck_assert("getter_with_return" == props[6].name);
+  ck_assert("value_override" == props[7].name);
 
   auto property = props[0];
   ck_assert(property.getter.is_engaged());
@@ -249,17 +253,136 @@ EFL_START_TEST(eolian_cxx_test_properties)
   });
   ck_assert(*property.getter == *function);
 
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(1, property.setter->values.size());
+
   property = props[1];
   ck_assert(property.getter.is_engaged());
   ck_assert(!property.setter.is_engaged());
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
 
   property = props[2];
   ck_assert(!property.getter.is_engaged());
   ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(1, property.setter->values.size());
 
   property = props[3];
   ck_assert(property.getter.is_engaged());
   ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(1, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
+
+  property = props[4];
+  ck_assert(property.getter.is_engaged());
+  ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(2, property.getter->values.size());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(2, property.setter->values.size());
+
+  property = props[5];
+  ck_assert(property.getter.is_engaged());
+  ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(1, property.setter->values.size());
+
+  property = props[6];
+  ck_assert(property.getter.is_engaged());
+  ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(1, property.setter->values.size());
+
+  property = props[7];
+  ck_assert(property.getter.is_engaged());
+  ck_assert(property.setter.is_engaged());
+  ck_assert_int_eq(0, property.getter->keys.size());
+  ck_assert_int_eq(1, property.getter->values.size());
+  ck_assert_int_eq(0, property.setter->keys.size());
+  ck_assert_int_eq(1, property.setter->values.size());
+
+}
+EFL_END_TEST
+
+EFL_START_TEST(eolian_cxx_test_property_accessor_info)
+{
+  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);
+
+  auto props = cls.properties;
+  auto property = props[0];
+  auto getter = *property.getter;
+
+  // Single-valued getter
+  ck_assert(getter.return_type.c_type == "int");
+  ck_assert_int_eq(0, getter.parameters.size());
+  ck_assert(getter.explicit_return_type == 
efl::eolian::grammar::attributes::void_);
+  ck_assert_int_eq(1, getter.values.size());
+  ck_assert_int_eq(0, getter.keys.size());
+
+  // Single-valued setter
+  property = props[2];
+  auto setter = *property.setter;
+  ck_assert(setter.return_type.c_type == "void");
+  ck_assert_int_eq(1, setter.parameters.size());
+  ck_assert(setter.explicit_return_type == 
efl::eolian::grammar::attributes::void_);
+  ck_assert_int_eq(1, setter.values.size());
+  ck_assert_int_eq(0, setter.keys.size());
+
+  // Multi valued getter
+  property = props[4];
+  getter = *property.getter;
+  ck_assert(getter.return_type.c_type == "void");
+  ck_assert_int_eq(2, getter.parameters.size());
+  ck_assert(getter.explicit_return_type == 
efl::eolian::grammar::attributes::void_);
+  ck_assert_int_eq(2, getter.values.size());
+  ck_assert_int_eq(0, getter.keys.size());
+
+  // Setter with return value
+  property = props[5];
+  setter = *property.setter;
+  ck_assert_str_eq("Eina_Bool", setter.return_type.c_type.c_str());
+  ck_assert_int_eq(1, setter.parameters.size());
+  ck_assert_str_eq("Eina_Bool", setter.explicit_return_type.c_type.c_str());
+  ck_assert_int_eq(1, setter.values.size());
+  ck_assert_int_eq(0, setter.keys.size());
+
+  // Getter with return value
+  property = props[6];
+  getter = *property.getter;
+  ck_assert_str_eq("Eina_Bool", getter.return_type.c_type.c_str());
+  ck_assert_int_eq(1, getter.parameters.size());
+  ck_assert_str_eq("Eina_Bool", getter.explicit_return_type.c_type.c_str());
+  ck_assert_int_eq(1, getter.values.size());
+  ck_assert_int_eq(0, getter.keys.size());
+
+  // Value override. This mimics Efl.Ui.Win.icon_object behavior.
+  property = props[7];
+  getter = *property.getter;
+  ck_assert_str_eq("const Property_Holder *", 
getter.return_type.c_type.c_str());
+  ck_assert_int_eq(0, getter.parameters.size());
+  ck_assert_str_eq("void", getter.explicit_return_type.c_type.c_str());
+  ck_assert_int_eq(1, getter.values.size());
+  ck_assert_int_eq(0, getter.keys.size());
+
+  setter = *property.setter;
+  ck_assert_str_eq("void", setter.return_type.c_type.c_str());
+  ck_assert_int_eq(1, setter.parameters.size());
+  ck_assert_str_eq("void", setter.explicit_return_type.c_type.c_str());
+  ck_assert_str_eq("Property_Holder *", 
setter.parameters[0].type.c_type.c_str());
+  ck_assert_int_eq(1, setter.values.size());
+  ck_assert_int_eq(0, setter.keys.size());
+
+
 
 }
 EFL_END_TEST
@@ -370,6 +493,7 @@ eolian_cxx_test_binding(TCase* tc)
    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);
+   tcase_add_test(tc, eolian_cxx_test_property_accessor_info);
    tcase_add_test(tc, eolian_cxx_test_parent_extensions);
    tcase_add_test(tc, eolian_cxx_test_cls_get);
    tcase_add_test(tc, eolian_cxx_test_constructors);
diff --git a/src/tests/eolian_cxx/property_holder.eo 
b/src/tests/eolian_cxx/property_holder.eo
index 6c16c4ee1b..8509ffe648 100644
--- a/src/tests/eolian_cxx/property_holder.eo
+++ b/src/tests/eolian_cxx/property_holder.eo
@@ -38,5 +38,47 @@ class Property_Holder extends Efl.Object
             key: string;
          }
       }
+
+      @property multi_value_prop {
+         get {}
+         set {}
+         values {
+            x: int;
+            y: int;
+         }
+      }
+
+      @property setter_with_return {
+         get {}
+         set {
+            return: bool;
+         }
+         values {
+            data: int;
+         }
+      }
+
+      @property getter_with_return {
+         get {
+            return: bool;
+         }
+         set {}
+         values {
+            data: int;
+         }
+      }
+
+      @property value_override {
+         get {
+            values {
+               getter: const(Property_Holder);
+            }
+         }
+         set {
+            values {
+               setter: Property_Holder;
+            }
+         }
+      }
    }
 }

-- 


Reply via email to