summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-05-10 22:00:07 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2018-05-11 11:01:59 -0300
commitda6f5932f1ec0392d23d84907863271810d90567 (patch)
tree2dcf9729be38d78b2bacfa811072c7fbc5d161a1 /src/bin/eolian_mono
parent95e3468aeee915c4b429066f14c39f2a0715f571 (diff)
efl_mono: Support type aliases.
Summary: Due to the absence of typedef from C#, we generate thin structs with implicit operators to allow reference the data from their typedef'd name from C#. The other alternatives would be always converting to the lowest base on the alias stack (losing the meaningfulness of the typedef name) or using the 'using' directive. The latter has the restriction that it makes an alias visible only in the file they are declared. Reviewers: felipealmeida, cedric, segfaultxavi Reviewed By: segfaultxavi Subscribers: zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6157
Diffstat (limited to 'src/bin/eolian_mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/alias_definition.hh77
-rw-r--r--src/bin/eolian_mono/eolian/mono/blacklist.hh5
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/name_helpers.hh5
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc23
5 files changed, 104 insertions, 7 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/alias_definition.hh b/src/bin/eolian_mono/eolian/mono/alias_definition.hh
new file mode 100644
index 0000000000..91659fb7bd
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/alias_definition.hh
@@ -0,0 +1,77 @@
1#ifndef EOLIAN_MONO_ALIAS_DEFINITION_HH
2#define EOLIAN_MONO_ALIAS_DEFINITION_HH
3
4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp"
6#include "grammar/indentation.hpp"
7
8#include "using_decl.hh"
9#include "name_helpers.hh"
10#include "blacklist.hh"
11#include "documentation.hh"
12#include "generation_contexts.hh"
13
14namespace eolian_mono {
15
16struct alias_definition_generator
17{
18 template<typename OutputIterator, typename Context>
19 bool generate(OutputIterator sink, attributes::alias_def const& alias, Context const& context) const
20 {
21 if (blacklist::is_alias_blacklisted(alias))
22 {
23 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "Alias " << name_helpers::alias_full_eolian_name(alias) << "is blacklisted. Skipping.";
24 return true;
25 }
26
27 if (alias.is_undefined)
28 {
29 EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "Alias " << name_helpers::alias_full_eolian_name(alias) << "is undefined. Skipping.";
30 return true;
31 }
32
33 if (!name_helpers::open_namespaces(sink, alias.namespaces, context))
34 return false;
35
36 std::string const& alias_name = alias.eolian_name;
37 if (!as_generator(
38 "public struct " << alias_name << " {\n"
39 << scope_tab << "private " << type << " payload;\n"
40 << scope_tab << "public static implicit operator " << alias_name << "(" << type << " x)\n"
41 << scope_tab << "{\n"
42 << scope_tab << scope_tab << "return new " << alias_name << "{payload=x};\n"
43 << scope_tab << "}\n"
44 << scope_tab << "public static implicit operator " << type << "(" << alias_name << " x)\n"
45 << scope_tab << "{\n"
46 << scope_tab << scope_tab << "return x.payload;\n"
47 << scope_tab << "}\n"
48 << "}\n"
49 ).generate(sink, std::make_tuple(alias.base_type, alias.base_type, alias.base_type), context))
50 return false;
51
52 if (!name_helpers::close_namespaces(sink, alias.namespaces, context))
53 return false;
54
55 return true;
56 }
57} const alias_definition {};
58
59}
60
61namespace efl { namespace eolian { namespace grammar {
62
63template<>
64struct is_eager_generator< ::eolian_mono::alias_definition_generator> : std::true_type {};
65template<>
66struct is_generator< ::eolian_mono::alias_definition_generator> : std::true_type {};
67
68namespace type_traits {
69
70template<>
71struct attributes_needed< ::eolian_mono::alias_definition_generator> : std::integral_constant<int, 1> {};
72
73}
74
75} } }
76
77#endif
diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh
index fe1640ea67..6fe4d584c4 100644
--- a/src/bin/eolian_mono/eolian/mono/blacklist.hh
+++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh
@@ -73,6 +73,11 @@ inline bool is_struct_blacklisted(attributes::regular_type_def const& struct_)
73 return is_struct_blacklisted(name_helpers::type_full_eolian_name(struct_)); 73 return is_struct_blacklisted(name_helpers::type_full_eolian_name(struct_));
74} 74}
75 75
76inline bool is_alias_blacklisted(attributes::alias_def const& alias)
77{
78 return name_helpers::alias_full_eolian_name(alias) == "Eina.Error";
79}
80
76} 81}
77 82
78} 83}
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index d7e31ddae2..7f94de7736 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -12,6 +12,7 @@ struct class_context
12 inherit_native, 12 inherit_native,
13 structs, 13 structs,
14 function_ptr, 14 function_ptr,
15 alias,
15 }; 16 };
16 wrapper_kind current_wrapper_kind; 17 wrapper_kind current_wrapper_kind;
17}; 18};
diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
index bba06e9221..6dd0cc567c 100644
--- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh
+++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh
@@ -187,6 +187,11 @@ inline std::string managed_method_name(attributes::function_def const& f)
187 return candidate; 187 return candidate;
188} 188}
189 189
190inline std::string alias_full_eolian_name(attributes::alias_def const& alias)
191{
192 return join_namespaces(alias.namespaces, '.') + alias.eolian_name;
193}
194
190inline std::string function_ptr_full_eolian_name(attributes::function_def const& func) 195inline std::string function_ptr_full_eolian_name(attributes::function_def const& func)
191{ 196{
192 return join_namespaces(func.namespaces, '.') + func.name; 197 return join_namespaces(func.namespaces, '.') + func.name;
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index 7f65a4fcaa..9bb5263fbf 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -32,6 +32,7 @@
32#include <eolian/mono/marshall_type_impl.hh> 32#include <eolian/mono/marshall_type_impl.hh>
33#include <eolian/mono/marshall_annotation.hh> 33#include <eolian/mono/marshall_annotation.hh>
34#include <eolian/mono/function_pointer.hh> 34#include <eolian/mono/function_pointer.hh>
35#include <eolian/mono/alias_definition.hh>
35 36
36namespace eolian_mono { 37namespace eolian_mono {
37 38
@@ -137,13 +138,21 @@ run(options_type const& opts)
137 efl::eolian::grammar::context_null()); 138 efl::eolian::grammar::context_null());
138 EINA_ITERATOR_FOREACH(aliases, tp) 139 EINA_ITERATOR_FOREACH(aliases, tp)
139 { 140 {
140 if (eolian_typedecl_type_get(tp) != EOLIAN_TYPEDECL_FUNCTION_POINTER) 141 if (eolian_typedecl_type_get(tp) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
141 continue; 142 {
142 143 const Eolian_Function *fp = eolian_typedecl_function_pointer_get(tp);
143 const Eolian_Function *fp = eolian_typedecl_function_pointer_get(tp); 144 efl::eolian::grammar::attributes::function_def function_def(fp, EOLIAN_FUNCTION_POINTER, tp, opts.unit);
144 efl::eolian::grammar::attributes::function_def function_def(fp, EOLIAN_FUNCTION_POINTER, tp, opts.unit); 145 if (!eolian_mono::function_pointer.generate(iterator, function_def, context))
145 if (!eolian_mono::function_pointer.generate(iterator, function_def, context)) 146 throw std::runtime_error("Failed to generate function pointer wrapper");
146 throw std::runtime_error("Failed to generate function pointer wrapper"); 147 }
148 else // Regular aliases
149 {
150 efl::eolian::grammar::attributes::alias_def alias(tp, opts.unit);
151 auto alias_cxt = context_add_tag(class_context{class_context::alias}, context);
152
153 if (!eolian_mono::alias_definition.generate(iterator, alias, alias_cxt))
154 throw std::runtime_error("Failed to generate alias.");
155 }
147 } 156 }
148 157
149 if (klass) 158 if (klass)