summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono/klass.hh
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/eolian_mono/eolian/mono/klass.hh
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/eolian_mono/eolian/mono/klass.hh')
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh56
1 files changed, 27 insertions, 29 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 20045de..2f0bc62 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"