summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-04-16 21:44:27 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2018-04-26 10:55:18 -0300
commita413914c1805ebbcd3b58880e5efa2d9527fd933 (patch)
tree77503787f3086f9ffbb78c5e3affe429b2ffa25f /src/bin/eolian_mono
parent8e151023b9a713be5fa251d6e182b3796f39a37a (diff)
efl_mono: Move event generators to its own header.
Summary: Making it easier to share code between self and inherited events. During this move, the namespace and keyword headers were merged into the name_helpers header. Also added the first seed of a generic namespace reducer function, to be used by other functions in later commits. Depends on D5994 Reviewers: felipealmeida Reviewed By: felipealmeida Subscribers: segfaultxavi, cedric Differential Revision: https://phab.enlightenment.org/D5995
Diffstat (limited to 'src/bin/eolian_mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/documentation.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/enum_definition.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh255
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_declaration.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_definition.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_registration.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/keyword.hh51
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh306
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh6
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh141
-rw-r--r--src/bin/eolian_mono/eolian/mono/namespace.hh27
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh3
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh3
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_fields.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh6
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc3
18 files changed, 432 insertions, 396 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/documentation.hh b/src/bin/eolian_mono/eolian/mono/documentation.hh
index 42fe9d24e1..f78c58a9d4 100644
--- a/src/bin/eolian_mono/eolian/mono/documentation.hh
+++ b/src/bin/eolian_mono/eolian/mono/documentation.hh
@@ -5,7 +5,7 @@
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/html_escaped_string.hpp" 6#include "grammar/html_escaped_string.hpp"
7#include "using_decl.hh" 7#include "using_decl.hh"
8#include "keyword.hh" 8#include "name_helpers.hh"
9 9
10#include <Eina.h> 10#include <Eina.h>
11 11
@@ -116,7 +116,7 @@ struct documentation_generator
116 template<typename OutputIterator, typename Context> 116 template<typename OutputIterator, typename Context>
117 bool generate_parameter(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 117 bool generate_parameter(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
118 { 118 {
119 return generate_tag_param(sink, escape_keyword(param.param_name), param.documentation.summary, context); 119 return generate_tag_param(sink, name_helpers::escape_keyword(param.param_name), param.documentation.summary, context);
120 } 120 }
121 121
122 template<typename OutputIterator, typename Context> 122 template<typename OutputIterator, typename Context>
diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
index d8bc54c175..da8505aedf 100644
--- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh
@@ -7,7 +7,7 @@
7#include "grammar/list.hpp" 7#include "grammar/list.hpp"
8#include "grammar/alternative.hpp" 8#include "grammar/alternative.hpp"
9#include "type.hh" 9#include "type.hh"
10#include "keyword.hh" 10#include "name_helpers.hh"
11#include "using_decl.hh" 11#include "using_decl.hh"
12 12
13namespace eolian_mono { 13namespace eolian_mono {
@@ -17,7 +17,7 @@ struct enum_definition_generator
17 template <typename OutputIterator, typename Context> 17 template <typename OutputIterator, typename Context>
18 bool generate(OutputIterator sink, attributes::enum_def const& enum_, Context const& context) const 18 bool generate(OutputIterator sink, attributes::enum_def const& enum_, Context const& context) const
19 { 19 {
20 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(enum_.namespaces)); 20 std::vector<std::string> cpp_namespaces = name_helpers::escape_namespace(attributes::cpp_namespaces(enum_.namespaces));
21 21
22 auto open_namespace = *("namespace " << string << " { ") << "\n"; 22 auto open_namespace = *("namespace " << string << " { ") << "\n";
23 if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false; 23 if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
new file mode 100644
index 0000000000..34aeab5fe0
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -0,0 +1,255 @@
1#ifndef EOLIAN_MONO_EVENTS_HH
2#define EOLINA_MONO_EVENTS_HH
3
4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp"
6#include "name_helpers.hh"
7#include "using_decl.hh"
8
9namespace eolian_mono {
10
11struct get_event_args_visitor
12{
13 std::string arg_type;
14
15 typedef get_event_args_visitor visitor_type;
16 typedef std::string result_type;
17 std::string operator()(grammar::attributes::regular_type_def const&) const
18 {
19 if (arg_type == "string")
20 return "eina.StringConversion.NativeUtf8ToManagedString(evt.Info)";
21 return "(" + arg_type + ")Marshal.PtrToStructure(evt.Info, typeof(" + arg_type + "))";
22 }
23 std::string operator()(grammar::attributes::klass_name const&) const
24 {
25 return "new " + arg_type + "Concrete(evt.Info)";
26 }
27 std::string operator()(attributes::complex_type_def const&) const
28 {
29 return "UNSUPPORTED";
30 }
31};
32
33struct event_argument_wrapper_generator
34{
35 template<typename OutputIterator, typename Context>
36 bool generate(OutputIterator sink, attributes::event_def const& evt, Context const& context) const
37 {
38 efl::eina::optional<grammar::attributes::type_def> etype = evt.type;
39 if (!etype.is_engaged())
40 return true;
41
42 std::string evt_name = name_helpers::managed_event_name(evt.name);
43 std::string arg_type = (*etype).original_type.visit(name_helpers::get_csharp_type_visitor{});
44
45 return as_generator("///<summary>Event argument wrapper for event " << evt_name << ".</summary>\n"
46 << "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
47 << scope_tab << "///<summary>Actual event payload.</summary>\n"
48 << scope_tab << "public " << arg_type << " arg { get; set; }\n"
49 << "}\n"
50 ).generate(sink, attributes::unused, context);
51 }
52} const event_argument_wrapper {};
53
54struct event_declaration_generator
55{
56 template<typename OutputIterator, typename Context>
57 bool generate(OutputIterator sink, attributes::event_def const& evt, Context const& context) const
58 {
59 std::string wrapper_args_type;
60 std::string evt_name = name_helpers::managed_event_name(evt.name);
61 std::string evt_args_name = name_helpers::managed_event_args_name(evt);
62
63 efl::eina::optional<grammar::attributes::type_def> etype = evt.type;
64 if (etype.is_engaged())
65 wrapper_args_type = "<" + evt_args_name + ">";
66
67 if (!as_generator(
68 documentation(1)
69 << scope_tab << "event EventHandler" << wrapper_args_type << " " << evt_name << ";\n"
70 ).generate(sink, evt, context))
71 return false;
72
73 return true;
74 }
75} const event_declaration {};
76
77struct event_registration_generator
78{
79 attributes::klass_def const* klass;
80 template<typename OutputIterator, typename Context>
81 bool generate(OutputIterator sink, attributes::event_def const& evt, Context const& context) const
82 {
83 std::string wrapper_event_name;
84
85 if (klass)
86 wrapper_event_name = name_helpers::translate_inherited_event_name(evt, *klass);
87 else
88 wrapper_event_name = name_helpers::managed_event_name(evt.name);
89
90 return as_generator(scope_tab << scope_tab << "evt_" << wrapper_event_name << "_delegate = "
91 << "new efl.Event_Cb(on_" << wrapper_event_name << "_NativeCallback);\n"
92 ).generate(sink, attributes::unused, context);
93 }
94};
95
96struct event_registration_parameterized
97{
98 event_registration_generator operator()(attributes::klass_def const* klass=NULL) const
99 {
100 return {klass};
101 }
102} const event_registration;
103
104struct event_definition_generator
105{
106 attributes::klass_def const& klass;
107 bool is_inherited_event;
108
109 template<typename OutputIterator, typename Context>
110 bool generate(OutputIterator sink, attributes::event_def const& evt, Context context) const
111 {
112 std::string managed_evt_name = name_helpers::managed_event_name(evt.name);
113
114 std::string wrapper_evt_name;
115 if (is_inherited_event)
116 wrapper_evt_name = name_helpers::translate_inherited_event_name(evt, klass);
117 else
118 wrapper_evt_name = managed_evt_name;
119
120 std::string klass_name;
121 if (is_inherited_event)
122 klass_name = name_helpers::klass_get_full_name(klass);
123 else
124 klass_name = klass.eolian_name;
125
126
127 std::string upper_c_name = utils::to_uppercase(evt.c_name);
128 std::string wrapper_args_type = "EventArgs";
129 std::string wrapper_args_template = "";
130 std::string event_args = "EventArgs args = EventArgs.Empty;\n";
131 std::string visibility = is_inherit_context(context) ? "protected" : "private";
132
133 efl::eina::optional<grammar::attributes::type_def> etype = evt.type;
134
135 if (etype.is_engaged())
136 {
137 wrapper_args_type = name_helpers::managed_event_args_name(evt);
138 wrapper_args_template = "<" + wrapper_args_type + ">";
139 std::string arg_type = wrapper_args_type + " args = new " + wrapper_args_type + "();\n"; // = (*etype).original_type.visit(get_csharp_type_visitor{});
140 std::string actual_arg_type = (*etype).original_type.visit(name_helpers::get_csharp_type_visitor{});
141 arg_type += " args.arg = " + (*etype).original_type.visit(get_event_args_visitor{actual_arg_type}) + ";\n";
142
143 event_args = arg_type;
144 }
145
146 // Wrapper event declaration
147 if(!as_generator(documentation(1)).generate(sink, evt, context))
148 return false;
149
150 if(!as_generator(
151 scope_tab << visibility << " event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << ";\n"
152 << scope_tab << "///<summary>Method to raise event "<< wrapper_evt_name << ".</summary>\n"
153 << scope_tab << visibility << " void On_" << wrapper_evt_name << "(" << wrapper_args_type << " e)\n"
154 << scope_tab << "{\n"
155 << scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n"
156 << scope_tab << scope_tab << "lock (eventLock) {\n"
157 << scope_tab << scope_tab << scope_tab << "evt = " << wrapper_evt_name << ";\n"
158 << scope_tab << scope_tab << "}\n"
159 << scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n"
160 << scope_tab << "}\n"
161 << scope_tab << "private void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n"
162 << scope_tab << "{\n"
163 << scope_tab << scope_tab << event_args
164 << scope_tab << scope_tab << "try {\n"
165 << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
166 << scope_tab << scope_tab << "} catch (Exception e) {\n"
167 << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n"
168 << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
169 << scope_tab << scope_tab << "}\n"
170 << scope_tab << "}\n"
171 << scope_tab << "efl.Event_Cb evt_" << wrapper_evt_name << "_delegate;\n"
172 << scope_tab << "event EventHandler" << wrapper_args_template << " " << klass_name << "." << managed_evt_name << "{\n")
173 .generate(sink, NULL, context))
174 return false;
175
176 if (!as_generator(
177 scope_tab << scope_tab << "add {\n"
178 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
179 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
180 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
181 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " += value;\n"
182 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
183 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
184 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
185 << scope_tab << scope_tab << "}\n"
186 << scope_tab << scope_tab << "remove {\n"
187 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
188 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
189 << scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
190 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " -= value;\n"
191 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
192 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
193 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
194 << scope_tab << scope_tab << "}\n"
195 << scope_tab << "}\n")
196 .generate(sink, NULL, context))
197 return false;
198
199 return true;
200 }
201};
202
203struct event_definition_parameterized
204{
205 event_definition_generator operator()(attributes::klass_def const& klass, bool is_inherited_event=false) const
206 {
207 return {klass, is_inherited_event};
208 }
209} const event_definition;
210
211}
212
213namespace efl { namespace eolian { namespace grammar {
214
215template <>
216struct is_eager_generator<struct ::eolian_mono::event_argument_wrapper_generator> : std::true_type {};
217template <>
218struct is_generator<struct ::eolian_mono::event_argument_wrapper_generator> : std::true_type {};
219
220template <>
221struct is_eager_generator<struct ::eolian_mono::event_declaration_generator> : std::true_type {};
222template <>
223struct is_generator<struct ::eolian_mono::event_declaration_generator> : std::true_type {};
224
225template <>
226struct is_eager_generator<struct ::eolian_mono::event_registration_generator> : std::true_type {};
227template <>
228struct is_generator<struct ::eolian_mono::event_registration_generator> : std::true_type {};
229template <>
230struct is_generator<struct ::eolian_mono::event_registration_parameterized> : std::true_type {};
231
232template <>
233struct is_eager_generator<struct ::eolian_mono::event_definition_generator> : std::true_type {};
234template <>
235struct is_generator<struct ::eolian_mono::event_definition_generator> : std::true_type {};
236template <>
237struct is_generator<struct ::eolian_mono::event_definition_parameterized> : std::true_type {};
238
239namespace type_traits {
240template <>
241struct attributes_needed<struct ::eolian_mono::event_argument_wrapper_generator> : std::integral_constant<int, 1> {};
242template <>
243struct attributes_needed<struct ::eolian_mono::event_declaration_generator> : std::integral_constant<int, 1> {};
244template <>
245struct attributes_needed<struct ::eolian_mono::event_registration_generator> : std::integral_constant<int, 1> {};
246template <>
247struct attributes_needed<struct ::eolian_mono::event_registration_parameterized> : std::integral_constant<int, 1> {};
248template <>
249struct attributes_needed<struct ::eolian_mono::event_definition_generator> : std::integral_constant<int, 1> {};
250template <>
251struct attributes_needed<struct ::eolian_mono::event_definition_parameterized> : std::integral_constant<int, 1> {};
252}
253} } }
254
255#endif
diff --git a/src/bin/eolian_mono/eolian/mono/function_declaration.hh b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
index 1d6a1b2f0e..80a2782bf4 100644
--- a/src/bin/eolian_mono/eolian/mono/function_declaration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_declaration.hh
@@ -9,7 +9,7 @@
9#include "grammar/alternative.hpp" 9#include "grammar/alternative.hpp"
10#include "type.hh" 10#include "type.hh"
11#include "parameter.hh" 11#include "parameter.hh"
12#include "keyword.hh" 12#include "name_helpers.hh"
13#include "using_decl.hh" 13#include "using_decl.hh"
14#include "blacklist.hh" 14#include "blacklist.hh"
15 15
@@ -28,7 +28,7 @@ struct function_declaration_generator
28 28
29 return as_generator 29 return as_generator
30 (eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n") 30 (eolian_mono::type(true) << " " << string << "(" << (parameter % ", ") << ");\n")
31 .generate(sink, std::make_tuple(f.return_type, managed_method_name(f.name), f.parameters), context); 31 .generate(sink, std::make_tuple(f.return_type, name_helpers::managed_method_name(f.name), f.parameters), context);
32 } 32 }
33}; 33};
34 34
diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh
index 14c70791f6..bf7d15e36a 100644
--- a/src/bin/eolian_mono/eolian/mono/function_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh
@@ -16,7 +16,6 @@
16#include "function_helpers.hh" 16#include "function_helpers.hh"
17#include "marshall_type.hh" 17#include "marshall_type.hh"
18#include "parameter.hh" 18#include "parameter.hh"
19#include "keyword.hh"
20#include "documentation.hh" 19#include "documentation.hh"
21#include "using_decl.hh" 20#include "using_decl.hh"
22#include "generation_contexts.hh" 21#include "generation_contexts.hh"
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 2c0c193c33..44c7458fcc 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -31,7 +31,7 @@ struct function_pointer {
31 bool generate(OutputIterator sink, attributes::function_def const& f, std::vector<std::string> const &namesp, Context const& context) const 31 bool generate(OutputIterator sink, attributes::function_def const& f, std::vector<std::string> const &namesp, Context const& context) const
32 { 32 {
33 // FIXME export Typedecl in eolian_cxx API 33 // FIXME export Typedecl in eolian_cxx API
34 std::vector<std::string> namespaces = escape_namespace(namesp); 34 std::vector<std::string> namespaces = name_helpers::escape_namespace(namesp);
35 auto funcptr_ctx = context_add_tag(class_context{class_context::function_ptr}, context); 35 auto funcptr_ctx = context_add_tag(class_context{class_context::function_ptr}, context);
36 36
37 std::string return_type; 37 std::string return_type;
@@ -48,16 +48,16 @@ struct function_pointer {
48 if (!as_generator(documentation 48 if (!as_generator(documentation
49 << "public delegate " << type << " " << string 49 << "public delegate " << type << " " << string
50 << "(" << (parameter % ", ") << ");\n") 50 << "(" << (parameter % ", ") << ");\n")
51 .generate(sink, std::make_tuple(f, f.return_type, escape_keyword(f.name), f.parameters), funcptr_ctx)) 51 .generate(sink, std::make_tuple(f, f.return_type, name_helpers::escape_keyword(f.name), f.parameters), funcptr_ctx))
52 return false; 52 return false;
53 // "Internal" delegate, 1-to-1 with the Unamaged function type 53 // "Internal" delegate, 1-to-1 with the Unamaged function type
54 if (!as_generator(marshall_native_annotation(true) 54 if (!as_generator(marshall_native_annotation(true)
55 << "internal delegate " << marshall_type(true) << " " << string // public? 55 << "internal delegate " << marshall_type(true) << " " << string // public?
56 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n") 56 << "Internal(IntPtr data" << *grammar::attribute_reorder<-1, -1>((", " << marshall_native_annotation << " " << marshall_parameter)) << ");\n")
57 .generate(sink, std::make_tuple(f.return_type, f.return_type, escape_keyword(f.name), f.parameters), funcptr_ctx)) 57 .generate(sink, std::make_tuple(f.return_type, f.return_type, name_helpers::escape_keyword(f.name), f.parameters), funcptr_ctx))
58 return false; 58 return false;
59 59
60 std::string f_name = escape_keyword(f.name); 60 std::string f_name = name_helpers::escape_keyword(f.name);
61 // Wrapper type, with callback matching the Unamanaged one 61 // Wrapper type, with callback matching the Unamanaged one
62 if (!as_generator("internal class " << f_name << "Wrapper\n" 62 if (!as_generator("internal class " << f_name << "Wrapper\n"
63 << "{\n\n" 63 << "{\n\n"
diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh
index 26f8f1b4c8..a653a3d98c 100644
--- a/src/bin/eolian_mono/eolian/mono/function_registration.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh
@@ -13,7 +13,6 @@
13#include "type.hh" 13#include "type.hh"
14#include "marshall_type.hh" 14#include "marshall_type.hh"
15#include "parameter.hh" 15#include "parameter.hh"
16#include "keyword.hh"
17#include "using_decl.hh" 16#include "using_decl.hh"
18#include "generation_contexts.hh" 17#include "generation_contexts.hh"
19#include "blacklist.hh" 18#include "blacklist.hh"
diff --git a/src/bin/eolian_mono/eolian/mono/keyword.hh b/src/bin/eolian_mono/eolian/mono/keyword.hh
deleted file mode 100644
index e73db31ec8..0000000000
--- a/src/bin/eolian_mono/eolian/mono/keyword.hh
+++ /dev/null
@@ -1,51 +0,0 @@
1#ifndef EOLIAN_CXX_KEYWORD_HH
2#define EOLIAN_CXX_KEYWORD_HH
3
4#include <string>
5#include <strings.h>
6#include <vector>
7
8#include "name_helpers.hh"
9
10namespace eolian_mono {
11namespace detail {
12inline bool is_iequal(std::string const& lhs, std::string const& rhs)
13{
14 return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
15}
16}
17
18inline std::string escape_keyword(std::string const& name)
19{
20 using detail::is_iequal;
21 if(is_iequal(name, "delete")
22 || is_iequal(name, "do")
23 || is_iequal(name, "lock")
24 || is_iequal(name, "event")
25 || is_iequal(name, "in")
26 || is_iequal(name, "object")
27 || is_iequal(name, "interface")
28 || is_iequal(name, "string")
29 || is_iequal(name, "internal")
30 || is_iequal(name, "fixed")
31 || is_iequal(name, "base"))
32 return "kw_" + name;
33
34 if (is_iequal(name, "Finalize"))
35 return name + "Add"; // Eo's Finalize is actually the end of efl_add.
36 return name;
37}
38
39
40std::string managed_method_name(std::string const& underscore_name)
41{
42 std::vector<std::string> names = utils::split(underscore_name, '_');
43
44 name_helpers::reorder_verb(names);
45
46 return escape_keyword(utils::to_pascal_case(names));
47}
48
49}
50
51#endif
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 280819b60d..cc347b7765 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -10,12 +10,13 @@
10#include "grammar/list.hpp" 10#include "grammar/list.hpp"
11#include "grammar/alternative.hpp" 11#include "grammar/alternative.hpp"
12#include "type.hh" 12#include "type.hh"
13#include "namespace.hh" 13#include "name_helpers.hh"
14#include "function_definition.hh" 14#include "function_definition.hh"
15#include "function_registration.hh" 15#include "function_registration.hh"
16#include "function_declaration.hh" 16#include "function_declaration.hh"
17#include "documentation.hh" 17#include "documentation.hh"
18#include "part_definition.hh" 18#include "part_definition.hh"
19#include "events.hh"
19#include "grammar/string.hpp" 20#include "grammar/string.hpp"
20#include "grammar/attribute_replace.hpp" 21#include "grammar/attribute_replace.hpp"
21#include "grammar/integral.hpp" 22#include "grammar/integral.hpp"
@@ -85,59 +86,6 @@ is_inherit_context(Context const& context)
85 return context_find_tag<class_context>(context).current_wrapper_kind == class_context::inherit; 86 return context_find_tag<class_context>(context).current_wrapper_kind == class_context::inherit;
86} 87}
87 88
88struct get_csharp_type_visitor
89{
90 typedef get_csharp_type_visitor visitor_type;
91 typedef std::string result_type;
92 std::string operator()(grammar::attributes::regular_type_def const& type) const
93 {
94 std::stringstream csharp_name;
95 for (auto&& i : escape_namespace(type.namespaces))
96 csharp_name << utils::to_lowercase(i) << ".";
97 csharp_name << type.base_type;
98
99 return csharp_name.str();
100 }
101 std::string operator()(grammar::attributes::klass_name const& name) const
102 {
103 std::stringstream csharp_name;
104 for (auto&& i : escape_namespace(name.namespaces))
105 csharp_name << utils::to_lowercase(i) << ".";
106 csharp_name << name.eolian_name;
107
108 return csharp_name.str();
109 }
110 std::string operator()(attributes::complex_type_def const&) const
111 {
112 return "UNSUPPORTED";
113 }
114};
115
116struct get_event_args_visitor
117{
118
119 std::string arg_type;
120
121 typedef get_event_args_visitor visitor_type;
122 typedef std::string result_type;
123 std::string operator()(grammar::attributes::regular_type_def const&) const
124 {
125 if (arg_type == "string")
126 {
127 return "eina.StringConversion.NativeUtf8ToManagedString(evt.Info)";
128 }
129 return "(" + arg_type + ")Marshal.PtrToStructure(evt.Info, typeof(" + arg_type + "))";
130 }
131 std::string operator()(grammar::attributes::klass_name const&) const
132 {
133 return "new " + arg_type + "Concrete(evt.Info)";
134 }
135 std::string operator()(attributes::complex_type_def const&) const
136 {
137 return "UNSUPPORTED";
138 }
139};
140
141struct klass 89struct klass
142{ 90{
143 template <typename OutputIterator, typename Context> 91 template <typename OutputIterator, typename Context>
@@ -161,32 +109,11 @@ struct klass
161 break; 109 break;
162 } 110 }
163 111
164 std::vector<std::string> namespaces = escape_namespace(cls.namespaces); 112 std::vector<std::string> namespaces = name_helpers::escape_namespace(cls.namespaces);
165 auto open_namespace = *("namespace " << string << " { ") << "\n"; 113 auto open_namespace = *("namespace " << string << " { ") << "\n";
166 if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false; 114 if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false;
167 auto methods = cls.get_all_methods(); 115 auto methods = cls.get_all_methods();
168 116
169 // FIXME Generate local event argument wrappers
170 for (auto&& e : cls.events)
171 {
172 efl::eina::optional<grammar::attributes::type_def> etype = e.type;
173 if (!etype.is_engaged())
174 continue;
175
176 std::string evt_name = name_helpers::managed_event_name(e.name);
177 std::string arg_type = (*etype).original_type.visit(get_csharp_type_visitor{});
178
179 if (!as_generator("///<summary>Event argument wrapper for event " << string << ".</summary>\n"
180 ).generate(sink, evt_name, context))
181 return false;
182
183 if (!as_generator("public class " << evt_name << "_Args : EventArgs {\n"
184 << scope_tab << "///<summary>Actual event payload.</summary>\n"
185 << scope_tab << "public " << arg_type << " arg { get; set; }\n"
186 << "}\n").generate(sink, NULL, context))
187 return false;
188 }
189
190 // Interface class 117 // Interface class
191 { 118 {
192 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context); 119 auto iface_cxt = context_add_tag(class_context{class_context::interface}, context);
@@ -204,7 +131,7 @@ struct klass
204 , last = std::end(cls.immediate_inherits); first != last; ++first) 131 , last = std::end(cls.immediate_inherits); first != last; ++first)
205 { 132 {
206 if(!as_generator("\n" << scope_tab << *(lower_case[string] << ".") << string << " ,") 133 if(!as_generator("\n" << scope_tab << *(lower_case[string] << ".") << string << " ,")
207 .generate(sink, std::make_tuple(escape_namespace(first->namespaces), first->eolian_name), iface_cxt)) 134 .generate(sink, std::make_tuple(name_helpers::escape_namespace(first->namespaces), first->eolian_name), iface_cxt))
208 return false; 135 return false;
209 // if(std::next(first) != last) 136 // if(std::next(first) != last)
210 // *sink++ = ','; 137 // *sink++ = ',';
@@ -216,28 +143,8 @@ struct klass
216 if(!as_generator(*(scope_tab << function_declaration)) 143 if(!as_generator(*(scope_tab << function_declaration))
217 .generate(sink, cls.functions, iface_cxt)) return false; 144 .generate(sink, cls.functions, iface_cxt)) return false;
218 145
219 // FIXME Move the event generator into another generator like function? 146 if (!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt))
220 for (auto &&e : cls.events) 147 return false;
221 {
222 std::string wrapper_args_type;
223 std::string evt_name = name_helpers::managed_event_name(e.name);
224 std::replace(evt_name.begin(), evt_name.end(), ',', '_');
225
226 efl::eina::optional<grammar::attributes::type_def> etype = e.type;
227 if (etype.is_engaged())
228 wrapper_args_type = "<" + evt_name + "_Args>";
229
230
231 if (!as_generator(documentation(1)).generate(sink, e, iface_cxt))
232 return false;
233
234 //FIXME Add a way to generate camelcase names
235 if (!as_generator(
236 scope_tab << "event EventHandler" << wrapper_args_type << " "
237 << evt_name << ";\n"
238 ).generate(sink, NULL, iface_cxt))
239 return false;
240 }
241 148
242 for (auto &&p : cls.parts) 149 for (auto &&p : cls.parts)
243 if (!as_generator( 150 if (!as_generator(
@@ -346,6 +253,9 @@ struct klass
346 if(!as_generator(*(function_definition)) 253 if(!as_generator(*(function_definition))
347 .generate(sink, methods, concrete_cxt)) return false; 254 .generate(sink, methods, concrete_cxt)) return false;
348 255
256 if(!as_generator(*(event_argument_wrapper)).generate(sink, cls.events, context))
257 return false;
258
349 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; 259 if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
350 } 260 }
351 261
@@ -527,29 +437,16 @@ struct klass
527 // Generate event registrations here 437 // Generate event registrations here
528 438
529 // Assigning the delegates 439 // Assigning the delegates
530 for (auto&& e : cls.events) 440 if (!as_generator(*(event_registration())).generate(sink, cls.events, context))
531 { 441 return false;
532 if (!as_generator(scope_tab << scope_tab << "evt_" << grammar::string_replace(',', '_') << "_delegate = "
533 << "new efl.Event_Cb(on_" << grammar::string_replace(',', '_') << "_NativeCallback);\n")
534 .generate(sink, std::make_tuple(e.name, e.name), context))
535 return false;
536 }
537 442
538 for (auto&& c : cls.inherits) 443 for (auto&& c : cls.inherits)
539 { 444 {
540 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit); 445 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit);
541 446
542 for (auto&& e : klass.events) 447 if (!as_generator(*(event_registration(&klass))).generate(sink, klass.events, context))
543 { 448 return false;
544 std::string wrapper_event_name = translate_inherited_event_name(e, klass);
545
546 if (!as_generator(scope_tab << scope_tab << "evt_" << wrapper_event_name << "_delegate = "
547 << "new efl.Event_Cb(on_" << wrapper_event_name << "_NativeCallback);\n")
548 .generate(sink, NULL, context))
549 return false;
550 }
551 } 449 }
552
553 450
554 if (!as_generator( 451 if (!as_generator(
555 scope_tab << "}\n" 452 scope_tab << "}\n"
@@ -559,19 +456,6 @@ struct klass
559 return true; 456 return true;
560 } 457 }
561 458
562 static std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass)
563 {
564 std::stringstream s;
565
566 for (auto&& n : klass.namespaces)
567 {
568 s << n;
569 s << '_';
570 }
571 s << klass.cxx_name << '_' << name_helpers::managed_event_name(evt.name);
572 return s.str();
573 }
574
575 template <typename OutputIterator, typename Context> 459 template <typename OutputIterator, typename Context>
576 bool generate_events(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const 460 bool generate_events(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
577 { 461 {
@@ -628,171 +512,15 @@ struct klass
628 return false; 512 return false;
629 513
630 // Self events 514 // Self events
631 for (auto&& e : cls.events) 515 if (!as_generator(*(event_definition(cls))).generate(sink, cls.events, context))
632 { 516 return false;
633 std::string upper_name = name_helpers::managed_event_name(e.name);
634 std::string upper_c_name = utils::to_uppercase(e.c_name);
635 std::string event_name = e.name;
636 std::replace(event_name.begin(), event_name.end(), ',', '_');
637
638 std::string wrapper_args_type = "EventArgs";
639 std::string wrapper_args_template = "";
640 std::string event_args = "EventArgs args = EventArgs.Empty;\n";
641
642 efl::eina::optional<grammar::attributes::type_def> etype = e.type;
643 if (etype.is_engaged())
644 {
645 wrapper_args_type = upper_name + "_Args";
646 wrapper_args_template = "<" + wrapper_args_type + ">";
647 std::string arg_type = wrapper_args_type + " args = new " + wrapper_args_type + "();\n"; // = (*etype).original_type.visit(get_csharp_type_visitor{});
648 std::string actual_arg_type = (*etype).original_type.visit(get_csharp_type_visitor{});
649 arg_type += "args.arg = " + (*etype).original_type.visit(get_event_args_visitor{actual_arg_type}) + ";\n";
650
651 event_args = arg_type;
652 }
653 // Marshal.PtrToStructure for value types
654
655 // Wrapper event declaration
656 if(!as_generator(documentation(1)).generate(sink, e, context))
657 return false;
658
659 if(!as_generator(
660 scope_tab << visibility << " event EventHandler" << wrapper_args_template << " " << upper_name << ";\n"
661 << scope_tab << "///<summary>Method to raise event "<< event_name << ".</summary>\n"
662 << scope_tab << visibility << " void On_" << event_name << "(" << wrapper_args_type << " e)\n"
663 << scope_tab << "{\n"
664 << scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n"
665 << scope_tab << scope_tab << "lock (eventLock) {\n"
666 << scope_tab << scope_tab << scope_tab << "evt = " << upper_name << ";\n"
667 << scope_tab << scope_tab << "}\n"
668 << scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n"
669 << scope_tab << "}\n"
670 << scope_tab << "private void on_" << event_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n"
671 << scope_tab << "{\n"
672 << scope_tab << scope_tab << event_args
673 << scope_tab << scope_tab << "try {\n"
674 << scope_tab << scope_tab << scope_tab << "On_" << event_name << "(args);\n"
675 << scope_tab << scope_tab << "} catch (Exception e) {\n"
676 << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n"
677 << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
678 << scope_tab << scope_tab << "}\n"
679 << scope_tab << "}\n"
680 << scope_tab << "efl.Event_Cb evt_" << event_name << "_delegate;\n"
681 << scope_tab << "event EventHandler" << wrapper_args_template << " " << cls.cxx_name << "." << upper_name << "{\n")
682 .generate(sink, NULL, context))
683 return false;
684
685 if (!as_generator(
686 scope_tab << scope_tab << "add {\n"
687 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
688 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
689 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << event_name << "_delegate))\n"
690 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << upper_name << " += value;\n"
691 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
692 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
693 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
694 << scope_tab << scope_tab << "}\n"
695 << scope_tab << scope_tab << "remove {\n"
696 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
697 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
698 << scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << event_name << "_delegate))\n"
699 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << upper_name << " -= value;\n"
700 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
701 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
702 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
703 << scope_tab << scope_tab << "}\n"
704 << scope_tab << "}\n")
705 .generate(sink, NULL, context))
706 return false;
707 }
708 517
709 // Inherited events 518 // Inherited events
710 for (auto&& c : cls.inherits) 519 for (auto&& c : cls.inherits)
711 { 520 {
712 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit); 521 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit);
713 522 if (!as_generator(*(event_definition(klass, true))).generate(sink, klass.events, context))
714 // FIXME Enable inherited events registration. Beware of conflicting events 523 return false;
715 for (auto&& e : klass.events)
716 {
717
718 std::string wrapper_evt_name = translate_inherited_event_name(e, klass);
719 std::string upper_name = name_helpers::managed_event_name(e.name);
720 std::string upper_c_name = utils::to_uppercase(e.c_name);
721
722 std::stringstream wrapper_args_type;
723 std::string wrapper_args_template;
724 std::string event_args = "EventArgs args = EventArgs.Empty;\n";
725
726 efl::eina::optional<grammar::attributes::type_def> etype = e.type;
727 if (etype.is_engaged())
728 {
729 for (auto&& i : klass.namespaces)
730 {
731 wrapper_args_type << escape_keyword(utils::to_lowercase(i)) << ".";
732 }
733 wrapper_args_type << upper_name << "_Args";
734 wrapper_args_template = "<" + wrapper_args_type.str() + ">";
735 std::string arg_type = wrapper_args_type.str() + " args = new " + wrapper_args_type.str() + "();\n"; // = (*etype).original_type.visit(get_csharp_type_visitor{});
736 std::string actual_arg_type = (*etype).original_type.visit(get_csharp_type_visitor{});
737 arg_type += "args.arg = " + (*etype).original_type.visit(get_event_args_visitor{actual_arg_type}) + ";\n";
738 event_args = arg_type;
739 }
740 else
741 {
742 wrapper_args_type << "EventArgs";
743 }
744
745 if (!as_generator(documentation(1)).generate(sink, e, context))
746 return false;
747
748 if (!as_generator(
749 scope_tab << visibility << " event EventHandler" << wrapper_args_template << " " << wrapper_evt_name << ";\n"
750 << scope_tab << "///<summary>Method to raise event "<< wrapper_evt_name << ".</summary>\n"
751 << scope_tab << visibility << " void On_" << wrapper_evt_name << "(" << wrapper_args_type.str() << " e)\n"
752 << scope_tab << "{\n"
753 << scope_tab << scope_tab << "EventHandler" << wrapper_args_template << " evt;\n"
754 << scope_tab << scope_tab << "lock (eventLock) {\n"
755 << scope_tab << scope_tab << scope_tab << "evt = " << wrapper_evt_name << ";\n"
756 << scope_tab << scope_tab << "}\n"
757 << scope_tab << scope_tab << "if (evt != null) { evt(this, e); }\n"
758 << scope_tab << "}\n"
759 << scope_tab << "efl.Event_Cb evt_" << wrapper_evt_name << "_delegate;\n"
760 << scope_tab << "private void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)"
761 << scope_tab << "{\n"
762 << scope_tab << scope_tab << event_args
763 << scope_tab << scope_tab << "try {\n"
764 << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n"
765 << scope_tab << scope_tab << "} catch (Exception e) {\n"
766 << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.ToString());\n"
767 << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n"
768 << scope_tab << scope_tab << "}\n"
769 << scope_tab << "}\n"
770 << scope_tab << "event EventHandler" << wrapper_args_template << " " << *(lower_case[string] << ".") << klass.cxx_name << ".")
771 .generate(sink, escape_namespace(klass.namespaces), context))
772 return false;
773 if (!as_generator(upper_name << " {\n"
774 << scope_tab << scope_tab << "add {\n"
775 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
776 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
777 << scope_tab << scope_tab << scope_tab << scope_tab << "if (add_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
778 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " += value;\n"
779 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
780 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error adding proxy for event {key}\");\n"
781 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
782 << scope_tab << scope_tab << "}\n"
783 << scope_tab << scope_tab << "remove {\n"
784 << scope_tab << scope_tab << scope_tab << "lock (eventLock) {\n"
785 << scope_tab << scope_tab << scope_tab << scope_tab << "string key = \"_" << upper_c_name << "\";\n"
786 << scope_tab << scope_tab << scope_tab << scope_tab << "if (remove_cpp_event_handler(key, this.evt_" << wrapper_evt_name << "_delegate))\n"
787 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << wrapper_evt_name << " -= value;\n"
788 << scope_tab << scope_tab << scope_tab << scope_tab << "else\n"
789 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error($\"Error removing proxy for event {key}\");\n"
790 << scope_tab << scope_tab << scope_tab << "}\n" // End of lock block
791 << scope_tab << scope_tab << "}\n"
792 << scope_tab << "}\n")
793 .generate(sink, NULL, context))
794 return false;
795 }
796 } 524 }
797 return true; 525 return true;
798 } 526 }
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index f521a79840..4516b97453 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -4,7 +4,7 @@
4#include "grammar/generator.hpp" 4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp" 6#include "grammar/case.hpp"
7#include "namespace.hh" 7#include "name_helpers.hh"
8#include "type_impl.hh" 8#include "type_impl.hh"
9 9
10namespace eolian_mono { 10namespace eolian_mono {
@@ -144,7 +144,7 @@ struct marshall_annotation_visitor_generate
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 std::vector<std::string> namespaces = escape_namespace(klass_name.namespaces); 147 std::vector<std::string> namespaces = name_helpers::escape_namespace(klass_name.namespaces);
148 return as_generator 148 return as_generator
149 ((is_return ? return_prefix : no_return_prefix) 149 ((is_return ? return_prefix : no_return_prefix)
150 << *(lower_case[string] << ".") << string 150 << *(lower_case[string] << ".") << string
@@ -251,7 +251,7 @@ struct marshall_native_annotation_visitor_generate
251 { 251 {
252 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 252 const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<";
253 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; 253 const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<";
254 std::vector<std::string> namespaces = escape_namespace(klass_name.namespaces); 254 std::vector<std::string> namespaces = name_helpers::escape_namespace(klass_name.namespaces);
255 return as_generator 255 return as_generator
256 ((is_return ? return_prefix : no_return_prefix) 256 ((is_return ? return_prefix : no_return_prefix)
257 << *(lower_case[string] << ".") << string 257 << *(lower_case[string] << ".") << string
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 2bf8212eee..ee9659c6b1 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -5,7 +5,7 @@
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp" 6#include "grammar/case.hpp"
7#include "helpers.hh" 7#include "helpers.hh"
8#include "namespace.hh" 8#include "name_helpers.hh"
9#include "type_impl.hh" 9#include "type_impl.hh"
10#include "generation_contexts.hh" 10#include "generation_contexts.hh"
11#include "blacklist.hh" 11#include "blacklist.hh"
@@ -161,7 +161,7 @@ struct marshall_type_visitor_generate
161 if ((is_out || is_return) && is_ptr) 161 if ((is_out || is_return) && is_ptr)
162 return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); 162 return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
163 return as_generator(*(lower_case[string] << ".") << string << "_StructInternal") 163 return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
164 .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context); 164 .generate(sink, std::make_tuple(name_helpers::escape_namespace(regular.namespaces), regular.base_type), *context);
165 } 165 }
166 else if (eina::optional<bool> b = call_match 166 else if (eina::optional<bool> b = call_match
167 (match_table 167 (match_table
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index 3747b92356..4dffb9893a 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -9,6 +9,8 @@
9#include <vector> 9#include <vector>
10#include "utils.hh" 10#include "utils.hh"
11 11
12#include "grammar/integral.hpp"
13#include "grammar/generator.hpp"
12#include "grammar/klass_def.hpp" 14#include "grammar/klass_def.hpp"
13 15
14namespace eolian_mono { 16namespace eolian_mono {
@@ -21,6 +23,62 @@ namespace name_helpers {
21 23
22namespace attributes = efl::eolian::grammar::attributes; 24namespace attributes = efl::eolian::grammar::attributes;
23 25
26namespace detail {
27inline bool is_iequal(std::string const& lhs, std::string const& rhs)
28{
29 return strcasecmp(lhs.c_str(), rhs.c_str()) == 0;
30}
31}
32
33inline std::string escape_keyword(std::string const& name)
34{
35 using detail::is_iequal;
36 if(is_iequal(name, "delete")
37 || is_iequal(name, "do")
38 || is_iequal(name, "lock")
39 || is_iequal(name, "event")
40 || is_iequal(name, "in")
41 || is_iequal(name, "object")
42 || is_iequal(name, "interface")
43 || is_iequal(name, "string")
44 || is_iequal(name, "internal")
45 || is_iequal(name, "fixed")
46 || is_iequal(name, "base"))
47 return "kw_" + name;
48
49 if (is_iequal(name, "Finalize"))
50 return name + "Add"; // Eo's Finalize is actually the end of efl_add.
51 return name;
52}
53
54inline std::vector<std::string> escape_namespace(std::vector<std::string> namespaces)
55{
56 // if(namespaces.empty())
57 // namespaces.push_back("nonamespace");
58 // else
59 {
60 for(auto&& i : namespaces)
61 i = escape_keyword(i);
62 }
63 return namespaces;
64}
65
66inline std::string get_namespaces(std::vector<std::string> const& namespaces, char separator,
67 std::function<std::string(std::string const&)> func=[] (std::string const& c) { return c; })
68{
69 std::stringstream s;
70 for (auto&& n : namespaces)
71 s << func(n) << separator;
72
73 return s.str();
74}
75
76inline std::string get_namespaces(attributes::klass_def const& klass, char separator,
77 std::function<std::string(std::string const&)> func=[] (std::string const& c) { return c; })
78{
79 return get_namespaces(klass.namespaces, separator, func);
80}
81
24static const std::vector<std::string> verbs = 82static const std::vector<std::string> verbs =
25 { 83 {
26 "add", 84 "add",
@@ -112,11 +170,56 @@ void reorder_verb(std::vector<std::string> &names)
112 } 170 }
113} 171}
114 172
173inline std::string klass_name_to_csharp(attributes::klass_name const& clsname)
174{
175 std::ostringstream output;
176
177 for (auto namesp : clsname.namespaces)
178 output << utils::to_lowercase(namesp) << ".";
179
180 output << clsname.eolian_name;
181
182 return output.str();
183}
184
185inline std::string managed_method_name(std::string const& underscore_name)
186{
187 std::vector<std::string> names = utils::split(underscore_name, '_');
188
189 name_helpers::reorder_verb(names);
190
191 return escape_keyword(utils::to_pascal_case(names));
192}
193
115inline std::string managed_event_name(std::string const& name) 194inline std::string managed_event_name(std::string const& name)
116{ 195{
117 return utils::to_pascal_case(utils::split(name, ','), "") + "Evt"; 196 return utils::to_pascal_case(utils::split(name, ','), "") + "Evt";
118} 197}
119 198
199inline std::string managed_event_args_short_name(attributes::event_def evt)
200{
201 return name_helpers::managed_event_name(evt.name) + "_Args";
202}
203
204inline std::string managed_event_args_name(attributes::event_def evt)
205{
206 std::string prefix = name_helpers::klass_name_to_csharp(evt.klass);
207 return prefix + "Concrete." + managed_event_args_short_name(evt);
208}
209
210inline std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass)
211{
212 std::stringstream s;
213
214 for (auto&& n : klass.namespaces)
215 {
216 s << n;
217 s << '_';
218 }
219 s << klass.cxx_name << '_' << managed_event_name(evt.name);
220 return s.str();
221}
222
120inline std::string type_full_name(attributes::regular_type_def const& type) 223inline std::string type_full_name(attributes::regular_type_def const& type)
121{ 224{
122 std::string full_name; 225 std::string full_name;
@@ -144,14 +247,14 @@ inline std::string to_field_name(std::string const& in)
144 return utils::capitalize(in); 247 return utils::capitalize(in);
145} 248}
146 249
147inline std::string klass_name_to_csharp(attributes::klass_name const& clsname) 250inline std::string klass_get_full_name(attributes::klass_def const& klass)
148{ 251{
149 std::ostringstream output; 252 std::ostringstream output;
150 253
151 for (auto namesp : clsname.namespaces) 254 for(auto namesp : klass.namespaces)
152 output << utils::to_lowercase(namesp) << "."; 255 output << utils::to_lowercase(escape_keyword(namesp)) << ".";
153 256
154 output << clsname.eolian_name; 257 output << klass.eolian_name;
155 258
156 return output.str(); 259 return output.str();
157} 260}
@@ -171,6 +274,36 @@ inline std::string klass_get_name(attributes::klass_name const &clsname)
171 return output.str(); 274 return output.str();
172} 275}
173 276
277struct get_csharp_type_visitor
278{
279 typedef get_csharp_type_visitor visitor_type;
280 typedef std::string result_type;
281 std::string operator()(attributes::regular_type_def const& type) const
282 {
283 std::stringstream csharp_name;
284 for (auto&& i : escape_namespace(type.namespaces))
285 csharp_name << utils::to_lowercase(i) << ".";
286 csharp_name << type.base_type;
287
288 return csharp_name.str();
289 }
290 std::string operator()(attributes::klass_name const& name) const
291 {
292 std::stringstream csharp_name;
293 for (auto&& i : escape_namespace(name.namespaces))
294 csharp_name << utils::to_lowercase(i) << ".";
295 csharp_name << name.eolian_name;
296
297 return csharp_name.str();
298 }
299 std::string operator()(attributes::complex_type_def const&) const
300 {
301 return "UNSUPPORTED";
302 }
303};
304
305
306
174} // namespace name_helpers 307} // namespace name_helpers
175 308
176} // namespace eolian_mono 309} // namespace eolian_mono
diff --git a/src/bin/eolian_mono/eolian/mono/namespace.hh b/src/bin/eolian_mono/eolian/mono/namespace.hh
deleted file mode 100644
index b0f1ddb0b3..0000000000
--- a/src/bin/eolian_mono/eolian/mono/namespace.hh
+++ /dev/null
@@ -1,27 +0,0 @@
1#ifndef EOLIAN_MONO_NAMESPACE_HH
2#define EOLIAN_MONO_NAMESPACE_HH
3
4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp"
7#include "grammar/type.hpp"
8#include "using_decl.hh"
9#include "keyword.hh"
10
11namespace eolian_mono {
12
13std::vector<std::string> escape_namespace(std::vector<std::string> namespaces)
14{
15 // if(namespaces.empty())
16 // namespaces.push_back("nonamespace");
17 // else
18 {
19 for(auto&& i : namespaces)
20 i = escape_keyword(i);
21 }
22 return namespaces;
23}
24
25}
26
27#endif
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index 8ee330ee00..2cf472c12d 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -8,8 +8,9 @@
8#include "marshall_type.hh" 8#include "marshall_type.hh"
9#include "type.hh" 9#include "type.hh"
10#include "using_decl.hh" 10#include "using_decl.hh"
11#include "keyword.hh" 11#include "name_helpers.hh"
12 12
13using namespace eolian_mono::name_helpers;
13 14
14namespace eolian_mono { 15namespace eolian_mono {
15 struct parameter_generator; 16 struct parameter_generator;
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 9ff47de51d..ab5db8f180 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -9,7 +9,6 @@
9#include "name_helpers.hh" 9#include "name_helpers.hh"
10#include "helpers.hh" 10#include "helpers.hh"
11#include "type.hh" 11#include "type.hh"
12#include "keyword.hh"
13#include "using_decl.hh" 12#include "using_decl.hh"
14#include "documentation.hh" 13#include "documentation.hh"
15#include "struct_fields.hh" 14#include "struct_fields.hh"
@@ -444,7 +443,7 @@ struct struct_entities_generator
444 if (blacklist::is_struct_blacklisted(struct_)) 443 if (blacklist::is_struct_blacklisted(struct_))
445 return true; 444 return true;
446 445
447 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces)); 446 std::vector<std::string> cpp_namespaces = name_helpers::escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
448 447
449 auto open_namespace = *("namespace " << string << " { ") << "\n"; 448 auto open_namespace = *("namespace " << string << " { ") << "\n";
450 if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) 449 if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context)))
diff --git a/src/bin/eolian_mono/eolian/mono/struct_fields.hh b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
index a036034ae5..42a20e1aba 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_fields.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_fields.hh
@@ -8,7 +8,6 @@
8#include "grammar/alternative.hpp" 8#include "grammar/alternative.hpp"
9#include "name_helpers.hh" 9#include "name_helpers.hh"
10#include "type.hh" 10#include "type.hh"
11#include "keyword.hh"
12#include "using_decl.hh" 11#include "using_decl.hh"
13#include "documentation.hh" 12#include "documentation.hh"
14 13
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index ffd2de0a14..169ae18333 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -4,7 +4,7 @@
4#include "grammar/generator.hpp" 4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp" 6#include "grammar/case.hpp"
7#include "namespace.hh" 7#include "name_helpers.hh"
8 8
9namespace eolian_mono { 9namespace eolian_mono {
10 10
@@ -256,7 +256,7 @@ struct visitor_generate
256 // ? /*" const"*/ "" : "") 256 // ? /*" const"*/ "" : "")
257 /*<< (regular.base_qualifier & qualifier_info::is_ref? "&" : "")*/ 257 /*<< (regular.base_qualifier & qualifier_info::is_ref? "&" : "")*/
258 ) 258 )
259 .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context)) 259 .generate(sink, std::make_tuple(name_helpers::escape_namespace(regular.namespaces), regular.base_type), *context))
260 return true; 260 return true;
261 else 261 else
262 return false; 262 return false;
@@ -274,7 +274,7 @@ struct visitor_generate
274 // .generate(sink, attributes::unused, *context); 274 // .generate(sink, attributes::unused, *context);
275 return 275 return
276 as_generator(*(lower_case[string] << ".") << string) 276 as_generator(*(lower_case[string] << ".") << string)
277 .generate(sink, std::make_tuple(eolian_mono::escape_namespace(klass.namespaces), klass.eolian_name), *context) 277 .generate(sink, std::make_tuple(name_helpers::escape_namespace(klass.namespaces), klass.eolian_name), *context)
278 // && (!(klass.base_qualifier & qualifier_info::is_ref) 278 // && (!(klass.base_qualifier & qualifier_info::is_ref)
279 // || as_generator("&").generate(sink, attributes::unused, *context)) 279 // || as_generator("&").generate(sink, attributes::unused, *context))
280 ; 280 ;
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index f7f2781a6b..e1b53d95ad 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -23,6 +23,7 @@
23#include <Eina.hh> 23#include <Eina.hh>
24#include <Eolian_Cxx.hh> 24#include <Eolian_Cxx.hh>
25 25
26#include <eolian/mono/name_helpers.hh>
26#include <eolian/mono/klass.hh> 27#include <eolian/mono/klass.hh>
27#include <eolian/mono/enum_definition.hh> 28#include <eolian/mono/enum_definition.hh>
28#include <eolian/mono/struct_definition.hh> 29#include <eolian/mono/struct_definition.hh>
@@ -150,7 +151,7 @@ run(options_type const& opts)
150 } 151 }
151 152
152 if (!eolian_mono::function_pointer 153 if (!eolian_mono::function_pointer
153 .generate(iterator, function_def, escape_namespace(namespaces), context)) 154 .generate(iterator, function_def, eolian_mono::name_helpers::escape_namespace(namespaces), context))
154 { 155 {
155 throw std::runtime_error("Failed to generate function pointer wrapper"); 156 throw std::runtime_error("Failed to generate function pointer wrapper");
156 } 157 }