felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=65f868786a59533a1cbf9d58b886cdc4f49ceb94

commit 65f868786a59533a1cbf9d58b886cdc4f49ceb94
Author: Lauro Moura <lauromo...@expertisesolutions.com.br>
Date:   Tue Apr 10 22:30:40 2018 -0300

    efl_mono: Proper support for @class methods.
    
    Previously, class methods were implemented as regular instance methods.
    This commits generates C# static methods for @class methods on the
    *Concrete classes (and their childs).
---
 src/Makefile_Efl_Mono.am                           |  6 ++++--
 .../eolian/mono/function_declaration.hh            |  2 +-
 .../eolian_mono/eolian/mono/function_definition.hh | 13 ++++++------
 .../eolian/mono/function_registration.hh           |  2 +-
 src/bin/eolian_mono/eolian/mono/helpers.hh         | 15 ++++++++++++++
 src/bin/eolian_mono/eolian/mono/klass.hh           |  9 ++++----
 src/lib/eolian_cxx/grammar/klass_def.hpp           | 21 +++++++++++++------
 src/tests/efl_mono/Eo.cs                           | 17 +++++++++++++++
 src/tests/efl_mono/libefl_mono_native_test.c       | 24 ++++++++++++++++++++++
 src/tests/efl_mono/test_child.eo                   |  9 ++++++++
 src/tests/efl_mono/test_testing.eo                 |  8 ++++++++
 11 files changed, 106 insertions(+), 20 deletions(-)

diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 45928f977a..01f6a12dd3 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -48,6 +48,7 @@ lib_efl_mono_libefl_mono_dll_sources = \
 
 efl_mono_test_files = \
        tests/efl_mono/test_testing.eo \
+       tests/efl_mono/test_child.eo \
        tests/efl_mono/test_numberwrapper.eo \
        tests/efl_mono/mono_test_driver.sh
 
@@ -382,10 +383,11 @@ tests_efl_mono_libefl_mono_native_test_la_LDFLAGS = 
-rpath $(abs_top_builddir)/t
 tests_efl_mono_libefl_mono_native_test_la_DEPENDENCIES = 
@USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ 
@USE_ELDBUS_INTERNAL_LIBS@
 tests_efl_mono_libefl_mono_native_test_la_LIBTOOLFLAGS = --tag=disable-static
 
-tests/efl_mono/libefl_mono_native_test.c: tests/efl_mono/test_testing.eo.h 
tests/efl_mono/test_testing.eo.c tests/efl_mono/test_numberwrapper.eo.h 
tests/efl_mono/test_numberwrapper.eo.c
+tests/efl_mono/libefl_mono_native_test.c: tests/efl_mono/test_testing.eo.h 
tests/efl_mono/test_testing.eo.c tests/efl_mono/test_child.eo.h 
tests/efl_mono/test_child.eo.c tests/efl_mono/test_numberwrapper.eo.h 
tests/efl_mono/test_numberwrapper.eo.c
 
 # Intermediate C Sharp test DLL
 efl_mono_test_eolian_mono_files = tests/efl_mono/test_testing.eo.cs \
+tests/efl_mono/test_child.eo.cs \
 tests/efl_mono/test_numberwrapper.eo.cs
 
 tests/efl_mono/libefl_mono_test.dll: $(efl_mono_test_eolian_mono_files) 
tests/efl_mono/$(am__dirstamp) lib/efl_mono/libefl_mono.dll 
tests/efl_mono/libefl_mono_native_test.la 
tests/efl_mono/libefl_mono_test.dll.config
@@ -456,7 +458,7 @@ tests/efl_mono/%.eo.cs: tests/efl_mono/%.eo 
$(_EOLIAN_MONO_DEP)
        $(MKDIR_P) $(dir $@); \
        $(EOLIAN_MONO) $(EOLIAN_FLAGS) $(EOLIAN_MONO_FLAGS) --dllimport 
"@DLIB_PREFIX_MONO@efl_mono_native_test@DLIB_SUFFIX_MONO@" -o $@ $(ALL_EO_REFS) 
$<
 
-CLEANFILES += tests/efl_mono/libefl_mono_test.dll 
tests/efl_mono/test_testing.eo.cs tests/efl_mono/test_numberwrapper.eo.cs 
tests/efl_mono/test_testing.eo.c tests/efl_mono/test_numberwrapper.eo.c 
tests/efl_mono/test_testing.eo.h tests/efl_mono/test_numberwrapper.eo.h 
tests/efl_mono/efl_mono.config
+CLEANFILES += tests/efl_mono/libefl_mono_test.dll 
tests/efl_mono/test_testing.eo.cs tests/efl_mono/test_child.eo.cs 
tests/efl_mono/test_numberwrapper.eo.cs tests/efl_mono/test_testing.eo.c 
tests/efl_mono/test_child.eo.c tests/efl_mono/test_numberwrapper.eo.c 
tests/efl_mono/test_testing.eo.h tests/efl_mono/test_child.eo.h 
tests/efl_mono/test_numberwrapper.eo.h tests/efl_mono/efl_mono.config
 
 endif
 
diff --git a/src/bin/eolian_mono/eolian/mono/function_declaration.hh 
b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
index 76bbd6103b..fe35c5341d 100644
--- a/src/bin/eolian_mono/eolian/mono/function_declaration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
@@ -19,7 +19,7 @@ struct function_declaration_generator
   template <typename OutputIterator, typename Context>
   bool generate(OutputIterator sink, attributes::function_def const& f, 
Context const& context) const
   {
-    if(is_function_blacklisted(f.c_name))
+    if(is_function_blacklisted(f.c_name) || f.is_static)
       return true;
 
     if(!as_generator(documentation).generate(sink, f, context))
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh 
b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 04e8921fad..e030434687 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -11,6 +11,7 @@
 #include "grammar/alternative.hpp"
 #include "grammar/attribute_reorder.hpp"
 #include "type.hh"
+#include "helpers.hh"
 #include "function_helpers.hh"
 #include "marshall_type.hh"
 #include "parameter.hh"
@@ -28,7 +29,7 @@ struct native_function_definition_generator
   template <typename OutputIterator, typename Context>
   bool generate(OutputIterator sink, attributes::function_def const& f, 
Context const& context) const
   {
-    if(is_function_blacklisted(f.c_name))
+    if(is_function_blacklisted(f.c_name) || f.is_static) // Only Concrete 
classes implement static methods.
       return true;
     else
       {
@@ -131,10 +132,11 @@ struct function_definition_generator
   template <typename OutputIterator, typename Context>
   bool generate(OutputIterator sink, attributes::function_def const& f, 
Context const& context) const
   {
+    if(do_super && f.is_static) // Static methods goes only on Concrete 
classes.
+      return true;
     if(is_function_blacklisted(f.c_name))
       return true;
-    else
-      {
+
     if(!as_generator
        ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << 
context_find_tag<library_context>(context).actual_library_name(f.filename) << 
")]\n"
         << scope_tab << eolian_mono::marshall_annotation(true)
@@ -159,11 +161,11 @@ struct function_definition_generator
       return false;
 
     if(!as_generator
-       (scope_tab << (do_super ? "virtual " : "") << "public " << return_type 
<< " " << string << "(" << (parameter % ", ")
+       (scope_tab << (do_super ? "virtual " : "") << "public " << (f.is_static 
? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
         << ") {\n "
         << eolian_mono::function_definition_preamble() << string << "("
         << (do_super ? "efl.eo.Globals.efl_super(" : "")
-        << "this.raw_handle"
+        << (f.is_static ? klass_get_name(f.klass) + "()": "this.raw_handle")
         << (do_super ? ", this.raw_klass)" : "")
         << *(", " << argument_invocation ) << ");\n"
         << eolian_mono::function_definition_epilogue()
@@ -172,7 +174,6 @@ struct function_definition_generator
       return false;
 
     return true;
-      }
   }
 
   bool do_super;
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh 
b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index a88c938924..aaae5511af 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -28,7 +28,7 @@ struct function_registration_generator
   template <typename OutputIterator, typename Context>
   bool generate(OutputIterator sink, attributes::function_def const& f, 
Context const& context) const
   {
-    if(is_function_blacklisted(f.c_name))
+    if(is_function_blacklisted(f.c_name) || f.is_static) // Static methods 
aren't overrideable
       return true;
     else
       {
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh 
b/src/bin/eolian_mono/eolian/mono/helpers.hh
index a281f524d5..420efc6984 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -125,6 +125,21 @@ inline std::string 
klass_name_to_csharp(attributes::klass_name const& clsname)
   return output.str();
 }
 
+inline std::string klass_get_name(attributes::klass_name const &clsname)
+{
+  std::ostringstream output;
+
+  output << klass_name_to_csharp(clsname);
+  output << "Concrete.";
+
+  for (auto namesp : clsname.namespaces)
+    output << utils::to_lowercase(namesp) << "_";
+  output << utils::to_lowercase(clsname.eolian_name);
+  output << "_class_get";
+
+  return output.str();
+}
+
 }
 
 #endif
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh 
b/src/bin/eolian_mono/eolian/mono/klass.hh
index 2bfdbea3d7..bf3f27cdd5 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -69,12 +69,12 @@ static bool generate_equals_method(OutputIterator sink, 
Context const &context)
 
 /* Get the actual number of functions of a class, checking for blacklisted 
ones */
 static std::size_t
-get_function_count(grammar::attributes::klass_def const& cls)
+get_inheritable_function_count(grammar::attributes::klass_def const& cls)
 {
    auto methods = cls.get_all_methods();
    return std::count_if(methods.cbegin(), methods.cend(), 
[](grammar::attributes::function_def const& func)
      {
-        return !is_function_blacklisted(func.c_name);
+        return !is_function_blacklisted(func.c_name) && !func.is_static;
      });
 }
 
@@ -268,8 +268,9 @@ struct klass
              << scope_tab << "}\n"
              << scope_tab << "///<summary>Delegate for function to be called 
from inside the native constructor.</summary>\n"
              << scope_tab << "public delegate void ConstructingMethod(" << 
string << " obj);\n"
+             << scope_tab << "///<summary>Returns the pointer the unerlying Eo 
class object. Used internally on class methods.</summary>\n"
              << scope_tab << "[System.Runtime.InteropServices.DllImport(" << 
context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
-             << ")] private static extern System.IntPtr\n"
+             << ")] public static extern System.IntPtr\n"
              << scope_tab << scope_tab << class_get_name << "();\n"
              << (class_type == "class" ? "" : "/*")
              << scope_tab << "///<summary>Creates a new instance.</summary>\n"
@@ -451,7 +452,7 @@ struct klass
          if(!as_generator("}\n").generate(sink, attributes::unused, 
inherit_cxt)) return false;
        }
 
-     std::size_t function_count = get_function_count(cls);
+     std::size_t function_count = get_inheritable_function_count(cls);
 
      int function_registration_index = 0;
      auto index_generator = [&function_registration_index]
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp 
b/src/lib/eolian_cxx/grammar/klass_def.hpp
index 1db8df9444..d5a5894cac 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -109,6 +109,9 @@ struct klass_name
    qualifier_def base_qualifier;
    class_type type;
 
+   klass_name() {
+   }
+
    klass_name(std::vector<std::string> namespaces
               , std::string eolian_name, qualifier_def base_qualifier
               , class_type type)
@@ -527,6 +530,7 @@ enum class function_type
 
 struct function_def
 {
+  klass_name klass;
   type_def return_type;
   std::string name;
   std::vector<parameter_def> parameters;
@@ -543,7 +547,8 @@ struct function_def
 
   friend inline bool operator==(function_def const& lhs, function_def const& 
rhs)
   {
-    return lhs.return_type == rhs.return_type
+    return lhs.klass == rhs.klass
+      && lhs.return_type == rhs.return_type
       && lhs.name == rhs.name
       && lhs.parameters == rhs.parameters
       && lhs.c_name == rhs.c_name
@@ -561,7 +566,8 @@ struct function_def
     return !(lhs == rhs);
   }
   function_def() = default;
-  function_def(type_def _return_type, std::string const& _name,
+  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,
@@ -572,8 +578,9 @@ struct function_def
                bool _is_beta = false,
                bool _is_protected = false,
                Eolian_Unit const* unit = nullptr)
-    : return_type(_return_type), name(_name), parameters(_parameters),
-      c_name(_c_name), filename(_filename), documentation(_documentation),
+    : klass(_klass), return_type(_return_type), name(_name),
+      parameters(_parameters), c_name(_c_name), filename(_filename),
+      documentation(_documentation),
       return_documentation(_return_documentation),
       property_documentation(_property_documentation),
       type(_type),
@@ -633,8 +640,10 @@ struct function_def
      c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE);
      if (type != EOLIAN_FUNCTION_POINTER)
        {
-          const Eolian_Class *klass = eolian_function_class_get(function);
-          filename = eolian_object_file_get((const Eolian_Object *)klass);
+          const Eolian_Class *eolian_klass = 
eolian_function_class_get(function);
+          filename = eolian_object_file_get((const Eolian_Object 
*)eolian_klass);
+          klass = klass_name(eolian_klass,
+              {attributes::qualifier_info::is_none, std::string()});
        }
      else
        {
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index 60d66821c7..a0c7a9ea40 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -191,4 +191,21 @@ class TestEoParent
     }
 }
 
+class TestKlassMethods
+{
+    public static void basic_class_method()
+    {
+        int reference = 0xbeef;
+        test.TestingConcrete.SetKlassProp(reference);
+        Test.AssertEquals(reference, test.TestingConcrete.GetKlassProp());
+    }
+
+    public static void inherited_class_method()
+    {
+        int reference = 0xdead;
+        test.ChildConcrete.SetKlassProp(reference);
+        Test.AssertEquals(reference, test.ChildConcrete.GetKlassProp());
+    }
+}
+
 }
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c 
b/src/tests/efl_mono/libefl_mono_native_test.c
index b16c1625f9..b14fab86c7 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -3763,6 +3763,30 @@ void _test_testing_call_format_cb(EINA_UNUSED Eo *obj, 
EINA_UNUSED Test_Testing_
     func_free_cb(func_data);
 }
 
+/* Class Properties */
+static int _test_testing_klass_prop = 0;
+
+int _test_testing_klass_prop_get(Eo *klass, EINA_UNUSED void *pd)
+{
+    EINA_LOG_ERR("FAIL on GET");
+   if (klass != test_testing_class_get())
+     {
+        eina_error_set(EINVAL);
+        return -1;
+     }
+   return _test_testing_klass_prop;
+}
+
+void _test_testing_klass_prop_set(Eo *klass, EINA_UNUSED void *pd, int value)
+{
+    EINA_LOG_ERR("FAIL on SET");
+   if (klass != test_testing_class_get())
+     {
+        eina_error_set(EINVAL);
+     }
+   _test_testing_klass_prop = value;
+}
+
 #include "test_testing.eo.c"
 #include "test_numberwrapper.eo.c"
 
diff --git a/src/tests/efl_mono/test_child.eo b/src/tests/efl_mono/test_child.eo
new file mode 100644
index 0000000000..d12ba6d3c6
--- /dev/null
+++ b/src/tests/efl_mono/test_child.eo
@@ -0,0 +1,9 @@
+import eina_types;
+
+class Test.Child (Test.Testing) {
+
+   implements {
+      class.constructor;
+      class.destructor;
+   }
+}
diff --git a/src/tests/efl_mono/test_testing.eo 
b/src/tests/efl_mono/test_testing.eo
index 9a9aa0f2d1..966df8e8bc 100644
--- a/src/tests/efl_mono/test_testing.eo
+++ b/src/tests/efl_mono/test_testing.eo
@@ -1583,6 +1583,14 @@ class Test.Testing (Efl.Object, Efl.Part) {
             @in func: Test.FormatCb;
          }
       }
+
+      @property klass_prop @class {
+         get {}
+         set {}
+         values {
+            prop: int;
+         }
+      }
    }
    implements {
       class.constructor;

-- 


Reply via email to