summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-04-10 22:30:40 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2018-04-12 21:23:42 -0300
commit65f868786a59533a1cbf9d58b886cdc4f49ceb94 (patch)
treea0d2478b2f8504cb14d2e06ea78cb3c5b655764a
parenta252c3445d2cf45aba332b6fcd634e54ee7239dc (diff)
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).
-rw-r--r--src/Makefile_Efl_Mono.am6
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_declaration.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh13
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh15
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh9
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp21
-rw-r--r--src/tests/efl_mono/Eo.cs17
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c24
-rw-r--r--src/tests/efl_mono/test_child.eo9
-rw-r--r--src/tests/efl_mono/test_testing.eo8
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 = \
48 48
49efl_mono_test_files = \ 49efl_mono_test_files = \
50 tests/efl_mono/test_testing.eo \ 50 tests/efl_mono/test_testing.eo \
51 tests/efl_mono/test_child.eo \
51 tests/efl_mono/test_numberwrapper.eo \ 52 tests/efl_mono/test_numberwrapper.eo \
52 tests/efl_mono/mono_test_driver.sh 53 tests/efl_mono/mono_test_driver.sh
53 54
@@ -382,10 +383,11 @@ tests_efl_mono_libefl_mono_native_test_la_LDFLAGS = -rpath $(abs_top_builddir)/t
382tests_efl_mono_libefl_mono_native_test_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ELDBUS_INTERNAL_LIBS@ 383tests_efl_mono_libefl_mono_native_test_la_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ELDBUS_INTERNAL_LIBS@
383tests_efl_mono_libefl_mono_native_test_la_LIBTOOLFLAGS = --tag=disable-static 384tests_efl_mono_libefl_mono_native_test_la_LIBTOOLFLAGS = --tag=disable-static
384 385
385tests/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 386tests/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
386 387
387# Intermediate C Sharp test DLL 388# Intermediate C Sharp test DLL
388efl_mono_test_eolian_mono_files = tests/efl_mono/test_testing.eo.cs \ 389efl_mono_test_eolian_mono_files = tests/efl_mono/test_testing.eo.cs \
390tests/efl_mono/test_child.eo.cs \
389tests/efl_mono/test_numberwrapper.eo.cs 391tests/efl_mono/test_numberwrapper.eo.cs
390 392
391tests/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 393tests/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)
456 $(MKDIR_P) $(dir $@); \ 458 $(MKDIR_P) $(dir $@); \
457 $(EOLIAN_MONO) $(EOLIAN_FLAGS) $(EOLIAN_MONO_FLAGS) --dllimport "@DLIB_PREFIX_MONO@efl_mono_native_test@DLIB_SUFFIX_MONO@" -o $@ $(ALL_EO_REFS) $< 459 $(EOLIAN_MONO) $(EOLIAN_FLAGS) $(EOLIAN_MONO_FLAGS) --dllimport "@DLIB_PREFIX_MONO@efl_mono_native_test@DLIB_SUFFIX_MONO@" -o $@ $(ALL_EO_REFS) $<
458 460
459CLEANFILES += 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 461CLEANFILES += 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
460 462
461endif 463endif
462 464
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
19 template <typename OutputIterator, typename Context> 19 template <typename OutputIterator, typename Context>
20 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 20 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
21 { 21 {
22 if(is_function_blacklisted(f.c_name)) 22 if(is_function_blacklisted(f.c_name) || f.is_static)
23 return true; 23 return true;
24 24
25 if(!as_generator(documentation).generate(sink, f, context)) 25 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 @@
11#include "grammar/alternative.hpp" 11#include "grammar/alternative.hpp"
12#include "grammar/attribute_reorder.hpp" 12#include "grammar/attribute_reorder.hpp"
13#include "type.hh" 13#include "type.hh"
14#include "helpers.hh"
14#include "function_helpers.hh" 15#include "function_helpers.hh"
15#include "marshall_type.hh" 16#include "marshall_type.hh"
16#include "parameter.hh" 17#include "parameter.hh"
@@ -28,7 +29,7 @@ struct native_function_definition_generator
28 template <typename OutputIterator, typename Context> 29 template <typename OutputIterator, typename Context>
29 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 30 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
30 { 31 {
31 if(is_function_blacklisted(f.c_name)) 32 if(is_function_blacklisted(f.c_name) || f.is_static) // Only Concrete classes implement static methods.
32 return true; 33 return true;
33 else 34 else
34 { 35 {
@@ -131,10 +132,11 @@ struct function_definition_generator
131 template <typename OutputIterator, typename Context> 132 template <typename OutputIterator, typename Context>
132 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 133 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
133 { 134 {
135 if(do_super && f.is_static) // Static methods goes only on Concrete classes.
136 return true;
134 if(is_function_blacklisted(f.c_name)) 137 if(is_function_blacklisted(f.c_name))
135 return true; 138 return true;
136 else 139
137 {
138 if(!as_generator 140 if(!as_generator
139 ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n" 141 ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n"
140 << scope_tab << eolian_mono::marshall_annotation(true) 142 << scope_tab << eolian_mono::marshall_annotation(true)
@@ -159,11 +161,11 @@ struct function_definition_generator
159 return false; 161 return false;
160 162
161 if(!as_generator 163 if(!as_generator
162 (scope_tab << (do_super ? "virtual " : "") << "public " << return_type << " " << string << "(" << (parameter % ", ") 164 (scope_tab << (do_super ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
163 << ") {\n " 165 << ") {\n "
164 << eolian_mono::function_definition_preamble() << string << "(" 166 << eolian_mono::function_definition_preamble() << string << "("
165 << (do_super ? "efl.eo.Globals.efl_super(" : "") 167 << (do_super ? "efl.eo.Globals.efl_super(" : "")
166 << "this.raw_handle" 168 << (f.is_static ? klass_get_name(f.klass) + "()": "this.raw_handle")
167 << (do_super ? ", this.raw_klass)" : "") 169 << (do_super ? ", this.raw_klass)" : "")
168 << *(", " << argument_invocation ) << ");\n" 170 << *(", " << argument_invocation ) << ");\n"
169 << eolian_mono::function_definition_epilogue() 171 << eolian_mono::function_definition_epilogue()
@@ -172,7 +174,6 @@ struct function_definition_generator
172 return false; 174 return false;
173 175
174 return true; 176 return true;
175 }
176 } 177 }
177 178
178 bool do_super; 179 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
28 template <typename OutputIterator, typename Context> 28 template <typename OutputIterator, typename Context>
29 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 29 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
30 { 30 {
31 if(is_function_blacklisted(f.c_name)) 31 if(is_function_blacklisted(f.c_name) || f.is_static) // Static methods aren't overrideable
32 return true; 32 return true;
33 else 33 else
34 { 34 {
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)
125 return output.str(); 125 return output.str();
126} 126}
127 127
128inline std::string klass_get_name(attributes::klass_name const &clsname)
129{
130 std::ostringstream output;
131
132 output << klass_name_to_csharp(clsname);
133 output << "Concrete.";
134
135 for (auto namesp : clsname.namespaces)
136 output << utils::to_lowercase(namesp) << "_";
137 output << utils::to_lowercase(clsname.eolian_name);
138 output << "_class_get";
139
140 return output.str();
141}
142
128} 143}
129 144
130#endif 145#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)
69 69
70/* Get the actual number of functions of a class, checking for blacklisted ones */ 70/* Get the actual number of functions of a class, checking for blacklisted ones */
71static std::size_t 71static std::size_t
72get_function_count(grammar::attributes::klass_def const& cls) 72get_inheritable_function_count(grammar::attributes::klass_def const& cls)
73{ 73{
74 auto methods = cls.get_all_methods(); 74 auto methods = cls.get_all_methods();
75 return std::count_if(methods.cbegin(), methods.cend(), [](grammar::attributes::function_def const& func) 75 return std::count_if(methods.cbegin(), methods.cend(), [](grammar::attributes::function_def const& func)
76 { 76 {
77 return !is_function_blacklisted(func.c_name); 77 return !is_function_blacklisted(func.c_name) && !func.is_static;
78 }); 78 });
79} 79}
80 80
@@ -268,8 +268,9 @@ struct klass
268 << scope_tab << "}\n" 268 << scope_tab << "}\n"
269 << scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n" 269 << scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n"
270 << scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n" 270 << scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n"
271 << scope_tab << "///<summary>Returns the pointer the unerlying Eo class object. Used internally on class methods.</summary>\n"
271 << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename) 272 << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
272 << ")] private static extern System.IntPtr\n" 273 << ")] public static extern System.IntPtr\n"
273 << scope_tab << scope_tab << class_get_name << "();\n" 274 << scope_tab << scope_tab << class_get_name << "();\n"
274 << (class_type == "class" ? "" : "/*") 275 << (class_type == "class" ? "" : "/*")
275 << scope_tab << "///<summary>Creates a new instance.</summary>\n" 276 << scope_tab << "///<summary>Creates a new instance.</summary>\n"
@@ -451,7 +452,7 @@ struct klass
451 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 452 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
452 } 453 }
453 454
454 std::size_t function_count = get_function_count(cls); 455 std::size_t function_count = get_inheritable_function_count(cls);
455 456
456 int function_registration_index = 0; 457 int function_registration_index = 0;
457 auto index_generator = [&function_registration_index] 458 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
109 qualifier_def base_qualifier; 109 qualifier_def base_qualifier;
110 class_type type; 110 class_type type;
111 111
112 klass_name() {
113 }
114
112 klass_name(std::vector<std::string> namespaces 115 klass_name(std::vector<std::string> namespaces
113 , std::string eolian_name, qualifier_def base_qualifier 116 , std::string eolian_name, qualifier_def base_qualifier
114 , class_type type) 117 , class_type type)
@@ -527,6 +530,7 @@ enum class function_type
527 530
528struct function_def 531struct function_def
529{ 532{
533 klass_name klass;
530 type_def return_type; 534 type_def return_type;
531 std::string name; 535 std::string name;
532 std::vector<parameter_def> parameters; 536 std::vector<parameter_def> parameters;
@@ -543,7 +547,8 @@ struct function_def
543 547
544 friend inline bool operator==(function_def const& lhs, function_def const& rhs) 548 friend inline bool operator==(function_def const& lhs, function_def const& rhs)
545 { 549 {
546 return lhs.return_type == rhs.return_type 550 return lhs.klass == rhs.klass
551 && lhs.return_type == rhs.return_type
547 && lhs.name == rhs.name 552 && lhs.name == rhs.name
548 && lhs.parameters == rhs.parameters 553 && lhs.parameters == rhs.parameters
549 && lhs.c_name == rhs.c_name 554 && lhs.c_name == rhs.c_name
@@ -561,7 +566,8 @@ struct function_def
561 return !(lhs == rhs); 566 return !(lhs == rhs);
562 } 567 }
563 function_def() = default; 568 function_def() = default;
564 function_def(type_def _return_type, std::string const& _name, 569 function_def(klass_name _klass,
570 type_def _return_type, std::string const& _name,
565 std::vector<parameter_def> const& _parameters, 571 std::vector<parameter_def> const& _parameters,
566 std::string const& _c_name, 572 std::string const& _c_name,
567 std::string _filename, 573 std::string _filename,
@@ -572,8 +578,9 @@ struct function_def
572 bool _is_beta = false, 578 bool _is_beta = false,
573 bool _is_protected = false, 579 bool _is_protected = false,
574 Eolian_Unit const* unit = nullptr) 580 Eolian_Unit const* unit = nullptr)
575 : return_type(_return_type), name(_name), parameters(_parameters), 581 : klass(_klass), return_type(_return_type), name(_name),
576 c_name(_c_name), filename(_filename), documentation(_documentation), 582 parameters(_parameters), c_name(_c_name), filename(_filename),
583 documentation(_documentation),
577 return_documentation(_return_documentation), 584 return_documentation(_return_documentation),
578 property_documentation(_property_documentation), 585 property_documentation(_property_documentation),
579 type(_type), 586 type(_type),
@@ -633,8 +640,10 @@ struct function_def
633 c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE); 640 c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE);
634 if (type != EOLIAN_FUNCTION_POINTER) 641 if (type != EOLIAN_FUNCTION_POINTER)
635 { 642 {
636 const Eolian_Class *klass = eolian_function_class_get(function); 643 const Eolian_Class *eolian_klass = eolian_function_class_get(function);
637 filename = eolian_object_file_get((const Eolian_Object *)klass); 644 filename = eolian_object_file_get((const Eolian_Object *)eolian_klass);
645 klass = klass_name(eolian_klass,
646 {attributes::qualifier_info::is_none, std::string()});
638 } 647 }
639 else 648 else
640 { 649 {
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
191 } 191 }
192} 192}
193 193
194class TestKlassMethods
195{
196 public static void basic_class_method()
197 {
198 int reference = 0xbeef;
199 test.TestingConcrete.SetKlassProp(reference);
200 Test.AssertEquals(reference, test.TestingConcrete.GetKlassProp());
201 }
202
203 public static void inherited_class_method()
204 {
205 int reference = 0xdead;
206 test.ChildConcrete.SetKlassProp(reference);
207 Test.AssertEquals(reference, test.ChildConcrete.GetKlassProp());
208 }
209}
210
194} 211}
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_
3763 func_free_cb(func_data); 3763 func_free_cb(func_data);
3764} 3764}
3765 3765
3766/* Class Properties */
3767static int _test_testing_klass_prop = 0;
3768
3769int _test_testing_klass_prop_get(Eo *klass, EINA_UNUSED void *pd)
3770{
3771 EINA_LOG_ERR("FAIL on GET");
3772 if (klass != test_testing_class_get())
3773 {
3774 eina_error_set(EINVAL);
3775 return -1;
3776 }
3777 return _test_testing_klass_prop;
3778}
3779
3780void _test_testing_klass_prop_set(Eo *klass, EINA_UNUSED void *pd, int value)
3781{
3782 EINA_LOG_ERR("FAIL on SET");
3783 if (klass != test_testing_class_get())
3784 {
3785 eina_error_set(EINVAL);
3786 }
3787 _test_testing_klass_prop = value;
3788}
3789
3766#include "test_testing.eo.c" 3790#include "test_testing.eo.c"
3767#include "test_numberwrapper.eo.c" 3791#include "test_numberwrapper.eo.c"
3768 3792
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 @@
1import eina_types;
2
3class Test.Child (Test.Testing) {
4
5 implements {
6 class.constructor;
7 class.destructor;
8 }
9}
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) {
1583 @in func: Test.FormatCb; 1583 @in func: Test.FormatCb;
1584 } 1584 }
1585 } 1585 }
1586
1587 @property klass_prop @class {
1588 get {}
1589 set {}
1590 values {
1591 prop: int;
1592 }
1593 }
1586 } 1594 }
1587 implements { 1595 implements {
1588 class.constructor; 1596 class.constructor;