summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-04-23 11:48:03 +0200
committerXavi Artigas <xavierartigas@yahoo.es>2019-04-23 11:57:51 +0200
commit766e837a861e401d574d225ac8473367218788b3 (patch)
tree5e3bf56ad67583d448851a70dc73f81a1f09af89 /src/bin
parent6547d45b817fbb20333878d189c4def26cdfa819 (diff)
csharp: refactor native_inherit into a nested class.
Summary: Efl.Ui.Button_NativeInherit -> Efl.Ui.Button.NativeMethods Will help using EFL# with completion tools. * Added pragmas around the native function definitions to avoid warnings related to the name of native functions * Updated some style fixes for native function wrappers. Their preamble and epilogue styling will be dealt with in future diffs. As a side effect, concrete classes had to be made public again as they hold the function pointers to the native methods of their interfaces. Thus a third party library class that implements IFoo should be able to access these methods. Fixes T7743 Depends on D8622 Reviewers: vitor.sousa, felipealmeida, segfaultxavi Reviewed By: vitor.sousa, segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7743 Differential Revision: https://phab.enlightenment.org/D8645
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh77
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh27
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh102
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh20
4 files changed, 124 insertions, 102 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 23025480c0..0dbd097f1d 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -34,12 +34,14 @@ struct native_function_definition_generator
34 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl; 34 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl;
35 if(blacklist::is_function_blacklisted(f, context)) 35 if(blacklist::is_function_blacklisted(f, context))
36 return true; 36 return true;
37 else 37
38 { 38 auto const& indent = current_indentation(context);
39
40 // Delegate for the C# method we will export to EO as a method implementation.
39 if(!as_generator 41 if(!as_generator
40 ("\n\n" << scope_tab 42 (
41 << eolian_mono::marshall_annotation(true) 43 indent << eolian_mono::marshall_annotation(true) << "\n"
42 << " private delegate " 44 << indent << "private delegate "
43 << eolian_mono::marshall_type(true) 45 << eolian_mono::marshall_type(true)
44 << " " 46 << " "
45 << string 47 << string
@@ -49,14 +51,15 @@ struct native_function_definition_generator
49 ( 51 (
50 (marshall_annotation << " " << marshall_parameter) 52 (marshall_annotation << " " << marshall_parameter)
51 ) % ", ") 53 ) % ", ")
52 << ");\n") 54 << ");\n\n")
53 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context)) 55 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
54 return false; 56 return false;
55 57
58 // API delegate is the wrapper for the Eo methods exported from C that we will use from C#.
56 if(!as_generator 59 if(!as_generator
57 ("\n\n" << scope_tab 60 (
58 << eolian_mono::marshall_annotation(true) 61 indent << eolian_mono::marshall_annotation(true) << "\n"
59 << " public delegate " 62 << indent << "public delegate "
60 << eolian_mono::marshall_type(true) 63 << eolian_mono::marshall_type(true)
61 << " " 64 << " "
62 << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj") 65 << string << "_api_delegate(" << (f.is_static ? "" : "System.IntPtr obj")
@@ -65,17 +68,18 @@ struct native_function_definition_generator
65 ( 68 (
66 (marshall_annotation << " " << marshall_parameter) 69 (marshall_annotation << " " << marshall_parameter)
67 ) % ", ") 70 ) % ", ")
68 << ");\n") 71 << ");\n\n")
69 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context)) 72 .generate(sink, std::make_tuple(f.return_type, f.return_type, f.c_name, f.parameters), context))
70 return false; 73 return false;
71 74
75 // Delegate holder (so it can't be collected).
72 if(!as_generator 76 if(!as_generator
73 (scope_tab 77 (indent << "public static Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<"
74 << " public static Efl.Eo.FunctionWrapper<" << string << "_api_delegate> " << string << "_ptr = new Efl.Eo.FunctionWrapper<" 78 << string << "_api_delegate>(Module, \"" << string << "\");\n\n")
75 << string << "_api_delegate>(_Module, \"" << string << "\");\n")
76 .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context)) 79 .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, f.c_name), context))
77 return false; 80 return false;
78 81
82 // Actual method implementation to be called from C.
79 std::string return_type; 83 std::string return_type;
80 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) 84 if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context))
81 return false; 85 return false;
@@ -92,34 +96,37 @@ struct native_function_definition_generator
92 self = ""; 96 self = "";
93 97
94 if(!as_generator 98 if(!as_generator
95 (scope_tab 99 (indent << "private static "
96 << " private static "
97 << eolian_mono::marshall_type(true) << " " 100 << eolian_mono::marshall_type(true) << " "
98 << string 101 << string
99 << "(System.IntPtr obj, System.IntPtr pd" 102 << "(System.IntPtr obj, System.IntPtr pd"
100 << *(", " << marshall_parameter) 103 << *(", " << marshall_parameter)
101 << ")\n" 104 << ")\n"
102 << scope_tab << "{\n" 105 << indent << "{\n"
103 /****/ 106 << indent << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n"
104 << scope_tab << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n" 107 << indent << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);\n"
105 /****/ 108 << indent << scope_tab << "if (wrapper != null)\n"
106 << scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);\n" 109 << indent << scope_tab << "{\n"
107 << scope_tab << scope_tab << "if(wrapper != null) {\n" 110 << eolian_mono::native_function_definition_preamble()
108 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() 111 << indent << scope_tab << scope_tab << "try\n"
109 << scope_tab << scope_tab << scope_tab << "try {\n" 112 << indent << scope_tab << scope_tab << "{\n"
110 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != "void" ? "_ret_var = " : "") 113 << indent << scope_tab << scope_tab << scope_tab << (return_type != "void" ? "_ret_var = " : "")
111 << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")wrapper).") << string 114 << (f.is_static ? "" : "((") << klass_cast_name << (f.is_static ? "." : ")wrapper).") << string
112 << "(" << (native_argument_invocation % ", ") << ");\n" 115 << "(" << (native_argument_invocation % ", ") << ");\n"
113 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n" 116 << indent << scope_tab << scope_tab << "}\n"
114 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" 117 << indent << scope_tab << scope_tab << "catch (Exception e)\n"
115 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);\n" 118 << indent << scope_tab << scope_tab << "{\n"
116 << scope_tab << scope_tab << scope_tab << "}\n" 119 << indent << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
117 << eolian_mono::native_function_definition_epilogue(*klass) 120 << indent << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);\n"
118 << scope_tab << scope_tab << "} else {\n" 121 << indent << scope_tab << scope_tab << "}\n\n"
119 << scope_tab << scope_tab << scope_tab << (return_type != "void" ? "return " : "") << string 122 << eolian_mono::native_function_definition_epilogue(*klass) << "\n"
123 << indent << scope_tab << "}\n"
124 << indent << scope_tab << "else\n"
125 << indent << scope_tab << "{\n"
126 << indent << scope_tab << scope_tab << (return_type != "void" ? "return " : "") << string
120 << "_ptr.Value.Delegate(" << self << ((!f.is_static && f.parameters.size() > 0) ? ", " : "") << (argument % ", ") << ");\n" 127 << "_ptr.Value.Delegate(" << self << ((!f.is_static && f.parameters.size() > 0) ? ", " : "") << (argument % ", ") << ");\n"
121 << scope_tab << scope_tab << "}\n" 128 << indent << scope_tab << "}\n"
122 << scope_tab << "}\n" 129 << indent << "}\n\n"
123 ) 130 )
124 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters 131 .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters
125 , /***/f.c_name/***/ 132 , /***/f.c_name/***/
@@ -139,11 +146,11 @@ struct native_function_definition_generator
139 146
140 // This is the delegate that will be passed to Eo to be called from C. 147 // This is the delegate that will be passed to Eo to be called from C.
141 if(!as_generator( 148 if(!as_generator(
142 scope_tab << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n" 149 indent << "private static " << f.c_name << "_delegate " << f.c_name << "_static_delegate;\n\n"
143 ).generate(sink, attributes::unused, context)) 150 ).generate(sink, attributes::unused, context))
144 return false; 151 return false;
152
145 return true; 153 return true;
146 }
147 } 154 }
148}; 155};
149 156
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index fc044e6b72..b490808b9a 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -30,35 +30,34 @@ struct function_registration_generator
30 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
31 { 31 {
32 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_registration_generator: " << f.name << std::endl; 32 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_registration_generator: " << f.name << std::endl;
33 auto const& indent = current_indentation(context);
34
33 if(blacklist::is_function_blacklisted(f, context) || f.is_static) // Static methods aren't overrideable 35 if(blacklist::is_function_blacklisted(f, context) || f.is_static) // Static methods aren't overrideable
34 return true; 36 return true;
35 else
36 {
37 // auto index = index_generator();
38 37
39 if(!as_generator( 38 if(!as_generator(
40 scope_tab << scope_tab << "if (" << f.c_name << "_static_delegate == null)\n" 39 indent << "if (" << f.c_name << "_static_delegate == null)\n"
41 << scope_tab << scope_tab << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" << 40 << indent << "{\n"
42 escape_keyword(f.name) << ");\n" 41 << indent << scope_tab << f.c_name << "_static_delegate = new " << f.c_name << "_delegate(" << escape_keyword(f.name) << ");\n"
42 << indent << "}\n\n"
43 ).generate(sink, attributes::unused, context)) 43 ).generate(sink, attributes::unused, context))
44 return false; 44 return false;
45 45
46 if(!as_generator 46 if(!as_generator(
47 (scope_tab << scope_tab 47 indent << "if (methods.FirstOrDefault(m => m.Name == \"" << string << "\") != null)\n"
48 << "if (methods.FirstOrDefault(m => m.Name == \"" << string << "\") != null)\n" 48 << indent << "{\n"
49 << scope_tab << scope_tab << scope_tab 49 << indent << scope_tab << "descs.Add(new Efl_Op_Description() {"
50 << "descs.Add(new Efl_Op_Description() {"
51#ifdef _WIN32 50#ifdef _WIN32
52 << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")" 51 << "api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\")"
53#else 52#else
54 << "api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, \"" << string << "\")" 53 << "api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(Module.Module, \"" << string << "\")"
55#endif 54#endif
56 << ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate)});\n" 55 << ", func = Marshal.GetFunctionPointerForDelegate(" << string << "_static_delegate) });\n"
56 << indent << "}\n\n"
57 ) 57 )
58 .generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.c_name, f.c_name), context)) 58 .generate(sink, std::make_tuple(name_helpers::managed_method_name(f), f.c_name, f.c_name), context))
59 return false; 59 return false;
60 return true; 60 return true;
61 }
62 } 61 }
63}; 62};
64 63
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index b4af094b4f..c81a23fe08 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -88,6 +88,8 @@ struct klass
88 { 88 {
89 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "klass_generator: " << cls.eolian_name << std::endl; 89 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "klass_generator: " << cls.eolian_name << std::endl;
90 90
91 auto const& indent = current_indentation(context);
92
91 if (blacklist::is_class_blacklisted(cls, context)) 93 if (blacklist::is_class_blacklisted(cls, context))
92 { 94 {
93 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "class " << cls.eolian_name << " is blacklisted. Skipping." << std::endl; 95 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "class " << cls.eolian_name << " is blacklisted. Skipping." << std::endl;
@@ -131,7 +133,7 @@ struct klass
131 return false; 133 return false;
132 134
133 // Mark the interface with the proper native Efl_Class* getter 135 // Mark the interface with the proper native Efl_Class* getter
134 if(!as_generator(lit("[") << name_helpers::klass_native_inherit_name(cls) << "]\n") 136 if(!as_generator(lit("[") << name_helpers::klass_full_native_inherit_name(cls) << "]\n")
135 .generate(sink, attributes::unused, iface_cxt)) 137 .generate(sink, attributes::unused, iface_cxt))
136 return false; 138 return false;
137 139
@@ -209,10 +211,12 @@ struct klass
209 auto concrete_name = name_helpers::klass_concrete_name(cls); 211 auto concrete_name = name_helpers::klass_concrete_name(cls);
210 auto interface_name = name_helpers::klass_interface_name(cls); 212 auto interface_name = name_helpers::klass_interface_name(cls);
211 213
214 // We can't make these internal yet as they have methods that are used by
215 // other classes that implement the interface.
212 if(!as_generator 216 if(!as_generator
213 ( 217 (
214 documentation 218 documentation
215 << "sealed internal class " << concrete_name << " : " << "\n" 219 << "sealed public class " << concrete_name << " : " << "\n"
216 << (klass_full_concrete_or_interface_name % ",") << "\n" 220 << (klass_full_concrete_or_interface_name % ",") << "\n"
217 << (inherit_classes.size() > 0 ? ", " : "" ) << interface_name << "\n" 221 << (inherit_classes.size() > 0 ? ", " : "" ) << interface_name << "\n"
218 << scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n" 222 << scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n"
@@ -281,6 +285,8 @@ struct klass
281 ).generate(sink, attributes::unused, concrete_cxt)) 285 ).generate(sink, attributes::unused, concrete_cxt))
282 return false; 286 return false;
283 287
288 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context)))
289 return true;
284 290
285 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; 291 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
286 } 292 }
@@ -296,7 +302,7 @@ struct klass
296 if(!as_generator 302 if(!as_generator
297 ( 303 (
298 documentation 304 documentation
299 << "[" << name_helpers::klass_native_inherit_name(cls) << "]\n" 305 << "[" << name_helpers::klass_full_native_inherit_name(cls) << "]\n"
300 << "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : " 306 << "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : "
301 << (klass_full_concrete_or_interface_name % ",") // classes 307 << (klass_full_concrete_or_interface_name % ",") // classes
302 << (inherit_classes.empty() ? "" : ",") 308 << (inherit_classes.empty() ? "" : ",")
@@ -358,11 +364,24 @@ struct klass
358 ).generate(sink, attributes::unused, inherit_cxt)) 364 ).generate(sink, attributes::unused, inherit_cxt))
359 return false; 365 return false;
360 366
367 if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context)))
368 return true;
369
361 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 370 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
362 } 371 }
363 372
364 // Native Inherit class 373
365 //if(class_type == "class") 374 if(!name_helpers::close_namespaces(sink, cls.namespaces, context))
375 return false;
376
377 return true;
378 }
379
380 // NativeInherit class. Contains function pointers for the native Eo methods and delegates that are registered in Eo as virtual method implementations
381 // These delegates are called from C to C#, checking whether the C# subclass reimplemented it.
382 template <typename OutputIterator, typename Context>
383 bool generate_native_inherit_class(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
384 {
366 { 385 {
367 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native, 386 auto inative_cxt = context_add_tag(class_context{class_context::inherit_native,
368 name_helpers::klass_full_concrete_or_interface_name(cls)}, 387 name_helpers::klass_full_concrete_or_interface_name(cls)},
@@ -370,6 +389,9 @@ struct klass
370 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); 389 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
371 auto inherit_name = name_helpers::klass_inherit_name(cls); 390 auto inherit_name = name_helpers::klass_inherit_name(cls);
372 auto implementable_methods = helpers::get_all_implementable_methods(cls); 391 auto implementable_methods = helpers::get_all_implementable_methods(cls);
392 bool root = !helpers::has_regular_ancestor(cls);
393 auto const& indent = current_indentation(inative_cxt);
394
373 std::string base_name; 395 std::string base_name;
374 if(!root) 396 if(!root)
375 { 397 {
@@ -379,12 +401,28 @@ struct klass
379 401
380 if(!as_generator 402 if(!as_generator
381 ( 403 (
382 "public class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"{\n" 404 indent << lit("/// <summary>Wrapper for native methods and virtual method delegates.\n")
383 << scope_tab << "public " << (root ? "" : "new ") << " static Efl.Eo.NativeModule _Module = new Efl.Eo.NativeModule(" 405 << indent << "/// For internal use by generated code only.</summary>\n"
384 << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ");\n" 406 << indent << "public " << (root ? "" : "new " ) << "class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"\n"
385 << scope_tab << "public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n" 407 << indent << "{\n"
386 << scope_tab << "{\n" 408 ).generate(sink, attributes::unused, inative_cxt))
387 << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n" 409 return false;
410
411 if(implementable_methods.size() >= 1)
412 {
413 if(!as_generator(
414 indent << scope_tab << "private static Efl.Eo.NativeModule Module = new Efl.Eo.NativeModule("
415 << indent << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ");\n"
416 ).generate(sink, attributes::unused, inative_cxt))
417 return false;
418 }
419
420 if(!as_generator(
421 indent << scope_tab << "/// <summary>Gets the list of Eo operations to override.</summary>\n"
422 << indent << scope_tab << "/// <returns>The list of Eo operations to be overload.</returns>\n"
423 << indent << scope_tab << "public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)\n"
424 << indent << scope_tab << "{\n"
425 << indent << scope_tab << scope_tab << "var descs = new System.Collections.Generic.List<Efl_Op_Description>();\n"
388 ) 426 )
389 .generate(sink, attributes::unused, inative_cxt)) 427 .generate(sink, attributes::unused, inative_cxt))
390 return false; 428 return false;
@@ -394,53 +432,46 @@ struct klass
394 // only non-registrable methods like class functions, leading to unused `methods` variable. 432 // only non-registrable methods like class functions, leading to unused `methods` variable.
395 std::string tmp_registration; 433 std::string tmp_registration;
396 if(!as_generator(*(function_registration(cls))) 434 if(!as_generator(*(function_registration(cls)))
397 .generate(std::back_inserter(tmp_registration), implementable_methods, inative_cxt)) 435 .generate(std::back_inserter(tmp_registration), implementable_methods, change_indentation(indent.inc(2), inative_cxt)))
398 return false; 436 return false;
399 437
400 if (tmp_registration.find("methods") != std::string::npos) 438 if (tmp_registration.find("methods") != std::string::npos)
401 if (!as_generator( 439 if (!as_generator(
402 scope_tab << scope_tab << "var methods = Efl.Eo.Globals.GetUserMethods(type);\n" 440 indent << scope_tab << scope_tab << "var methods = Efl.Eo.Globals.GetUserMethods(type);\n\n"
403 << tmp_registration 441 << tmp_registration
404 ).generate(sink, attributes::unused, inative_cxt)) 442 ).generate(sink, attributes::unused, inative_cxt))
405 return false; 443 return false;
406 444
407 if(!root) 445 if(!root)
408 if(!as_generator(scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, inative_cxt)) 446 if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, inative_cxt))
409 return false; 447 return false;
410 448
411 if(!as_generator( 449 if(!as_generator(
412 scope_tab << scope_tab << "return descs;\n" 450 indent << scope_tab << scope_tab << "return descs;\n"
413 << scope_tab << "}\n" 451 << indent << scope_tab << "}\n"
414 ).generate(sink, attributes::unused, inative_cxt)) 452 ).generate(sink, attributes::unused, inative_cxt))
415 return false; 453 return false;
416 454
417 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces) 455 // Attribute getter of the native 'Efl_Class *' handle (for proper inheritance from additional explicit interfaces)
418 if(!as_generator( 456 if(!as_generator(
419 scope_tab << "public override IntPtr GetEflClass()\n" 457 indent << scope_tab << "/// <summary>Returns the Eo class for the native methods of this class.</summary>\n"
420 << scope_tab << "{\n" 458 << indent << scope_tab << "/// <returns>The native class pointer.</returns>\n"
421 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n" 459 << indent << scope_tab << "public override IntPtr GetEflClass()\n"
422 << scope_tab << "}\n\n" 460 << indent << scope_tab << "{\n"
423 ).generate(sink, attributes::unused, inative_cxt)) 461 << indent << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
424 return false; 462 << indent << scope_tab << "}\n\n"
425
426 if(!as_generator(
427 scope_tab << "public static " << (root ? "" : "new ") << " IntPtr GetEflClassStatic()\n"
428 << scope_tab << "{\n"
429 << scope_tab << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n"
430 << scope_tab << "}\n\n"
431 ).generate(sink, attributes::unused, inative_cxt)) 463 ).generate(sink, attributes::unused, inative_cxt))
432 return false; 464 return false;
433 465
434 // Native method definitions 466 // Native method definitions
435 if(!as_generator(*(native_function_definition(cls))) 467 if(!as_generator(
436 .generate(sink, implementable_methods, inative_cxt)) return false; 468 indent << scope_tab << "#pragma warning disable CA1707, SA1300, SA1600\n\n"
469 << *(native_function_definition(cls))
470 << indent << scope_tab << "#pragma warning restore CA1707, SA1300, SA1600\n\n")
471 .generate(sink, implementable_methods, change_indentation(indent.inc(), inative_cxt))) return false;
437 472
438 if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false; 473 if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false;
439 } 474 }
440
441 if(!name_helpers::close_namespaces(sink, cls.namespaces, context))
442 return false;
443
444 return true; 475 return true;
445 } 476 }
446 477
@@ -469,7 +500,7 @@ struct klass
469 << scope_tab << scope_tab << "{\n" 500 << scope_tab << scope_tab << "{\n"
470 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n" 501 << scope_tab << scope_tab << scope_tab << "if (((object)this).GetType() == typeof(" << inherit_name << "))\n"
471 << scope_tab << scope_tab << scope_tab << "{\n" 502 << scope_tab << scope_tab << scope_tab << "{\n"
472 << scope_tab << scope_tab << scope_tab << scope_tab << "return " << native_inherit_full_name << ".GetEflClassStatic();\n" 503 << scope_tab << scope_tab << scope_tab << scope_tab << "return GetEflClassStatic();\n"
473 << scope_tab << scope_tab << scope_tab << "}\n" 504 << scope_tab << scope_tab << scope_tab << "}\n"
474 << scope_tab << scope_tab << scope_tab << "else\n" 505 << scope_tab << scope_tab << scope_tab << "else\n"
475 << scope_tab << scope_tab << scope_tab << "{\n" 506 << scope_tab << scope_tab << scope_tab << "{\n"
@@ -513,7 +544,6 @@ struct klass
513 { 544 {
514 bool root = !helpers::has_regular_ancestor(cls); 545 bool root = !helpers::has_regular_ancestor(cls);
515 auto inherit_name = name_helpers::klass_concrete_name(cls); 546 auto inherit_name = name_helpers::klass_concrete_name(cls);
516 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
517 547
518 if(!as_generator( 548 if(!as_generator(
519 scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename) 549 scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index 858ab59a89..4d9fff92de 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -398,29 +398,15 @@ inline std::string klass_inherit_name(T const& klass)
398} 398}
399 399
400template<typename T> 400template<typename T>
401inline std::string klass_native_inherit_name(T const& klass) 401inline std::string klass_native_inherit_name(EINA_UNUSED T const& klass)
402{ 402{
403 switch(klass.type) 403 return "NativeMethods";
404 {
405 case attributes::class_type::abstract_:
406 case attributes::class_type::regular:
407 return klass_concrete_name(klass) + "NativeInherit";
408 default:
409 return klass_interface_name(klass) + "NativeInherit";
410 }
411} 404}
412 405
413template<typename T> 406template<typename T>
414inline std::string klass_full_native_inherit_name(T const& klass) 407inline std::string klass_full_native_inherit_name(T const& klass)
415{ 408{
416 switch(klass.type) 409 return klass_full_concrete_name(klass) + "." + klass_native_inherit_name(klass);
417 {
418 case attributes::class_type::abstract_:
419 case attributes::class_type::regular:
420 return klass_full_concrete_name(klass) + "NativeInherit";
421 default:
422 return klass_full_interface_name(klass) + "NativeInherit";
423 }
424} 410}
425 411
426template<typename T> 412template<typename T>