summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-04-05 19:53:37 -0300
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-04-05 19:56:42 -0300
commit1e22db1150049e313bcba7906fc5ffc9a745eaf0 (patch)
tree3dd72d0486e2e03d90e10e5f96554176326aa783 /src/bin
parent4edf8036e05c8e70f54abf6513e0df165a725a18 (diff)
csharp: Make classes abstract and rework casting
Summary: Abstract Eo classes are now proper C# abstract classes. As a side effect, returning Eo instances from native code was reworked to return instances of their actual Eo classes instead of previous behavior of returning a generic Efl.Object and using static_cast. Instead of `var window = Efl.Ui.Win.static_cast(widget.GetParent());` Use `var window = widget.GetParent() as Efl.Ui.Win;` Another side effect was that `efl_constructor` was removed from the list of supported `Efl.Object` overrides. It is invoked inside `efl_add_internal_start`, before the bindings makes the association of the newly created EoId with the C# instance that created it, making the managed delegate meaningless. C# users then can use regular C# constructors to initialize fields. Also changed to set the private data of C#-inherited classes before the call to constructing methods (aka constructor parameters) so C# classes can override them correctly. Fixes T7778 Fixes T7757 Reviewers: vitor.sousa, felipealmeida, segfaultxavi Reviewed By: vitor.sousa, segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7778, T7757, T7702 Differential Revision: https://phab.enlightenment.org/D8550
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh56
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh3
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh6
6 files changed, 33 insertions, 37 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index df94b6acb6..02cda670d9 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -16,6 +16,7 @@ inline bool is_function_blacklisted(std::string const& c_name)
16{ 16{
17 return 17 return
18 c_name == "efl_event_callback_array_priority_add" 18 c_name == "efl_event_callback_array_priority_add"
19 || c_name == "efl_constructor"
19 || c_name == "efl_player_position_get" 20 || c_name == "efl_player_position_get"
20 || c_name == "efl_ui_widget_focus_set" 21 || c_name == "efl_ui_widget_focus_set"
21 || c_name == "efl_ui_widget_focus_get" 22 || c_name == "efl_ui_widget_focus_get"
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index f688602b2d..ea042fb08e 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -73,7 +73,7 @@ struct unpack_event_args_visitor
73 } 73 }
74 bool operator()(grammar::attributes::klass_name const& cls) const 74 bool operator()(grammar::attributes::klass_name const& cls) const
75 { 75 {
76 return as_generator("new " + name_helpers::klass_full_concrete_name(cls) + "(evt.Info)").generate(sink, attributes::unused, *context); 76 return as_generator("(Efl.Eo.Globals.CreateWrapperFor(evt.Info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context);
77 } 77 }
78 bool operator()(attributes::complex_type_def const&) const 78 bool operator()(attributes::complex_type_def const&) const
79 { 79 {
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 0d6eff628e..3abf82fe11 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -103,7 +103,7 @@ struct native_function_definition_generator
103 /****/ 103 /****/
104 << scope_tab << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n" 104 << scope_tab << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n"
105 /****/ 105 /****/
106 << scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.data_get(pd);\n" 106 << scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);\n"
107 << scope_tab << scope_tab << "if(wrapper != null) {\n" 107 << scope_tab << scope_tab << "if(wrapper != null) {\n"
108 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() 108 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
109 << scope_tab << scope_tab << scope_tab << "try {\n" 109 << scope_tab << scope_tab << scope_tab << "try {\n"
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 20045de39b..2f0bc62d6c 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -32,20 +32,6 @@
32namespace eolian_mono { 32namespace eolian_mono {
33 33
34template <typename OutputIterator, typename Context> 34template <typename OutputIterator, typename Context>
35static bool generate_static_cast_method(OutputIterator sink, grammar::attributes::klass_def const& cls, Context const &context)
36{
37 return as_generator(
38 scope_tab << "///<summary>Casts obj into an instance of this type.</summary>\n"
39 << scope_tab << "public " << (helpers::has_regular_ancestor(cls) ? "new " : "") <<"static " << name_helpers::klass_concrete_name(cls) << " static_cast(Efl.Object obj)\n"
40 << scope_tab << "{\n"
41 << scope_tab << scope_tab << "if (obj == null)\n"
42 << scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n"
43 << scope_tab << scope_tab << "return new " << name_helpers::klass_concrete_name(cls) << "(obj.NativeHandle);\n"
44 << scope_tab << "}\n"
45 ).generate(sink, nullptr, context);
46}
47
48template <typename OutputIterator, typename Context>
49static bool generate_equals_method(OutputIterator sink, Context const &context) 35static bool generate_equals_method(OutputIterator sink, Context const &context)
50{ 36{
51 return as_generator( 37 return as_generator(
@@ -110,7 +96,7 @@ struct klass
110 suffix = "CLASS"; 96 suffix = "CLASS";
111 break; 97 break;
112 case attributes::class_type::abstract_: 98 case attributes::class_type::abstract_:
113 class_type = "class"; 99 class_type = "abstract class";
114 suffix = "CLASS"; 100 suffix = "CLASS";
115 break; 101 break;
116 case attributes::class_type::mixin: 102 case attributes::class_type::mixin:
@@ -207,7 +193,7 @@ struct klass
207 }); 193 });
208 194
209 // Concrete class for interfaces, mixins, etc. 195 // Concrete class for interfaces, mixins, etc.
210 if(class_type != "class") 196 if(class_type != "class" && class_type != "abstract class")
211 { 197 {
212 auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context); 198 auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context);
213 auto concrete_name = name_helpers::klass_concrete_name(cls); 199 auto concrete_name = name_helpers::klass_concrete_name(cls);
@@ -234,7 +220,7 @@ struct klass
234 << ")] internal static extern System.IntPtr\n" 220 << ")] internal static extern System.IntPtr\n"
235 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" 221 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
236 << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n" 222 << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
237 << scope_tab << "public " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n" 223 << scope_tab << "private " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
238 << scope_tab << "{\n" 224 << scope_tab << "{\n"
239 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "") 225 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
240 << scope_tab << scope_tab << "RegisterEventProxies();\n" 226 << scope_tab << scope_tab << "RegisterEventProxies();\n"
@@ -246,9 +232,6 @@ struct klass
246 if (!generate_dispose_methods(sink, cls, concrete_cxt)) 232 if (!generate_dispose_methods(sink, cls, concrete_cxt))
247 return false; 233 return false;
248 234
249 if (!generate_static_cast_method(sink, cls, concrete_cxt))
250 return false;
251
252 if (!generate_equals_method(sink, concrete_cxt)) 235 if (!generate_equals_method(sink, concrete_cxt))
253 return false; 236 return false;
254 237
@@ -296,7 +279,7 @@ struct klass
296 } 279 }
297 280
298 // Inheritable class 281 // Inheritable class
299 if(class_type == "class") 282 if(class_type == "class" || class_type == "abstract class")
300 { 283 {
301 auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context); 284 auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context);
302 285
@@ -327,9 +310,6 @@ struct klass
327 if (!generate_dispose_methods(sink, cls, inherit_cxt)) 310 if (!generate_dispose_methods(sink, cls, inherit_cxt))
328 return false; 311 return false;
329 312
330 if (!generate_static_cast_method(sink, cls, inherit_cxt))
331 return false;
332
333 if (!generate_equals_method(sink, inherit_cxt)) 313 if (!generate_equals_method(sink, inherit_cxt))
334 return false; 314 return false;
335 315
@@ -430,7 +410,7 @@ struct klass
430 << scope_tab << "}\n" 410 << scope_tab << "}\n"
431 ).generate(sink, attributes::unused, inative_cxt)) 411 ).generate(sink, attributes::unused, inative_cxt))
432 return false; 412 return false;
433 413
434 // Native method definitions 414 // Native method definitions
435 if(!as_generator(*(native_function_definition(cls))) 415 if(!as_generator(*(native_function_definition(cls)))
436 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false; 416 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
@@ -534,7 +514,7 @@ struct klass
534 << scope_tab << scope_tab << "FinishInstantiation();\n" 514 << scope_tab << scope_tab << "FinishInstantiation();\n"
535 << scope_tab << "}\n" 515 << scope_tab << "}\n"
536 << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n" 516 << scope_tab << "///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
537 << scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n" 517 << scope_tab << "protected " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
538 << scope_tab << "{\n" 518 << scope_tab << "{\n"
539 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "") 519 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
540 << scope_tab << scope_tab << "RegisterEventProxies();\n" 520 << scope_tab << scope_tab << "RegisterEventProxies();\n"
@@ -542,6 +522,23 @@ struct klass
542 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context)) 522 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
543 return false; 523 return false;
544 524
525 // Some abstract classes (like Efl.App) have a simple regular class that is used to instantiate them
526 // in a controlled manner. These fake-private classes can be returned from C and we use a similarly-named
527 // private class to be able to instantiate them when they get to the C# world.
528 if (cls.type == attributes::class_type::abstract_)
529 {
530 if (!as_generator(
531 scope_tab << "[Efl.Eo.PrivateNativeClass]\n"
532 << scope_tab << "private class " << inherit_name << "Realized : " << inherit_name << "\n"
533 << scope_tab << "{\n"
534 << scope_tab << scope_tab << "private " << inherit_name << "Realized(IntPtr ptr) : base(ptr)\n"
535 << scope_tab << scope_tab << "{\n"
536 << scope_tab << scope_tab << "}\n"
537 << scope_tab << "}\n"
538 ).generate(sink, attributes::unused, context))
539 return false;
540 }
541
545 // Internal constructors 542 // Internal constructors
546 if (!root) 543 if (!root)
547 { 544 {
@@ -564,13 +561,14 @@ struct klass
564 << scope_tab << scope_tab << "}\n" 561 << scope_tab << scope_tab << "}\n"
565 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n" 562 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
566 << scope_tab << scope_tab << "RegisterEventProxies();\n" 563 << scope_tab << scope_tab << "RegisterEventProxies();\n"
564 << scope_tab << scope_tab << "if (inherited)\n"
565 << scope_tab << scope_tab << "{\n"
566 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.PrivateDataSet(this);\n"
567 << scope_tab << scope_tab << "}\n"
567 << scope_tab << "}\n" 568 << scope_tab << "}\n"
568 569
569 << scope_tab << "protected void FinishInstantiation()\n" 570 << scope_tab << "protected void FinishInstantiation()\n"
570 << scope_tab << "{\n" 571 << scope_tab << "{\n"
571 << scope_tab << scope_tab << "if (inherited) {\n"
572 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.data_set(this);\n"
573 << scope_tab << scope_tab << "}\n"
574 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle);\n" 572 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle);\n"
575 << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n" 573 << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
576 << scope_tab << "}\n" 574 << scope_tab << "}\n"
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
index 7894086f95..06cdf1584f 100644
--- a/src/bin/eolian_mono/eolian/mono/part_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -27,8 +27,7 @@ struct part_definition_generator
27 << scope_tab << "{\n" 27 << scope_tab << "{\n"
28 << scope_tab << scope_tab << "get\n" 28 << scope_tab << scope_tab << "get\n"
29 << scope_tab << scope_tab << "{\n" 29 << scope_tab << scope_tab << "{\n"
30 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\");\n" 30 << scope_tab << scope_tab << scope_tab << "return Efl.IPartNativeInherit.efl_part_get_ptr.Value.Delegate(NativeHandle, \"" << part.name << "\") as " << part_klass_name << ";\n"
31 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
32 << scope_tab << scope_tab << "}\n" 31 << scope_tab << scope_tab << "}\n"
33 << scope_tab << "}\n" 32 << scope_tab << "}\n"
34 ).generate(sink, part.documentation, context); 33 ).generate(sink, part.documentation, context);
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 35f772554f..c059dd9cbe 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -159,10 +159,8 @@ struct to_external_field_convert_generator
159 if (!as_generator( 159 if (!as_generator(
160 "\n" 160 "\n"
161 << indent << scope_tab << scope_tab << "_external_struct." << string 161 << indent << scope_tab << scope_tab << "_external_struct." << string
162 << " = (" << concrete_name << ") System.Activator.CreateInstance(typeof(" 162 << " = (" << concrete_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n"
163 << concrete_name << "), new System.Object[] {_internal_struct." << string << "});\n" 163 ).generate(sink, std::make_tuple(field_name, field_name), context))
164 << indent << scope_tab << scope_tab << "Efl.Eo.Globals.efl_ref(_internal_struct." << string << ");\n")
165 .generate(sink, std::make_tuple(field_name, field_name, field_name), context))
166 return false; 164 return false;
167 } 165 }
168 else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *") 166 else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")