summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2017-12-12 12:06:46 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2017-12-15 22:26:29 -0200
commitacd99be98bc6f3218af9322b23acb52ed29fb008 (patch)
tree3cee18189cc4ab31f4595721ca904bf0cc8d6847 /src/bin/eolian_mono
parentb20dd869a4a10fb28a9c743910e2f2a1d2e7d1cc (diff)
efl_mono: tests and better support for structs, plus some other fixes
Fix several integer binding type deduction based in its size on C. Generation for function pointers no longer use modified argument name which is different from the parameter name. New generation context for structs. bool from UnmanagedType.I1 to UnmanagedType.U1 (correct use inside structs according to mono documentation). byte (signed char) and int8 now is correctly represented by sbyte in C#. Check parameter direction in some out generators in parameter.hh. Add efl_libs.csv to gitignore. Make eina.Value pointer constructor public. Add missing fields to efl.kw_event.Description struct. Remove eina.File workaround (let struct gen handle it). Remove is_function_ptr bool from regular_type_def and add a typedecl_type enum to it. Also add some helper methods for easier comparison. Left some test cases commented for when pointer parameters are properly working.
Diffstat (limited to 'src/bin/eolian_mono')
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh59
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh114
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh437
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh39
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc3
9 files changed, 608 insertions, 65 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 84fdb79881..0f91a4c41c 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -69,14 +69,14 @@ struct function_pointer {
69 69
70 << scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n" 70 << scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n"
71 << scope_tab << "{\n" 71 << scope_tab << "{\n"
72 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n" 72 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation_no_conversion % ", ") << ");\n"
73 << scope_tab << "}\n\n" 73 << scope_tab << "}\n\n"
74 74
75 << scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n" 75 << scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
76 << scope_tab << "{\n" 76 << scope_tab << "{\n"
77 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n" 77 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
78 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n" 78 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
79 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation % ", ") << ");\n" 79 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation_no_conversion % ", ") << ");\n"
80 << scope_tab << "}\n" 80 << scope_tab << "}\n"
81 << "}\n" 81 << "}\n"
82 ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context)) 82 ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context))
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index f220c94cb6..8563afcb12 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -10,6 +10,7 @@ struct class_context
10 concrete, 10 concrete,
11 inherit, 11 inherit,
12 inherit_native, 12 inherit_native,
13 structs,
13 }; 14 };
14 wrapper_kind current_wrapper_kind; 15 wrapper_kind current_wrapper_kind;
15}; 16};
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
new file mode 100644
index 0000000000..28b54a5aef
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -0,0 +1,59 @@
1#ifndef EOLIAN_MONO_HELPERS_HH
2#define EOLIAN_MONO_HELPERS_HH
3
4#include "grammar/klass_def.hpp"
5
6namespace eolian_mono {
7
8namespace attributes = efl::eolian::grammar::attributes;
9
10inline std::string type_full_name(attributes::regular_type_def const& type)
11{
12 std::string full_name;
13 for (auto& name : type.namespaces)
14 {
15 full_name += name + ".";
16 }
17 full_name += type.base_type;
18 return full_name;
19}
20
21inline std::string struct_full_name(attributes::struct_def const& struct_)
22{
23 std::string full_name;
24 for (auto& name : struct_.namespaces)
25 {
26 full_name += name + ".";
27 }
28 full_name += struct_.cxx_name;
29 return full_name;
30}
31
32// Blacklist structs that require some kind of manual binding.
33inline bool is_struct_blacklisted(std::string const& full_name)
34{
35 return full_name == "Efl.Event.Description"
36 // || full_name == "Eina.File"
37 || full_name == "Eina.Binbuf"
38 || full_name == "Eina.Slice"
39 || full_name == "Eina.Rw_Slice";
40}
41
42inline bool is_struct_blacklisted(attributes::struct_def const& struct_)
43{
44 return is_struct_blacklisted(struct_full_name(struct_));
45}
46
47inline bool is_struct_blacklisted(attributes::regular_type_def const& struct_)
48{
49 return is_struct_blacklisted(type_full_name(struct_));
50}
51
52inline bool need_struct_conversion(attributes::regular_type_def const* regular)
53{
54 return regular && regular->is_struct() && !is_struct_blacklisted(*regular);
55}
56
57}
58
59#endif
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 2765dcdc25..8774cd855c 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -51,7 +51,7 @@ struct marshall_annotation_visitor_generate
51 match const parameter_match_table[] = 51 match const parameter_match_table[] =
52 { 52 {
53 // signed primitives 53 // signed primitives
54 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }}, 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 }},
@@ -80,7 +80,7 @@ struct marshall_annotation_visitor_generate
80 match const return_match_table[] = 80 match const return_match_table[] =
81 { 81 {
82 // signed primitives 82 // signed primitives
83 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }}, 83 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
84 {"string", true, [&] { 84 {"string", true, [&] {
85 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 85 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
86 }}, 86 }},
@@ -170,7 +170,7 @@ struct marshall_native_annotation_visitor_generate
170 match const parameter_match_table[] = 170 match const parameter_match_table[] =
171 { 171 {
172 // signed primitives 172 // signed primitives
173 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }}, 173 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
174 {"string", true, [&] { 174 {"string", true, [&] {
175 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 175 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
176 }}, 176 }},
@@ -191,7 +191,7 @@ struct marshall_native_annotation_visitor_generate
191 match const return_match_table[] = 191 match const return_match_table[] =
192 { 192 {
193 // signed primitives 193 // signed primitives
194 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }}, 194 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
195 {"string", true, [&] { 195 {"string", true, [&] {
196 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 196 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
197 }}, 197 }},
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 caeb17f83f..7950b31213 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -4,6 +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 "helpers.hh"
7#include "namespace.hh" 8#include "namespace.hh"
8#include "type_impl.hh" 9#include "type_impl.hh"
9#include "generation_contexts.hh" 10#include "generation_contexts.hh"
@@ -148,7 +149,12 @@ struct marshall_type_visitor_generate
148 }} 149 }}
149 }; 150 };
150 151
151 if(eina::optional<bool> b = call_match 152 if (regular.is_struct() && !is_struct_blacklisted(regular))
153 {
154 return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
155 .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context);
156 }
157 else if (eina::optional<bool> b = call_match
152 (match_table 158 (match_table
153 , [&] (match const& m) 159 , [&] (match const& m)
154 { 160 {
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index e9aa957ad7..0e3fa326d5 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -4,6 +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 "helpers.hh"
7#include "marshall_type.hh" 8#include "marshall_type.hh"
8#include "type.hh" 9#include "type.hh"
9#include "using_decl.hh" 10#include "using_decl.hh"
@@ -226,6 +227,9 @@ inline bool param_is_acceptable(attributes::parameter_def const &param, std::str
226 227
227inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native) 228inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native)
228{ 229{
230 if (param.direction == attributes::parameter_direction::in)
231 return false;
232
229 if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)) 233 if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
230 || (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 234 || (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
231 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 235 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -261,11 +265,18 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo
261 ) 265 )
262 return true; 266 return true;
263 267
268 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
269 if (need_struct_conversion(regular))
270 return true;
271
264 return false; 272 return false;
265} 273}
266 274
267inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/) 275inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/)
268{ 276{
277 if (param.direction != attributes::parameter_direction::in)
278 return false;
279
269 if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT) 280 if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
270 || param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT) 281 || param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT)
271 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT) 282 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
@@ -299,6 +310,10 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool
299 ) 310 )
300 return true; 311 return true;
301 312
313 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
314 if (need_struct_conversion(regular))
315 return true;
316
302 return false; 317 return false;
303} 318}
304 319
@@ -320,7 +335,9 @@ inline std::string direction_modifier(attributes::parameter_def const& param)
320 } 335 }
321 else if (param.direction != attributes::parameter_direction::in) 336 else if (param.direction != attributes::parameter_direction::in)
322 { 337 {
323 if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice") 338 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
339 if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice"
340 || need_struct_conversion(regular))
324 return " ref "; 341 return " ref ";
325 else 342 else
326 return " out "; 343 return " out ";
@@ -335,7 +352,7 @@ struct is_fp_visitor
335 352
336 bool operator()(grammar::attributes::regular_type_def const &type) const 353 bool operator()(grammar::attributes::regular_type_def const &type) const
337 { 354 {
338 return type.is_function_ptr; 355 return type.is_function_ptr();
339 } 356 }
340 357
341 template<typename T> 358 template<typename T>
@@ -445,14 +462,18 @@ struct native_argument_invocation_generator
445// Generates the correct parameter name when invoking a function 462// Generates the correct parameter name when invoking a function
446struct argument_invocation_generator 463struct argument_invocation_generator
447{ 464{
465 constexpr argument_invocation_generator(bool conversion_vars)
466 : use_conversion_vars(conversion_vars)
467 {}
468
448 template <typename OutputIterator, typename Context> 469 template <typename OutputIterator, typename Context>
449 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 470 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
450 { 471 {
451 std::string arg = direction_modifier(param); 472 std::string arg = direction_modifier(param);
452 473
453 if (param_should_use_out_var(param, false)) 474 if (use_conversion_vars && param_should_use_out_var(param, false))
454 arg += out_variable_name(param.param_name); 475 arg += out_variable_name(param.param_name);
455 else if (param_should_use_in_var(param, false)) 476 else if (use_conversion_vars && param_should_use_in_var(param, false))
456 arg += in_variable_name(param.param_name); 477 arg += in_variable_name(param.param_name);
457 else if (param.type.original_type.visit(is_fp_visitor{})) 478 else if (param.type.original_type.visit(is_fp_visitor{}))
458 { 479 {
@@ -465,7 +486,11 @@ struct argument_invocation_generator
465 486
466 return as_generator(arg).generate(sink, attributes::unused, context); 487 return as_generator(arg).generate(sink, attributes::unused, context);
467 } 488 }
468} const argument_invocation {}; 489
490 bool const use_conversion_vars;
491} const argument_invocation {true};
492
493argument_invocation_generator const argument_invocation_no_conversion {false};
469 494
470struct native_convert_in_variable_generator 495struct native_convert_in_variable_generator
471{ 496{
@@ -475,7 +500,14 @@ struct native_convert_in_variable_generator
475 if (param.direction != attributes::parameter_direction::in) 500 if (param.direction != attributes::parameter_direction::in)
476 return true; 501 return true;
477 502
478 if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") 503 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
504 if (need_struct_conversion(regular))
505 {
506 return as_generator(
507 "var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
508 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
509 }
510 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
479 { 511 {
480 return as_generator( 512 return as_generator(
481 "var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n" 513 "var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
@@ -530,7 +562,14 @@ struct convert_in_variable_generator
530 if (param.direction != attributes::parameter_direction::in) 562 if (param.direction != attributes::parameter_direction::in)
531 return true; 563 return true;
532 564
533 if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") 565 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
566 if (need_struct_conversion(regular))
567 {
568 return as_generator(
569 "var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
570 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
571 }
572 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
534 { 573 {
535 auto var_name = in_variable_name(param.param_name); 574 auto var_name = in_variable_name(param.param_name);
536 if (!as_generator( 575 if (!as_generator(
@@ -608,7 +647,17 @@ struct convert_out_variable_generator
608 template <typename OutputIterator, typename Context> 647 template <typename OutputIterator, typename Context>
609 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 648 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
610 { 649 {
611 if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 650 if (param.direction == attributes::parameter_direction::in)
651 return true;
652
653 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
654 if (need_struct_conversion(regular))
655 {
656 return as_generator(
657 "var " << string << " = new " << marshall_type << "();\n"
658 ).generate(sink, std::make_tuple(out_variable_name(param.param_name), param.type), context);
659 }
660 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
612 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 661 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
613 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT) 662 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
614 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT) 663 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -665,7 +714,12 @@ struct native_convert_out_variable_generator
665 template <typename OutputIterator, typename Context> 714 template <typename OutputIterator, typename Context>
666 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 715 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
667 { 716 {
668 if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT) 717 if (param.direction == attributes::parameter_direction::in)
718 return true;
719
720 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
721 if (need_struct_conversion(regular)
722 || param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
669 || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 723 || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
670 { 724 {
671 return as_generator( 725 return as_generator(
@@ -740,7 +794,17 @@ struct convert_out_assign_generator
740 template <typename OutputIterator, typename Context> 794 template <typename OutputIterator, typename Context>
741 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 795 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
742 { 796 {
743 if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 797 if (param.direction == attributes::parameter_direction::in)
798 return true;
799
800 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
801 if (need_struct_conversion(regular))
802 {
803 return as_generator(
804 string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
805 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
806 }
807 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
744 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 808 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
745 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT) 809 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
746 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT) 810 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -829,7 +893,14 @@ struct convert_return_generator
829 template <typename OutputIterator, typename Context> 893 template <typename OutputIterator, typename Context>
830 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const 894 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
831 { 895 {
832 if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *") 896 auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
897 if (need_struct_conversion(regular))
898 {
899 return as_generator(
900 "return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
901 ).generate(sink, ret_type, context);
902 }
903 else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
833 { 904 {
834 if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n" 905 if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n"
835 << scope_tab << scope_tab << "return _binbuf_ret;\n") 906 << scope_tab << scope_tab << "return _binbuf_ret;\n")
@@ -881,7 +952,17 @@ struct native_convert_out_assign_generator
881 template <typename OutputIterator, typename Context> 952 template <typename OutputIterator, typename Context>
882 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 953 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
883 { 954 {
884 if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 955 if (param.direction == attributes::parameter_direction::in)
956 return true;
957
958 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
959 if (need_struct_conversion(regular))
960 {
961 return as_generator(
962 string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n"
963 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
964 }
965 else if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
885 { 966 {
886 return as_generator( 967 return as_generator(
887 string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n" 968 string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n"
@@ -1001,7 +1082,14 @@ struct native_convert_return_generator
1001 template <typename OutputIterator, typename Context> 1082 template <typename OutputIterator, typename Context>
1002 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const 1083 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
1003 { 1084 {
1004 if (ret_type.c_type == "const char *") 1085 auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
1086 if (need_struct_conversion(regular))
1087 {
1088 return as_generator(
1089 "return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
1090 ).generate(sink, ret_type, context);
1091 }
1092 else if (ret_type.c_type == "const char *")
1005 { 1093 {
1006 if(!ret_type.has_own) 1094 if(!ret_type.has_own)
1007 { 1095 {
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index ee05852904..62992357f2 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -6,28 +6,28 @@
6#include "grammar/indentation.hpp" 6#include "grammar/indentation.hpp"
7#include "grammar/list.hpp" 7#include "grammar/list.hpp"
8#include "grammar/alternative.hpp" 8#include "grammar/alternative.hpp"
9#include "helpers.hh"
9#include "type.hh" 10#include "type.hh"
10#include "keyword.hh" 11#include "keyword.hh"
11#include "using_decl.hh" 12#include "using_decl.hh"
12 13
13namespace eolian_mono { 14namespace eolian_mono {
14 15
15// Blacklist structs that require some kind of manual binding. 16inline std::string binding_struct_name(attributes::struct_def const& struct_)
16static bool is_struct_blacklisted(attributes::struct_def const& struct_)
17{ 17{
18 std::string full_name; 18 return struct_.cxx_name;
19 19}
20 for (auto it=struct_.namespaces.begin(); it != struct_.namespaces.end(); it++) 20
21 { 21inline std::string binding_struct_internal_name(attributes::struct_def const& struct_)
22 full_name += *it + "."; 22{
23 } 23 return struct_.cxx_name + "_StructInternal";
24 24}
25 full_name += struct_.cxx_name; 25
26 return full_name == "Efl.Event.Description" 26inline std::string to_field_name(std::string const& in)
27 || full_name == "Eina.File" 27{
28 || full_name == "Eina.Binbuf" 28 std::string field_name = in;
29 || full_name == "Eina.Slice" 29 field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
30 || full_name == "Eina.Rw_Slice"; 30 return field_name;
31} 31}
32 32
33struct struct_definition_generator 33struct struct_definition_generator
@@ -35,33 +35,22 @@ struct struct_definition_generator
35 template <typename OutputIterator, typename Context> 35 template <typename OutputIterator, typename Context>
36 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const 36 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
37 { 37 {
38 if (is_struct_blacklisted(struct_))
39 return true;
40
41 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
42
43 auto open_namespace = *("namespace " << string << " { ") << "\n";
44 if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
45
46 if(!as_generator 38 if(!as_generator
47 ( 39 (
40 "[StructLayout(LayoutKind.Sequential)]\n"
48 "public struct " << string << "\n{\n" 41 "public struct " << string << "\n{\n"
49 ) 42 )
50 .generate(sink, struct_.cxx_name, context)) 43 .generate(sink, binding_struct_name(struct_), context))
51 return false; 44 return false;
52 45
53 // iterate struct fields 46 // iterate struct fields
54 for(auto first = std::begin(struct_.fields) 47 for (auto const& field : struct_.fields)
55 , last = std::end(struct_.fields); first != last; ++first)
56 { 48 {
57 auto field_name = (*first).name;
58 auto field_type = (*first).type;
59 field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
60 if (!as_generator 49 if (!as_generator
61 ( 50 (
62 "public " << type << " " << string << ";\n" 51 " public " << type << " " << string << ";\n"
63 ) 52 )
64 .generate(sink, std::make_tuple(field_type, field_name), context)) 53 .generate(sink, std::make_tuple(field.type, to_field_name(field.name)), context))
65 return false; 54 return false;
66 } 55 }
67 56
@@ -77,14 +66,354 @@ struct struct_definition_generator
77 66
78 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; 67 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
79 68
69 return true;
70 }
71} const struct_definition {};
72
73
74struct struct_internal_definition_generator
75{
76 template <typename OutputIterator, typename Context>
77 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
78 {
79 if (!as_generator
80 (
81 "[StructLayout(LayoutKind.Sequential)]\n"
82 "public struct " << string << "\n{\n"
83 )
84 .generate(sink, binding_struct_internal_name(struct_), context))
85 return false;
86
87 // iterate struct fields
88 for (auto const& field : struct_.fields)
89 {
90 auto field_name = to_field_name(field.name);
91 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
92 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
93
94 if (klass
95 || (regular && (regular->base_type == "string"
96 || regular->base_type == "mstring"
97 || regular->base_type == "stringshare"
98 || regular->base_type == "any_value_ptr")))
99 {
100 if (!as_generator(" public System.IntPtr " << string << ";\n")
101 .generate(sink, field_name, context))
102 return false;
103 }
104 else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
105 .generate(sink, std::make_tuple(field.type, field.type, field_name), context))
106 return false;
107 }
108
109 // Check whether this is an extern struct without declared fields in .eo file and generate a
110 // placeholder field if positive.
111 // Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
112 // those 'mini-amd64.c condition fields not met' crashes.
113 if (struct_.fields.size() == 0)
114 {
115 if (!as_generator("public IntPtr field;\n").generate(sink, nullptr, context))
116 return false;
117 }
118
119 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
120
121 return true;
122 }
123} const struct_internal_definition {};
124
125
126// Conversors generation //
127
128struct to_internal_field_convert_generator
129{
130 template <typename OutputIterator, typename Context>
131 bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
132 {
133 auto field_name = to_field_name(field.name);
134 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
135 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
136 auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
137
138 if (klass)
139 {
140 if (!as_generator(
141 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".raw_handle;\n")
142 .generate(sink, std::make_tuple(field_name, field_name), context))
143 return false;
144 }
145 else if ((complex && (complex->outer.base_type == "array"
146 || complex->outer.base_type == "inarray"
147 || complex->outer.base_type == "list"
148 || complex->outer.base_type == "inlist"
149 || complex->outer.base_type == "iterator"
150 || complex->outer.base_type == "hash"))
151 || field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
152 {
153 // Always assumes pointer
154 if (!as_generator(
155 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n")
156 .generate(sink, std::make_tuple(field_name, field_name), context))
157 return false;
158 }
159 else if (need_struct_conversion(regular))
160 {
161 if (!as_generator(
162 scope_tab << scope_tab << "_internal_struct." << string << " = " << type << "_StructConvertion.ToInternal(_external_struct." << string << ");\n")
163 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
164 return false;
165 }
166 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring"))
167 {
168 if (!as_generator(
169 scope_tab << scope_tab << "_internal_struct." << string << " = eina.MemoryNative.StrDup(_external_struct." << string << ");\n")
170 .generate(sink, std::make_tuple(field_name, field_name), context))
171 return false;
172 }
173 else if (regular && regular->base_type == "stringshare")
174 {
175 if (!as_generator(
176 scope_tab << scope_tab << "_internal_struct." << string << " = eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n")
177 .generate(sink, std::make_tuple(field_name, field_name), context))
178 return false;
179 }
180 else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
181 || field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
182 {
183 if (!as_generator(
184 "\n" <<
185 scope_tab << scope_tab << "_internal_struct." << field_name << ".Len = _external_struct." << field_name << ".Len;\n" <<
186 scope_tab << scope_tab << "_internal_struct." << field_name << ".Mem = _external_struct." << field_name << ".Mem;\n\n")
187 .generate(sink, attributes::unused, context))
188 return false;
189 }
190 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
191 {
192 if (!as_generator(
193 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".GetNative();\n"
194 ).generate(sink, std::make_tuple(field_name, field_name), context))
195 return false;
196 }
197 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
198 {
199 if (!as_generator(
200 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n"
201 ).generate(sink, std::make_tuple(field_name, field_name), context))
202 return false;
203 }
204 else // primitives and enums
205 {
206 if (!as_generator(
207 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ";\n")
208 .generate(sink, std::make_tuple(field_name, field_name), context))
209 return false;
210 }
211 return true;
212 }
213} const to_internal_field_convert {};
214
215struct to_external_field_convert_generator
216{
217 template <typename OutputIterator, typename Context>
218 bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
219 {
220 auto field_name = to_field_name(field.name);
221 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
222 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
223 auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
224
225 if (klass)
226 {
227 if (!as_generator(
228 "\n"
229 << scope_tab << scope_tab << "_external_struct." << string
230 << " = (" << type << ") System.Activator.CreateInstance(typeof("
231 << type << "Concrete), new System.Object[] {_internal_struct." << string << "});\n"
232 << scope_tab << scope_tab << "efl.eo.Globals.efl_ref(_internal_struct." << string << ");\n\n")
233 .generate(sink, std::make_tuple(field_name, field.type, field.type, field_name, field_name), context))
234 return false;
235 }
236 else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
237 {
238 if (!as_generator(
239 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false);\n")
240 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
241 return false;
242 }
243 else if (complex && (complex->outer.base_type == "array"
244 || complex->outer.base_type == "inarray"
245 || complex->outer.base_type == "list"
246 || complex->outer.base_type == "inlist"
247 || complex->outer.base_type == "iterator"))
248 {
249 // Always assumes pointer
250 if (!as_generator(
251 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
252 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
253 return false;
254 }
255 else if (complex && complex->outer.base_type == "hash")
256 {
257 if (!as_generator(
258 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false, false);\n")
259 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
260 return false;
261 }
262 else if (need_struct_conversion(regular))
263 {
264 if (!as_generator(
265 scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConvertion.ToExternal(_internal_struct." << string << ");\n")
266 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
267 return false;
268 }
269 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare"))
270 {
271 if (!as_generator(
272 scope_tab << scope_tab << "_external_struct." << string << " = eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n")
273 .generate(sink, std::make_tuple(field_name, field_name), context))
274 return false;
275 }
276 else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
277 || field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
278 {
279 if (!as_generator(
280 "\n" <<
281 scope_tab << scope_tab << "_external_struct." << field_name << ".Len = _internal_struct." << field_name << ".Len;\n" <<
282 scope_tab << scope_tab << "_external_struct." << field_name << ".Mem = _internal_struct." << field_name << ".Mem;\n\n")
283 .generate(sink, attributes::unused, context))
284 return false;
285 }
286 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
287 {
288 if (!as_generator(
289 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ");\n"
290 ).generate(sink, std::make_tuple(field_name, field_name), context))
291 return false;
292 }
293 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
294 {
295 if (!as_generator(
296 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ", eina.ValueOwnership.Unmanaged);\n"
297 ).generate(sink, std::make_tuple(field_name, field_name), context))
298 return false;
299 }
300 else // primitives and enums
301 {
302 if (!as_generator(
303 scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << ";\n")
304 .generate(sink, std::make_tuple(field_name, field_name), context))
305 return false;
306 }
307 return true;
308 }
309} const to_external_field_convert {};
310
311struct struct_binding_conversion_functions_generator
312{
313 template <typename OutputIterator, typename Context>
314 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
315 {
316 // Open conversion class
317 if (!as_generator
318 (
319 "public static class " << string << "_StructConvertion\n{\n"
320 )
321 .generate(sink, struct_.cxx_name, context))
322 return false;
323
324 // to internal
325 if (!as_generator
326 (
327 scope_tab << "public static " << string << " ToInternal(" << string << " _external_struct)\n"
328 << scope_tab << "{\n"
329 << scope_tab << scope_tab << "var _internal_struct = new " << string << "();\n\n"
330 )
331 .generate(sink, std::make_tuple(binding_struct_internal_name(struct_)
332 , binding_struct_name(struct_)
333 , binding_struct_internal_name(struct_)
334 ), context))
335 return false;
336
337 for (auto const& field : struct_.fields)
338 {
339 if (!to_internal_field_convert.generate(sink, field, context))
340 return false;
341 }
342
343 if (!as_generator
344 (
345 "\n"
346 << scope_tab << scope_tab << "return _internal_struct;\n"
347 << scope_tab << "}\n\n"
348 )
349 .generate(sink, attributes::unused, context))
350 return false;
351
352 // to external
353 if (!as_generator
354 (
355 scope_tab << "public static " << string << " ToExternal(" << string << " _internal_struct)\n"
356 << scope_tab << "{\n"
357 << scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
358 )
359 .generate(sink, std::make_tuple(binding_struct_name(struct_)
360 , binding_struct_internal_name(struct_)
361 , binding_struct_name(struct_)
362 ), context))
363 return false;
364
365 for (auto const& field : struct_.fields)
366 {
367 if (!to_external_field_convert.generate(sink, field, context))
368 return false;
369 }
370
371 if (!as_generator
372 (
373 "\n"
374 << scope_tab << scope_tab << "return _external_struct;\n"
375 << scope_tab << "}\n\n"
376 )
377 .generate(sink, attributes::unused, context))
378 return false;
379
380 // Close conversion class
381 if (!as_generator("}\n").generate(sink, attributes::unused, context))
382 return false;
383
384 return true;
385 }
386} const struct_binding_conversion_functions {};
387
388struct struct_entities_generator
389{
390 template <typename OutputIterator, typename Context>
391 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
392 {
393 if (is_struct_blacklisted(struct_))
394 return true;
395
396 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
397
398 auto open_namespace = *("namespace " << string << " { ") << "\n";
399 if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context)))
400 return false;
401
402 if (!struct_definition.generate(sink, struct_, context))
403 return false;
404
405 if (!struct_internal_definition.generate(sink, struct_, context))
406 return false;
407
408 if (!struct_binding_conversion_functions.generate(sink, struct_, context))
409 return false;
410
80 auto close_namespace = *(lit("} ")) << "\n"; 411 auto close_namespace = *(lit("} ")) << "\n";
81 if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false; 412 if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
82 413
83 return true; 414 return true;
84 } 415 }
85}; 416} const struct_entities {};
86
87struct_definition_generator const struct_definition = {};
88 417
89} 418}
90 419
@@ -95,9 +424,49 @@ struct is_eager_generator< ::eolian_mono::struct_definition_generator> : std::tr
95template <> 424template <>
96struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {}; 425struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {};
97 426
427template <>
428struct is_eager_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
429template <>
430struct is_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
431
432template <>
433struct is_eager_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
434template <>
435struct is_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
436
437template <>
438struct is_eager_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
439template <>
440struct is_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
441
442template <>
443struct is_eager_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
444template <>
445struct is_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
446
447template <>
448struct is_eager_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
449template <>
450struct is_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
451
98namespace type_traits { 452namespace type_traits {
99template <> 453template <>
100struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {}; 454struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {};
455
456template <>
457struct attributes_needed< ::eolian_mono::struct_internal_definition_generator> : std::integral_constant<int, 1> {};
458
459template <>
460struct attributes_needed< ::eolian_mono::to_internal_field_convert_generator> : std::integral_constant<int, 1> {};
461
462template <>
463struct attributes_needed< ::eolian_mono::to_external_field_convert_generator> : std::integral_constant<int, 1> {};
464
465template <>
466struct attributes_needed< ::eolian_mono::struct_binding_conversion_functions_generator> : std::integral_constant<int, 1> {};
467
468template <>
469struct attributes_needed< ::eolian_mono::struct_entities_generator> : std::integral_constant<int, 1> {};
101} 470}
102 471
103} } } 472} } }
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index d6d753b88d..3d3950c172 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -13,12 +13,28 @@ namespace eina = efl::eina;
13template <typename T> 13template <typename T>
14T const* as_const_pointer(T* p) { return p; } 14T const* as_const_pointer(T* p) { return p; }
15 15
16inline
16attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name) 17attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name)
17{ 18{
18 v.base_type = name; 19 v.base_type = name;
19 return v; 20 return v;
20} 21}
21 22
23template <typename T>
24attributes::regular_type_def replace_base_integer(attributes::regular_type_def v)
25{
26 bool s = std::is_signed<T>::value;
27 switch (sizeof(T))
28 {
29 case 1: return s ? replace_base_type(v, " sbyte") : replace_base_type(v, " byte");
30 case 2: return s ? replace_base_type(v, " short") : replace_base_type(v, " ushort");
31 case 4: return s ? replace_base_type(v, " int") : replace_base_type(v, " uint");
32 case 8: return s ? replace_base_type(v, " long") : replace_base_type(v, " ulong");
33 default: return v;
34 }
35}
36
37inline
22attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular) 38attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
23{ 39{
24 v.outer = regular; 40 v.outer = regular;
@@ -62,26 +78,29 @@ struct visitor_generate
62 const match_table[] = 78 const match_table[] =
63 { 79 {
64 // signed primitives 80 // signed primitives
65 {"byte", nullptr, [&] { return replace_base_type(regular, " byte"); }} 81 {"byte", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
66 , {"llong", nullptr, [&] { return replace_base_type(regular, " long"); }} 82 , {"short", nullptr, [&] { return replace_base_integer<short>(regular); }}
67 , {"int8", nullptr, [&] { return replace_base_type(regular, " byte"); }} 83 , {"int", nullptr, [&] { return replace_base_integer<int>(regular); }}
84 , {"long", nullptr, [&] { return replace_base_integer<long>(regular); }}
85 , {"llong", nullptr, [&] { return replace_base_integer<long long>(regular); }}
86 , {"int8", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
68 , {"int16", nullptr, [&] { return replace_base_type(regular, " short"); }} 87 , {"int16", nullptr, [&] { return replace_base_type(regular, " short"); }}
69 , {"int32", nullptr, [&] { return replace_base_type(regular, " int"); }} 88 , {"int32", nullptr, [&] { return replace_base_type(regular, " int"); }}
70 , {"int64", nullptr, [&] { return replace_base_type(regular, " long"); }} 89 , {"int64", nullptr, [&] { return replace_base_type(regular, " long"); }}
71 , {"ssize", nullptr, [&] { return replace_base_type(regular, " long"); }} 90 , {"ssize", nullptr, [&] { return replace_base_integer<ssize_t>(regular); }}
72 // unsigned primitives 91 // unsigned primitives
73 , {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte"); }} 92 , {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte"); }}
74 , {"ushort", nullptr, [&] { return replace_base_type(regular, " ushort"); }} 93 , {"ushort", nullptr, [&] { return replace_base_integer<unsigned short>(regular); }}
75 , {"uint", nullptr, [&] { return replace_base_type(regular, " uint"); }} 94 , {"uint", nullptr, [&] { return replace_base_integer<unsigned int>(regular); }}
76 , {"ulong", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 95 , {"ulong", nullptr, [&] { return replace_base_integer<unsigned long>(regular); }}
77 , {"ullong", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 96 , {"ullong", nullptr, [&] { return replace_base_integer<unsigned long long>(regular); }}
78 , {"uint8", nullptr, [&] { return replace_base_type(regular, " byte"); }} 97 , {"uint8", nullptr, [&] { return replace_base_type(regular, " byte"); }}
79 , {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort"); }} 98 , {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort"); }}
80 , {"uint32", nullptr, [&] { return replace_base_type(regular, " uint"); }} 99 , {"uint32", nullptr, [&] { return replace_base_type(regular, " uint"); }}
81 , {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 100 , {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
82 , {"size", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 101 , {"size", nullptr, [&] { return replace_base_integer<size_t>(regular); }}
83 102
84 , {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " long"); }} 103 , {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
85 , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} 104 , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
86 , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} 105 , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
87 , {"void", nullptr, [&] 106 , {"void", nullptr, [&]
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index 43eebfc1f2..db50906318 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -183,7 +183,8 @@ run(options_type const& opts)
183 , struct_last; struct_iterator != struct_last; ++struct_iterator) 183 , struct_last; struct_iterator != struct_last; ++struct_iterator)
184 { 184 {
185 efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit); 185 efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit);
186 if (!eolian_mono::struct_definition.generate(iterator, struct_, efl::eolian::grammar::context_null())) 186 auto structs_cxt = context_add_tag(class_context{class_context::structs}, context);
187 if (!eolian_mono::struct_entities.generate(iterator, struct_, structs_cxt))
187 { 188 {
188 throw std::runtime_error("Failed to generate struct"); 189 throw std::runtime_error("Failed to generate struct");
189 } 190 }