cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=067a8baffa692668acc0f19c91e2198195f480e2

commit 067a8baffa692668acc0f19c91e2198195f480e2
Author: Lauro Moura <lauromo...@expertisesolutions.com.br>
Date:   Thu Mar 8 15:43:14 2018 -0800

    csharp: generate helper constructors for structs.
    
    Summary:
    C# does not have a literal form for structs (like C++'s {} aggregate
    initialization). Before this commit the user would need to explicitly
    instantiate a struct and assign the required values to it, like:
    
       eina.Size2D size;
       size.W = width;
       size.H = height;
       widget.SetSize(size);
    
    As a workaround, this commit generates helper constructor with
    parameters corresponding to the struct fields in the order they are
    declared. These parameters have default values if one does not want to
    explicitly initialize all fields directly. With these constructs, the
    above code could be translated to:
    
       widget.SetSize(new eina.Size2D(width, height));
    
    It should be noted that the constructed struct will live on the managed
    memory (GC) instead of the stack.
    
    Test Plan: run "make check"
    
    Reviewers: felipealmeida
    
    Subscribers: cedric
    
    Differential Revision: https://phab.enlightenment.org/D5838
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/Makefile_Efl_Mono.am                           |  1 +
 src/bin/eolian_mono/eolian/mono/helpers.hh         |  6 ++
 .../eolian_mono/eolian/mono/struct_definition.hh   | 23 +++++---
 src/bin/eolian_mono/eolian/mono/struct_fields.hh   | 68 ++++++++++++++++++++++
 src/tests/efl_mono/Structs.cs                      | 11 ++++
 5 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 9344fbda2f..e442d09fb5 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -78,6 +78,7 @@ bin_eolian_mono_eolian_mono_SOURCES = \
        bin/eolian_mono/eolian/mono/function_registration.hh \
        bin/eolian_mono/eolian/mono/enum_definition.hh \
        bin/eolian_mono/eolian/mono/struct_definition.hh \
+       bin/eolian_mono/eolian/mono/struct_fields.hh \
        bin/eolian_mono/eolian/mono/parameter.hh \
        bin/eolian_mono/eolian/mono/utils.hh \
        bin/eolian_mono/eolian/mono/using_decl.hh \
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh 
b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 7d013bd6f5..e02fd05b70 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -76,6 +76,12 @@ inline bool 
need_pointer_conversion(attributes::regular_type_def const* regular)
    return false;
 }
 
+inline std::string to_field_name(std::string const& in)
+{
+  std::string field_name = in;
+  field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a 
field name
+  return field_name;
+}
 
 }
 
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh 
b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 324e787748..a0ff03315e 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -11,6 +11,7 @@
 #include "keyword.hh"
 #include "using_decl.hh"
 #include "documentation.hh"
+#include "struct_fields.hh"
 
 namespace eolian_mono {
 
@@ -24,13 +25,6 @@ inline std::string 
binding_struct_internal_name(attributes::struct_def const& st
    return struct_.cxx_name + "_StructInternal";
 }
 
-inline std::string to_field_name(std::string const& in)
-{
-  std::string field_name = in;
-  field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a 
field name
-  return field_name;
-}
-
 struct struct_definition_generator
 {
   template <typename OutputIterator, typename Context>
@@ -70,6 +64,21 @@ struct struct_definition_generator
            if (!as_generator("///<summary>Placeholder field</summary>\npublic 
IntPtr field;\n").generate(sink, nullptr, context))
              return false;
        }
+     else
+       {
+          // Constructor with default parameters for easy struct initialization
+          auto struct_name = binding_struct_name(struct_);
+          if(!as_generator(
+                      scope_tab << "///<summary>Constructor for " << string << 
".</summary>\n"
+                      << scope_tab << "public " << string << "(\n"
+                      << ((scope_tab << scope_tab << field_argument_default) % 
",\n")
+                      << scope_tab << ")\n"
+                      << scope_tab << "{\n"
+                      << *(scope_tab << scope_tab << field_argument_assignment 
<< ";\n")
+                      << scope_tab << "}\n")
+             .generate(sink, std::make_tuple(struct_name, struct_name, 
struct_.fields, struct_.fields), context))
+              return false;
+       }
 
      if(!as_generator("}\n").generate(sink, attributes::unused, context)) 
return false;
 
diff --git a/src/bin/eolian_mono/eolian/mono/struct_fields.hh 
b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
new file mode 100644
index 0000000000..0cd018b06f
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
@@ -0,0 +1,68 @@
+#ifndef EOLIAN_MONO_STRUCT_FIELDS_HH
+#define EOLIAN_MONO_STRUCT_FIELDS_HH
+
+#include "grammar/generator.hpp"
+#include "grammar/klass_def.hpp"
+#include "grammar/indentation.hpp"
+#include "grammar/list.hpp"
+#include "grammar/alternative.hpp"
+#include "helpers.hh"
+#include "type.hh"
+#include "keyword.hh"
+#include "using_decl.hh"
+#include "documentation.hh"
+
+namespace eolian_mono {
+
+struct field_argument_default_generator
+{
+   template<typename OutputIterator, typename Context>
+   bool generate(OutputIterator sink, attributes::struct_field_def const& 
field, Context const& context) const
+   {
+       if (!as_generator(type << " " << string << "=default(" << type << ")")
+               .generate(sink, std::make_tuple(field.type, 
to_field_name(field.name), field.type), context))
+           return false;
+       return true;
+   }
+} const field_argument_default {};
+
+struct field_argument_assignment_generator
+{
+   template<typename OutputIterator, typename Context>
+   bool generate(OutputIterator sink, attributes::struct_field_def const& 
field, Context const& context) const
+   {
+       if (!as_generator("this." << string << " = " << string)
+               .generate(sink, std::make_tuple(to_field_name(field.name), 
to_field_name(field.name)), context))
+           return false;
+       return true;
+   }
+} const field_argument_assignment {};
+
+}
+
+namespace efl { namespace eolian { namespace grammar {
+
+template<>
+struct is_eager_generator< ::eolian_mono::field_argument_default_generator> : 
std::true_type {};
+template<>
+struct is_generator< ::eolian_mono::field_argument_default_generator> : 
std::true_type {};
+
+template<>
+struct is_eager_generator< ::eolian_mono::field_argument_assignment_generator> 
: std::true_type {};
+template<>
+struct is_generator< ::eolian_mono::field_argument_assignment_generator> : 
std::true_type {};
+
+namespace type_traits {
+
+template <>
+struct attributes_needed< ::eolian_mono::field_argument_default_generator> : 
std::integral_constant<int, 1> {};
+
+template <>
+struct attributes_needed< ::eolian_mono::field_argument_assignment_generator> 
: std::integral_constant<int, 1> {};
+
+}
+
+} } }
+
+#endif
+
diff --git a/src/tests/efl_mono/Structs.cs b/src/tests/efl_mono/Structs.cs
index dcdea0d757..07917d0c56 100644
--- a/src/tests/efl_mono/Structs.cs
+++ b/src/tests/efl_mono/Structs.cs
@@ -245,6 +245,17 @@ class TestStructs
         checkZeroedStructComplex(complex);
     }
 
+    public static void parameter_initialization()
+    {
+        var simple = new test.StructSimple(0x1, 0x2, (char)0x3, 0x4, 0x5);
+        Test.AssertEquals(0x1, simple.Fbyte);
+        Test.AssertEquals(0x2, simple.Fubyte);
+        Test.AssertEquals(0x3, simple.Fchar);
+        Test.AssertEquals(0x4, simple.Fshort);
+        Test.AssertEquals(0x5, simple.Fushort);
+        Test.AssertEquals(0, simple.Fint);
+    }
+
     // As parameters
 
     public static void simple_in()

-- 


Reply via email to