summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-11-29 21:04:37 -0200
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2018-11-29 21:29:48 -0200
commit3623753c1d6b893955a1c31e8559a2312f674192 (patch)
treee862682ff92d34ce4ebf44c95efa24ba3a57fe7a /src/bin/eolian_mono
parenteec7bc458eee333fd7237a3bd43e8c2c884f21ca (diff)
csharp: Change to new class API.
Summary: As discussed in T7204: - Eo Interfaces/mixins -> C# Interfaces with concrete class implementations - Eo Regular/Abstracts -> Proper C# classes - Added some new generators and helper methods. - Refactored the class generator, splitting into helper methods Eo handles now are stored only in the "root" class in any given inheritance tree (generally, Efl.Object), and accessible to each child. Methods also are defined in a single place instead of repeatedly generated in everyfile, reducing the size of the generated .dll from 30MB to around 4.5MB. Mixins are generated as C# interfaces but any regular class it inherits from is lost, as we can't have interfaces inheriting from regular classes. This will be dealt with in a later commit. Summary of API Changes: - Merged Inherit/Concrete classes. (These suffixes disappear from regular classes). - Interface still have implementations with 'Concrete' suffix for when they are returned from methods. - Removed 'I' from interface names. - Removed interfaces for regular/abstract Eo classes. - Concrete classes for interfaces/mixins hold the event argument struct. - Removed '_' from classes, enums, structs, etc, as indicated in C# naming conventions. - Namespaces are now Camel.Cased. - Renamed IWrapper's raw_handle/raw_klass to NativeHandle/NativeClass Also renamed the test classes as after the namespace change, the test namespace Test can conflict with the helper Test namespace. (And use more meaningful names than Test.Testing...) Also Fixes T7336 by removing a deprecated example and adding efl_loop_timer_example to build system. Fixes T7451 by hiding the class_get DllImports and renaming the IWrapper fields. The native handlers are used in the manual binding. Still need to work: - As there are still some events names clashing (e.g. Efl.Ui.Bg with "resize" from Efl.Gfx.Entity and Efl.Gfx.Image), Events are currently declared on the interface and implemented "namespaced" in the classes, requiring the cast to the interface to access the event. - The Mixin Conundrum. Mixin inheritance will be dealt in a future commit. Depends on D7260 Reviewers: segfaultxavi, vitor.sousa, felipealmeida, Jaehyun_Cho Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7451, T7336 Differential Revision: https://phab.enlightenment.org/D7262
Diffstat (limited to 'src/bin/eolian_mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/async_function_definition.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/enum_definition.hh5
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh193
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh28
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_helpers.hh38
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh17
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh157
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh534
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh76
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type.hh2
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh14
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh185
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh32
-rw-r--r--src/bin/eolian_mono/eolian/mono/part_definition.hh7
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh28
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh31
-rw-r--r--src/bin/eolian_mono/eolian/mono/using_decl.hh25
-rw-r--r--src/bin/eolian_mono/eolian/mono/utils.hh7
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc5
21 files changed, 961 insertions, 435 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
index 3030c74e1e..1dc705ad3a 100644
--- a/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
@@ -54,7 +54,7 @@ struct async_function_declaration_generator
54 return true; 54 return true;
55 55
56 if (!as_generator( 56 if (!as_generator(
57 scope_tab << "System.Threading.Tasks.Task<eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") << 57 scope_tab << "System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") <<
58 " System.Threading.CancellationToken token=default(System.Threading.CancellationToken));\n" 58 " System.Threading.CancellationToken token=default(System.Threading.CancellationToken));\n"
59 ).generate(sink, f.parameters, context)) 59 ).generate(sink, f.parameters, context))
60 return false; 60 return false;
@@ -89,10 +89,10 @@ struct async_function_definition_generator
89 std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding); 89 std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding);
90 90
91 if(!as_generator( 91 if(!as_generator(
92 scope_tab << "public System.Threading.Tasks.Task<eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") << " System.Threading.CancellationToken token)\n" 92 scope_tab << "public System.Threading.Tasks.Task<Eina.Value> " << name_helpers::managed_async_method_name(f) << "(" << *(parameter << ",") << " System.Threading.CancellationToken token=default(System.Threading.CancellationToken))\n"
93 << scope_tab << "{\n" 93 << scope_tab << "{\n"
94 << scope_tab << scope_tab << "eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ",") << ");\n" 94 << scope_tab << scope_tab << "Eina.Future future = " << name_helpers::managed_method_name(f) << "(" << (string % ",") << ");\n"
95 << scope_tab << scope_tab << "return efl.eo.Globals.WrapAsync(future, token);\n" 95 << scope_tab << scope_tab << "return Efl.Eo.Globals.WrapAsync(future, token);\n"
96 << scope_tab << "}\n" 96 << scope_tab << "}\n"
97 ).generate(sink, std::make_tuple(f.parameters, param_forwarding), context)) 97 ).generate(sink, std::make_tuple(f.parameters, param_forwarding), context))
98 return false; 98 return false;
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index a436bcc203..99ec12e91d 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -62,6 +62,8 @@ inline bool is_struct_blacklisted(std::string const& full_name)
62 || full_name == "Eina.Slice" 62 || full_name == "Eina.Slice"
63 || full_name == "Eina.Rw_Slice" 63 || full_name == "Eina.Rw_Slice"
64 || full_name == "Eina.Promise" 64 || full_name == "Eina.Promise"
65 || full_name == "Eina.Value"
66 || full_name == "Eina.Value_Type"
65 || full_name == "Eina.Future"; 67 || full_name == "Eina.Future";
66} 68}
67 69
diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
index 9261f5b2e6..78af78af2c 100644
--- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
@@ -27,16 +27,15 @@ struct enum_definition_generator
27 ( 27 (
28 "public enum " << string << "\n{\n" 28 "public enum " << string << "\n{\n"
29 ) 29 )
30 .generate(sink, name_helpers::enum_managed_name(enum_), context)) 30 .generate(sink, name_helpers::typedecl_managed_name(enum_), context))
31 return false; 31 return false;
32 32
33 // iterate enum fiels 33 // iterate enum fiels
34 for(auto first = std::begin(enum_.fields) 34 for(auto first = std::begin(enum_.fields)
35 , last = std::end(enum_.fields); first != last; ++first) 35 , last = std::end(enum_.fields); first != last; ++first)
36 { 36 {
37 auto name = (*first).name; 37 auto name = name_helpers::enum_field_managed_name((*first).name);
38 auto literal = (*first).value.literal; 38 auto literal = (*first).value.literal;
39 name[0] = std::toupper(name[0]); // Hack to allow 'static' as a field name
40 if (!as_generator 39 if (!as_generator
41 ( 40 (
42 documentation << string << " = " << string << ",\n" 41 documentation << string << " = " << string << ",\n"
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index a5fe8ec788..426763626b 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -41,8 +41,8 @@ struct unpack_event_args_visitor
41 {"bool", [&arg] { return arg + " != IntPtr.Zero"; }} 41 {"bool", [&arg] { return arg + " != IntPtr.Zero"; }}
42 , {"int", [&arg] { return arg + ".ToInt32()"; }} 42 , {"int", [&arg] { return arg + ".ToInt32()"; }}
43 , {"uint", [&arg] { return "(uint)" + arg + ".ToInt32()";}} 43 , {"uint", [&arg] { return "(uint)" + arg + ".ToInt32()";}}
44 , {"string", [&arg] { return "eina.StringConversion.NativeUtf8ToManagedString(" + arg + ")"; }} 44 , {"string", [&arg] { return "Eina.StringConversion.NativeUtf8ToManagedString(" + arg + ")"; }}
45 , {"Eina.Error", [&arg] { return "(eina.Error)Marshal.PtrToStructure(" + arg + ", typeof(eina.Error))"; }} 45 , {"Eina.Error", [&arg] { return "(Eina.Error)Marshal.PtrToStructure(" + arg + ", typeof(Eina.Error))"; }}
46 }; 46 };
47 47
48 std::string full_type_name = name_helpers::type_full_eolian_name(regular); 48 std::string full_type_name = name_helpers::type_full_eolian_name(regular);
@@ -71,6 +71,9 @@ struct unpack_event_args_visitor
71 } 71 }
72}; 72};
73 73
74/*
75 * Generates a struct wrapping the argument of a given event.
76 */
74struct event_argument_wrapper_generator 77struct event_argument_wrapper_generator
75{ 78{
76 template<typename OutputIterator, typename Context> 79 template<typename OutputIterator, typename Context>
@@ -97,6 +100,11 @@ struct event_argument_wrapper_generator
97 } 100 }
98} const event_argument_wrapper {}; 101} const event_argument_wrapper {};
99 102
103/*
104 * Generates an event declaration as a C# Interface member.
105 * In regular/abstract classes they are declared directly in their
106 * implementation in event_definition_generator.
107 */
100struct event_declaration_generator 108struct event_declaration_generator
101{ 109{
102 template<typename OutputIterator, typename Context> 110 template<typename OutputIterator, typename Context>
@@ -104,11 +112,9 @@ struct event_declaration_generator
104 { 112 {
105 std::string wrapper_args_type; 113 std::string wrapper_args_type;
106 std::string evt_name = name_helpers::managed_event_name(evt.name); 114 std::string evt_name = name_helpers::managed_event_name(evt.name);
107 std::string evt_args_name = name_helpers::managed_event_args_name(evt);
108 115
109 efl::eina::optional<grammar::attributes::type_def> etype = evt.type; 116 if (evt.type.is_engaged())
110 if (etype.is_engaged()) 117 wrapper_args_type = "<" + name_helpers::managed_event_args_name(evt) + ">";
111 wrapper_args_type = "<" + evt_args_name + ">";
112 118
113 if (!as_generator( 119 if (!as_generator(
114 documentation(1) 120 documentation(1)
@@ -122,34 +128,39 @@ struct event_declaration_generator
122 128
123struct event_registration_generator 129struct event_registration_generator
124{ 130{
125 attributes::klass_def const* klass; 131 attributes::klass_def const& klass;
132 attributes::klass_def const& leaf_klass;
133 bool is_inherited_event;
134
126 template<typename OutputIterator, typename Context> 135 template<typename OutputIterator, typename Context>
127 bool generate(OutputIterator sink, attributes::event_def const& evt, Context const& context) const 136 bool generate(OutputIterator sink, attributes::event_def const& evt, Context const& context) const
128 { 137 {
129 std::string wrapper_event_name; 138 std::string wrapper_event_name;
130 139
131 if (klass) 140 if (is_inherited_event && !helpers::is_unique_event(evt, leaf_klass))
132 wrapper_event_name = name_helpers::translate_inherited_event_name(evt, *klass); 141 wrapper_event_name = name_helpers::translate_inherited_event_name(evt, klass);
133 else 142 else
134 wrapper_event_name = name_helpers::managed_event_name(evt.name); 143 wrapper_event_name = name_helpers::managed_event_name(evt.name);
135 144
136 return as_generator(scope_tab << scope_tab << "evt_" << wrapper_event_name << "_delegate = " 145 return as_generator(scope_tab << scope_tab << "evt_" << wrapper_event_name << "_delegate = "
137 << "new efl.Event_Cb(on_" << wrapper_event_name << "_NativeCallback);\n" 146 << "new Efl.EventCb(on_" << wrapper_event_name << "_NativeCallback);\n"
138 ).generate(sink, attributes::unused, context); 147 ).generate(sink, attributes::unused, context);
139 } 148 }
140}; 149};
141 150
142struct event_registration_parameterized 151struct event_registration_parameterized
143{ 152{
144 event_registration_generator operator()(attributes::klass_def const* klass=NULL) const 153 event_registration_generator operator()(attributes::klass_def const& klass, attributes::klass_def const& leaf_klass) const
145 { 154 {
146 return {klass}; 155 bool is_inherited_event = klass != leaf_klass;
156 return {klass, leaf_klass, is_inherited_event};
147 } 157 }
148} const event_registration; 158} const event_registration;
149 159
150struct event_definition_generator 160struct event_definition_generator
151{ 161{
152 attributes::klass_def const& klass; 162 attributes::klass_def const& klass;
163 attributes::klass_def const& leaf_klass;
153 bool is_inherited_event; 164 bool is_inherited_event;
154 165
155 template<typename OutputIterator, typename Context> 166 template<typename OutputIterator, typename Context>
@@ -157,8 +168,12 @@ struct event_definition_generator
157 { 168 {
158 std::string managed_evt_name = name_helpers::managed_event_name(evt.name); 169 std::string managed_evt_name = name_helpers::managed_event_name(evt.name);
159 170
171 bool is_unique = helpers::is_unique_event(evt, leaf_klass);
172 bool use_explicit_impl = is_inherited_event && !is_unique;
173
174 // The name of the public event that goes in the public API.
160 std::string wrapper_evt_name; 175 std::string wrapper_evt_name;
161 if (is_inherited_event) 176 if (use_explicit_impl)
162 wrapper_evt_name = name_helpers::translate_inherited_event_name(evt, klass); 177 wrapper_evt_name = name_helpers::translate_inherited_event_name(evt, klass);
163 else 178 else
164 wrapper_evt_name = managed_evt_name; 179 wrapper_evt_name = managed_evt_name;
@@ -167,14 +182,11 @@ struct event_definition_generator
167 if (is_inherited_event) 182 if (is_inherited_event)
168 klass_name = name_helpers::klass_full_interface_name(klass); 183 klass_name = name_helpers::klass_full_interface_name(klass);
169 else 184 else
170 klass_name = name_helpers::klass_interface_name(klass); 185 klass_name = name_helpers::klass_concrete_name(klass);
171
172 186
173 std::string upper_c_name = utils::to_uppercase(evt.c_name);
174 std::string wrapper_args_type = "EventArgs"; 187 std::string wrapper_args_type = "EventArgs";
175 std::string wrapper_args_template = ""; 188 std::string wrapper_args_template = "";
176 std::string event_args = "EventArgs args = EventArgs.Empty;\n"; 189 std::string event_args = "EventArgs args = EventArgs.Empty;\n";
177 std::string visibility = is_inherit_context(context) ? "protected" : "private";
178 190
179 efl::eina::optional<grammar::attributes::type_def> etype = evt.type; 191 efl::eina::optional<grammar::attributes::type_def> etype = evt.type;
180 192
@@ -196,68 +208,125 @@ struct event_definition_generator
196 event_args = arg_initializer; 208 event_args = arg_initializer;
197 } 209 }
198 210
199 // Wrapper event declaration 211 if(!as_generator("private static object " << wrapper_evt_name << "Key = new object();\n")
212 .generate(sink, attributes::unused, context))
213 return false;
214
200 if(!as_generator(documentation(1)).generate(sink, evt, context)) 215 if(!as_generator(documentation(1)).generate(sink, evt, context))
201 return false; 216 return false;
202 217
203 if(!as_generator( 218 // Visible event declaration. Either a regular class member or an explicit interface implementation.
204 scope_tab << visibility << " event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << ";\n" 219 if (klass.type == attributes::class_type::interface_ || klass.type == attributes::class_type::mixin)
205 << scope_tab << "///<summary>Method to raise event "<< wrapper_evt_name << ".</summary>\n" 220 {
206 << scope_tab << visibility << " void On_" << wrapper_evt_name << "(" << wrapper_args_type << " e)\n" 221 // Public event implementation.
207 << scope_tab << "{\n" 222 if (!as_generator(
208 << scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n" 223 scope_tab << (!use_explicit_impl ? "public " : " ") << "event EventHandler" << wrapper_args_template << " " << (use_explicit_impl ? (klass_name + ".") : "") << managed_evt_name << "\n"
209 << scope_tab << scope_tab << "lock (eventLock) {\n" 224 ).generate(sink, attributes::unused, context))
210 << scope_tab << scope_tab << scope_tab << "evt = " << wrapper_evt_name << ";\n" 225 return false;
211 << scope_tab << scope_tab << "}\n" 226 }
212 << scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n" 227 else // For inheritable classes event handling.
213 << scope_tab << "}\n" 228 {
214 << scope_tab << "private void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event_StructInternal evt)\n" 229 // We may have inherited an event with the same name as this concrete event, thus
230 // the concrete event would "hide" the interface one, requiring the new keyword.
231 std::string visibility = "public ";
232 if (!is_unique)
233 visibility += "new ";
234
235 if (!as_generator(
236 scope_tab << visibility << "event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << "\n"
237 ).generate(sink, attributes::unused, context))
238 return false;
239 }
240
241 if (!generate_event_add_remove(sink, evt, wrapper_evt_name, context))
242 return false;
243
244 if (!generate_event_trigger(sink, wrapper_evt_name, wrapper_args_type, wrapper_args_template, context))
245 return false;
246
247 // Store the delegate for this event in this instance. This is initialized in register_event_proxies()
248 // We can't initialize them directly here as they depend on the member methods being valid (i.e.
249 // the constructor being called).
250 if (!as_generator(scope_tab << "Efl.EventCb evt_" << wrapper_evt_name << "_delegate;\n").generate(sink, attributes::unused, context))
251 return false;
252
253 // Callback to be given to C's callback_priority_add
254 if (!as_generator(
255 scope_tab << "private void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref Efl.Event_StructInternal evt)\n"
215 << scope_tab << "{\n" 256 << scope_tab << "{\n"
216 << scope_tab << scope_tab << event_args 257 << scope_tab << scope_tab << event_args
217 << scope_tab << scope_tab << "try {\n" 258 << scope_tab << scope_tab << "try {\n"
218 << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n" 259 << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
219 << scope_tab << scope_tab << "} catch (Exception e) {\n" 260 << scope_tab << scope_tab << "} catch (Exception e) {\n"
220 << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n" 261 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error(e.ToString());\n"
221 << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n" 262 << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.EFL_ERROR);\n"
222 << scope_tab << scope_tab << "}\n" 263 << scope_tab << scope_tab << "}\n"
223 << scope_tab << "}\n" 264 << scope_tab << "}\n\n"
224 << scope_tab << "efl.Event_Cb evt_" << wrapper_evt_name << "_delegate;\n" 265 ).generate(sink, attributes::unused, context))
225 << scope_tab << "event EventHandler" << wrapper_args_template << " " << klass_name << "." << managed_evt_name << "{\n") 266 return false;
226 .generate(sink, NULL, context))
227 return false;
228
229 if (!as_generator(
230 scope_tab << scope_tab << "add {\n"
231 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
232 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
233 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
234 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " += value;\n"
235 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
236 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
237 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
238 << scope_tab << scope_tab << "}\n"
239 << scope_tab << scope_tab << "remove {\n"
240 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
241 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
242 << scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
243 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " -= value;\n"
244 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
245 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
246 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
247 << scope_tab << scope_tab << "}\n"
248 << scope_tab << "}\n")
249 .generate(sink, NULL, context))
250 return false;
251 267
252 return true; 268 return true;
253 } 269 }
270
271 template<typename OutputIterator, typename Context>
272 bool generate_event_trigger(OutputIterator sink
273 , std::string const& event_name
274 , std::string const& event_args_type
275 , std::string const& event_template_args
276 , Context context) const
277 {
278 auto delegate_type = "EventHandler" + event_template_args;
279 if (!as_generator(
280 scope_tab << "///<summary>Method to raise event "<< event_name << ".</summary>\n"
281 << scope_tab << "public void On_" << event_name << "(" << event_args_type << " e)\n"
282 << scope_tab << "{\n"
283 << scope_tab << scope_tab << delegate_type << " evt;\n"
284 << scope_tab << scope_tab << "lock (eventLock) {\n"
285 << scope_tab << scope_tab << "evt = (" << delegate_type << ")eventHandlers[" << event_name << "Key];\n"
286 << scope_tab << scope_tab << "}\n"
287 << scope_tab << scope_tab << "evt?.Invoke(this, e);\n"
288 << scope_tab << "}\n"
289 ).generate(sink, nullptr, context))
290 return false;
291
292 return true;
293 }
294
295 template<typename OutputIterator, typename Context>
296 bool generate_event_add_remove(OutputIterator sink, attributes::event_def const &evt, const std::string& event_name, Context context) const
297 {
298 std::string upper_c_name = utils::to_uppercase(evt.c_name);
299 return as_generator(
300 scope_tab << "{\n"
301 << scope_tab << scope_tab << "add {\n"
302 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
303 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
304 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << event_name << "_delegate)) {\n"
305 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eventHandlers.AddHandler(" << event_name << "Key , value);\n"
306 << scope_tab << scope_tab << scope_tab << scope_tab << "} else\n"
307 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Error adding proxy for event {key}\");\n"
308 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
309 << scope_tab << scope_tab << "}\n"
310 << scope_tab << scope_tab << "remove {\n"
311 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
312 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
313 << scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << event_name << "_delegate)) { \n"
314 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eventHandlers.RemoveHandler(" << event_name << "Key , value);\n"
315 << scope_tab << scope_tab << scope_tab << scope_tab << "} else\n"
316 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Error removing proxy for event {key}\");\n"
317 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
318 << scope_tab << scope_tab << "}\n"
319 << scope_tab << "}\n"
320 ).generate(sink, attributes::unused, context);
321 }
254}; 322};
255 323
256struct event_definition_parameterized 324struct event_definition_parameterized
257{ 325{
258 event_definition_generator operator()(attributes::klass_def const& klass, bool is_inherited_event=false) const 326 event_definition_generator operator()(attributes::klass_def const& klass, attributes::klass_def const& leaf_klass) const
259 { 327 {
260 return {klass, is_inherited_event}; 328 bool is_inherited_event = klass != leaf_klass;
329 return {klass, leaf_klass, is_inherited_event};
261 } 330 }
262} const event_definition; 331} const event_definition;
263 332
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 7e44b2938b..93765065b8 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -83,22 +83,22 @@ struct native_function_definition_generator
83 << ")\n" 83 << ")\n"
84 << scope_tab << "{\n" 84 << scope_tab << "{\n"
85 /****/ 85 /****/
86 << scope_tab << scope_tab << "eina.Log.Debug(\"function " << string << " was called\");\n" 86 << scope_tab << scope_tab << "Eina.Log.Debug(\"function " << string << " was called\");\n"
87 /****/ 87 /****/
88 << scope_tab << scope_tab << "efl.eo.IWrapper wrapper = efl.eo.Globals.data_get(pd);\n" 88 << scope_tab << scope_tab << "Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.data_get(pd);\n"
89 << scope_tab << scope_tab << "if(wrapper != null) {\n" 89 << scope_tab << scope_tab << "if(wrapper != null) {\n"
90 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() 90 << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble()
91 << scope_tab << scope_tab << scope_tab << "try {\n" 91 << scope_tab << scope_tab << scope_tab << "try {\n"
92 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_inherit_name << ")wrapper)." << string 92 << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_inherit_name << ")wrapper)." << string
93 << "(" << (native_argument_invocation % ", ") << ");\n" 93 << "(" << (native_argument_invocation % ", ") << ");\n"
94 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n" 94 << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n"
95 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" 95 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
96 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n" 96 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.EFL_ERROR);\n"
97 << scope_tab << scope_tab << scope_tab << "}\n" 97 << scope_tab << scope_tab << scope_tab << "}\n"
98 << eolian_mono::native_function_definition_epilogue(*klass) 98 << eolian_mono::native_function_definition_epilogue(*klass)
99 << scope_tab << scope_tab << "} else {\n" 99 << scope_tab << scope_tab << "} else {\n"
100 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string 100 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string
101 << "(efl.eo.Globals.efl_super(obj, " << klass_inherit_name << ".klass)" << *(", " << argument) << ");\n" 101 << "(Efl.Eo.Globals.efl_super(obj, " << klass_inherit_name << ".klass)" << *(", " << argument) << ");\n"
102 << scope_tab << scope_tab << "}\n" 102 << scope_tab << scope_tab << "}\n"
103 << scope_tab << "}\n" 103 << scope_tab << "}\n"
104 ) 104 )
@@ -137,7 +137,7 @@ struct function_definition_generator
137 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 137 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
138 { 138 {
139 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_definition_generator: " << f.c_name << std::endl; 139 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_definition_generator: " << f.c_name << std::endl;
140 if(do_super && f.is_static) // Static methods goes only on Concrete classes. 140 if(!do_super && f.is_static) // Static methods goes only on Concrete classes.
141 return true; 141 return true;
142 if(blacklist::is_function_blacklisted(f.c_name)) 142 if(blacklist::is_function_blacklisted(f.c_name))
143 return true; 143 return true;
@@ -145,7 +145,7 @@ struct function_definition_generator
145 if(!as_generator 145 if(!as_generator
146 ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n" 146 ("\n\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(f.filename) << ")]\n"
147 << scope_tab << eolian_mono::marshall_annotation(true) 147 << scope_tab << eolian_mono::marshall_annotation(true)
148 << " private static extern " 148 << (do_super ? " protected " : " private ") << "static extern "
149 << eolian_mono::marshall_type(true) 149 << eolian_mono::marshall_type(true)
150 << " " << string 150 << " " << string
151 << "(System.IntPtr obj" 151 << "(System.IntPtr obj"
@@ -165,13 +165,19 @@ struct function_definition_generator
165 (documentation(1)).generate(sink, f, context)) 165 (documentation(1)).generate(sink, f, context))
166 return false; 166 return false;
167 167
168 std::string self = "this.NativeHandle";
169
170 // inherited is set in the constructor, true if this instance is from a pure C# class (not generated).
171 if (do_super && !f.is_static)
172 self = "(inherited ? Efl.Eo.Globals.efl_super(" + self + ", this.NativeClass) : " + self + ")";
173 else
174 self = name_helpers::klass_get_full_name(f.klass) + "()";
175
168 if(!as_generator 176 if(!as_generator
169 (scope_tab << (do_super ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ") 177 (scope_tab << ((do_super && !f.is_static) ? "virtual " : "") << "public " << (f.is_static ? "static " : "") << return_type << " " << string << "(" << (parameter % ", ")
170 << ") {\n " 178 << ") {\n "
171 << eolian_mono::function_definition_preamble() << string << "(" 179 << eolian_mono::function_definition_preamble() << string << "("
172 << (do_super ? "efl.eo.Globals.efl_super(" : "") 180 << self
173 << (f.is_static ? name_helpers::klass_get_full_name(f.klass) + "()": "this.raw_handle")
174 << (do_super ? ", this.raw_klass)" : "")
175 << *(", " << argument_invocation ) << ");\n" 181 << *(", " << argument_invocation ) << ");\n"
176 << eolian_mono::function_definition_epilogue() 182 << eolian_mono::function_definition_epilogue()
177 << " }\n") 183 << " }\n")
diff --git a/src/bin/eolian_mono/eolian/mono/function_helpers.hh b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
index acfe850032..06bf5d44ec 100644
--- a/src/bin/eolian_mono/eolian/mono/function_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_helpers.hh
@@ -34,14 +34,10 @@ struct native_function_definition_preamble_generator
34 return false; 34 return false;
35 35
36 if (!as_generator( 36 if (!as_generator(
37 scope_tab << scope_tab << "//Placeholder in variables\n" 37 *(scope_tab << scope_tab << native_convert_in_variable)
38 << *(scope_tab << scope_tab << native_convert_in_variable << "\n") 38 << *(scope_tab << scope_tab << native_convert_out_variable)
39 << scope_tab << scope_tab << "//Placeholder out variables\n" 39 << *(scope_tab << scope_tab << native_convert_function_pointer)
40 << *(scope_tab << scope_tab << native_convert_out_variable << "\n") 40 << scope_tab << scope_tab << scope_tab << native_convert_return_variable
41 << scope_tab << scope_tab << "//Function pointer wrappers\n"
42 << *(scope_tab << scope_tab << native_convert_function_pointer << "\n")
43 << scope_tab << scope_tab << "//Return variable and function call\n"
44 << scope_tab << scope_tab << scope_tab << native_convert_return_variable << "\n"
45 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.parameters, f.return_type), context)) 41 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.parameters, f.return_type), context))
46 return false; 42 return false;
47 43
@@ -61,13 +57,9 @@ struct function_definition_preamble_generator
61 return false; 57 return false;
62 58
63 if (!as_generator( 59 if (!as_generator(
64 scope_tab << scope_tab << "//Placeholder in variables\n" 60 *(scope_tab << scope_tab << convert_in_variable)
65 << *(scope_tab << scope_tab << convert_in_variable << "\n") 61 << *(scope_tab << scope_tab << convert_out_variable)
66 << scope_tab << scope_tab << "//Placeholder out variables\n" 62 << *(scope_tab << scope_tab << convert_function_pointer)
67 << *(scope_tab << scope_tab << convert_out_variable << "\n")
68 << scope_tab << scope_tab << "//Function pointers handling\n"
69 << *(scope_tab << scope_tab << convert_function_pointer << "\n")
70 << scope_tab << scope_tab << "//Return variable and function call\n"
71 << scope_tab << scope_tab << convert_return_variable 63 << scope_tab << scope_tab << convert_return_variable
72 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.parameters, f.return_type), context)) 64 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.parameters, f.return_type), context))
73 return false; 65 return false;
@@ -90,11 +82,8 @@ struct native_function_definition_epilogue_generator
90 return false; 82 return false;
91 83
92 if (!as_generator( 84 if (!as_generator(
93 scope_tab << scope_tab << "//Assigning out variables\n" 85 *(scope_tab << scope_tab << native_convert_out_assign(*klass))
94 << *(scope_tab << scope_tab << native_convert_out_assign(*klass) << "\n") 86 << *(scope_tab << scope_tab << native_convert_in_ptr_assign)
95 << scope_tab << scope_tab << "//Placeholder in ptr variables that need to be updated\n"
96 << *(scope_tab << scope_tab << native_convert_in_ptr_assign << "\n")
97 << scope_tab << scope_tab << "//Converting return variable\n"
98 << scope_tab << scope_tab << native_convert_return(*klass) 87 << scope_tab << scope_tab << native_convert_return(*klass)
99 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context)) 88 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context))
100 return false; 89 return false;
@@ -110,12 +99,9 @@ struct function_definition_epilogue_generator
110 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const 99 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
111 { 100 {
112 if (!as_generator( 101 if (!as_generator(
113 scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n" 102 scope_tab << scope_tab << "Eina.Error.RaiseIfOccurred();\n"
114 << scope_tab << scope_tab << "//Assigning out variables\n" 103 << *(scope_tab << scope_tab << convert_out_assign)
115 << *(scope_tab << scope_tab << convert_out_assign << "\n") 104 << *(scope_tab << scope_tab << convert_in_ptr_assign)
116 << scope_tab << scope_tab << "//Placeholder in ptr variables that need to be updated\n"
117 << *(scope_tab << scope_tab << convert_in_ptr_assign << "\n")
118 << scope_tab << scope_tab << "//Converting return variable\n"
119 << scope_tab << scope_tab << convert_return 105 << scope_tab << scope_tab << convert_return
120 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context)) 106 ).generate(sink, std::make_tuple(f.parameters, f.parameters, f.return_type), context))
121 return false; 107 return false;
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index f373a13121..95c0e0fa1e 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -38,28 +38,29 @@ struct function_pointer {
38 if (!name_helpers::open_namespaces(sink, f.namespaces, funcptr_ctx)) 38 if (!name_helpers::open_namespaces(sink, f.namespaces, funcptr_ctx))
39 return false; 39 return false;
40 40
41 std::string f_name = name_helpers::typedecl_managed_name(f);
42
41 // C# visible delegate 43 // C# visible delegate
42 if (!as_generator(documentation 44 if (!as_generator(documentation
43 << "public delegate " << type << " " << string 45 << "public delegate " << type << " " << string
44 << "(" << (parameter % ", ") << ");\n") 46 << "(" << (parameter % ", ") << ");\n")
45 .generate(sink, std::make_tuple(f, f.return_type, name_helpers::escape_keyword(f.name), f.parameters), funcptr_ctx)) 47 .generate(sink, std::make_tuple(f, f.return_type, f_name, f.parameters), funcptr_ctx))
46 return false; 48 return false;
47 // "Internal" delegate, 1-to-1 with the Unamaged function type 49 // "Internal" delegate, 1-to-1 with the Unamaged function type
48 if (!as_generator(marshall_native_annotation(true) 50 if (!as_generator(marshall_native_annotation(true)
49 << "internal delegate " << marshall_type(true) << " " << string // public? 51 << "public delegate " << marshall_type(true) << " " << string // public?
50 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n") 52 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n")
51 .generate(sink, std::make_tuple(f.return_type, f.return_type, name_helpers::escape_keyword(f.name), f.parameters), funcptr_ctx)) 53 .generate(sink, std::make_tuple(f.return_type, f.return_type, f_name, f.parameters), funcptr_ctx))
52 return false; 54 return false;
53 55
54 std::string f_name = name_helpers::escape_keyword(f.name);
55 // Wrapper type, with callback matching the Unamanaged one 56 // Wrapper type, with callback matching the Unamanaged one
56 if (!as_generator("internal class " << f_name << "Wrapper\n" 57 if (!as_generator("internal class " << f_name << "Wrapper\n"
57 << "{\n\n" 58 << "{\n\n"
58 << scope_tab << "private " << f_name << "Internal _cb;\n" 59 << scope_tab << "private " << f_name << "Internal _cb;\n"
59 << scope_tab << "private IntPtr _cb_data;\n" 60 << scope_tab << "private IntPtr _cb_data;\n"
60 << scope_tab << "private Eina_Free_Cb _cb_free_cb;\n\n" 61 << scope_tab << "private EinaFreeCb _cb_free_cb;\n\n"
61 62
62 << scope_tab << "internal " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, Eina_Free_Cb _cb_free_cb)\n" 63 << scope_tab << "internal " << f_name << "Wrapper (" << f_name << "Internal _cb, IntPtr _cb_data, EinaFreeCb _cb_free_cb)\n"
63 << scope_tab << "{\n" 64 << scope_tab << "{\n"
64 << scope_tab << scope_tab << "this._cb = _cb;\n" 65 << scope_tab << scope_tab << "this._cb = _cb;\n"
65 << scope_tab << scope_tab << "this._cb_data = _cb_data;\n" 66 << scope_tab << scope_tab << "this._cb_data = _cb_data;\n"
@@ -88,8 +89,8 @@ struct function_pointer {
88 << scope_tab << scope_tab << "try {\n" 89 << scope_tab << scope_tab << "try {\n"
89 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "cb(" << (native_argument_invocation % ", ") << ");\n" 90 << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "cb(" << (native_argument_invocation % ", ") << ");\n"
90 << scope_tab << scope_tab << "} catch (Exception e) {\n" 91 << scope_tab << scope_tab << "} catch (Exception e) {\n"
91 << scope_tab << scope_tab << scope_tab << "eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" 92 << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Callback error: {e.ToString()}\");\n"
92 << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n" 93 << scope_tab << scope_tab << scope_tab << "Eina.Error.Set(Eina.Error.EFL_ERROR);\n"
93 << scope_tab << scope_tab << "}\n" 94 << scope_tab << scope_tab << "}\n"
94 << native_function_definition_epilogue(nullptr) 95 << native_function_definition_epilogue(nullptr)
95 << scope_tab << "}\n" 96 << scope_tab << "}\n"
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index 22fc42599b..e8a41047f9 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -40,7 +40,7 @@ struct function_registration_generator
40#ifdef _WIN32 40#ifdef _WIN32
41 (scope_tab << scope_tab << "descs[" << index << "].api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\");\n" 41 (scope_tab << scope_tab << "descs[" << index << "].api_func = Marshal.StringToHGlobalAnsi(\"" << string << "\");\n"
42#else 42#else
43 (scope_tab << scope_tab << "descs[" << index << "].api_func = efl.eo.Globals.dlsym(efl.eo.Globals.RTLD_DEFAULT, \"" << string << "\");\n" 43 (scope_tab << scope_tab << "descs[" << index << "].api_func = Efl.Eo.Globals.dlsym(Efl.Eo.Globals.RTLD_DEFAULT, \"" << string << "\");\n"
44#endif 44#endif
45 << scope_tab << scope_tab << "descs[" << index << "].func = Marshal.GetFunctionPointerForDelegate(" << name_helpers::klass_native_inherit_name(*klass) << "." << string << "_static_delegate);\n" 45 << scope_tab << scope_tab << "descs[" << index << "].func = Marshal.GetFunctionPointerForDelegate(" << name_helpers::klass_native_inherit_name(*klass) << "." << string << "_static_delegate);\n"
46 ) 46 )
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
index 40a99915ab..ed72345009 100644
--- a/src/bin/eolian_mono/eolian/mono/helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -65,6 +65,163 @@ inline bool need_pointer_conversion(attributes::regular_type_def const* regular)
65 return false; 65 return false;
66} 66}
67 67
68// While klass_def has immediate_inherits, we need a way to get all interfaces inherited by an interface
69// either directly or through another interface.
70std::set<attributes::klass_name, attributes::compare_klass_name_by_name> interface_inherits(attributes::klass_def const& cls)
71{
72 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> inherits;
73
74 std::function<void(attributes::klass_name const&)> inherit_algo =
75 [&] (attributes::klass_name const& klass)
76 {
77 // TODO we could somehow cache klass_def instantiations
78 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
79 for(auto&& inherit : c.immediate_inherits)
80 {
81 switch(inherit.type)
82 {
83 case attributes::class_type::mixin:
84 case attributes::class_type::interface_:
85 inherits.insert(inherit);
86 inherit_algo(inherit);
87 break;
88 case attributes::class_type::regular:
89 case attributes::class_type::abstract_:
90 inherit_algo(inherit);
91 default:
92 break;
93 }
94 }
95 };
96
97 inherit_algo(get_klass_name(cls));
98
99
100 return inherits;
101}
102
103// Returns the set of interfaces implemented by this type that haven't been implemented
104// by a regular parent class.
105std::set<attributes::klass_name, attributes::compare_klass_name_by_name> non_implemented_interfaces(attributes::klass_def const& cls)
106{
107 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> implemented_interfaces;
108 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> interfaces;
109
110 std::function<void(attributes::klass_name const&, bool)> inherit_algo =
111 [&] (attributes::klass_name const& klass, bool is_implemented)
112 {
113 // TODO we could somehow cache klass_def instantiations
114 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
115 for(auto&& inherit : c.immediate_inherits)
116 {
117 switch(inherit.type)
118 {
119 case attributes::class_type::mixin:
120 case attributes::class_type::interface_:
121 interfaces.insert(inherit);
122 if (is_implemented)
123 implemented_interfaces.insert(inherit);
124 inherit_algo(inherit, is_implemented);
125 break;
126 case attributes::class_type::abstract_:
127 case attributes::class_type::regular:
128 inherit_algo(inherit, true);
129 default:
130 break;
131 }
132 }
133 };
134
135 inherit_algo(get_klass_name(cls), false);
136
137 for (auto&& inherit : implemented_interfaces)
138 interfaces.erase(inherit);
139
140
141 return interfaces;
142}
143
144
145/*
146 * Determines whether this class has any regular ancestor or not
147 */
148bool has_regular_ancestor(attributes::klass_def const& cls)
149{
150 auto inherits = cls.inherits;
151 std::function<bool(attributes::klass_name const&)> is_regular =
152 [&] (attributes::klass_name const& klass)
153 {
154 return klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_;
155 };
156
157 return std::any_of(inherits.begin(), inherits.end(), is_regular);
158}
159
160/*
161 * Gets all methods that this class should implement (i.e. that come from an unimplemented interface/mixin and the class itself)
162 */
163std::vector<attributes::function_def> get_all_implementable_methods(attributes::klass_def const& cls)
164{
165 std::vector<attributes::function_def> ret;
166
167 std::copy(cls.functions.begin(), cls.functions.end(), std::back_inserter(ret));
168
169 // Non implemented interfaces
170 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> implemented_interfaces;
171 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> interfaces;
172 std::function<void(attributes::klass_name const&, bool)> inherit_algo =
173 [&] (attributes::klass_name const &klass, bool is_implemented)
174 {
175 attributes::klass_def c(get_klass(klass, cls.unit), cls.unit);
176 for (auto&& inherit: c.immediate_inherits)
177 {
178 switch(inherit.type)
179 {
180 case attributes::class_type::mixin:
181 case attributes::class_type::interface_:
182 interfaces.insert(inherit);
183 if (is_implemented)
184 implemented_interfaces.insert(inherit);
185 inherit_algo(inherit, is_implemented);
186 break;
187 case attributes::class_type::abstract_:
188 case attributes::class_type::regular:
189 inherit_algo(inherit, true);
190 default:
191 break;
192 }
193 }
194 };
195
196 inherit_algo(attributes::get_klass_name(cls), false);
197
198 for (auto&& inherit : implemented_interfaces)
199 interfaces.erase(inherit);
200
201 for (auto&& inherit : interfaces)
202 {
203 attributes::klass_def klass(get_klass(inherit, cls.unit), cls.unit);
204 std::copy(klass.functions.cbegin(), klass.functions.cend(), std::back_inserter(ret));
205 }
206
207 return ret;
208}
209
210/*
211 * Checks whether the given is unique going up the inheritance tree from leaf_klass
212 */
213inline bool is_unique_event(attributes::event_def const& evt
214 , attributes::klass_def const& leaf_klass)
215{
216 auto events = leaf_klass.get_all_events();
217 int i = 1;
218 return !std::any_of(events.cbegin(), events.cend(),
219 [&evt, &i](const attributes::event_def &other) {
220 return evt.name == other.name && i++ == 2;
221 });
222}
223
224
68} // namespace helpers 225} // namespace helpers
69 226
70} // namespace eolian_mono 227} // namespace eolian_mono
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 7a4051131b..077a0fad07 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -4,6 +4,7 @@
4#include "grammar/integral.hpp" 4#include "grammar/integral.hpp"
5#include "grammar/generator.hpp" 5#include "grammar/generator.hpp"
6#include "grammar/klass_def.hpp" 6#include "grammar/klass_def.hpp"
7#include "grammar/attribute_conditional.hpp"
7#include "blacklist.hh" 8#include "blacklist.hh"
8 9
9#include "grammar/indentation.hpp" 10#include "grammar/indentation.hpp"
@@ -35,11 +36,11 @@ static bool generate_static_cast_method(OutputIterator sink, grammar::attributes
35{ 36{
36 return as_generator( 37 return as_generator(
37 scope_tab << "///<summary>Casts obj into an instance of this type.</summary>\n" 38 scope_tab << "///<summary>Casts obj into an instance of this type.</summary>\n"
38 << scope_tab << "public static " << name_helpers::klass_interface_name(cls) << " static_cast(efl.IObject obj)\n" 39 << scope_tab << "public " << (helpers::has_regular_ancestor(cls) ? "new " : "") <<"static " << name_helpers::klass_concrete_name(cls) << " static_cast(Efl.Object obj)\n"
39 << scope_tab << "{\n" 40 << scope_tab << "{\n"
40 << scope_tab << scope_tab << "if (obj == null)\n" 41 << scope_tab << scope_tab << "if (obj == null)\n"
41 << scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n" 42 << scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n"
42 << scope_tab << scope_tab << "return new " << name_helpers::klass_concrete_name(cls) << "(obj.raw_handle);\n" 43 << scope_tab << scope_tab << "return new " << name_helpers::klass_concrete_name(cls) << "(obj.NativeHandle);\n"
43 << scope_tab << "}\n" 44 << scope_tab << "}\n"
44 ).generate(sink, nullptr, context); 45 ).generate(sink, nullptr, context);
45} 46}
@@ -51,29 +52,29 @@ static bool generate_equals_method(OutputIterator sink, Context const &context)
51 scope_tab << "///<summary>Verifies if the given object is equal to this one.</summary>\n" 52 scope_tab << "///<summary>Verifies if the given object is equal to this one.</summary>\n"
52 << scope_tab << "public override bool Equals(object obj)\n" 53 << scope_tab << "public override bool Equals(object obj)\n"
53 << scope_tab << "{\n" 54 << scope_tab << "{\n"
54 << scope_tab << scope_tab << "var other = obj as efl.IObject;\n" 55 << scope_tab << scope_tab << "var other = obj as Efl.Object;\n"
55 << scope_tab << scope_tab << "if (other == null)\n" 56 << scope_tab << scope_tab << "if (other == null)\n"
56 << scope_tab << scope_tab << scope_tab << "return false;\n" 57 << scope_tab << scope_tab << scope_tab << "return false;\n"
57 << scope_tab << scope_tab << "return this.raw_handle == other.raw_handle;\n" 58 << scope_tab << scope_tab << "return this.NativeHandle == other.NativeHandle;\n"
58 << scope_tab << "}\n" 59 << scope_tab << "}\n"
59 << scope_tab << "///<summary>Gets the hash code for this object based on the native pointer it points to.</summary>\n" 60 << scope_tab << "///<summary>Gets the hash code for this object based on the native pointer it points to.</summary>\n"
60 << scope_tab << "public override int GetHashCode()\n" 61 << scope_tab << "public override int GetHashCode()\n"
61 << scope_tab << "{\n" 62 << scope_tab << "{\n"
62 << scope_tab << scope_tab << "return this.raw_handle.ToInt32();\n" 63 << scope_tab << scope_tab << "return this.NativeHandle.ToInt32();\n"
63 << scope_tab << "}\n" 64 << scope_tab << "}\n"
64 << scope_tab << "///<summary>Turns the native pointer into a string representation.</summary>\n" 65 << scope_tab << "///<summary>Turns the native pointer into a string representation.</summary>\n"
65 << scope_tab << "public override String ToString()\n" 66 << scope_tab << "public override String ToString()\n"
66 << scope_tab << "{\n" 67 << scope_tab << "{\n"
67 << scope_tab << scope_tab << "return $\"{this.GetType().Name}@[{this.raw_handle.ToInt32():x}]\";\n" 68 << scope_tab << scope_tab << "return $\"{this.GetType().Name}@[{this.NativeHandle.ToInt32():x}]\";\n"
68 << scope_tab << "}\n" 69 << scope_tab << "}\n"
69 ).generate(sink, nullptr, context); 70 ).generate(sink, nullptr, context);
70} 71}
71 72
72/* Get the actual number of functions of a class, checking for blacklisted ones */ 73/* Get the actual number of functions of a class, checking for blacklisted ones */
73static std::size_t 74static std::size_t
74get_inheritable_function_count(grammar::attributes::klass_def const& cls) 75get_implementable_function_count(grammar::attributes::klass_def const& cls)
75{ 76{
76 auto methods = cls.get_all_methods(); 77 auto methods = helpers::get_all_implementable_methods(cls);
77 return std::count_if(methods.cbegin(), methods.cend(), [](grammar::attributes::function_def const& func) 78 return std::count_if(methods.cbegin(), methods.cend(), [](grammar::attributes::function_def const& func)
78 { 79 {
79 return !blacklist::is_function_blacklisted(func.c_name) && !func.is_static; 80 return !blacklist::is_function_blacklisted(func.c_name) && !func.is_static;
@@ -97,6 +98,9 @@ struct klass
97 switch(cls.type) 98 switch(cls.type)
98 { 99 {
99 case attributes::class_type::regular: 100 case attributes::class_type::regular:
101 class_type = "class";
102 suffix = "CLASS";
103 break;
100 case attributes::class_type::abstract_: 104 case attributes::class_type::abstract_:
101 class_type = "class"; 105 class_type = "class";
102 suffix = "CLASS"; 106 suffix = "CLASS";
@@ -117,6 +121,7 @@ struct klass
117 auto methods = cls.get_all_methods(); 121 auto methods = cls.get_all_methods();
118 122
119 // Interface class 123 // Interface class
124 if(class_type == "interface")
120 { 125 {
121 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context); 126 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context);
122 127
@@ -132,11 +137,12 @@ struct klass
132 for(auto first = std::begin(cls.immediate_inherits) 137 for(auto first = std::begin(cls.immediate_inherits)
133 , last = std::end(cls.immediate_inherits); first != last; ++first) 138 , last = std::end(cls.immediate_inherits); first != last; ++first)
134 { 139 {
135 if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt)) 140 if(first->type != attributes::class_type::regular && first->type != attributes::class_type::abstract_)
136 return false; 141 if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt))
142 return false;
137 } 143 }
138 144
139 if(!as_generator("\n" << scope_tab << "efl.eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt)) 145 if(!as_generator("\n" << scope_tab << "Efl.Eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt))
140 return false; 146 return false;
141 147
142 if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt)) 148 if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt))
@@ -154,85 +160,74 @@ struct klass
154 for (auto &&p : cls.parts) 160 for (auto &&p : cls.parts)
155 if (!as_generator( 161 if (!as_generator(
156 documentation(1) 162 documentation(1)
157 << name_helpers::klass_full_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n" 163 << name_helpers::klass_full_concrete_or_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n"
158 ).generate(sink, p, iface_cxt)) 164 ).generate(sink, p, iface_cxt))
159 return false; 165 return false;
160 166
161 // End of interface declaration 167 // End of interface declaration
162 if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false; 168 if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false;
169
163 } 170 }
164 171
165 // Concrete class 172 // Events arguments go in the top namespace to avoid the Concrete suffix clutter in interface events.
166 // if(class_type == "class") 173 // Regular/abstract class events go here too for consistency.
174 if(!as_generator(*(event_argument_wrapper)).generate(sink, cls.events, context))
175 return false;
176
177 bool root = !helpers::has_regular_ancestor(cls);
178 std::set<attributes::klass_name, attributes::compare_klass_name_by_name> inherit_interfaces = helpers::non_implemented_interfaces(cls);
179 std::vector<attributes::klass_name> inherit_classes;
180 std::copy_if(cls.immediate_inherits.begin(), cls.immediate_inherits.end()
181 , std::back_inserter(inherit_classes)
182 , [] (attributes::klass_name const& klass)
183 {
184 switch (klass.type)
185 {
186 case attributes::class_type::regular:
187 case attributes::class_type::abstract_:
188 return true;
189 default:
190 return false;
191 };
192 });
193
194 // Concrete class for interfaces, mixins, etc.
195 if(class_type != "class")
167 { 196 {
168 auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context); 197 auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context);
169 auto concrete_name = name_helpers::klass_concrete_name(cls); 198 auto concrete_name = name_helpers::klass_concrete_name(cls);
170 auto interface_name = name_helpers::klass_interface_name(cls); 199 auto interface_name = name_helpers::klass_interface_name(cls);
200
171 if(!as_generator 201 if(!as_generator
172 ( 202 (
173 documentation 203 documentation
174 << "sealed public class " << concrete_name << " : " << interface_name << "\n{\n" 204 << "sealed public class " << concrete_name << " : " << "\n"
175 << scope_tab << "System.IntPtr handle;\n" 205 << (klass_full_concrete_or_interface_name % ",") << "\n"
176 << scope_tab << "///<summary>Pointer to the native instance.</summary>\n" 206 << (inherit_classes.size() > 0 ? ", " : "" ) << interface_name << "\n"
177 << scope_tab << "public System.IntPtr raw_handle {\n" 207 << scope_tab << *(", " << name_helpers::klass_full_concrete_or_interface_name) << "\n"
178 << scope_tab << scope_tab << "get { return handle; }\n" 208 << "{\n"
179 << scope_tab << "}\n" 209 ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt))
180 << scope_tab << "///<summary>Pointer to the native class description.</summary>\n" 210 return false;
181 << scope_tab << "public System.IntPtr raw_klass {\n" 211
182 << scope_tab << scope_tab << "get { return efl.eo.Globals.efl_class_get(handle); }\n" 212 if (!generate_fields(sink, cls, concrete_cxt))
183 << scope_tab << "}\n" 213 return false;
184 << scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n" 214
185 << scope_tab << "public delegate void ConstructingMethod(" << interface_name << " obj);\n" 215 if (!as_generator
186 << scope_tab << "///<summary>Returns the pointer the underlying Eo class object. Used internally on class methods.</summary>\n" 216 (
187 << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename) 217 scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
188 << ")] public static extern System.IntPtr\n" 218 << ")] internal static extern System.IntPtr\n"
189 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" 219 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
190 << (class_type == "class" ? "" : "/*")
191 << scope_tab << "///<summary>Creates a new instance.</summary>\n"
192 << scope_tab << "///<param>Parent instance.</param>\n"
193 << scope_tab << "///<param>Delegate to call constructing methods that should be run inside the constructor.</param>\n"
194 << scope_tab << "public " << concrete_name << "(efl.IObject parent = null, ConstructingMethod init_cb=null)\n"
195 << scope_tab << "{\n"
196 << scope_tab << scope_tab << "System.IntPtr klass = " << name_helpers::klass_get_name(cls) << "();\n"
197 << scope_tab << scope_tab << "System.IntPtr parent_ptr = System.IntPtr.Zero;\n"
198 << scope_tab << scope_tab << "if(parent != null)\n"
199 << scope_tab << scope_tab << scope_tab << "parent_ptr = parent.raw_handle;\n"
200 << scope_tab << scope_tab << "handle = efl.eo.Globals._efl_add_internal_start(\"file\", 0, klass, parent_ptr, 1, 0);\n"
201 << scope_tab << scope_tab << "register_event_proxies();\n"
202 << scope_tab << scope_tab << "if (init_cb != null) {\n"
203 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
204 << scope_tab << scope_tab << "}\n"
205 << scope_tab << scope_tab << "handle = efl.eo.Globals._efl_add_end(handle, 1, 0);\n" // replace handle with the actual final handle
206 << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
207 << scope_tab << "}\n"
208 << (class_type == "class" ? "" : "*/")
209 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n" 220 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
210 << scope_tab << "public " << concrete_name << "(System.IntPtr raw)\n" 221 << scope_tab << "public " << concrete_name << "(System.IntPtr raw)\n"
211 << scope_tab << "{\n" 222 << scope_tab << "{\n"
212 << scope_tab << scope_tab << "handle = raw;\n" 223 << scope_tab << scope_tab << "handle = raw;\n"
213 << scope_tab << scope_tab << "register_event_proxies();\n" 224 << scope_tab << scope_tab << "register_event_proxies();\n"
214 << scope_tab << "}\n" 225 << scope_tab << "}\n"
215 << scope_tab << "///<summary>Destructor.</summary>\n"
216 << scope_tab << "~" << concrete_name << "()\n"
217 << scope_tab << "{\n"
218 << scope_tab << scope_tab << "Dispose(false);\n"
219 << scope_tab << "}\n"
220 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
221 << scope_tab << "internal void Dispose(bool disposing)\n"
222 << scope_tab << "{\n"
223 << scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n"
224 << scope_tab << scope_tab << scope_tab << "efl.eo.Globals.efl_unref(handle);\n"
225 << scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
226 << scope_tab << scope_tab << "}\n"
227 << scope_tab << "}\n"
228 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
229 << scope_tab << "public void Dispose()\n"
230 << scope_tab << "{\n"
231 << scope_tab << scope_tab << "Dispose(true);\n"
232 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
233 << scope_tab << "}\n"
234 ) 226 )
235 .generate(sink, cls, concrete_cxt)) 227 .generate(sink, attributes::unused, concrete_cxt))
228 return false;
229
230 if (!generate_dispose_methods(sink, cls, concrete_cxt))
236 return false; 231 return false;
237 232
238 if (!generate_static_cast_method(sink, cls, concrete_cxt)) 233 if (!generate_static_cast_method(sink, cls, concrete_cxt))
@@ -249,100 +244,53 @@ struct klass
249 244
250 // Parts 245 // Parts
251 if(!as_generator(*(part_definition)) 246 if(!as_generator(*(part_definition))
252 .generate(sink, cls.get_all_parts(), concrete_cxt)) return false; 247 .generate(sink, cls.parts, concrete_cxt)) return false;
253 248
254 // Concrete function definitions 249 // Concrete function definitions
250 auto implemented_methods = helpers::get_all_implementable_methods(cls);
255 if(!as_generator(*(function_definition)) 251 if(!as_generator(*(function_definition))
256 .generate(sink, methods, concrete_cxt)) return false; 252 .generate(sink, implemented_methods, concrete_cxt)) return false;
257 253
258 // Async wrappers 254 // Async wrappers
259 if(!as_generator(*(async_function_definition)).generate(sink, methods, concrete_cxt)) 255 if(!as_generator(*(async_function_definition)).generate(sink, implemented_methods, concrete_cxt))
260 return false;
261
262 if(!as_generator(*(event_argument_wrapper)).generate(sink, cls.events, context))
263 return false; 256 return false;
264 257
265 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; 258 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
259
266 } 260 }
267 261
268 // Inherit class 262 // Inheritable class
269 if(class_type == "class") 263 if(class_type == "class")
270 { 264 {
271 auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context); 265 auto inherit_cxt = context_add_tag(class_context{class_context::inherit}, context);
272 bool cls_has_string_return = has_string_return(cls);
273 bool cls_has_stringshare_return = has_stringshare_return(cls);
274
275 auto interface_name = name_helpers::klass_interface_name(cls);
276 auto inherit_name = name_helpers::klass_inherit_name(cls);
277 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
278
279 266
280 if(!as_generator 267 // Class header
268 if(!as_generator
281 ( 269 (
282 documentation 270 documentation
283 << "public " << class_type << " " << inherit_name << " : " << interface_name << "\n{\n" 271 << "public " << class_type << " " << name_helpers::klass_concrete_name(cls) << " : "
284 << scope_tab << "System.IntPtr handle;\n" 272 << (klass_full_concrete_or_interface_name % ",") // classes
285 << scope_tab << "internal static System.IntPtr klass = System.IntPtr.Zero;\n" 273 << (inherit_classes.empty() ? "" : ",")
286 << scope_tab << "private static readonly object klassAllocLock = new object();\n" 274 << " Efl.Eo.IWrapper" << (root ? ", IDisposable" : "")
287 << scope_tab << (cls_has_string_return ? ("internal Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();") : "") << "\n" 275 << (inherit_interfaces.empty() ? "" : ",")
288 << scope_tab << (cls_has_stringshare_return ? ("internal Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();") : "") << "\n" 276 << (klass_full_concrete_or_interface_name % ",") // interfaces
289 << scope_tab << "///<summary>Pointer to the native instance.</summary>\n" 277 << "\n{\n"
290 << scope_tab << "public System.IntPtr raw_handle {\n" 278 )
291 << scope_tab << scope_tab << "get { return handle; }\n" 279 .generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), inherit_cxt))
292 << scope_tab << "}\n" 280 return false;
293 << scope_tab << "///<summary>Pointer to the native class description.</summary>\n" 281
294 << scope_tab << "public System.IntPtr raw_klass {\n" 282
295 << scope_tab << scope_tab << "get { return klass; }\n" 283 // Class body
296 << scope_tab << "}\n" 284 if(!generate_fields(sink, cls, inherit_cxt))
297 << scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n" 285 return false;
298 << scope_tab << "public delegate void ConstructingMethod(" << interface_name << " obj);\n" 286
299 << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(inherit_cxt).actual_library_name(cls.filename) 287 if (!generate_constructors(sink, cls, inherit_cxt))
300 << ")] private static extern System.IntPtr\n" 288 return false;
301 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" 289
302 << scope_tab << "///<summary>Creates a new instance.</summary>\n" 290 if (!generate_dispose_methods(sink, cls, inherit_cxt))
303 << scope_tab << "///<param>Parent instance.</param>\n" 291 return false;
304 << scope_tab << "///<param>Delegate to call constructing methods that should be run inside the constructor.</param>\n" 292
305 << scope_tab << "public " << inherit_name << "(efl.IObject parent = null, ConstructingMethod init_cb=null)\n" 293 if (!generate_static_cast_method(sink, cls, inherit_cxt))
306 << scope_tab << "{\n"
307 << scope_tab << scope_tab << "if (klass == System.IntPtr.Zero) {\n"
308 << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n"
309 << scope_tab << scope_tab << scope_tab << scope_tab << "if (klass == System.IntPtr.Zero) {\n"
310 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "klass = efl.eo.Globals.register_class(new efl.eo.Globals.class_initializer(" << native_inherit_name << ".class_initializer), \"" << cls.eolian_name << "\", " << name_helpers::klass_get_name(cls) << "());\n"
311 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
312 << scope_tab << scope_tab << scope_tab << "}\n"
313 << scope_tab << scope_tab << "}\n"
314 << scope_tab << scope_tab << "handle = efl.eo.Globals.instantiate_start(klass, parent);\n"
315 << scope_tab << scope_tab << "register_event_proxies();\n"
316 << scope_tab << scope_tab << "if (init_cb != null) {\n"
317 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
318 << scope_tab << scope_tab << "}\n"
319 << scope_tab << scope_tab << "efl.eo.Globals.data_set(this);\n"
320 << scope_tab << scope_tab << "handle = efl.eo.Globals.instantiate_end(handle);\n"
321 << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n"
322 << scope_tab << "}\n"
323 << scope_tab << "///<summary>Destructor.</summary>\n"
324 << scope_tab << "~" << inherit_name << "()\n"
325 << scope_tab << "{\n"
326 << scope_tab << scope_tab << "Dispose(false);\n"
327 << scope_tab << "}\n"
328 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
329 << scope_tab << "protected virtual void Dispose(bool disposing)\n"
330 << scope_tab << "{\n"
331 << scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n"
332 << scope_tab << scope_tab << scope_tab << "efl.eo.Globals.efl_unref(handle);\n"
333 << scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
334 << scope_tab << scope_tab << "}\n"
335 << scope_tab << "}\n"
336 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
337 << scope_tab << "public void Dispose()\n"
338 << scope_tab << "{\n"
339 << scope_tab << (cls_has_string_return ? "efl.eo.Globals.free_dict_values(cached_strings);" : "") << "\n"
340 << scope_tab << (cls_has_stringshare_return ? "efl.eo.Globals.free_stringshare_values(cached_stringshares);" : "") << "\n"
341 << scope_tab << scope_tab << "Dispose(true);\n"
342 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
343 << scope_tab << "}\n"
344 )
345 .generate(sink, cls, inherit_cxt))
346 return false; 294 return false;
347 295
348 if (!generate_equals_method(sink, inherit_cxt)) 296 if (!generate_equals_method(sink, inherit_cxt))
@@ -356,20 +304,21 @@ struct klass
356 304
357 // Parts 305 // Parts
358 if(!as_generator(*(part_definition)) 306 if(!as_generator(*(part_definition))
359 .generate(sink, cls.get_all_parts(), inherit_cxt)) return false; 307 .generate(sink, cls.parts, inherit_cxt)) return false;
360 308
361 // Inherit function definitions 309 // Inherit function definitions
310 auto implemented_methods = helpers::get_all_implementable_methods(cls);
362 if(!as_generator(*(function_definition(true))) 311 if(!as_generator(*(function_definition(true)))
363 .generate(sink, methods, inherit_cxt)) return false; 312 .generate(sink, implemented_methods, inherit_cxt)) return false;
364 313
365 // Async wrappers 314 // Async wrappers
366 if(!as_generator(*(async_function_definition(true))).generate(sink, methods, inherit_cxt)) 315 if(!as_generator(*(async_function_definition(true))).generate(sink, implemented_methods, inherit_cxt))
367 return false; 316 return false;
368 317
369 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 318 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
370 } 319 }
371 320
372 std::size_t function_count = get_inheritable_function_count(cls); 321 std::size_t function_count = get_implementable_function_count(cls);
373 322
374 int function_registration_index = 0; 323 int function_registration_index = 0;
375 auto index_generator = [&function_registration_index] 324 auto index_generator = [&function_registration_index]
@@ -394,7 +343,7 @@ struct klass
394 343
395 // Native wrapper registration 344 // Native wrapper registration
396 if(!as_generator(*(function_registration(index_generator, cls))) 345 if(!as_generator(*(function_registration(index_generator, cls)))
397 .generate(sink, methods, inative_cxt)) return false; 346 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
398 347
399 if(!as_generator 348 if(!as_generator
400 ( scope_tab << scope_tab << "IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*" << function_count << ");\n" 349 ( scope_tab << scope_tab << "IntPtr descs_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(descs[0])*" << function_count << ");\n"
@@ -409,7 +358,7 @@ struct klass
409 << scope_tab << scope_tab << "ops.count = (UIntPtr)" << function_count << ";\n" 358 << scope_tab << scope_tab << "ops.count = (UIntPtr)" << function_count << ";\n"
410 << scope_tab << scope_tab << "IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n" 359 << scope_tab << scope_tab << "IntPtr ops_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ops));\n"
411 << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n" 360 << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n"
412 << scope_tab << scope_tab << "efl.eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n" 361 << scope_tab << scope_tab << "Efl.Eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n"
413 ).generate(sink, attributes::unused, inative_cxt)) return false; 362 ).generate(sink, attributes::unused, inative_cxt)) return false;
414 363
415 364
@@ -419,7 +368,7 @@ struct klass
419 // 368 //
420 // Native method definitions 369 // Native method definitions
421 if(!as_generator(*(native_function_definition(cls))) 370 if(!as_generator(*(native_function_definition(cls)))
422 .generate(sink, methods, inative_cxt)) return false; 371 .generate(sink, helpers::get_all_implementable_methods(cls), inative_cxt)) return false;
423 372
424 if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false; 373 if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false;
425 } 374 }
@@ -431,11 +380,222 @@ struct klass
431 } 380 }
432 381
433 template <typename OutputIterator, typename Context> 382 template <typename OutputIterator, typename Context>
383 bool generate_fields(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
384 {
385 std::string visibility = is_inherit_context(context) ? "protected " : "private ";
386 bool root = !helpers::has_regular_ancestor(cls);
387 bool is_inherit = is_inherit_context(context);
388
389 std::string class_getter = "return Efl.Eo.Globals.efl_class_get(handle);";
390
391 // The klass field is static but there is no problem if multiple C# classes inherit from this generated one
392 // as it is just a simple wrapper, forwarding the Eo calls either to the user API (where C#'s virtual method
393 // resolution kicks in) or to the base implementation (efl_super).
394 if (is_inherit)
395 {
396 if(!as_generator(
397 scope_tab << "public " << (root ? "" : "new ") << "static System.IntPtr klass = System.IntPtr.Zero;\n"
398 ).generate(sink, attributes::unused, context))
399 return false;
400 class_getter = "return klass;";
401 }
402
403 std::string raw_klass_modifier;
404 if (!root)
405 raw_klass_modifier = "override ";
406 else if (is_inherit)
407 raw_klass_modifier = "virtual ";
408
409 if(!as_generator(
410 scope_tab << "///<summary>Pointer to the native class description.</summary>\n"
411 << scope_tab << "public " << raw_klass_modifier << "System.IntPtr NativeClass {\n"
412 << scope_tab << scope_tab << "get {\n"
413 << scope_tab << scope_tab << scope_tab << class_getter << "\n" //return klass; }\n"
414 << scope_tab << scope_tab << "}\n"
415 << scope_tab << "}\n"
416 ).generate(sink, attributes::unused, context))
417 return false;
418
419 // The remaining fields aren't needed in children classes.
420 if (!root)
421 return true;
422
423 if (cls.get_all_events().size() > 0)
424 if (!as_generator(scope_tab << (is_inherit ? "protected " : "private ") << "EventHandlerList eventHandlers = new EventHandlerList();\n").generate(sink, attributes::unused, context))
425 return false;
426
427 if (is_inherit)
428 {
429 if (!as_generator(
430 scope_tab << "private static readonly object klassAllocLock = new object();\n"
431 << scope_tab << "protected bool inherited;\n"
432 ).generate(sink, attributes::unused, context))
433 return false;
434 }
435
436 return as_generator(
437 scope_tab << visibility << " System.IntPtr handle;\n"
438 << scope_tab << "public Dictionary<String, IntPtr> cached_strings = new Dictionary<String, IntPtr>();" << "\n"
439 << scope_tab << "public Dictionary<String, IntPtr> cached_stringshares = new Dictionary<String, IntPtr>();" << "\n"
440 << scope_tab << "///<summary>Pointer to the native instance.</summary>\n"
441 << scope_tab << "public System.IntPtr NativeHandle {\n"
442 << scope_tab << scope_tab << "get { return handle; }\n"
443 << scope_tab << "}\n"
444 ).generate(sink, attributes::unused, context);
445 }
446
447 template <typename OutputIterator, typename Context>
448 bool generate_constructors(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
449 {
450 bool root = !helpers::has_regular_ancestor(cls);
451 auto inherit_name = name_helpers::klass_concrete_name(cls);
452 auto native_inherit_name = name_helpers::klass_native_inherit_name(cls);
453
454 if(!as_generator(
455 scope_tab << "///<summary>Delegate for function to be called from inside the native constructor.</summary>\n"
456 << scope_tab << "public" << (root ? "" : " new") << " delegate void ConstructingMethod(" << inherit_name << " obj);\n"
457 << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(context).actual_library_name(cls.filename)
458 << ")] internal static extern System.IntPtr\n"
459 << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n"
460 ).generate(sink, attributes::unused, context))
461 return false;
462
463
464 if (!root)
465 {
466 return as_generator(
467 scope_tab << "///<summary>Creates a new instance.</summary>\n"
468 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
469 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
470 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : base(" << native_inherit_name << ".class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n"
471 << scope_tab << "{\n"
472 << scope_tab << scope_tab << "if (init_cb != null) {\n"
473 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
474 << scope_tab << scope_tab << "}\n"
475 << scope_tab << scope_tab << "FinishInstantiation();\n"
476 << scope_tab << "}\n"
477
478 << scope_tab << "///<summary>Internal constructor to forward the wrapper initialization to the root class.</summary>\n"
479 << scope_tab << "protected " << inherit_name << "(Efl.Eo.Globals.class_initializer class_initializer, String klass_name, IntPtr base_klass, Type managed_type, Efl.Object parent, ref IntPtr target_klass) : base(class_initializer, klass_name, base_klass, managed_type, parent, ref target_klass) {}\n"
480
481 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
482 << scope_tab << "public " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
483 << scope_tab << "{\n"
484 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
485 << scope_tab << scope_tab << "register_event_proxies();\n"
486 << scope_tab << "}\n"
487 ).generate(sink, attributes::unused, context);
488 }
489
490 // Detailed constructors go only in root classes.
491 return as_generator(
492 scope_tab << "///<summary>Creates a new instance.</summary>\n"
493 << scope_tab << "///<param name=\"parent\">Parent instance.</param>\n"
494 << scope_tab << "///<param name=\"init_cb\">Delegate to call constructing methods that should be run inside the constructor.</param>\n"
495 << scope_tab << "public " << inherit_name << "(Efl.Object parent = null, ConstructingMethod init_cb=null) : this(" << native_inherit_name << ".class_initializer, \"" << inherit_name << "\", " << name_helpers::klass_get_name(cls) << "(), typeof(" << inherit_name << "), parent, ref klass)\n"
496 << scope_tab << "{\n"
497 << scope_tab << scope_tab << "if (init_cb != null) {\n"
498 << scope_tab << scope_tab << scope_tab << "init_cb(this);\n"
499 << scope_tab << scope_tab << "}\n"
500 << scope_tab << scope_tab << "FinishInstantiation();\n"
501 << scope_tab << "}\n"
502
503 << scope_tab << "protected " << inherit_name << "(Efl.Eo.Globals.class_initializer class_initializer, String klass_name, IntPtr base_klass, Type managed_type, Efl.Object parent, ref IntPtr target_klass)\n"
504 << scope_tab << "{\n"
505 << scope_tab << scope_tab << "inherited = this.GetType() != managed_type;\n"
506 << scope_tab << scope_tab << "IntPtr actual_klass = base_klass;\n"
507 << scope_tab << scope_tab << "if (inherited) {\n"
508 << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n"
509 << scope_tab << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n"
510 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n"
511 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "target_klass = Efl.Eo.Globals.register_class(class_initializer, klass_name, base_klass);\n"
512 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (target_klass == System.IntPtr.Zero) {\n"
513 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "throw new System.InvalidOperationException(\"Failed to initialize class '" << inherit_name << "'\");\n"
514 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
515 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
516 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n"
517 << scope_tab << scope_tab << scope_tab << "}\n"
518 << scope_tab << scope_tab << scope_tab << "actual_klass = target_klass;\n"
519 << scope_tab << scope_tab << "}\n"
520 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
521 << scope_tab << scope_tab << "register_event_proxies();\n"
522 << scope_tab << "}\n"
523
524 << scope_tab << "protected void FinishInstantiation()\n"
525 << scope_tab << "{\n"
526 << scope_tab << scope_tab << "if (inherited) {\n"
527 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.data_set(this);\n"
528 << scope_tab << scope_tab << "}\n"
529 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle);\n"
530 << scope_tab << scope_tab << "Eina.Error.RaiseIfOccurred();\n"
531 << scope_tab << "}\n"
532
533 << scope_tab << "///<summary>Constructs an instance from a native pointer.</summary>\n"
534 << scope_tab << "public " << inherit_name << "(System.IntPtr raw)\n"
535 << scope_tab << "{\n"
536 << scope_tab << scope_tab << "handle = raw;\n"
537 << scope_tab << scope_tab << "register_event_proxies();\n"
538 << scope_tab << "}\n"
539 ).generate(sink, attributes::unused, context);
540 }
541
542
543 template <typename OutputIterator, typename Context>
544 bool generate_dispose_methods(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
545 {
546 std::string name = join_namespaces(cls.namespaces, '.') + cls.eolian_name;
547 if (helpers::has_regular_ancestor(cls))
548 return true;
549
550 std::string visibility = is_inherit_context(context) ? "protected virtual " : "";
551
552 auto inherit_name = name_helpers::klass_concrete_name(cls);
553
554 return as_generator(
555
556 scope_tab << "///<summary>Destructor.</summary>\n"
557 << scope_tab << "~" << inherit_name << "()\n"
558 << scope_tab << "{\n"
559 << scope_tab << scope_tab << "Dispose(false);\n"
560 << scope_tab << "}\n"
561
562 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
563 << scope_tab << visibility << "void Dispose(bool disposing)\n"
564 << scope_tab << "{\n"
565 << scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n"
566 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_unref(handle);\n"
567 << scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
568 << scope_tab << scope_tab << "}\n"
569 << scope_tab << "}\n"
570
571 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
572 << scope_tab << "public void Dispose()\n"
573 << scope_tab << "{\n"
574 << scope_tab << "Efl.Eo.Globals.free_dict_values(cached_strings);" << "\n"
575 << scope_tab << "Efl.Eo.Globals.free_stringshare_values(cached_stringshares);" << "\n"
576 << scope_tab << scope_tab << "Dispose(true);\n"
577 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
578 << scope_tab << "}\n"
579 ).generate(sink, attributes::unused, context);
580 }
581
582 template <typename OutputIterator, typename Context>
434 bool generate_events_registration(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const 583 bool generate_events_registration(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
435 { 584 {
585 bool root = !helpers::has_regular_ancestor(cls);
586 std::string virtual_modifier = " ";
587
588 if (!root)
589 virtual_modifier = "override ";
590 else
591 {
592 if (is_inherit_context(context))
593 virtual_modifier = "virtual ";
594 }
595
436 // Event proxy registration 596 // Event proxy registration
437 if (!as_generator( 597 if (!as_generator(
438 scope_tab << "private void register_event_proxies()\n" 598 scope_tab << (is_inherit_context(context) || !root ? "protected " : "") << virtual_modifier << "void register_event_proxies()\n"
439 << scope_tab << "{\n" 599 << scope_tab << "{\n"
440 ) 600 )
441 .generate(sink, NULL, context)) 601 .generate(sink, NULL, context))
@@ -443,15 +603,23 @@ struct klass
443 603
444 // Generate event registrations here 604 // Generate event registrations here
445 605
606 if (!root)
607 if (!as_generator(scope_tab << scope_tab << "base.register_event_proxies();\n").generate(sink, NULL, context))
608 return false;
609
446 // Assigning the delegates 610 // Assigning the delegates
447 if (!as_generator(*(event_registration())).generate(sink, cls.events, context)) 611 if (!as_generator(*(event_registration(cls, cls))).generate(sink, cls.events, context))
448 return false; 612 return false;
449 613
450 for (auto&& c : cls.inherits) 614 for (auto&& c : helpers::non_implemented_interfaces(cls))
451 { 615 {
616 // Only non-regular types (which declare events through interfaces) need to register them.
617 if (c.type == attributes::class_type::regular)
618 continue;
619
452 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit); 620 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit);
453 621
454 if (!as_generator(*(event_registration(&klass))).generate(sink, klass.events, context)) 622 if (!as_generator(*(event_registration(klass, cls))).generate(sink, klass.events, context))
455 return false; 623 return false;
456 } 624 }
457 625
@@ -470,53 +638,59 @@ struct klass
470 if (!has_events(cls)) 638 if (!has_events(cls))
471 return true; 639 return true;
472 640
473 std::string visibility = is_inherit_context(context) ? "protected" : "private"; 641 std::string visibility = is_inherit_context(context) ? "protected " : "private ";
474 642
475 if (!as_generator(scope_tab << "private readonly object eventLock = new object();\n" 643 if (!helpers::has_regular_ancestor(cls))
476 << scope_tab << "private Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n") 644 {
477 .generate(sink, NULL, context)) 645 if (!as_generator(scope_tab << visibility << "readonly object eventLock = new object();\n"
478 return false; 646 << scope_tab << visibility << "Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n")
647 .generate(sink, NULL, context))
648 return false;
479 649
480 // Callback registration functions 650 // Callback registration functions
481 if (!as_generator( 651 if (!as_generator(
482 scope_tab << "private bool add_cpp_event_handler(string key, efl.Event_Cb evt_delegate) {\n" 652 scope_tab << visibility << "bool add_cpp_event_handler(string key, Efl.EventCb evt_delegate) {\n"
483 << scope_tab << scope_tab << "int event_count = 0;\n" 653 << scope_tab << scope_tab << "int event_count = 0;\n"
484 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n" 654 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n"
485 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 655 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
486 << scope_tab << scope_tab << "if (event_count == 0) {\n" 656 << scope_tab << scope_tab << "if (event_count == 0) {\n"
487 << scope_tab << scope_tab << scope_tab << "IntPtr desc = efl.Event_Description.GetNative(key);\n" 657
658 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n"
488 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 659 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
489 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to get native event {key}\");\n" 660 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
490 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 661 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
491 << scope_tab << scope_tab << scope_tab << "}\n" 662 << scope_tab << scope_tab << scope_tab << "}\n"
492 << scope_tab << scope_tab << scope_tab << "bool result = efl.eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evt_delegate, System.IntPtr.Zero);\n" 663
664 << scope_tab << scope_tab << scope_tab << " bool result = Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evt_delegate, System.IntPtr.Zero);\n"
493 << scope_tab << scope_tab << scope_tab << "if (!result) {\n" 665 << scope_tab << scope_tab << scope_tab << "if (!result) {\n"
494 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to add event proxy for event {key}\");\n" 666 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to add event proxy for event {key}\");\n"
495 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 667 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
496 << scope_tab << scope_tab << scope_tab << "}\n" 668 << scope_tab << scope_tab << scope_tab << "}\n"
497 << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n" 669 << scope_tab << scope_tab << scope_tab << "Eina.Error.RaiseIfOccurred();\n"
498 << scope_tab << scope_tab << "} \n" 670 << scope_tab << scope_tab << "} \n"
499 << scope_tab << scope_tab << "event_cb_count[key]++;\n" 671 << scope_tab << scope_tab << "event_cb_count[key]++;\n"
500 << scope_tab << scope_tab << "return true;\n" 672 << scope_tab << scope_tab << "return true;\n"
501 << scope_tab << "}\n" 673 << scope_tab << "}\n"
502 << scope_tab << "private bool remove_cpp_event_handler(string key, efl.Event_Cb evt_delegate) {\n" 674 << scope_tab << visibility << "bool remove_cpp_event_handler(string key, Efl.EventCb evt_delegate) {\n"
503 << scope_tab << scope_tab << "int event_count = 0;\n" 675 << scope_tab << scope_tab << "int event_count = 0;\n"
504 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n" 676 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n"
505 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 677 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n"
506 << scope_tab << scope_tab << "if (event_count == 1) {\n" 678 << scope_tab << scope_tab << "if (event_count == 1) {\n"
507 << scope_tab << scope_tab << scope_tab << "IntPtr desc = efl.Event_Description.GetNative(key);\n" 679
680 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(key);\n"
508 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 681 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n"
509 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to get native event {key}\");\n" 682 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
510 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 683 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
511 << scope_tab << scope_tab << scope_tab << "}\n" 684 << scope_tab << scope_tab << scope_tab << "}\n"
512 << scope_tab << scope_tab << scope_tab << "bool result = efl.eo.Globals.efl_event_callback_del(handle, desc, evt_delegate, System.IntPtr.Zero);\n" 685
686 << scope_tab << scope_tab << scope_tab << "bool result = Efl.Eo.Globals.efl_event_callback_del(handle, desc, evt_delegate, System.IntPtr.Zero);\n"
513 << scope_tab << scope_tab << scope_tab << "if (!result) {\n" 687 << scope_tab << scope_tab << scope_tab << "if (!result) {\n"
514 << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Failed to remove event proxy for event {key}\");\n" 688 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to remove event proxy for event {key}\");\n"
515 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 689 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n"
516 << scope_tab << scope_tab << scope_tab << "}\n" 690 << scope_tab << scope_tab << scope_tab << "}\n"
517 << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n" 691 << scope_tab << scope_tab << scope_tab << "Eina.Error.RaiseIfOccurred();\n"
518 << scope_tab << scope_tab << "} else if (event_count == 0) {\n" 692 << scope_tab << scope_tab << "} else if (event_count == 0) {\n"
519 << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Trying to remove proxy for event {key} when there is nothing registered.\");\n" 693 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Trying to remove proxy for event {key} when there is nothing registered.\");\n"
520 << scope_tab << scope_tab << scope_tab << "return false;\n" 694 << scope_tab << scope_tab << scope_tab << "return false;\n"
521 << scope_tab << scope_tab << "} \n" 695 << scope_tab << scope_tab << "} \n"
522 << scope_tab << scope_tab << "event_cb_count[key]--;\n" 696 << scope_tab << scope_tab << "event_cb_count[key]--;\n"
@@ -525,16 +699,20 @@ struct klass
525 ) 699 )
526 .generate(sink, NULL, context)) 700 .generate(sink, NULL, context))
527 return false; 701 return false;
702 }
528 703
529 // Self events 704 // Self events
530 if (!as_generator(*(event_definition(cls))).generate(sink, cls.events, context)) 705 if (!as_generator(*(event_definition(cls, cls))).generate(sink, cls.events, context))
531 return false; 706 return false;
532 707
533 // Inherited events 708 // Inherited events
534 for (auto&& c : cls.inherits) 709
710 // For now, as mixins can inherit from regular classes, we can't filter out inherited events.
711 auto inherits = helpers::non_implemented_interfaces(cls);
712 for (auto&& c : inherits)
535 { 713 {
536 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit); 714 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit);
537 if (!as_generator(*(event_definition(klass, true))).generate(sink, klass.events, context)) 715 if (!as_generator(*(event_definition(klass, cls))).generate(sink, klass.events, context))
538 return false; 716 return false;
539 } 717 }
540 return true; 718 return true;
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index a2426569ab..6ddb990da8 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -53,34 +53,34 @@ struct marshall_annotation_visitor_generate
53 // signed primitives 53 // signed primitives
54 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }}, 54 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
55 {"string", true, [&] { 55 {"string", true, [&] {
56 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 56 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
57 }}, 57 }},
58 {"string", false, [&] { 58 {"string", false, [&] {
59 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringKeepOwnershipMarshaler))]"; 59 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
60 }}, 60 }},
61 {"mstring", true, [&] { 61 {"mstring", true, [&] {
62 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 62 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
63 }}, 63 }},
64 {"mstring", false, [&] { 64 {"mstring", false, [&] {
65 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringKeepOwnershipMarshaler))]"; 65 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
66 }}, 66 }},
67 {"stringshare", true, [&] { 67 {"stringshare", true, [&] {
68 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringsharePassOwnershipMarshaler))]"; 68 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
69 }}, 69 }},
70 {"stringshare", false, [&] { 70 {"stringshare", false, [&] {
71 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringshareKeepOwnershipMarshaler))]"; 71 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringshareKeepOwnershipMarshaler))]";
72 }}, 72 }},
73 {"any_value_ptr", true, [&] { 73 {"any_value_ptr", true, [&] {
74 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.ValueMarshalerOwn))]"; 74 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshalerOwn))]";
75 }}, 75 }},
76 {"any_value_ptr", false, [&] { 76 {"any_value_ptr", false, [&] {
77 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.ValueMarshaler))]"; 77 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshaler))]";
78 }}, 78 }},
79 {"strbuf", true, [&] { 79 {"strbuf", true, [&] {
80 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufPassOwnershipMarshaler))]"; 80 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
81 }}, 81 }},
82 {"strbuf", false, [&] { 82 {"strbuf", false, [&] {
83 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufKeepOwnershipMarshaler))]"; 83 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
84 }}, 84 }},
85 }; 85 };
86 match const return_match_table[] = 86 match const return_match_table[] =
@@ -88,34 +88,34 @@ struct marshall_annotation_visitor_generate
88 // signed primitives 88 // signed primitives
89 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }}, 89 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
90 {"string", true, [&] { 90 {"string", true, [&] {
91 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 91 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
92 }}, 92 }},
93 {"string", false, [&] { 93 {"string", false, [&] {
94 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringKeepOwnershipMarshaler))]"; 94 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
95 }}, 95 }},
96 {"mstring", true, [&] { 96 {"mstring", true, [&] {
97 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 97 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
98 }}, 98 }},
99 {"mstring", false, [&] { 99 {"mstring", false, [&] {
100 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringKeepOwnershipMarshaler))]"; 100 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
101 }}, 101 }},
102 {"stringshare", true, [&] { 102 {"stringshare", true, [&] {
103 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringsharePassOwnershipMarshaler))]"; 103 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
104 }}, 104 }},
105 {"stringshare", false, [&] { 105 {"stringshare", false, [&] {
106 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringshareKeepOwnershipMarshaler))]"; 106 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringshareKeepOwnershipMarshaler))]";
107 }}, 107 }},
108 {"any_value_ptr", true, [&] { 108 {"any_value_ptr", true, [&] {
109 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.ValueMarshalerOwn))]"; 109 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshalerOwn))]";
110 }}, 110 }},
111 {"any_value_ptr", false, [&] { 111 {"any_value_ptr", false, [&] {
112 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.ValueMarshaler))]"; 112 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueMarshaler))]";
113 }}, 113 }},
114 {"strbuf", true, [&] { 114 {"strbuf", true, [&] {
115 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufPassOwnershipMarshaler))]"; 115 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
116 }}, 116 }},
117 {"strbuf", false, [&] { 117 {"strbuf", false, [&] {
118 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufKeepOwnershipMarshaler))]"; 118 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
119 }}, 119 }},
120 }; 120 };
121 121
@@ -142,11 +142,11 @@ struct marshall_annotation_visitor_generate
142 } 142 }
143 bool operator()(attributes::klass_name const& klass_name) const 143 bool operator()(attributes::klass_name const& klass_name) const
144 { 144 {
145 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 145 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<";
146 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 146 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<";
147 return as_generator 147 return as_generator
148 ((is_return ? return_prefix : no_return_prefix) 148 ((is_return ? return_prefix : no_return_prefix)
149 << string << ", efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" 149 << string << ", Efl.Eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]"
150 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); 150 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context);
151 } 151 }
152 bool operator()(attributes::complex_type_def const& c) const 152 bool operator()(attributes::complex_type_def const& c) const
@@ -154,7 +154,7 @@ struct marshall_annotation_visitor_generate
154 if (c.outer.base_type == "future") 154 if (c.outer.base_type == "future")
155 { 155 {
156 std::string prefix = is_return ? "return: " : ""; 156 std::string prefix = is_return ? "return: " : "";
157 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.FutureMarshaler))]").generate(sink, nullptr, *context); 157 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.FutureMarshaler))]").generate(sink, nullptr, *context);
158 } 158 }
159 return true; 159 return true;
160 } 160 }
@@ -187,26 +187,26 @@ struct marshall_native_annotation_visitor_generate
187 // signed primitives 187 // signed primitives
188 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }}, 188 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
189 {"string", true, [&] { 189 {"string", true, [&] {
190 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 190 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
191 }}, 191 }},
192 {"string", false, [&] { 192 {"string", false, [&] {
193 if (is_out) 193 if (is_out)
194 return ""; 194 return "";
195 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringKeepOwnershipMarshaler))]"; 195 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringKeepOwnershipMarshaler))]";
196 }}, 196 }},
197 {"stringshare", true, [&] { 197 {"stringshare", true, [&] {
198 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringsharePassOwnershipMarshaler))]"; 198 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
199 }}, 199 }},
200 {"stringshare", false, [&] { 200 {"stringshare", false, [&] {
201 if (is_out) 201 if (is_out)
202 return ""; 202 return "";
203 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringshareKeepOwnershipMarshaler))]"; 203 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringshareKeepOwnershipMarshaler))]";
204 }}, 204 }},
205 {"strbuf", true, [&] { 205 {"strbuf", true, [&] {
206 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufPassOwnershipMarshaler))]"; 206 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
207 }}, 207 }},
208 {"strbuf", false, [&] { 208 {"strbuf", false, [&] {
209 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufKeepOwnershipMarshaler))]"; 209 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
210 }}, 210 }},
211 }; 211 };
212 match const return_match_table[] = 212 match const return_match_table[] =
@@ -214,18 +214,18 @@ struct marshall_native_annotation_visitor_generate
214 // signed primitives 214 // signed primitives
215 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }}, 215 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
216 {"string", true, [&] { 216 {"string", true, [&] {
217 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 217 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringPassOwnershipMarshaler))]";
218 }}, 218 }},
219 {"string", false, [&] { return ""; }}, 219 {"string", false, [&] { return ""; }},
220 {"stringshare", true, [&] { 220 {"stringshare", true, [&] {
221 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringsharePassOwnershipMarshaler))]"; 221 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StringsharePassOwnershipMarshaler))]";
222 }}, 222 }},
223 {"stringshare", false, [&] { return ""; }}, 223 {"stringshare", false, [&] { return ""; }},
224 {"strbuf", true, [&] { 224 {"strbuf", true, [&] {
225 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufPassOwnershipMarshaler))]"; 225 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufPassOwnershipMarshaler))]";
226 }}, 226 }},
227 {"strbuf", false, [&] { 227 {"strbuf", false, [&] {
228 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StrbufKeepOwnershipMarshaler))]"; 228 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
229 }}, 229 }},
230 }; 230 };
231 231
@@ -252,11 +252,11 @@ struct marshall_native_annotation_visitor_generate
252 } 252 }
253 bool operator()(attributes::klass_name const& klass_name) const 253 bool operator()(attributes::klass_name const& klass_name) const
254 { 254 {
255 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 255 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<";
256 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 256 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Efl.Eo.MarshalTest<";
257 return as_generator 257 return as_generator
258 ((is_return ? return_prefix : no_return_prefix) 258 ((is_return ? return_prefix : no_return_prefix)
259 << string << ", efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" 259 << string << ", Efl.Eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]"
260 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); 260 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context);
261 } 261 }
262 bool operator()(attributes::complex_type_def const& c) const 262 bool operator()(attributes::complex_type_def const& c) const
@@ -264,7 +264,7 @@ struct marshall_native_annotation_visitor_generate
264 if (c.outer.base_type == "future") 264 if (c.outer.base_type == "future")
265 { 265 {
266 std::string prefix = is_return ? "return: " : ""; 266 std::string prefix = is_return ? "return: " : "";
267 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.FutureMarshaler))]").generate(sink, nullptr, *context); 267 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.FutureMarshaler))]").generate(sink, nullptr, *context);
268 } 268 }
269 return true; 269 return true;
270 } 270 }
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type.hh b/src/bin/eolian_mono/eolian/mono/marshall_type.hh
index 79ce8b6380..add954ade2 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type.hh
@@ -22,7 +22,7 @@ struct marshall_native_annotation_visitor_generate;
22 * 22 *
23 * For example, Eina.Value can be marshaled either as an eina.Value instance through 23 * For example, Eina.Value can be marshaled either as an eina.Value instance through
24 * CustomMarshallers if we have a ptr(Eina.Value) or through the intermediate 24 * CustomMarshallers if we have a ptr(Eina.Value) or through the intermediate
25 * eina.Value_Native blittable struct if it is passed by value. 25 * eina.ValueNative blittable struct if it is passed by value.
26 * 26 *
27 * For details, check marshall_type_impl.h with the actual conversion rules. 27 * For details, check marshall_type_impl.h with the actual conversion rules.
28 */ 28 */
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
index 95970dedd6..e14369ad7b 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -94,7 +94,7 @@ struct marshall_type_visitor_generate
94 { 94 {
95 regular_type_def r = regular; 95 regular_type_def r = regular;
96 r.base_qualifier.qualifier ^= qualifier_info::is_ref; 96 r.base_qualifier.qualifier ^= qualifier_info::is_ref;
97 return replace_base_type(r, " eina.Strbuf"); 97 return replace_base_type(r, " Eina.Strbuf");
98 }} 98 }}
99 , {"Binbuf", true, [&] 99 , {"Binbuf", true, [&]
100 { 100 {
@@ -115,9 +115,9 @@ struct marshall_type_visitor_generate
115 regular_type_def r = regular; 115 regular_type_def r = regular;
116 r.namespaces.clear(); 116 r.namespaces.clear();
117 if (is_ptr) 117 if (is_ptr)
118 r.base_type = " eina.Value"; 118 r.base_type = " Eina.Value";
119 else 119 else
120 r.base_type = " eina.Value_Native"; 120 r.base_type = " Eina.ValueNative";
121 return r; 121 return r;
122 }} 122 }}
123 , {"any_value", false, [&] 123 , {"any_value", false, [&]
@@ -125,23 +125,23 @@ struct marshall_type_visitor_generate
125 regular_type_def r = regular; 125 regular_type_def r = regular;
126 r.namespaces.clear(); 126 r.namespaces.clear();
127 if (is_ptr) 127 if (is_ptr)
128 r.base_type = " eina.Value"; 128 r.base_type = " Eina.Value";
129 else 129 else
130 r.base_type = " eina.Value_Native"; 130 r.base_type = " Eina.ValueNative";
131 return r; 131 return r;
132 }} 132 }}
133 , {"any_value_ptr", true, [&] 133 , {"any_value_ptr", true, [&]
134 { 134 {
135 regular_type_def r = regular; 135 regular_type_def r = regular;
136 r.namespaces.clear(); 136 r.namespaces.clear();
137 r.base_type = " eina.Value"; 137 r.base_type = " Eina.Value";
138 return r; 138 return r;
139 }} 139 }}
140 , {"any_value_ptr", false, [&] 140 , {"any_value_ptr", false, [&]
141 { 141 {
142 regular_type_def r = regular; 142 regular_type_def r = regular;
143 r.namespaces.clear(); 143 r.namespaces.clear();
144 r.base_type = " eina.Value"; 144 r.base_type = " Eina.Value";
145 return r; 145 return r;
146 }} 146 }}
147 , {"void", nullptr, [&] 147 , {"void", nullptr, [&]
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index b1a03056ef..05bf783384 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -36,6 +36,10 @@ inline bool is_iequal(std::string const& lhs, std::string const& rhs)
36{ 36{
37 return strcasecmp(lhs.c_str(), rhs.c_str()) == 0; 37 return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
38} 38}
39inline bool is_equal(std::string const& lhs, std::string const& rhs)
40{
41 return lhs == rhs;
42}
39} 43}
40 44
41inline std::string identity(std::string const& str) 45inline std::string identity(std::string const& str)
@@ -45,21 +49,21 @@ inline std::string identity(std::string const& str)
45 49
46inline std::string escape_keyword(std::string const& name) 50inline std::string escape_keyword(std::string const& name)
47{ 51{
48 using detail::is_iequal; 52 using detail::is_equal;
49 if(is_iequal(name, "delete") 53 if(is_equal(name, "delete")
50 || is_iequal(name, "do") 54 || is_equal(name, "do")
51 || is_iequal(name, "lock") 55 || is_equal(name, "lock")
52 || is_iequal(name, "event") 56 || is_equal(name, "event")
53 || is_iequal(name, "in") 57 || is_equal(name, "in")
54 || is_iequal(name, "object") 58 || is_equal(name, "object")
55 || is_iequal(name, "interface") 59 || is_equal(name, "interface")
56 || is_iequal(name, "string") 60 || is_equal(name, "string")
57 || is_iequal(name, "internal") 61 || is_equal(name, "internal")
58 || is_iequal(name, "fixed") 62 || is_equal(name, "fixed")
59 || is_iequal(name, "base")) 63 || is_equal(name, "base"))
60 return "kw_" + name; 64 return "kw_" + name;
61 65
62 if (is_iequal(name, "Finalize")) 66 if (is_equal(name, "Finalize"))
63 return name + "Add"; // Eo's Finalize is actually the end of efl_add. 67 return name + "Add"; // Eo's Finalize is actually the end of efl_add.
64 return name; 68 return name;
65} 69}
@@ -169,7 +173,7 @@ void reorder_verb(std::vector<std::string> &names)
169 173
170inline std::string managed_namespace(std::string const& ns) 174inline std::string managed_namespace(std::string const& ns)
171{ 175{
172 return utils::to_lowercase(escape_keyword(ns)); 176 return escape_keyword(utils::remove_all(ns, '_'));
173} 177}
174 178
175inline std::string managed_method_name(attributes::function_def const& f) 179inline std::string managed_method_name(attributes::function_def const& f)
@@ -208,7 +212,7 @@ inline std::string type_full_eolian_name(attributes::regular_type_def const& typ
208 212
209inline std::string type_full_managed_name(attributes::regular_type_def const& type) 213inline std::string type_full_managed_name(attributes::regular_type_def const& type)
210{ 214{
211 return join_namespaces(type.namespaces, '.', managed_namespace) + type.base_type; 215 return join_namespaces(type.namespaces, '.', managed_namespace) + utils::remove_all(type.base_type, '_');
212} 216}
213 217
214inline std::string struct_full_eolian_name(attributes::struct_def const& struct_) 218inline std::string struct_full_eolian_name(attributes::struct_def const& struct_)
@@ -216,9 +220,22 @@ inline std::string struct_full_eolian_name(attributes::struct_def const& struct_
216 return join_namespaces(struct_.namespaces, '.') + struct_.cxx_name; 220 return join_namespaces(struct_.namespaces, '.') + struct_.cxx_name;
217} 221}
218 222
219inline std::string enum_managed_name(attributes::enum_def const& enum_) 223template<typename T>
224inline std::string typedecl_managed_name(T const& item)
225{
226 return utils::remove_all(item.cxx_name, '_');
227}
228
229inline std::string typedecl_managed_name(attributes::function_def const& func)
220{ 230{
221 return enum_.cxx_name; 231 return utils::remove_all(func.name, '_');
232}
233
234
235inline std::string enum_field_managed_name(std::string name)
236{
237 std::vector<std::string> names = utils::split(name, '_');
238 return utils::to_pascal_case(names);
222} 239}
223 240
224inline std::string to_field_name(std::string const& in) 241inline std::string to_field_name(std::string const& in)
@@ -226,41 +243,106 @@ inline std::string to_field_name(std::string const& in)
226 return utils::capitalize(in); 243 return utils::capitalize(in);
227} 244}
228 245
229// Class name translation (interface/concrete/inherit/etc) 246inline std::string managed_part_name(attributes::part_def const& part)
230template<typename T>
231inline std::string klass_interface_name(T const& klass)
232{ 247{
233 return "I" + klass.eolian_name; 248 std::vector<std::string> names = utils::split(part.name, '_');
249 return utils::to_pascal_case(names);
234} 250}
235 251
236template<typename T> 252// Class name translation (interface/concrete/inherit/etc)
237inline std::string klass_full_interface_name(T const& klass) 253struct klass_interface_name_generator
238{ 254{
239 return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_interface_name(klass); 255
240} 256 template <typename T>
257 std::string operator()(T const& klass) const
258 {
259 return utils::remove_all(klass.eolian_name, '_');
260 }
261
262 template <typename OutputIterator, typename Attr, typename Context>
263 bool generate(OutputIterator sink, Attr const& attribute, Context const& context) const
264 {
265 return as_generator((*this).operator()<Attr>(attribute)).generate(sink, attributes::unused, context);
266 }
267} klass_interface_name;
268
269struct klass_full_interface_name_generator
270{
271 template <typename T>
272 std::string operator()(T const& klass) const
273 {
274 return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_interface_name(klass);
275 }
276
277 template <typename OutputIterator, typename Attr, typename Context>
278 bool generate(OutputIterator sink, Attr const& attribute, Context const& context) const
279 {
280 return as_generator((*this).operator()<Attr>(attribute)).generate(sink, attributes::unused, context);
281 }
282} klass_full_interface_name;
241 283
242template<typename T> 284template<typename T>
243inline std::string klass_concrete_name(T const& klass) 285inline std::string klass_concrete_name(T const& klass)
244{ 286{
245 return klass.eolian_name; 287 std::string name = utils::remove_all(klass.eolian_name, '_');
288 if (klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_)
289 return name;
290 return name + "Concrete";
246} 291}
247 292
248template<typename T> 293struct klass_full_concrete_name_generator
249inline std::string klass_full_concrete_name(T const& klass)
250{ 294{
251 return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_concrete_name(klass); 295 template <typename T>
252} 296 std::string operator()(T const& klass) const
297 {
298 return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_concrete_name(klass);
299 }
300
301 template <typename OutputIterator, typename Attr, typename Context>
302 bool generate(OutputIterator sink, Attr const& attribute, Context const& context) const
303 {
304 return as_generator((*this).operator()<Attr>(attribute)).generate(sink, attributes::unused, context);
305 }
306} klass_full_concrete_name;
307
308struct klass_full_concrete_or_interface_name_generator
309{
310 template <typename T>
311 std::string operator()(T const& klass) const
312 {
313 switch(klass.type)
314 {
315 case attributes::class_type::abstract_:
316 case attributes::class_type::regular:
317 return klass_full_concrete_name(klass);
318 }
319 return klass_full_interface_name(klass);
320
321 }
322
323 template <typename OutputIterator, typename Context>
324 bool generate(OutputIterator, attributes::unused_type, Context const&) const
325 {
326 return true;
327 }
328
329 template <typename OutputIterator, typename Attr, typename Context>
330 bool generate(OutputIterator sink, Attr const& attribute, Context const& context) const
331 {
332 return as_generator((*this).operator()<Attr>(attribute)).generate(sink, attributes::unused, context);
333 }
334} klass_full_concrete_or_interface_name;
253 335
254template<typename T> 336template<typename T>
255inline std::string klass_inherit_name(T const& klass) 337inline std::string klass_inherit_name(T const& klass)
256{ 338{
257 return klass.eolian_name + "Inherit"; 339 return klass_concrete_name(klass);
258} 340}
259 341
260template<typename T> 342template<typename T>
261inline std::string klass_native_inherit_name(T const& klass) 343inline std::string klass_native_inherit_name(T const& klass)
262{ 344{
263 return klass.eolian_name + "NativeInherit"; 345 return klass_concrete_name(klass) + "NativeInherit";
264} 346}
265 347
266template<typename T> 348template<typename T>
@@ -282,17 +364,20 @@ inline std::string managed_event_name(std::string const& name)
282 364
283inline std::string managed_event_args_short_name(attributes::event_def const& evt) 365inline std::string managed_event_args_short_name(attributes::event_def const& evt)
284{ 366{
285 return name_helpers::managed_event_name(evt.name) + "_Args"; 367 std::string ret;
368 ret = klass_interface_name(evt.klass);
369 return ret + name_helpers::managed_event_name(evt.name) + "_Args";
286} 370}
287 371
288inline std::string managed_event_args_name(attributes::event_def evt) 372inline std::string managed_event_args_name(attributes::event_def evt)
289{ 373{
290 return klass_full_concrete_name(evt.klass) + "." + managed_event_args_short_name(evt); 374 return join_namespaces(evt.klass.namespaces, '.', managed_namespace) +
375 managed_event_args_short_name(evt);
291} 376}
292 377
293inline std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass) 378inline std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass)
294{ 379{
295 return join_namespaces(klass.namespaces, '_') + klass.cxx_name + "_" + managed_event_name(evt.name); 380 return join_namespaces(klass.namespaces, '_') + klass_interface_name(klass) + "_" + managed_event_name(evt.name);
296} 381}
297 382
298// Open/close namespaces 383// Open/close namespaces
@@ -318,4 +403,34 @@ bool close_namespaces(OutputIterator sink, std::vector<std::string> const& names
318 403
319} // namespace eolian_mono 404} // namespace eolian_mono
320 405
406
407namespace efl { namespace eolian { namespace grammar {
408
409template <>
410struct is_eager_generator<eolian_mono::name_helpers::klass_interface_name_generator> : std::true_type {};
411template <>
412struct is_generator<eolian_mono::name_helpers::klass_interface_name_generator> : std::true_type {};
413
414template <>
415struct is_eager_generator<eolian_mono::name_helpers::klass_full_interface_name_generator> : std::true_type {};
416template <>
417struct is_generator<eolian_mono::name_helpers::klass_full_interface_name_generator> : std::true_type {};
418
419template <>
420struct is_eager_generator<eolian_mono::name_helpers::klass_full_concrete_or_interface_name_generator> : std::true_type {};
421template <>
422struct is_generator<eolian_mono::name_helpers::klass_full_concrete_or_interface_name_generator> : std::true_type {};
423
424template <>
425struct is_eager_generator<eolian_mono::name_helpers::klass_full_concrete_name_generator> : std::true_type {};
426template <>
427struct is_generator<eolian_mono::name_helpers::klass_full_concrete_name_generator> : std::true_type {};
428
429namespace type_traits {
430template <>
431struct attributes_needed<struct ::eolian_mono::name_helpers::klass_full_concrete_or_interface_name_generator> : std::integral_constant<int, 1> {};
432}
433
434} } }
435
321#endif 436#endif
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index 55ea6f4115..70d22fb97e 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -458,7 +458,7 @@ struct marshall_parameter_generator
458 ).generate(sink, std::make_tuple(param, param_name), context); 458 ).generate(sink, std::make_tuple(param, param_name), context);
459 459
460 return as_generator( 460 return as_generator(
461 "IntPtr " << param_name << "_data, " << type << "Internal " << param_name << ", Eina_Free_Cb " 461 "IntPtr " << param_name << "_data, " << type << "Internal " << param_name << ", EinaFreeCb "
462 << param_name << "_free_cb" 462 << param_name << "_free_cb"
463 ).generate(sink, param, context); 463 ).generate(sink, param, context);
464 } 464 }
@@ -527,7 +527,7 @@ struct argument_invocation_generator
527 else if (param.type.original_type.visit(is_fp_visitor{})) 527 else if (param.type.original_type.visit(is_fp_visitor{}))
528 { 528 {
529 std::string param_name = escape_keyword(param.param_name); 529 std::string param_name = escape_keyword(param.param_name);
530 return as_generator("GCHandle.ToIntPtr(" << param_name << "_handle), " << type << "Wrapper.Cb, efl.eo.Globals.free_gchandle") 530 return as_generator("GCHandle.ToIntPtr(" << param_name << "_handle), " << type << "Wrapper.Cb, Efl.Eo.Globals.free_gchandle")
531 .generate(sink, param.type, context); 531 .generate(sink, param.type, context);
532 } 532 }
533 else 533 else
@@ -553,7 +553,7 @@ struct native_convert_in_variable_generator
553 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular)) 553 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular))
554 { 554 {
555 return as_generator( 555 return as_generator(
556 "var " << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n" 556 "var " << string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n"
557 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); 557 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
558 } 558 }
559 else if (helpers::need_struct_conversion(regular)) 559 else if (helpers::need_struct_conversion(regular))
@@ -565,7 +565,7 @@ struct native_convert_in_variable_generator
565 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") 565 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
566 { 566 {
567 return as_generator( 567 return as_generator(
568 "var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n" 568 "var " << string << " = new Eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
569 ).generate(sink, in_variable_name(param.param_name), context); 569 ).generate(sink, in_variable_name(param.param_name), context);
570 } 570 }
571 else if (param.type.c_type == "Eina_Hash *" || param.type.c_type == "const Eina_Hash *") 571 else if (param.type.c_type == "Eina_Hash *" || param.type.c_type == "const Eina_Hash *")
@@ -622,7 +622,7 @@ struct convert_in_variable_generator
622 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular)) 622 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(param, regular))
623 { 623 {
624 return as_generator( 624 return as_generator(
625 "var " << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n" 625 "var " << string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n"
626 ).generate(sink, in_variable_name(param.param_name), context); 626 ).generate(sink, in_variable_name(param.param_name), context);
627 } 627 }
628 else if (helpers::need_struct_conversion(regular)) 628 else if (helpers::need_struct_conversion(regular))
@@ -813,7 +813,7 @@ struct native_convert_out_variable_generator
813 ) 813 )
814 { 814 {
815 return as_generator( 815 return as_generator(
816 "eina.Binbuf " << string << " = default(eina.Binbuf);\n" 816 "Eina.Binbuf " << string << " = default(Eina.Binbuf);\n"
817 ).generate(sink, out_variable_name(param.param_name), context); 817 ).generate(sink, out_variable_name(param.param_name), context);
818 } 818 }
819 else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT) 819 else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
@@ -886,7 +886,7 @@ struct convert_out_assign_generator
886 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction)) 886 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction))
887 { 887 {
888 bool ret = as_generator( 888 bool ret = as_generator(
889 string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n" 889 string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n"
890 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context); 890 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
891 891
892 if (param.type.has_own) 892 if (param.type.has_own)
@@ -908,7 +908,7 @@ struct convert_out_assign_generator
908 ) 908 )
909 { 909 {
910 return as_generator( 910 return as_generator(
911 string << " = new eina.Binbuf(" << string << ", " << (param.type.has_own ? "true" : "false") << ");\n" 911 string << " = new Eina.Binbuf(" << string << ", " << (param.type.has_own ? "true" : "false") << ");\n"
912 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 912 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
913 } 913 }
914 else if (param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT) 914 else if (param_is_acceptable(param, "Eina_Hash *", WANT_OWN, WANT_OUT)
@@ -1032,7 +1032,7 @@ struct convert_return_generator
1032 if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown)) 1032 if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown))
1033 { 1033 {
1034 return as_generator( 1034 return as_generator(
1035 "var __ret_tmp = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n" 1035 "var __ret_tmp = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n"
1036 << scope_tab << scope_tab << (ret_type.has_own ? ("Marshal.FreeHGlobal(_ret_var);\n"): "\n") 1036 << scope_tab << scope_tab << (ret_type.has_own ? ("Marshal.FreeHGlobal(_ret_var);\n"): "\n")
1037 << scope_tab << scope_tab << "return __ret_tmp;\n" 1037 << scope_tab << scope_tab << "return __ret_tmp;\n"
1038 ).generate(sink, ret_type, context); 1038 ).generate(sink, ret_type, context);
@@ -1045,7 +1045,7 @@ struct convert_return_generator
1045 } 1045 }
1046 else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *") 1046 else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
1047 { 1047 {
1048 if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n" 1048 if (!as_generator("var _binbuf_ret = new Eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n"
1049 << scope_tab << scope_tab << "return _binbuf_ret;\n") 1049 << scope_tab << scope_tab << "return _binbuf_ret;\n")
1050 .generate(sink, attributes::unused, context)) 1050 .generate(sink, attributes::unused, context))
1051 return false; 1051 return false;
@@ -1104,7 +1104,7 @@ struct native_convert_out_assign_generator
1104 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction)) 1104 if (param.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(param.type, param.direction))
1105 { 1105 {
1106 return as_generator( 1106 return as_generator(
1107 string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n" 1107 string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n"
1108 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 1108 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
1109 } 1109 }
1110 else if (helpers::need_struct_conversion(regular)) 1110 else if (helpers::need_struct_conversion(regular))
@@ -1121,7 +1121,7 @@ struct native_convert_out_assign_generator
1121 return false; 1121 return false;
1122 } 1122 }
1123 return as_generator( 1123 return as_generator(
1124 string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n" 1124 string << "= Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n"
1125 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 1125 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
1126 } 1126 }
1127 else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)) 1127 else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
@@ -1132,7 +1132,7 @@ struct native_convert_out_assign_generator
1132 return false; 1132 return false;
1133 } 1133 }
1134 return as_generator( 1134 return as_generator(
1135 string << "= efl.eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n" 1135 string << "= Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n"
1136 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); 1136 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
1137 } 1137 }
1138 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 1138 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
@@ -1251,7 +1251,7 @@ struct native_convert_return_generator
1251 if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown) ) 1251 if (ret_type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion_in_return(ret_type, attributes::parameter_direction::unknown) )
1252 { 1252 {
1253 return as_generator( 1253 return as_generator(
1254 "return eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n" 1254 "return Eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n"
1255 ).generate(sink, attributes::unused, context); 1255 ).generate(sink, attributes::unused, context);
1256 } 1256 }
1257 else if (helpers::need_struct_conversion(regular)) 1257 else if (helpers::need_struct_conversion(regular))
@@ -1270,7 +1270,7 @@ struct native_convert_return_generator
1270 return false; 1270 return false;
1271 } 1271 }
1272 return as_generator( 1272 return as_generator(
1273 "return efl.eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n" 1273 "return Efl.Eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n"
1274 ).generate(sink, attributes::unused, context); 1274 ).generate(sink, attributes::unused, context);
1275 } 1275 }
1276 else 1276 else
@@ -1288,7 +1288,7 @@ struct native_convert_return_generator
1288 return false; 1288 return false;
1289 } 1289 }
1290 return as_generator( 1290 return as_generator(
1291 "return efl.eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n" 1291 "return Efl.Eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n"
1292 ).generate(sink, attributes::unused, context); 1292 ).generate(sink, attributes::unused, context);
1293 } 1293 }
1294 else 1294 else
diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh
index 94fc3cb63c..bd12ee2a40 100644
--- a/src/bin/eolian_mono/eolian/mono/part_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh
@@ -18,14 +18,13 @@ struct part_definition_generator
18 template <typename OutputIterator, typename Context> 18 template <typename OutputIterator, typename Context>
19 bool generate(OutputIterator sink, attributes::part_def const& part, Context const& context) const 19 bool generate(OutputIterator sink, attributes::part_def const& part, Context const& context) const
20 { 20 {
21 auto part_interface_name = name_helpers::klass_full_interface_name(part.klass); 21 auto part_klass_name = name_helpers::klass_full_concrete_or_interface_name(part.klass);
22 auto part_klass_name = name_helpers::klass_full_concrete_name(part.klass);
23 return as_generator(scope_tab << documentation 22 return as_generator(scope_tab << documentation
24 << scope_tab << "public " << part_interface_name << " " << utils::capitalize(part.name) << "\n" 23 << scope_tab << "public " << part_klass_name << " " << name_helpers::managed_part_name(part) << "\n"
25 << scope_tab << "{\n" 24 << scope_tab << "{\n"
26 << scope_tab << scope_tab << "get\n" 25 << scope_tab << scope_tab << "get\n"
27 << scope_tab << scope_tab << "{\n" 26 << scope_tab << scope_tab << "{\n"
28 << scope_tab << scope_tab << scope_tab << "efl.IObject obj = efl_part_get(raw_handle, \"" << part.name << "\");\n" 27 << scope_tab << scope_tab << scope_tab << "Efl.Object obj = efl_part_get(NativeHandle, \"" << part.name << "\");\n"
29 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n" 28 << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n"
30 << scope_tab << scope_tab << "}\n" 29 << scope_tab << scope_tab << "}\n"
31 << scope_tab << "}\n" 30 << scope_tab << "}\n"
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 58007a2cdd..99347ed1dc 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -18,12 +18,12 @@ namespace eolian_mono {
18 18
19inline std::string binding_struct_name(attributes::struct_def const& struct_) 19inline std::string binding_struct_name(attributes::struct_def const& struct_)
20{ 20{
21 return struct_.cxx_name; 21 return name_helpers::typedecl_managed_name(struct_);
22} 22}
23 23
24inline std::string binding_struct_internal_name(attributes::struct_def const& struct_) 24inline std::string binding_struct_internal_name(attributes::struct_def const& struct_)
25{ 25{
26 return struct_.cxx_name + "_StructInternal"; 26 return binding_struct_name(struct_) + "_StructInternal";
27} 27}
28 28
29struct struct_definition_generator 29struct struct_definition_generator
@@ -175,7 +175,7 @@ struct to_internal_field_convert_generator
175 if (klass) 175 if (klass)
176 { 176 {
177 if (!as_generator( 177 if (!as_generator(
178 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".raw_handle;\n") 178 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".NativeHandle;\n")
179 .generate(sink, std::make_tuple(field_name, field_name), context)) 179 .generate(sink, std::make_tuple(field_name, field_name), context))
180 return false; 180 return false;
181 } 181 }
@@ -196,7 +196,7 @@ struct to_internal_field_convert_generator
196 else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular)) 196 else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
197 { 197 {
198 if (!as_generator( 198 if (!as_generator(
199 scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n") 199 scope_tab << scope_tab << "_internal_struct." << string << " = Eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n")
200 .generate(sink, std::make_tuple(field_name, field_name), context)) 200 .generate(sink, std::make_tuple(field_name, field_name), context))
201 return false; 201 return false;
202 } 202 }
@@ -210,14 +210,14 @@ struct to_internal_field_convert_generator
210 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring")) 210 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring"))
211 { 211 {
212 if (!as_generator( 212 if (!as_generator(
213 scope_tab << scope_tab << "_internal_struct." << string << " = eina.MemoryNative.StrDup(_external_struct." << string << ");\n") 213 scope_tab << scope_tab << "_internal_struct." << string << " = Eina.MemoryNative.StrDup(_external_struct." << string << ");\n")
214 .generate(sink, std::make_tuple(field_name, field_name), context)) 214 .generate(sink, std::make_tuple(field_name, field_name), context))
215 return false; 215 return false;
216 } 216 }
217 else if (regular && regular->base_type == "stringshare") 217 else if (regular && regular->base_type == "stringshare")
218 { 218 {
219 if (!as_generator( 219 if (!as_generator(
220 scope_tab << scope_tab << "_internal_struct." << string << " = eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n") 220 scope_tab << scope_tab << "_internal_struct." << string << " = Eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n")
221 .generate(sink, std::make_tuple(field_name, field_name), context)) 221 .generate(sink, std::make_tuple(field_name, field_name), context))
222 return false; 222 return false;
223 } 223 }
@@ -273,9 +273,9 @@ struct to_external_field_convert_generator
273 if (!as_generator( 273 if (!as_generator(
274 "\n" 274 "\n"
275 << scope_tab << scope_tab << "_external_struct." << string 275 << scope_tab << scope_tab << "_external_struct." << string
276 << " = (" << interface_name << ") System.Activator.CreateInstance(typeof(" 276 << " = (" << concrete_name << ") System.Activator.CreateInstance(typeof("
277 << concrete_name << "), new System.Object[] {_internal_struct." << string << "});\n" 277 << concrete_name << "), new System.Object[] {_internal_struct." << string << "});\n"
278 << scope_tab << scope_tab << "efl.eo.Globals.efl_ref(_internal_struct." << string << ");\n\n") 278 << scope_tab << scope_tab << "Efl.Eo.Globals.efl_ref(_internal_struct." << string << ");\n\n")
279 .generate(sink, std::make_tuple(field_name, field_name, field_name), context)) 279 .generate(sink, std::make_tuple(field_name, field_name, field_name), context))
280 return false; 280 return false;
281 } 281 }
@@ -308,7 +308,7 @@ struct to_external_field_convert_generator
308 else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular)) 308 else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular))
309 { 309 {
310 if (!as_generator( 310 if (!as_generator(
311 scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n") 311 scope_tab << scope_tab << "_external_struct." << string << " = Eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n")
312 .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) 312 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
313 return false; 313 return false;
314 } 314 }
@@ -322,7 +322,7 @@ struct to_external_field_convert_generator
322 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare")) 322 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare"))
323 { 323 {
324 if (!as_generator( 324 if (!as_generator(
325 scope_tab << scope_tab << "_external_struct." << string << " = eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n") 325 scope_tab << scope_tab << "_external_struct." << string << " = Eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n")
326 .generate(sink, std::make_tuple(field_name, field_name), context)) 326 .generate(sink, std::make_tuple(field_name, field_name), context))
327 return false; 327 return false;
328 } 328 }
@@ -339,14 +339,14 @@ struct to_external_field_convert_generator
339 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value") 339 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
340 { 340 {
341 if (!as_generator( 341 if (!as_generator(
342 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ");\n" 342 scope_tab << scope_tab << "_external_struct." << string << " = new Eina.Value(_internal_struct." << string << ");\n"
343 ).generate(sink, std::make_tuple(field_name, field_name), context)) 343 ).generate(sink, std::make_tuple(field_name, field_name), context))
344 return false; 344 return false;
345 } 345 }
346 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *") 346 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
347 { 347 {
348 if (!as_generator( 348 if (!as_generator(
349 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ", eina.Ownership.Unmanaged);\n" 349 scope_tab << scope_tab << "_external_struct." << string << " = new Eina.Value(_internal_struct." << string << ", Eina.Ownership.Unmanaged);\n"
350 ).generate(sink, std::make_tuple(field_name, field_name), context)) 350 ).generate(sink, std::make_tuple(field_name, field_name), context))
351 return false; 351 return false;
352 } 352 }
@@ -369,8 +369,8 @@ struct struct_binding_conversion_functions_generator
369 // Open conversion class 369 // Open conversion class
370 if (!as_generator 370 if (!as_generator
371 ( 371 (
372 "/// <summary>Conversion class for struct " << struct_.cxx_name << "</summary>\n" 372 "/// <summary>Conversion class for struct " << name_helpers::typedecl_managed_name(struct_) << "</summary>\n"
373 "public static class " << struct_.cxx_name << "_StructConversion\n{\n" 373 "public static class " << name_helpers::typedecl_managed_name(struct_) << "_StructConversion\n{\n"
374 ) 374 )
375 .generate(sink, nullptr, context)) 375 .generate(sink, nullptr, context))
376 return false; 376 return false;
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index 09c4bc198d..3e4ae8d124 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -117,7 +117,7 @@ struct visitor_generate
117 }} 117 }}
118 , {"Eina.Error", nullptr, [&] // Eina.Error 118 , {"Eina.Error", nullptr, [&] // Eina.Error
119 { 119 {
120 return regular_type_def{" eina.Error", regular.base_qualifier, {}}; 120 return regular_type_def{" Eina.Error", regular.base_qualifier, {}};
121 }} // TODO 121 }} // TODO
122 , {"string", nullptr, [&] 122 , {"string", nullptr, [&]
123 { 123 {
@@ -139,16 +139,16 @@ struct visitor_generate
139 }} 139 }}
140 , {"strbuf", nullptr, [&] 140 , {"strbuf", nullptr, [&]
141 { 141 {
142 return regular_type_def{" eina.Strbuf", regular.base_qualifier, {}}; 142 return regular_type_def{" Eina.Strbuf", regular.base_qualifier, {}};
143 }} 143 }}
144 , {"any_value", true, [&] 144 , {"any_value", true, [&]
145 { return regular_type_def{" eina.Value", regular.base_qualifier, {}}; 145 { return regular_type_def{" Eina.Value", regular.base_qualifier, {}};
146 }} 146 }}
147 , {"any_value", false, [&] 147 , {"any_value", false, [&]
148 { return regular_type_def{" eina.Value", regular.base_qualifier, {}}; 148 { return regular_type_def{" Eina.Value", regular.base_qualifier, {}};
149 }} 149 }}
150 , {"any_value_ptr", nullptr, [&] 150 , {"any_value_ptr", nullptr, [&]
151 { return regular_type_def{" eina.Value", regular.base_qualifier, {}}; 151 { return regular_type_def{" Eina.Value", regular.base_qualifier, {}};
152 }} // FIXME add proper support for any_value_ptr 152 }} // FIXME add proper support for any_value_ptr
153 }; 153 };
154 std::string full_type_name = name_helpers::type_full_eolian_name(regular); 154 std::string full_type_name = name_helpers::type_full_eolian_name(regular);
@@ -237,7 +237,10 @@ struct visitor_generate
237 } 237 }
238 bool operator()(attributes::klass_name klass) const 238 bool operator()(attributes::klass_name klass) const
239 { 239 {
240 return as_generator(string).generate(sink, name_helpers::klass_full_interface_name(klass), *context); 240 if(klass.type == attributes::class_type::regular || klass.type == attributes::class_type::abstract_)
241 return as_generator(string).generate(sink, name_helpers::klass_full_concrete_name(klass), *context);
242 else
243 return as_generator(string).generate(sink, name_helpers::klass_full_interface_name(klass), *context);
241 } 244 }
242 bool operator()(attributes::complex_type_def const& complex) const 245 bool operator()(attributes::complex_type_def const& complex) const
243 { 246 {
@@ -255,51 +258,51 @@ struct visitor_generate
255 {"list", nullptr, nullptr, [&] 258 {"list", nullptr, nullptr, [&]
256 { 259 {
257 complex_type_def c = complex; 260 complex_type_def c = complex;
258 c.outer.base_type = "eina.List"; 261 c.outer.base_type = "Eina.List";
259 return c; 262 return c;
260 }} 263 }}
261 , {"inlist", nullptr, nullptr, [&] 264 , {"inlist", nullptr, nullptr, [&]
262 { 265 {
263 complex_type_def c = complex; 266 complex_type_def c = complex;
264 c.outer.base_type = "eina.Inlist"; 267 c.outer.base_type = "Eina.Inlist";
265 return c; 268 return c;
266 }} 269 }}
267 , {"array", nullptr, nullptr, [&] 270 , {"array", nullptr, nullptr, [&]
268 { 271 {
269 complex_type_def c = complex; 272 complex_type_def c = complex;
270 c.outer.base_type = "eina.Array"; 273 c.outer.base_type = "Eina.Array";
271 return c; 274 return c;
272 }} 275 }}
273 , {"inarray", nullptr, nullptr, [&] 276 , {"inarray", nullptr, nullptr, [&]
274 { 277 {
275 complex_type_def c = complex; 278 complex_type_def c = complex;
276 c.outer.base_type = "eina.Inarray"; 279 c.outer.base_type = "Eina.Inarray";
277 return c; 280 return c;
278 }} 281 }}
279 , {"hash", nullptr, nullptr 282 , {"hash", nullptr, nullptr
280 , [&] 283 , [&]
281 { 284 {
282 complex_type_def c = complex; 285 complex_type_def c = complex;
283 c.outer.base_type = "eina.Hash"; 286 c.outer.base_type = "Eina.Hash";
284 return c; 287 return c;
285 }} 288 }}
286 , {"future", nullptr, nullptr, [&] 289 , {"future", nullptr, nullptr, [&]
287 { 290 {
288 (*this)(regular_type_def{" eina.Future", complex.outer.base_qualifier, {}}); 291 (*this)(regular_type_def{" Eina.Future", complex.outer.base_qualifier, {}});
289 return attributes::type_def::variant_type(); 292 return attributes::type_def::variant_type();
290 } 293 }
291 } 294 }
292 , {"iterator", nullptr, nullptr, [&] 295 , {"iterator", nullptr, nullptr, [&]
293 { 296 {
294 complex_type_def c = complex; 297 complex_type_def c = complex;
295 c.outer.base_type = "eina.Iterator"; 298 c.outer.base_type = "Eina.Iterator";
296 return c; 299 return c;
297 } 300 }
298 } 301 }
299 , {"accessor", nullptr, nullptr, [&] 302 , {"accessor", nullptr, nullptr, [&]
300 { 303 {
301 complex_type_def c = complex; 304 complex_type_def c = complex;
302 c.outer.base_type = "eina.Accessor"; 305 c.outer.base_type = "Eina.Accessor";
303 return c; 306 return c;
304 } 307 }
305 } 308 }
diff --git a/src/bin/eolian_mono/eolian/mono/using_decl.hh b/src/bin/eolian_mono/eolian/mono/using_decl.hh
index fdea162f59..3d8b703392 100644
--- a/src/bin/eolian_mono/eolian/mono/using_decl.hh
+++ b/src/bin/eolian_mono/eolian/mono/using_decl.hh
@@ -11,18 +11,19 @@
11namespace eolian_mono { 11namespace eolian_mono {
12 12
13namespace grammar = efl::eolian::grammar; 13namespace grammar = efl::eolian::grammar;
14using efl::eolian::grammar::as_generator; 14using grammar::as_generator;
15using efl::eolian::grammar::string; 15using grammar::string;
16using efl::eolian::grammar::html_escaped_string; 16using grammar::html_escaped_string;
17using efl::eolian::grammar::operator<<; 17using grammar::operator<<;
18using efl::eolian::grammar::operator%; 18using grammar::operator%;
19using efl::eolian::grammar::operator*; 19using grammar::operator*;
20using efl::eolian::grammar::scope_tab; 20using grammar::scope_tab;
21using efl::eolian::grammar::lower_case; 21using grammar::lower_case;
22using efl::eolian::grammar::upper_case; 22using grammar::upper_case;
23using efl::eolian::grammar::lit; 23using grammar::lit;
24using efl::eolian::grammar::qualifier_info; 24using grammar::qualifier_info;
25using efl::eolian::grammar::context_find_tag; 25using grammar::context_find_tag;
26using grammar::attribute_conditional;
26 27
27} 28}
28 29
diff --git a/src/bin/eolian_mono/eolian/mono/utils.hh b/src/bin/eolian_mono/eolian/mono/utils.hh
index 0e1c2efc29..0912db8a71 100644
--- a/src/bin/eolian_mono/eolian/mono/utils.hh
+++ b/src/bin/eolian_mono/eolian/mono/utils.hh
@@ -2,6 +2,7 @@
2#define EOLIAN_MONO_UTILS_HPP 2#define EOLIAN_MONO_UTILS_HPP
3 3
4#include <string> 4#include <string>
5#include <vector>
5#include <sstream> 6#include <sstream>
6#include <iterator> 7#include <iterator>
7#include <algorithm> 8#include <algorithm>
@@ -63,6 +64,12 @@ namespace eolian_mono { namespace utils {
63 64
64 return ret; 65 return ret;
65 } 66 }
67
68 inline std::string remove_all(std::string name, char target)
69 {
70 name.erase(std::remove(name.begin(), name.end(), target), name.end());
71 return name;
72 }
66} } 73} }
67 74
68#endif 75#endif
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index e142725f7d..328b983052 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -128,7 +128,10 @@ run(options_type const& opts)
128 if (!as_generator("#pragma warning disable CS1591\n").generate(iterator, efl::eolian::grammar::attributes::unused, efl::eolian::grammar::context_null())) 128 if (!as_generator("#pragma warning disable CS1591\n").generate(iterator, efl::eolian::grammar::attributes::unused, efl::eolian::grammar::context_null()))
129 throw std::runtime_error("Failed to generate pragma to disable missing docs"); 129 throw std::runtime_error("Failed to generate pragma to disable missing docs");
130 130
131 if (!as_generator("using System;\nusing System.Runtime.InteropServices;\nusing System.Collections.Generic;\n") 131 if (!as_generator("using System;\n"
132 "using System.Runtime.InteropServices;\n"
133 "using System.Collections.Generic;\n"
134 "using System.ComponentModel;\n")
132 .generate(iterator, efl::eolian::grammar::attributes::unused, efl::eolian::grammar::context_null())) 135 .generate(iterator, efl::eolian::grammar::attributes::unused, efl::eolian::grammar::context_null()))
133 { 136 {
134 throw std::runtime_error("Failed to generate file preamble"); 137 throw std::runtime_error("Failed to generate file preamble");