aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-04-18 23:07:22 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2018-04-26 10:55:18 -0300
commit1837e2de10dd3231f9c8efbbf0b042a853980516 (patch)
tree5b60d96768f1c04e7356bfd1073963edc2ba2db3 /src
parentefl_mono: Actually test events by passing things by value and structs (diff)
downloadefl-1837e2de10dd3231f9c8efbbf0b042a853980516.tar.gz
efl_mono: Fix support for event arguments.
Summary: Using a type visitor scheme similar to type and marshall_type, to ease increasing coverage for other types if needed. Also, changed the filter functions for those selections to check for the full name of the regular_type_def, allowing a better specificity of the name selections. This fixes things like "Eina.Error", which was conflicting with Efl.Image.Load.Error when we compared only the last name. It didn't appear before as Load.Error only appears in a Efl.Image.Load event. Depends on https://phab.enlightenment.org/D5996 Reviewers: felipealmeida Reviewed By: felipealmeida Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D5997
Diffstat (limited to 'src')
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh73
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh5
2 files changed, 64 insertions, 14 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index 34aeab5fe0..b73e7d5bbd 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -1,32 +1,73 @@
#ifndef EOLIAN_MONO_EVENTS_HH
#define EOLINA_MONO_EVENTS_HH
+#include <iterator>
+
#include "grammar/generator.hpp"
#include "grammar/klass_def.hpp"
+#include "type_impl.hh" // For call_match
#include "name_helpers.hh"
#include "using_decl.hh"
namespace eolian_mono {
-struct get_event_args_visitor
+template<typename OutputIterator, typename Context>
+struct unpack_event_args_visitor
{
+ mutable OutputIterator sink;
+ Context const* context;
std::string arg_type;
+ attributes::type_def const& type;
- typedef get_event_args_visitor visitor_type;
- typedef std::string result_type;
- std::string operator()(grammar::attributes::regular_type_def const&) const
+ typedef unpack_event_args_visitor<OutputIterator, Context> visitor_type;
+ typedef bool result_type;
+ bool operator()(grammar::attributes::regular_type_def const& regular) const
{
- if (arg_type == "string")
- return "eina.StringConversion.NativeUtf8ToManagedString(evt.Info)";
- return "(" + arg_type + ")Marshal.PtrToStructure(evt.Info, typeof(" + arg_type + "))";
+ std::string const& arg = "evt.Info";
+
+ // Structs are usually passed by pointer to events, like having a ptr<> modifier
+ if (type.is_ptr || regular.is_struct())
+ return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))")
+ .generate(sink, attributes::unused, *context);
+
+ using attributes::regular_type_def;
+ struct match
+ {
+ eina::optional<std::string> name;
+ std::function<std::string()> function;
+ }
+ const match_table [] =
+ {
+ {"bool", [&arg] { return arg + " != IntPtr.Zero"; }}
+ , {"int", [&arg] { return arg + ".ToInt32()"; }}
+ , {"uint", [&arg] { return "(uint)" + arg + ".ToInt32()";}}
+ , {"string", [&arg] { return "eina.StringConversion.NativeUtf8ToManagedString(" + arg + ")"; }}
+ , {"Eina.Error", [&arg] { return "(eina.Error)Marshal.PtrToStructure(" + arg + ", typeof(eina.Error))"; }}
+ };
+
+ std::string full_type_name = name_helpers::type_full_name(regular);
+ auto filter_func = [&regular, &full_type_name] (match const& m)
+ {
+ return (!m.name || *m.name == regular.base_type || *m.name == full_type_name);
+ };
+
+ auto accept_func = [&](std::string const& conversion)
+ {
+ return as_generator(conversion).generate(sink, attributes::unused, *context);
+ };
+
+ if (eina::optional<bool> b = call_match(match_table, filter_func, accept_func))
+ return *b;
+ else
+ return as_generator("default(" + arg_type + ")").generate(sink, attributes::unused, *context);
}
- std::string operator()(grammar::attributes::klass_name const&) const
+ bool operator()(grammar::attributes::klass_name const&) const
{
- return "new " + arg_type + "Concrete(evt.Info)";
+ return as_generator("new " + arg_type + "Concrete(evt.Info)").generate(sink, attributes::unused, *context);
}
- std::string operator()(attributes::complex_type_def const&) const
+ bool operator()(attributes::complex_type_def const&) const
{
- return "UNSUPPORTED";
+ return as_generator("UNSUPPORTED").generate(sink, attributes::unused, *context);
}
};
@@ -138,7 +179,15 @@ struct event_definition_generator
wrapper_args_template = "<" + wrapper_args_type + ">";
std::string arg_type = wrapper_args_type + " args = new " + wrapper_args_type + "();\n"; // = (*etype).original_type.visit(get_csharp_type_visitor{});
std::string actual_arg_type = (*etype).original_type.visit(name_helpers::get_csharp_type_visitor{});
- arg_type += " args.arg = " + (*etype).original_type.visit(get_event_args_visitor{actual_arg_type}) + ";\n";
+
+ arg_type += " args.arg = ";
+
+ auto arg_type_sink = std::back_inserter(arg_type);
+
+ if (!(*etype).original_type.visit(unpack_event_args_visitor<decltype(arg_type_sink), Context>{arg_type_sink, &context, actual_arg_type, *etype}))
+ return false;
+
+ arg_type += ";\n";
event_args = arg_type;
}
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index 169ae18333..edd6cc80ed 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -115,7 +115,7 @@ struct visitor_generate
r.base_type = " void";
return r;
}}
- , {"Error", nullptr, [&] // Eina.Error
+ , {"Eina.Error", nullptr, [&] // Eina.Error
{
return regular_type_def{" eina.Error", regular.base_qualifier, {}};
}} // TODO
@@ -164,11 +164,12 @@ struct visitor_generate
// .generate(sink, attributes::unused, *context);
// }
// else
+ std::string full_type_name = name_helpers::type_full_name(regular);
if(eina::optional<bool> b = call_match
(match_table
, [&] (match const& m)
{
- return (!m.name || *m.name == regular.base_type)
+ return (!m.name || *m.name == regular.base_type || *m.name == full_type_name)
&& (!m.has_own || *m.has_own == (bool)(regular.base_qualifier & qualifier_info::is_own))
;
}