summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-05-07 19:22:59 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2018-05-17 16:56:31 -0300
commitc8fbc31ee2c567123ab59a3dd38b9d3ab575b4e1 (patch)
tree3b00f3cbb1d697f1e27e20bd8cd1d2674e91f4aa /src/bin/eolian_mono
parentfff0c86d99fa63bf7167830da27118d9f2366b4b (diff)
efl_mono: Start generating eina future in eolian_mono.
Summary: Besides the normal methods returning Futures, we now generate a wrapper with the "Async" suffix. This wrapper returns a Systems.Threading.Tasks.Task which can be awaited on and reflect the status of the Future. When an eina.Future fails with ECANCELED, TaskCanceledException is raised in the Task. Otherwise, an efl.FutureException(eina.Error) is raised. Depends on D6174 Reviewers: felipealmeida Reviewed By: felipealmeida Subscribers: cedric, zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6175
Diffstat (limited to 'src/bin/eolian_mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/async_function_definition.hh145
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh12
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh14
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh10
5 files changed, 175 insertions, 10 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
new file mode 100644
index 0000000000..3030c74e1e
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/async_function_definition.hh
@@ -0,0 +1,145 @@
1#ifndef EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH
2#define EOLIAN_MONO_ASYNC_FUNCTION_DEFINITION_HH
3
4#include <Eina.hh>
5
6#include "grammar/generator.hpp"
7#include "grammar/klass_def.hpp"
8
9#include "grammar/indentation.hpp"
10#include "grammar/list.hpp"
11#include "grammar/alternative.hpp"
12#include "grammar/attribute_reorder.hpp"
13#include "logging.hh"
14#include "type.hh"
15#include "name_helpers.hh"
16#include "helpers.hh"
17#include "function_helpers.hh"
18#include "marshall_type.hh"
19#include "parameter.hh"
20#include "documentation.hh"
21#include "using_decl.hh"
22#include "generation_contexts.hh"
23#include "blacklist.hh"
24
25namespace eolian_mono {
26
27struct is_future
28{
29 typedef is_future visitor_type;
30 typedef bool result_type;
31
32 bool operator()(grammar::attributes::complex_type_def const& c) const
33 {
34 return c.outer.base_type == "future";
35 }
36
37 template<typename T>
38 bool operator()(T const&) const
39 {
40 return false;
41 }
42};
43
44struct async_function_declaration_generator
45{
46 template<typename OutputIterator, typename Context>
47 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
48 {
49 if (f.is_static)
50 return true;
51 if (blacklist::is_function_blacklisted(f.c_name))
52 return true;
53 if (!f.return_type.original_type.visit(is_future{}))
54 return true;
55
56 if (!as_generator(
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"
59 ).generate(sink, f.parameters, context))
60 return false;
61
62 return true;
63 }
64} const async_function_declaration {};
65
66struct async_function_definition_generator
67{
68 async_function_definition_generator(bool do_super = false)
69 : do_super(do_super)
70 {}
71
72 template <typename OutputIterator, typename Context>
73 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const
74 {
75 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "async_function_definition_generator: " << f.c_name;
76
77 if(do_super && f.is_static) // Static methods goes only on Concrete classes.
78 return true;
79 if(blacklist::is_function_blacklisted(f.c_name))
80 return true;
81 if(!f.return_type.original_type.visit(is_future{}))
82 return true;
83
84 auto parameter_forwarding = [](attributes::parameter_def const& param) {
85 return direction_modifier(param) + " " + name_helpers::escape_keyword(param.param_name);
86 };
87 std::vector<std::string> param_forwarding;
88
89 std::transform(f.parameters.begin(), f.parameters.end(), std::back_inserter(param_forwarding), parameter_forwarding);
90
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"
93 << scope_tab << "{\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"
96 << scope_tab << "}\n"
97 ).generate(sink, std::make_tuple(f.parameters, param_forwarding), context))
98 return false;
99 return true;
100 }
101
102 bool do_super;
103};
104
105struct async_function_definition_parameterized
106{
107 async_function_definition_generator operator()(bool do_super=false) const
108 {
109 return {do_super};
110 }
111} const async_function_definition;
112async_function_definition_generator as_generator(async_function_definition_parameterized)
113{
114 return {};
115}
116
117}
118
119namespace efl { namespace eolian { namespace grammar {
120
121template <>
122struct is_eager_generator< ::eolian_mono::async_function_declaration_generator> : std::true_type {};
123template <>
124struct is_generator< ::eolian_mono::async_function_declaration_generator> : std::true_type {};
125
126template <>
127struct is_eager_generator< ::eolian_mono::async_function_definition_generator> : std::true_type {};
128template <>
129struct is_generator< ::eolian_mono::async_function_definition_generator> : std::true_type {};
130template <>
131struct is_generator< ::eolian_mono::async_function_definition_parameterized> : std::true_type {};
132
133namespace type_traits {
134template <>
135struct attributes_needed< ::eolian_mono::async_function_declaration_generator> : std::integral_constant<int, 1> {};
136
137template <>
138struct attributes_needed< ::eolian_mono::async_function_definition_generator> : std::integral_constant<int, 1> {};
139template <>
140struct attributes_needed< ::eolian_mono::async_function_definition_parameterized> : std::integral_constant<int, 1> {};
141}
142
143} } }
144
145#endif
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index b2d2d411a6..e85654756d 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -11,6 +11,7 @@
11#include "grammar/alternative.hpp" 11#include "grammar/alternative.hpp"
12#include "type.hh" 12#include "type.hh"
13#include "name_helpers.hh" 13#include "name_helpers.hh"
14#include "async_function_definition.hh"
14#include "function_definition.hh" 15#include "function_definition.hh"
15#include "function_registration.hh" 16#include "function_registration.hh"
16#include "function_declaration.hh" 17#include "function_declaration.hh"
@@ -144,6 +145,9 @@ struct klass
144 if(!as_generator(*(scope_tab << function_declaration)).generate(sink, cls.functions, iface_cxt)) 145 if(!as_generator(*(scope_tab << function_declaration)).generate(sink, cls.functions, iface_cxt))
145 return false; 146 return false;
146 147
148 if(!as_generator(*(scope_tab << async_function_declaration)).generate(sink, cls.functions, iface_cxt))
149 return false;
150
147 if(!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt)) 151 if(!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt))
148 return false; 152 return false;
149 153
@@ -251,6 +255,10 @@ struct klass
251 if(!as_generator(*(function_definition)) 255 if(!as_generator(*(function_definition))
252 .generate(sink, methods, concrete_cxt)) return false; 256 .generate(sink, methods, concrete_cxt)) return false;
253 257
258 // Async wrappers
259 if(!as_generator(*(async_function_definition)).generate(sink, methods, concrete_cxt))
260 return false;
261
254 if(!as_generator(*(event_argument_wrapper)).generate(sink, cls.events, context)) 262 if(!as_generator(*(event_argument_wrapper)).generate(sink, cls.events, context))
255 return false; 263 return false;
256 264
@@ -354,6 +362,10 @@ struct klass
354 if(!as_generator(*(function_definition(true))) 362 if(!as_generator(*(function_definition(true)))
355 .generate(sink, methods, inherit_cxt)) return false; 363 .generate(sink, methods, inherit_cxt)) return false;
356 364
365 // Async wrappers
366 if(!as_generator(*(async_function_definition(true))).generate(sink, methods, inherit_cxt))
367 return false;
368
357 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; 369 if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
358 } 370 }
359 371
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 576ccdb4c9..a2426569ab 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -149,8 +149,13 @@ struct marshall_annotation_visitor_generate
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&) const 152 bool operator()(attributes::complex_type_def const& c) const
153 { 153 {
154 if (c.outer.base_type == "future")
155 {
156 std::string prefix = is_return ? "return: " : "";
157 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.FutureMarshaler))]").generate(sink, nullptr, *context);
158 }
154 return true; 159 return true;
155 } 160 }
156}; 161};
@@ -254,8 +259,13 @@ struct marshall_native_annotation_visitor_generate
254 << 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") << ">))]"
255 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); 260 ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context);
256 } 261 }
257 bool operator()(attributes::complex_type_def const&) const 262 bool operator()(attributes::complex_type_def const& c) const
258 { 263 {
264 if (c.outer.base_type == "future")
265 {
266 std::string prefix = is_return ? "return: " : "";
267 return as_generator("[" << prefix << "MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(eina.FutureMarshaler))]").generate(sink, nullptr, *context);
268 }
259 return true; 269 return true;
260 } 270 }
261}; 271};
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index 912909b4a8..b1a03056ef 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -192,6 +192,10 @@ inline std::string alias_full_eolian_name(attributes::alias_def const& alias)
192 return join_namespaces(alias.namespaces, '.') + alias.eolian_name; 192 return join_namespaces(alias.namespaces, '.') + alias.eolian_name;
193} 193}
194 194
195inline std::string managed_async_method_name(attributes::function_def const& f)
196{
197 return managed_method_name(f) + "Async";
198}
195inline std::string function_ptr_full_eolian_name(attributes::function_def const& func) 199inline std::string function_ptr_full_eolian_name(attributes::function_def const& func)
196{ 200{
197 return join_namespaces(func.namespaces, '.') + func.name; 201 return join_namespaces(func.namespaces, '.') + func.name;
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index ee44460169..1028a76ad9 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -282,16 +282,10 @@ struct visitor_generate
282 complex_type_def c = complex; 282 complex_type_def c = complex;
283 c.outer.base_type = "eina.Hash"; 283 c.outer.base_type = "eina.Hash";
284 return c; 284 return c;
285 }} 285 }}
286 , {"promise", nullptr, nullptr, [&]
287 {
288 return replace_outer
289 (complex, regular_type_def{" ::efl::promise", complex.outer.base_qualifier, {}});
290 }
291 }
292 , {"future", nullptr, nullptr, [&] 286 , {"future", nullptr, nullptr, [&]
293 { 287 {
294 (*this)(regular_type_def{" int", complex.outer.base_qualifier, {}}); 288 (*this)(regular_type_def{" eina.Future", complex.outer.base_qualifier, {}});
295 return attributes::type_def::variant_type(); 289 return attributes::type_def::variant_type();
296 // return replace_outer 290 // return replace_outer
297 // (complex, regular_type_def{" ::efl::shared_future", complex.outer.base_qualifier, {}}); 291 // (complex, regular_type_def{" ::efl::shared_future", complex.outer.base_qualifier, {}});