From c9dd86579f1e4b585e5dadbc9f69df0abd263917 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Fri, 27 Apr 2018 18:08:25 -0300 Subject: [PATCH] efl_mono: More uniformization of the handling of names Summary: Uses a common helper to open and close namespaces, to get the managed and unmanaged name of things, the interface, concrete and inherit class names, etc. eolian_cxx: Add namespace information to func_def, as it'll avoid eolian-cxx clients dealing with the eolian C api directly when trying to access a function pointer namespace. Depends on D6048 Reviewers: felipealmeida, vitor.sousa Reviewed By: vitor.sousa Subscribers: cedric Tags: #efl Differential Revision: https://phab.enlightenment.org/D6049 --- src/bin/eolian_cxx/eolian_cxx.cc | 2 +- src/bin/eolian_mono/eolian/mono/blacklist.hh | 4 +- .../eolian/mono/enum_definition.hh | 12 +- src/bin/eolian_mono/eolian/mono/events.hh | 25 +-- .../eolian/mono/function_definition.hh | 20 +- .../eolian/mono/function_pointer.hh | 24 +- .../eolian/mono/function_registration.hh | 6 +- src/bin/eolian_mono/eolian/mono/helpers.hh | 2 +- src/bin/eolian_mono/eolian/mono/klass.hh | 110 +++++---- src/bin/eolian_mono/eolian/mono/logging.hh | 12 + .../eolian/mono/marshall_annotation.hh | 12 +- .../eolian/mono/marshall_type_impl.hh | 4 +- .../eolian_mono/eolian/mono/name_helpers.hh | 209 +++++++++--------- src/bin/eolian_mono/eolian/mono/parameter.hh | 45 ++-- .../eolian/mono/part_definition.hh | 7 +- .../eolian/mono/struct_definition.hh | 18 +- src/bin/eolian_mono/eolian/mono/type_impl.hh | 47 +--- src/bin/eolian_mono/eolian_mono.cc | 62 +++--- src/bindings/mono/eo_mono/workaround.cs | 27 --- src/lib/eolian_cxx/grammar/klass_def.hpp | 24 +- src/tests/efl_mono/Eo.cs | 2 +- 21 files changed, 315 insertions(+), 359 deletions(-) create mode 100644 src/bin/eolian_mono/eolian/mono/logging.hh diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc index c49bb875d6..70527ddc27 100644 --- a/src/bin/eolian_cxx/eolian_cxx.cc +++ b/src/bin/eolian_cxx/eolian_cxx.cc @@ -247,7 +247,7 @@ types_generate(std::string const& fname, options_type const& opts, const Eolian_Function *func = eolian_typedecl_function_pointer_get(tp); if (!func) return false; - function_def def(func, EOLIAN_FUNCTION_POINTER, opts.unit); + function_def def(func, EOLIAN_FUNCTION_POINTER, tp, opts.unit); def.c_name = eolian_typedecl_name_get(tp); std::replace(def.c_name.begin(), def.c_name.end(), '.', '_'); functions.push_back(std::move(def)); diff --git a/src/bin/eolian_mono/eolian/mono/blacklist.hh b/src/bin/eolian_mono/eolian/mono/blacklist.hh index 863d23d9f6..fe1640ea67 100644 --- a/src/bin/eolian_mono/eolian/mono/blacklist.hh +++ b/src/bin/eolian_mono/eolian/mono/blacklist.hh @@ -65,12 +65,12 @@ inline bool is_struct_blacklisted(std::string const& full_name) inline bool is_struct_blacklisted(attributes::struct_def const& struct_) { - return is_struct_blacklisted(name_helpers::struct_full_name(struct_)); + return is_struct_blacklisted(name_helpers::struct_full_eolian_name(struct_)); } inline bool is_struct_blacklisted(attributes::regular_type_def const& struct_) { - return is_struct_blacklisted(name_helpers::type_full_name(struct_)); + return is_struct_blacklisted(name_helpers::type_full_eolian_name(struct_)); } } diff --git a/src/bin/eolian_mono/eolian/mono/enum_definition.hh b/src/bin/eolian_mono/eolian/mono/enum_definition.hh index da8505aedf..f7c40d7201 100644 --- a/src/bin/eolian_mono/eolian/mono/enum_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/enum_definition.hh @@ -17,10 +17,8 @@ struct enum_definition_generator template bool generate(OutputIterator sink, attributes::enum_def const& enum_, Context const& context) const { - std::vector cpp_namespaces = name_helpers::escape_namespace(attributes::cpp_namespaces(enum_.namespaces)); - - auto open_namespace = *("namespace " << string << " { ") << "\n"; - if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false; + if(!name_helpers::open_namespaces(sink, enum_.namespaces, context)) + return false; if(!as_generator(documentation).generate(sink, enum_, context)) return false; @@ -49,9 +47,9 @@ struct enum_definition_generator if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; - auto close_namespace = *(lit("} ")) << "\n"; - if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false; - + if(!name_helpers::close_namespaces(sink, enum_.namespaces, context)) + return false; + return true; } }; diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh index b73e7d5bbd..1d56db7dd2 100644 --- a/src/bin/eolian_mono/eolian/mono/events.hh +++ b/src/bin/eolian_mono/eolian/mono/events.hh @@ -16,7 +16,6 @@ struct unpack_event_args_visitor { mutable OutputIterator sink; Context const* context; - std::string arg_type; attributes::type_def const& type; typedef unpack_event_args_visitor visitor_type; @@ -24,6 +23,7 @@ struct unpack_event_args_visitor bool operator()(grammar::attributes::regular_type_def const& regular) const { std::string const& arg = "evt.Info"; + std::string arg_type = name_helpers::type_full_managed_name(regular); // Structs are usually passed by pointer to events, like having a ptr<> modifier if (type.is_ptr || regular.is_struct()) @@ -45,7 +45,7 @@ struct unpack_event_args_visitor , {"Eina.Error", [&arg] { return "(eina.Error)Marshal.PtrToStructure(" + arg + ", typeof(eina.Error))"; }} }; - std::string full_type_name = name_helpers::type_full_name(regular); + std::string full_type_name = name_helpers::type_full_eolian_name(regular); auto filter_func = [®ular, &full_type_name] (match const& m) { return (!m.name || *m.name == regular.base_type || *m.name == full_type_name); @@ -61,9 +61,9 @@ struct unpack_event_args_visitor else return as_generator("default(" + arg_type + ")").generate(sink, attributes::unused, *context); } - bool operator()(grammar::attributes::klass_name const&) const + bool operator()(grammar::attributes::klass_name const& cls) const { - return as_generator("new " + arg_type + "Concrete(evt.Info)").generate(sink, attributes::unused, *context); + return as_generator("new " + name_helpers::klass_full_concrete_name(cls) + "(evt.Info)").generate(sink, attributes::unused, *context); } bool operator()(attributes::complex_type_def const&) const { @@ -160,9 +160,9 @@ struct event_definition_generator std::string klass_name; if (is_inherited_event) - klass_name = name_helpers::klass_get_full_name(klass); + klass_name = name_helpers::klass_full_interface_name(klass); else - klass_name = klass.eolian_name; + klass_name = name_helpers::klass_interface_name(klass); std::string upper_c_name = utils::to_uppercase(evt.c_name); @@ -177,19 +177,18 @@ struct event_definition_generator { wrapper_args_type = name_helpers::managed_event_args_name(evt); 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{}); + std::string arg_initializer = wrapper_args_type + " args = new " + wrapper_args_type + "();\n"; // = (*etype).original_type.visit(get_csharp_type_visitor{}); - arg_type += " args.arg = "; + arg_initializer += " args.arg = "; - auto arg_type_sink = std::back_inserter(arg_type); + auto arg_initializer_sink = std::back_inserter(arg_initializer); - if (!(*etype).original_type.visit(unpack_event_args_visitor{arg_type_sink, &context, actual_arg_type, *etype})) + if (!(*etype).original_type.visit(unpack_event_args_visitor{arg_initializer_sink, &context, *etype})) return false; - arg_type += ";\n"; + arg_initializer += ";\n"; - event_args = arg_type; + event_args = arg_initializer; } // Wrapper event declaration diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh index bf7d15e36a..b5553489c8 100644 --- a/src/bin/eolian_mono/eolian/mono/function_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh @@ -10,6 +10,7 @@ #include "grammar/list.hpp" #include "grammar/alternative.hpp" #include "grammar/attribute_reorder.hpp" +#include "logging.hh" #include "type.hh" #include "name_helpers.hh" #include "helpers.hh" @@ -30,6 +31,7 @@ struct native_function_definition_generator template bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_function_definition_generator: " << f.c_name << std::endl; if(blacklist::is_function_blacklisted(f.c_name) || f.is_static) // Only Concrete classes implement static methods. return true; else @@ -69,6 +71,8 @@ struct native_function_definition_generator if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) return false; + std::string klass_inherit_name = name_helpers::klass_inherit_name(*klass); + if(!as_generator (scope_tab << " private static " @@ -85,7 +89,7 @@ struct native_function_definition_generator << scope_tab << scope_tab << "if(wrapper != null) {\n" << scope_tab << scope_tab << scope_tab << eolian_mono::native_function_definition_preamble() << scope_tab << scope_tab << scope_tab << "try {\n" - << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << string << "Inherit)wrapper)." << string + << scope_tab << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "_ret_var = " : "") << "((" << klass_inherit_name << ")wrapper)." << string << "(" << (native_argument_invocation % ", ") << ");\n" << scope_tab << scope_tab << scope_tab << "} catch (Exception e) {\n" << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Warning($\"Callback error: {e.ToString()}\");\n" @@ -94,18 +98,18 @@ struct native_function_definition_generator << eolian_mono::native_function_definition_epilogue(*klass) << scope_tab << scope_tab << "} else {\n" << scope_tab << scope_tab << scope_tab << (return_type != " void" ? "return " : "") << string - << "(efl.eo.Globals.efl_super(obj, " << string << "Inherit.klass)" << *(", " << argument) << ");\n" + << "(efl.eo.Globals.efl_super(obj, " << klass_inherit_name << ".klass)" << *(", " << argument) << ");\n" << scope_tab << scope_tab << "}\n" << scope_tab << "}\n" ) .generate(sink, std::make_tuple(f.return_type, escape_keyword(f.name), f.parameters , /***/f.c_name/***/ , f - , klass->cxx_name, managed_method_name(f.name) + , managed_method_name(f.name) , f.parameters , f , f.c_name - , klass->cxx_name, f.parameters + , f.parameters ) , context)) return false; @@ -114,10 +118,9 @@ struct native_function_definition_generator (scope_tab << "private static " << string << "_delegate " - << string << "_static_delegate = new " << string << "_delegate(" << string << "NativeInherit." << string << ");\n" + << string << "_static_delegate = new " << string << "_delegate(" << name_helpers::klass_native_inherit_name(*klass) << "." << string << ");\n" ) - .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, klass->cxx_name - , escape_keyword(f.name)), context)) + .generate(sink, std::make_tuple(f.c_name, f.c_name, f.c_name, escape_keyword(f.name)), context)) return false; return true; } @@ -133,6 +136,7 @@ struct function_definition_generator template bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_definition_generator: " << f.c_name << std::endl; if(do_super && f.is_static) // Static methods goes only on Concrete classes. return true; if(blacklist::is_function_blacklisted(f.c_name)) @@ -166,7 +170,7 @@ struct function_definition_generator << ") {\n " << eolian_mono::function_definition_preamble() << string << "(" << (do_super ? "efl.eo.Globals.efl_super(" : "") - << (f.is_static ? name_helpers::klass_get_name(f.klass) + "()": "this.raw_handle") + << (f.is_static ? name_helpers::klass_get_full_name(f.klass) + "()": "this.raw_handle") << (do_super ? ", this.raw_klass)" : "") << *(", " << argument_invocation ) << ");\n" << eolian_mono::function_definition_epilogue() diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh index 44c7458fcc..f373a13121 100644 --- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh +++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh @@ -13,36 +13,30 @@ namespace eolian_mono { // Blacklist structs that require some kind of manual binding. -static bool is_function_ptr_blacklisted(attributes::function_def const& func, std::vector const &namesp) +static bool is_function_ptr_blacklisted(attributes::function_def const& func) { - std::stringstream full_name; - - for (auto&& i : namesp) - full_name << i << "."; - full_name << func.name; - - std::string name = full_name.str(); + std::string name = name_helpers::function_ptr_full_eolian_name(func); return false; } struct function_pointer { template - bool generate(OutputIterator sink, attributes::function_def const& f, std::vector const &namesp, Context const& context) const + bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_pointer_generator: " << f.name << std::endl; // FIXME export Typedecl in eolian_cxx API - std::vector namespaces = name_helpers::escape_namespace(namesp); auto funcptr_ctx = context_add_tag(class_context{class_context::function_ptr}, context); std::string return_type; if(!as_generator(eolian_mono::type(true)).generate(std::back_inserter(return_type), f.return_type, context)) return false; - if (is_function_ptr_blacklisted(f, namesp)) + if (is_function_ptr_blacklisted(f)) return true; - auto open_namespace = *("namespace " << string << " {") << "\n"; - if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(funcptr_ctx))) return false; + if (!name_helpers::open_namespaces(sink, f.namespaces, funcptr_ctx)) + return false; // C# visible delegate if (!as_generator(documentation @@ -103,8 +97,8 @@ struct function_pointer { ).generate(sink, std::make_tuple(f.return_type, f.parameters, f, f.parameters, f, f.return_type, f.return_type, f.parameters, f_name, f_name, f, f.parameters, f), funcptr_ctx)) return false; - auto close_namespace = *(lit("} ")) << "\n"; - if(!as_generator(close_namespace).generate(sink, namespaces, funcptr_ctx)) return false; + if (!name_helpers::close_namespaces(sink, f.namespaces, funcptr_ctx)) + return false; return true; } diff --git a/src/bin/eolian_mono/eolian/mono/function_registration.hh b/src/bin/eolian_mono/eolian/mono/function_registration.hh index a653a3d98c..22fc42599b 100644 --- a/src/bin/eolian_mono/eolian/mono/function_registration.hh +++ b/src/bin/eolian_mono/eolian/mono/function_registration.hh @@ -10,6 +10,7 @@ #include "grammar/list.hpp" #include "grammar/alternative.hpp" #include "grammar/attribute_reorder.hpp" +#include "logging.hh" #include "type.hh" #include "marshall_type.hh" #include "parameter.hh" @@ -28,6 +29,7 @@ struct function_registration_generator template bool generate(OutputIterator sink, attributes::function_def const& f, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "function_registration_generator: " << f.name << std::endl; if(blacklist::is_function_blacklisted(f.c_name) || f.is_static) // Static methods aren't overrideable return true; else @@ -40,9 +42,9 @@ struct function_registration_generator #else (scope_tab << scope_tab << "descs[" << index << "].api_func = efl.eo.Globals.dlsym(efl.eo.Globals.RTLD_DEFAULT, \"" << string << "\");\n" #endif - << scope_tab << scope_tab << "descs[" << index << "].func = Marshal.GetFunctionPointerForDelegate(" << string << "NativeInherit." << string << "_static_delegate);\n" + << scope_tab << scope_tab << "descs[" << index << "].func = Marshal.GetFunctionPointerForDelegate(" << name_helpers::klass_native_inherit_name(*klass) << "." << string << "_static_delegate);\n" ) - .generate(sink, std::make_tuple(f.c_name, klass->cxx_name, f.c_name), context)) + .generate(sink, std::make_tuple(f.c_name, f.c_name), context)) return false; return true; } diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh index 9af594191d..40a99915ab 100644 --- a/src/bin/eolian_mono/eolian/mono/helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/helpers.hh @@ -48,7 +48,7 @@ inline bool need_pointer_conversion(attributes::regular_type_def const* regular) return false; if (regular->is_enum() - || (regular->is_struct() && name_helpers::type_full_name(*regular) != "Eina.Binbuf") + || (regular->is_struct() && name_helpers::type_full_eolian_name(*regular) != "Eina.Binbuf") ) return true; diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index cc347b7765..7f67dddc08 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -30,15 +30,15 @@ namespace eolian_mono { template -static bool generate_static_cast_method(OutputIterator sink, const std::string &class_name, Context const &context) +static bool generate_static_cast_method(OutputIterator sink, grammar::attributes::klass_def const& cls, Context const &context) { return as_generator( scope_tab << "///Casts obj into an instance of this type.\n" - << scope_tab << "public static " << class_name << " static_cast(efl.Object obj)\n" + << scope_tab << "public static " << name_helpers::klass_interface_name(cls) << " static_cast(efl.Object obj)\n" << scope_tab << "{\n" << scope_tab << scope_tab << "if (obj == null)\n" << scope_tab << scope_tab << scope_tab << "throw new System.ArgumentNullException(\"obj\");\n" - << scope_tab << scope_tab << "return new " << class_name << "Concrete(obj.raw_handle);\n" + << scope_tab << scope_tab << "return new " << name_helpers::klass_concrete_name(cls) << "(obj.raw_handle);\n" << scope_tab << "}\n" ).generate(sink, nullptr, context); } @@ -91,6 +91,7 @@ struct klass template bool generate(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "klass_generator: " << cls.eolian_name << std::endl; std::string suffix, class_type; switch(cls.type) { @@ -109,9 +110,9 @@ struct klass break; } - std::vector namespaces = name_helpers::escape_namespace(cls.namespaces); - auto open_namespace = *("namespace " << string << " { ") << "\n"; - if(!as_generator(open_namespace).generate(sink, namespaces, add_lower_case_context(context))) return false; + if (!name_helpers::open_namespaces(sink, cls.namespaces, context)) + return false; + auto methods = cls.get_all_methods(); // Interface class @@ -130,25 +131,25 @@ struct klass for(auto first = std::begin(cls.immediate_inherits) , last = std::end(cls.immediate_inherits); first != last; ++first) { - if(!as_generator("\n" << scope_tab << *(lower_case[string] << ".") << string << " ,") - .generate(sink, std::make_tuple(name_helpers::escape_namespace(first->namespaces), first->eolian_name), iface_cxt)) + if(!as_generator("\n" << scope_tab << string << " ,").generate(sink, name_helpers::klass_full_interface_name(*first), iface_cxt)) return false; - // if(std::next(first) != last) - // *sink++ = ','; } - // if(cls.immediate_inherits.empty()) - if(!as_generator("\n" << scope_tab << "efl.eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt)) return false; - if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt)) return false; - - if(!as_generator(*(scope_tab << function_declaration)) - .generate(sink, cls.functions, iface_cxt)) return false; - if (!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt)) + if(!as_generator("\n" << scope_tab << "efl.eo.IWrapper, IDisposable").generate(sink, attributes::unused, iface_cxt)) + return false; + + if(!as_generator("\n{\n").generate(sink, attributes::unused, iface_cxt)) + return false; + + if(!as_generator(*(scope_tab << function_declaration)).generate(sink, cls.functions, iface_cxt)) + return false; + + if(!as_generator(*(event_declaration)).generate(sink, cls.events, iface_cxt)) return false; for (auto &&p : cls.parts) if (!as_generator( - name_helpers::klass_name_to_csharp(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n" + name_helpers::klass_full_interface_name(p.klass) << " " << utils::capitalize(p.name) << "{ get;}\n" ).generate(sink, attributes::unused, iface_cxt)) return false; @@ -156,15 +157,16 @@ struct klass if(!as_generator("}\n").generate(sink, attributes::unused, iface_cxt)) return false; } - auto class_get_name = *(lower_case[string] << "_") << lower_case[string] << "_class_get"; // Concrete class // if(class_type == "class") { auto concrete_cxt = context_add_tag(class_context{class_context::concrete}, context); + auto concrete_name = name_helpers::klass_concrete_name(cls); + auto interface_name = name_helpers::klass_interface_name(cls); if(!as_generator ( documentation - << "sealed public class " << string << "Concrete : " << string << "\n{\n" + << "sealed public class " << concrete_name << " : " << interface_name << "\n{\n" << scope_tab << "System.IntPtr handle;\n" << scope_tab << "///Pointer to the native instance.\n" << scope_tab << "public System.IntPtr raw_handle {\n" @@ -175,18 +177,18 @@ struct klass << scope_tab << scope_tab << "get { return efl.eo.Globals.efl_class_get(handle); }\n" << scope_tab << "}\n" << scope_tab << "///Delegate for function to be called from inside the native constructor.\n" - << scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n" + << scope_tab << "public delegate void ConstructingMethod(" << interface_name << " obj);\n" << scope_tab << "///Returns the pointer the unerlying Eo class object. Used internally on class methods.\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag(concrete_cxt).actual_library_name(cls.filename) << ")] public static extern System.IntPtr\n" - << scope_tab << scope_tab << class_get_name << "();\n" + << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" << (class_type == "class" ? "" : "/*") << scope_tab << "///Creates a new instance.\n" << scope_tab << "///Parent instance.\n" << scope_tab << "///Delegate to call constructing methods that should be run inside the constructor.\n" - << scope_tab << "public " << string << "Concrete(efl.Object parent = null, ConstructingMethod init_cb=null)\n" + << scope_tab << "public " << concrete_name << "(efl.Object parent = null, ConstructingMethod init_cb=null)\n" << scope_tab << "{\n" - << scope_tab << scope_tab << "System.IntPtr klass = " << class_get_name << "();\n" + << scope_tab << scope_tab << "System.IntPtr klass = " << name_helpers::klass_get_name(cls) << "();\n" << scope_tab << scope_tab << "System.IntPtr parent_ptr = System.IntPtr.Zero;\n" << scope_tab << scope_tab << "if(parent != null)\n" << scope_tab << scope_tab << scope_tab << "parent_ptr = parent.raw_handle;\n" @@ -200,13 +202,13 @@ struct klass << scope_tab << "}\n" << (class_type == "class" ? "" : "*/") << scope_tab << "///Constructs an instance from a native pointer.\n" - << scope_tab << "public " << string << "Concrete(System.IntPtr raw)\n" + << scope_tab << "public " << concrete_name << "(System.IntPtr raw)\n" << scope_tab << "{\n" << scope_tab << scope_tab << "handle = raw;\n" << scope_tab << scope_tab << "register_event_proxies();\n" << scope_tab << "}\n" << scope_tab << "///Destructor.\n" - << scope_tab << "~" << string << "Concrete()\n" + << scope_tab << "~" << concrete_name << "()\n" << scope_tab << "{\n" << scope_tab << scope_tab << "Dispose(false);\n" << scope_tab << "}\n" @@ -225,15 +227,10 @@ struct klass << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n" << scope_tab << "}\n" ) - .generate(sink - , std::make_tuple( cls, - cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name - , cls.cxx_name, cls.namespaces, cls.eolian_name, cls.cxx_name - , cls.cxx_name) - , concrete_cxt)) + .generate(sink, cls, concrete_cxt)) return false; - if (!generate_static_cast_method(sink, cls.cxx_name, concrete_cxt)) + if (!generate_static_cast_method(sink, cls, concrete_cxt)) return false; if (!generate_equals_method(sink, concrete_cxt)) @@ -266,10 +263,15 @@ struct klass bool cls_has_string_return = has_string_return(cls); bool cls_has_stringshare_return = has_stringshare_return(cls); + auto interface_name = name_helpers::klass_interface_name(cls); + auto inherit_name = name_helpers::klass_inherit_name(cls); + auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); + + if(!as_generator ( documentation - << "public " << class_type << " " << string << "Inherit : " << string << "\n{\n" + << "public " << class_type << " " << inherit_name << " : " << interface_name << "\n{\n" << scope_tab << "System.IntPtr handle;\n" << scope_tab << "internal static System.IntPtr klass = System.IntPtr.Zero;\n" << scope_tab << "private static readonly object klassAllocLock = new object();\n" @@ -284,20 +286,19 @@ struct klass << scope_tab << scope_tab << "get { return klass; }\n" << scope_tab << "}\n" << scope_tab << "///Delegate for function to be called from inside the native constructor.\n" - << scope_tab << "public delegate void ConstructingMethod(" << string << " obj);\n" + << scope_tab << "public delegate void ConstructingMethod(" << interface_name << " obj);\n" << scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag(inherit_cxt).actual_library_name(cls.filename) << ")] private static extern System.IntPtr\n" - << scope_tab << scope_tab << class_get_name << "();\n" + << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" << scope_tab << "///Creates a new instance.\n" << scope_tab << "///Parent instance.\n" << scope_tab << "///Delegate to call constructing methods that should be run inside the constructor.\n" - << scope_tab << "public " << string << "Inherit(efl.Object parent = null, ConstructingMethod init_cb=null)\n" + << scope_tab << "public " << inherit_name << "(efl.Object parent = null, ConstructingMethod init_cb=null)\n" << scope_tab << "{\n" << scope_tab << scope_tab << "if (klass == System.IntPtr.Zero) {\n" << scope_tab << scope_tab << scope_tab << "lock (klassAllocLock) {\n" << scope_tab << scope_tab << scope_tab << scope_tab << "if (klass == System.IntPtr.Zero) {\n" - << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "klass = efl.eo.Globals.register_class(new efl.eo.Globals.class_initializer(" << string << "NativeInherit.class_initializer), \"" << string << "\", " << class_get_name << "());\n" - //<< scope_tab << scope_tab << "klass = efl.eo.Globals.register_class(null/*new efl.eo.Globals.class_initializer(" << string << "NativeInherit.class_initializer)*/, " << class_get_name << "());\n" + << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "klass = efl.eo.Globals.register_class(new efl.eo.Globals.class_initializer(" << native_inherit_name << ".class_initializer), \"" << cls.eolian_name << "\", " << name_helpers::klass_get_name(cls) << "());\n" << scope_tab << scope_tab << scope_tab << scope_tab << "}\n" << scope_tab << scope_tab << scope_tab << "}\n" << scope_tab << scope_tab << "}\n" @@ -311,7 +312,7 @@ struct klass << scope_tab << scope_tab << "eina.Error.RaiseIfOccurred();\n" << scope_tab << "}\n" << scope_tab << "///Destructor.\n" - << scope_tab << "~" << string << "Inherit()\n" + << scope_tab << "~" << inherit_name << "()\n" << scope_tab << "{\n" << scope_tab << scope_tab << "Dispose(false);\n" << scope_tab << "}\n" @@ -332,15 +333,7 @@ struct klass << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n" << scope_tab << "}\n" ) - .generate(sink - , std::make_tuple( - cls, cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name - , cls.cxx_name, cls.cxx_name, cls.cxx_name, cls.namespaces, cls.eolian_name, cls.cxx_name - , cls.cxx_name) - , inherit_cxt)) - return false; - - if (!generate_static_cast_method(sink, cls.cxx_name, inherit_cxt)) + .generate(sink, cls, inherit_cxt)) return false; if (!generate_equals_method(sink, inherit_cxt)) @@ -375,14 +368,15 @@ struct klass if(class_type == "class") { auto inative_cxt = context_add_tag(class_context{class_context::inherit_native}, context); + auto native_inherit_name = name_helpers::klass_native_inherit_name(cls); if(!as_generator ( - "internal " << class_type << " " << string << "NativeInherit {\n" + "internal " << class_type << " " << native_inherit_name << " {\n" << scope_tab << "public static byte class_initializer(IntPtr klass)\n" << scope_tab << "{\n" << scope_tab << scope_tab << "Efl_Op_Description[] descs = new Efl_Op_Description[" << grammar::int_ << "];\n" ) - .generate(sink, std::make_tuple(cls.cxx_name, function_count), inative_cxt)) + .generate(sink, function_count, inative_cxt)) return false; // Native wrapper registration @@ -404,22 +398,22 @@ struct klass << scope_tab << scope_tab << "Marshal.StructureToPtr(ops, ops_ptr, false);\n" << scope_tab << scope_tab << "efl.eo.Globals.efl_class_functions_set(klass, ops_ptr, IntPtr.Zero);\n" ).generate(sink, attributes::unused, inative_cxt)) return false; - - + + if(!as_generator(scope_tab << scope_tab << "return 1;\n" << scope_tab << "}\n") .generate(sink, attributes::unused, inative_cxt)) return false; - + // // Native method definitions if(!as_generator(*(native_function_definition(cls))) .generate(sink, methods, inative_cxt)) return false; if(!as_generator("}\n").generate(sink, attributes::unused, inative_cxt)) return false; } - - auto close_namespace = *(lit("} ")) << "\n"; - if(!as_generator(close_namespace).generate(sink, namespaces, context)) return false; - + + if(!name_helpers::close_namespaces(sink, cls.namespaces, context)) + return false; + return true; } diff --git a/src/bin/eolian_mono/eolian/mono/logging.hh b/src/bin/eolian_mono/eolian/mono/logging.hh new file mode 100644 index 0000000000..d13c3957ad --- /dev/null +++ b/src/bin/eolian_mono/eolian/mono/logging.hh @@ -0,0 +1,12 @@ +#ifndef EOLIAN_MONO_LOGGING_HH +#define EOLIAN_MONO_LOGGING_HH + +#include + +namespace eolian_mono { + +efl::eina::log_domain domain("eolian_mono"); + +} + +#endif diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh index 4516b97453..576ccdb4c9 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh @@ -144,12 +144,10 @@ struct marshall_annotation_visitor_generate { const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; - std::vector namespaces = name_helpers::escape_namespace(klass_name.namespaces); return as_generator ((is_return ? return_prefix : no_return_prefix) - << *(lower_case[string] << ".") << string - << "Concrete, efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" - ).generate(sink, std::make_tuple(namespaces, klass_name.eolian_name), *context); + << string << ", efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" + ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); } bool operator()(attributes::complex_type_def const&) const { @@ -251,12 +249,10 @@ struct marshall_native_annotation_visitor_generate { const char no_return_prefix[] = "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; const char return_prefix[] = "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(efl.eo.MarshalTest<"; - std::vector namespaces = name_helpers::escape_namespace(klass_name.namespaces); return as_generator ((is_return ? return_prefix : no_return_prefix) - << *(lower_case[string] << ".") << string - << "Concrete, efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" - ).generate(sink, std::make_tuple(namespaces, klass_name.eolian_name), *context); + << string << ", efl.eo." << (klass_name.base_qualifier & qualifier_info::is_own ? "OwnTag" : "NonOwnTag") << ">))]" + ).generate(sink, name_helpers::klass_full_concrete_name(klass_name), *context); } bool operator()(attributes::complex_type_def const&) const { 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 ee9659c6b1..38dbbcb48c 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh @@ -160,8 +160,8 @@ struct marshall_type_visitor_generate { if ((is_out || is_return) && is_ptr) return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context); - return as_generator(*(lower_case[string] << ".") << string << "_StructInternal") - .generate(sink, std::make_tuple(name_helpers::escape_namespace(regular.namespaces), regular.base_type), *context); + return as_generator(string << "_StructInternal") + .generate(sink, name_helpers::type_full_managed_name(regular), *context); } else if (eina::optional b = call_match (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 4dffb9893a..59d6b59b18 100644 --- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh @@ -12,6 +12,14 @@ #include "grammar/integral.hpp" #include "grammar/generator.hpp" #include "grammar/klass_def.hpp" +#include "grammar/list.hpp" +#include "grammar/string.hpp" +#include "grammar/integral.hpp" + +using efl::eolian::grammar::as_generator; +using efl::eolian::grammar::string; +using efl::eolian::grammar::lit; +using efl::eolian::grammar::operator*; namespace eolian_mono { @@ -30,6 +38,11 @@ inline bool is_iequal(std::string const& lhs, std::string const& rhs) } } +inline std::string identity(std::string const& str) +{ + return str; +} + inline std::string escape_keyword(std::string const& name) { using detail::is_iequal; @@ -51,20 +64,10 @@ inline std::string escape_keyword(std::string const& name) return name; } -inline std::vector escape_namespace(std::vector namespaces) -{ - // if(namespaces.empty()) - // namespaces.push_back("nonamespace"); - // else - { - for(auto&& i : namespaces) - i = escape_keyword(i); - } - return namespaces; -} +typedef std::function string_transform_func; -inline std::string get_namespaces(std::vector const& namespaces, char separator, - std::function func=[] (std::string const& c) { return c; }) +inline std::string join_namespaces(std::vector const& namespaces, char separator, + string_transform_func func=identity) { std::stringstream s; for (auto&& n : namespaces) @@ -73,12 +76,6 @@ inline std::string get_namespaces(std::vector const& namespaces, ch return s.str(); } -inline std::string get_namespaces(attributes::klass_def const& klass, char separator, - std::function func=[] (std::string const& c) { return c; }) -{ - return get_namespaces(klass.namespaces, separator, func); -} - static const std::vector verbs = { "add", @@ -170,16 +167,9 @@ void reorder_verb(std::vector &names) } } -inline std::string klass_name_to_csharp(attributes::klass_name const& clsname) +inline std::string managed_namespace(std::string const& ns) { - std::ostringstream output; - - for (auto namesp : clsname.namespaces) - output << utils::to_lowercase(namesp) << "."; - - output << clsname.eolian_name; - - return output.str(); + return utils::to_lowercase(escape_keyword(ns)); } inline std::string managed_method_name(std::string const& underscore_name) @@ -191,55 +181,24 @@ inline std::string managed_method_name(std::string const& underscore_name) return escape_keyword(utils::to_pascal_case(names)); } -inline std::string managed_event_name(std::string const& name) +inline std::string function_ptr_full_eolian_name(attributes::function_def const& func) { - return utils::to_pascal_case(utils::split(name, ','), "") + "Evt"; + return join_namespaces(func.namespaces, '.') + func.name; } -inline std::string managed_event_args_short_name(attributes::event_def evt) +inline std::string type_full_eolian_name(attributes::regular_type_def const& type) { - return name_helpers::managed_event_name(evt.name) + "_Args"; + return join_namespaces(type.namespaces, '.') + type.base_type; } -inline std::string managed_event_args_name(attributes::event_def evt) +inline std::string type_full_managed_name(attributes::regular_type_def const& type) { - std::string prefix = name_helpers::klass_name_to_csharp(evt.klass); - return prefix + "Concrete." + managed_event_args_short_name(evt); + return join_namespaces(type.namespaces, '.', managed_namespace) + type.base_type; } -inline std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass) +inline std::string struct_full_eolian_name(attributes::struct_def const& struct_) { - std::stringstream s; - - for (auto&& n : klass.namespaces) - { - s << n; - s << '_'; - } - s << klass.cxx_name << '_' << managed_event_name(evt.name); - return s.str(); -} - -inline std::string type_full_name(attributes::regular_type_def const& type) -{ - std::string full_name; - for (auto& name : type.namespaces) - { - full_name += name + "."; - } - full_name += type.base_type; - return full_name; -} - -inline std::string struct_full_name(attributes::struct_def const& struct_) -{ - std::string full_name; - for (auto& name : struct_.namespaces) - { - full_name += name + "."; - } - full_name += struct_.cxx_name; - return full_name; + return join_namespaces(struct_.namespaces, '.') + struct_.cxx_name; } inline std::string to_field_name(std::string const& in) @@ -247,54 +206,87 @@ inline std::string to_field_name(std::string const& in) return utils::capitalize(in); } -inline std::string klass_get_full_name(attributes::klass_def const& klass) +// Class name translation (interface/concrete/inherit/etc) +template +inline std::string klass_interface_name(T const& klass) { - std::ostringstream output; - - for(auto namesp : klass.namespaces) - output << utils::to_lowercase(escape_keyword(namesp)) << "."; - - output << klass.eolian_name; - - return output.str(); + return klass.eolian_name; } -inline std::string klass_get_name(attributes::klass_name const &clsname) +template +inline std::string klass_full_interface_name(T const& klass) { - std::ostringstream output; - - output << klass_name_to_csharp(clsname); - output << "Concrete."; - - for (auto namesp : clsname.namespaces) - output << utils::to_lowercase(namesp) << "_"; - output << utils::to_lowercase(clsname.eolian_name); - output << "_class_get"; - - return output.str(); + return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_interface_name(klass); } +template +inline std::string klass_concrete_name(T const& klass) +{ + return klass.eolian_name + "Concrete"; +} + +template +inline std::string klass_full_concrete_name(T const& klass) +{ + return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_concrete_name(klass); +} + +template +inline std::string klass_inherit_name(T const& klass) +{ + return klass.eolian_name + "Inherit"; +} + +template +inline std::string klass_native_inherit_name(T const& klass) +{ + return klass.eolian_name + "NativeInherit"; +} + +template +inline std::string klass_get_name(T const& clsname) +{ + return utils::to_lowercase(join_namespaces(clsname.namespaces, '_') + clsname.eolian_name + "_class_get"); +} + +inline std::string klass_get_full_name(attributes::klass_name const& clsname) +{ + return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname); +} + +// Events +inline std::string managed_event_name(std::string const& name) +{ + return utils::to_pascal_case(utils::split(name, ','), "") + "Evt"; +} + +inline std::string managed_event_args_short_name(attributes::event_def const& evt) +{ + return name_helpers::managed_event_name(evt.name) + "_Args"; +} + +inline std::string managed_event_args_name(attributes::event_def evt) +{ + return klass_full_concrete_name(evt.klass) + "." + managed_event_args_short_name(evt); +} + +inline std::string translate_inherited_event_name(const attributes::event_def &evt, const attributes::klass_def &klass) +{ + return join_namespaces(klass.namespaces, '_') + klass.cxx_name + "_" + managed_event_name(evt.name); +} + +// Type visistor struct get_csharp_type_visitor { typedef get_csharp_type_visitor visitor_type; typedef std::string result_type; std::string operator()(attributes::regular_type_def const& type) const { - std::stringstream csharp_name; - for (auto&& i : escape_namespace(type.namespaces)) - csharp_name << utils::to_lowercase(i) << "."; - csharp_name << type.base_type; - - return csharp_name.str(); + return type_full_managed_name(type); } std::string operator()(attributes::klass_name const& name) const { - std::stringstream csharp_name; - for (auto&& i : escape_namespace(name.namespaces)) - csharp_name << utils::to_lowercase(i) << "."; - csharp_name << name.eolian_name; - - return csharp_name.str(); + return klass_full_interface_name(name); } std::string operator()(attributes::complex_type_def const&) const { @@ -302,6 +294,23 @@ struct get_csharp_type_visitor } }; +// Open/close namespaces +template +bool open_namespaces(OutputIterator sink, std::vector namespaces, Context context) +{ + std::transform(namespaces.begin(), namespaces.end(), namespaces.begin(), managed_namespace); + + auto open_namespace = *("namespace " << string << " { ") << "\n"; + return as_generator(open_namespace).generate(sink, namespaces, context); +} + +template +bool close_namespaces(OutputIterator sink, std::vector const& namespaces, Context context) +{ + auto close_namespace = *(lit("} ")) << "\n"; + return as_generator(close_namespace).generate(sink, namespaces, context); +} + } // namespace name_helpers diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index 2cf472c12d..f7c97b723f 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -413,11 +413,7 @@ struct type_name_visitor std::string operator()(grammar::attributes::regular_type_def const &type) const { - std::stringstream type_name; - for (auto&& i : escape_namespace(type.namespaces)) - type_name << i << "."; - type_name << type.base_type; - return type_name.str(); + return name_helpers::type_full_eolian_name(type); } template @@ -1077,6 +1073,7 @@ struct native_convert_out_assign_generator template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "native_convert_out_assign_generator: " << param.param_name << std::endl; if (param.direction == attributes::parameter_direction::in) return true; @@ -1095,15 +1092,25 @@ struct native_convert_out_assign_generator } else if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) { + if (klass == nullptr) + { + EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to assign out stringshare from native wrapper." << std::endl; + return false; + } return as_generator( - string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n" - ).generate(sink, std::make_tuple(escape_keyword(param.param_name), klass->cxx_name, out_variable_name(param.param_name)), context); + string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, " << string << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); } else if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)) { + if (klass == nullptr) + { + EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to assign out string from native wrapper." << std::endl; + return false; + } return as_generator( - string << "= efl.eo.Globals.cached_string_to_intptr(((" << string << "Inherit)wrapper).cached_strings, " << string << ");\n" - ).generate(sink, std::make_tuple(escape_keyword(param.param_name), klass->cxx_name, out_variable_name(param.param_name)), context); + string << "= efl.eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, " << string << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context); } else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) @@ -1230,9 +1237,14 @@ struct native_convert_return_generator { if(!ret_type.has_own) { + if (klass == nullptr) + { + EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to return string from native wrapper." << std::endl; + return false; + } return as_generator( - "return efl.eo.Globals.cached_string_to_intptr(((" << string << "Inherit)wrapper).cached_strings, _ret_var);\n" - ).generate(sink, klass->cxx_name, context); + "return efl.eo.Globals.cached_string_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_strings, _ret_var);\n" + ).generate(sink, attributes::unused, context); } else { @@ -1243,9 +1255,14 @@ struct native_convert_return_generator else if (ret_type.c_type == "Eina_Stringshare *") { // Correct check for string? if (!ret_type.has_own) { + if (klass == nullptr) + { + EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Null class found when trying to return stringshare from native wrapper." << std::endl; + return false; + } return as_generator( - "return efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, _ret_var);\n" - ).generate(sink, klass->cxx_name, context); + "return efl.eo.Globals.cached_stringshare_to_intptr(((" << name_helpers::klass_inherit_name(*klass) << ")wrapper).cached_stringshares, _ret_var);\n" + ).generate(sink, attributes::unused, context); } else { @@ -1375,7 +1392,7 @@ struct native_convert_function_pointer_generator EINA_LOG_ERR("Failed to get function pointer info for c type [%s]", param.type.c_type.c_str()); return false; } - attributes::function_def f(fd, EOLIAN_FUNCTION_POINTER, param.unit); + attributes::function_def f(fd, EOLIAN_FUNCTION_POINTER, tpd, param.unit); std::string param_name = escape_keyword(param.param_name); // Allocate GCHandle in "param_name"_handle for param; diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh index bb2e50f6c9..2a54ceb961 100644 --- a/src/bin/eolian_mono/eolian/mono/part_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh @@ -18,14 +18,15 @@ struct part_definition_generator template bool generate(OutputIterator sink, attributes::part_def const& part, Context const& context) const { - std::string part_klass_name = name_helpers::klass_name_to_csharp(part.klass); + auto part_interface_name = name_helpers::klass_full_interface_name(part.klass); + auto part_klass_name = name_helpers::klass_full_concrete_name(part.klass); return as_generator(scope_tab << documentation - << scope_tab << "public " << part_klass_name << " " << utils::capitalize(part.name) << "\n" + << scope_tab << "public " << part_interface_name << " " << utils::capitalize(part.name) << "\n" << scope_tab << "{\n" << scope_tab << scope_tab << "get\n" << scope_tab << scope_tab << "{\n" << scope_tab << scope_tab << scope_tab << "efl.Object obj = efl_part(raw_handle, \"" << part.name << "\");\n" - << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << "Concrete.static_cast(obj);\n" + << scope_tab << scope_tab << scope_tab << "return " << part_klass_name << ".static_cast(obj);\n" << scope_tab << scope_tab << "}\n" << scope_tab << "}\n" ).generate(sink, part.documentation, context); diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index ab5db8f180..79e6ec6f1b 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -31,7 +31,7 @@ struct struct_definition_generator template bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const { - + EINA_CXX_DOM_LOG_DBG(eolian_mono::domain) << "struct_definition_generator: " << struct_.cxx_name << std::endl; if(!as_generator(documentation).generate(sink, struct_, context)) return false; if(!as_generator @@ -267,13 +267,15 @@ struct to_external_field_convert_generator if (klass) { + auto interface_name = name_helpers::klass_full_interface_name(*klass); + auto concrete_name = name_helpers::klass_full_concrete_name(*klass); if (!as_generator( "\n" << scope_tab << scope_tab << "_external_struct." << string - << " = (" << type << ") System.Activator.CreateInstance(typeof(" - << type << "Concrete), new System.Object[] {_internal_struct." << string << "});\n" + << " = (" << interface_name << ") System.Activator.CreateInstance(typeof(" + << concrete_name << "), new System.Object[] {_internal_struct." << string << "});\n" << scope_tab << scope_tab << "efl.eo.Globals.efl_ref(_internal_struct." << string << ");\n\n") - .generate(sink, std::make_tuple(field_name, field.type, field.type, field_name, field_name), context)) + .generate(sink, std::make_tuple(field_name, field_name, field_name), context)) return false; } else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *") @@ -443,10 +445,8 @@ struct struct_entities_generator if (blacklist::is_struct_blacklisted(struct_)) return true; - std::vector cpp_namespaces = name_helpers::escape_namespace(attributes::cpp_namespaces(struct_.namespaces)); - auto open_namespace = *("namespace " << string << " { ") << "\n"; - if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) + if (!name_helpers::open_namespaces(sink, struct_.namespaces, context)) return false; if (!struct_definition.generate(sink, struct_, context)) @@ -458,10 +458,8 @@ struct struct_entities_generator if (!struct_binding_conversion_functions.generate(sink, struct_, context)) return false; - auto close_namespace = *(lit("} ")) << "\n"; - if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false; + return name_helpers::close_namespaces(sink, struct_.namespaces, context); - return true; } } const struct_entities {}; diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh index edd6cc80ed..ee44460169 100644 --- a/src/bin/eolian_mono/eolian/mono/type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh @@ -151,20 +151,7 @@ struct visitor_generate { return regular_type_def{" eina.Value", regular.base_qualifier, {}}; }} // FIXME add proper support for any_value_ptr }; - // if(regular.base_type == "void_ptr") - // { - // if(regular.base_qualifier & qualifier_info::is_ref) - // throw std::runtime_error("ref of void_ptr is invalid"); - // return as_generator - // ( - // lit("void") << (regular.base_qualifier & qualifier_info::is_const ? " const" : "") - // << "*" - // << (is_out ? "&" : "") - // ) - // .generate(sink, attributes::unused, *context); - // } - // else - std::string full_type_name = name_helpers::type_full_name(regular); + std::string full_type_name = name_helpers::type_full_eolian_name(regular); if(eina::optional b = call_match (match_table , [&] (match const& m) @@ -245,40 +232,12 @@ struct visitor_generate // } else { - // as_generator(" Generating: " << *(lower_case[string] << ".") << string << "\n") - // .generate(std::ostream_iterator(std::cerr), std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context); - if(as_generator - ( - *(lower_case[string] << ".") - << string - // << (regular.base_qualifier & qualifier_info::is_const - // || (regular.base_qualifier & qualifier_info::is_ref - // && !is_return && !is_out) - // ? /*" const"*/ "" : "") - /*<< (regular.base_qualifier & qualifier_info::is_ref? "&" : "")*/ - ) - .generate(sink, std::make_tuple(name_helpers::escape_namespace(regular.namespaces), regular.base_type), *context)) - return true; - else - return false; + return as_generator(string).generate(sink, name_helpers::type_full_managed_name(regular), *context); } } bool operator()(attributes::klass_name klass) const { - // as_generator(" Generating: " << *(lower_case[string] << ".") << string << "\n") - // .generate(std::ostream_iterator(std::cerr), std::make_tuple(attributes::cpp_namespaces(klass.namespaces), klass.eolian_name), *context); - // if(klass.namespaces.size() == 1 - // && klass.namespaces[0] == "Eina" - // && klass.eolian_name == "Error") - // return - // as_generator(" System.IntPtr") - // .generate(sink, attributes::unused, *context); - return - as_generator(*(lower_case[string] << ".") << string) - .generate(sink, std::make_tuple(name_helpers::escape_namespace(klass.namespaces), klass.eolian_name), *context) - // && (!(klass.base_qualifier & qualifier_info::is_ref) - // || as_generator("&").generate(sink, attributes::unused, *context)) - ; + return as_generator(string).generate(sink, name_helpers::klass_full_interface_name(klass), *context); } bool operator()(attributes::complex_type_def const& complex) const { diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc index e1b53d95ad..7f65a4fcaa 100644 --- a/src/bin/eolian_mono/eolian_mono.cc +++ b/src/bin/eolian_mono/eolian_mono.cc @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -48,8 +49,6 @@ struct options_type std::map references_map; }; -efl::eina::log_domain domain("eolian_mono"); - // Parses a CSV file in the format 'filename,library' (without trimming spaces around ',') static std::vector > parse_reference(std::string filename) @@ -142,19 +141,9 @@ run(options_type const& opts) continue; const Eolian_Function *fp = eolian_typedecl_function_pointer_get(tp); - efl::eolian::grammar::attributes::function_def function_def(fp, EOLIAN_FUNCTION_POINTER, opts.unit); - std::vector namespaces; - - for (efl::eina::iterator namespace_iterator(::eolian_typedecl_namespaces_get(tp)), namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) - { - namespaces.push_back(&*namespace_iterator); - } - - if (!eolian_mono::function_pointer - .generate(iterator, function_def, eolian_mono::name_helpers::escape_namespace(namespaces), context)) - { - throw std::runtime_error("Failed to generate function pointer wrapper"); - } + efl::eolian::grammar::attributes::function_def function_def(fp, EOLIAN_FUNCTION_POINTER, tp, opts.unit); + if (!eolian_mono::function_pointer.generate(iterator, function_def, context)) + throw std::runtime_error("Failed to generate function pointer wrapper"); } if (klass) @@ -168,30 +157,29 @@ run(options_type const& opts) throw std::runtime_error("Failed to generate class"); } } - //else + + // Enums + for (efl::eina::iterator enum_iterator( ::eolian_state_enums_by_file_get(opts.state, basename_input.c_str())) + , enum_last; enum_iterator != enum_last; ++enum_iterator) { - for (efl::eina::iterator enum_iterator( ::eolian_state_enums_by_file_get(opts.state, basename_input.c_str())) - , enum_last; enum_iterator != enum_last; ++enum_iterator) - { - efl::eolian::grammar::attributes::enum_def enum_(&*enum_iterator, opts.unit); - if (!eolian_mono::enum_definition.generate(iterator, enum_, efl::eolian::grammar::context_null())) - { - throw std::runtime_error("Failed to generate enum"); - } - } + efl::eolian::grammar::attributes::enum_def enum_(&*enum_iterator, opts.unit); + if (!eolian_mono::enum_definition.generate(iterator, enum_, efl::eolian::grammar::context_null())) + { + throw std::runtime_error("Failed to generate enum"); + } + } - for (efl::eina::iterator struct_iterator( ::eolian_state_structs_by_file_get(opts.state, basename_input.c_str())) - , struct_last; struct_iterator != struct_last; ++struct_iterator) - { - efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit); - auto structs_cxt = context_add_tag(class_context{class_context::structs}, context); - if (!eolian_mono::struct_entities.generate(iterator, struct_, structs_cxt)) - { - throw std::runtime_error("Failed to generate struct"); - } - } - - } + // Structs + for (efl::eina::iterator struct_iterator( ::eolian_state_structs_by_file_get(opts.state, basename_input.c_str())) + , struct_last; struct_iterator != struct_last; ++struct_iterator) + { + efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit); + auto structs_cxt = context_add_tag(class_context{class_context::structs}, context); + if (!eolian_mono::struct_entities.generate(iterator, struct_, structs_cxt)) + { + throw std::runtime_error("Failed to generate struct"); + } + } } static void diff --git a/src/bindings/mono/eo_mono/workaround.cs b/src/bindings/mono/eo_mono/workaround.cs index 7426087b88..df5eb818d1 100644 --- a/src/bindings/mono/eo_mono/workaround.cs +++ b/src/bindings/mono/eo_mono/workaround.cs @@ -492,33 +492,6 @@ public delegate void Change_Cb(IntPtr data, IntPtr obj, IntPtr part); } // namespace edje -[StructLayout(LayoutKind.Sequential)] -public struct Elm_Code -{ - IntPtr file; - IntPtr widgets; - IntPtr parsers; - - // Below is inside _Elm_Code_Config - [MarshalAsAttribute(UnmanagedType.U1)]bool config; -} - -[StructLayout(LayoutKind.Sequential)] -public struct Elm_Code_Line -{ - IntPtr file; - IntPtr content; - uint length; - uint number; - IntPtr modified; - - Elm_Code_Status_Type status; - IntPtr tokens; - - IntPtr data; - IntPtr status_text; -} - public enum Elm_Code_Status_Type { ELM_CODE_STATUS_TYPE_DEFAULT = 0, ELM_CODE_STATUS_TYPE_CURRENT, diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index 9c3681da1e..24969ab37a 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -530,12 +530,13 @@ enum class function_type struct function_def { - klass_name klass; + klass_name klass; // Klass information for function_def as method type_def return_type; std::string name; std::vector parameters; std::string c_name; std::string filename; + std::vector namespaces; // Namespaces for top-level function pointers documentation_def documentation; documentation_def return_documentation; documentation_def property_documentation; @@ -553,6 +554,7 @@ struct function_def && lhs.parameters == rhs.parameters && lhs.c_name == rhs.c_name && lhs.filename == rhs.filename + && lhs.namespaces == rhs.namespaces && lhs.documentation == rhs.documentation && lhs.return_documentation == rhs.return_documentation && lhs.property_documentation == rhs.property_documentation @@ -571,6 +573,7 @@ struct function_def std::vector const& _parameters, std::string const& _c_name, std::string _filename, + std::vector const& _namespaces, documentation_def _documentation, documentation_def _return_documentation, documentation_def _property_documentation, @@ -580,6 +583,7 @@ struct function_def Eolian_Unit const* unit = nullptr) : klass(_klass), return_type(_return_type), name(_name), parameters(_parameters), c_name(_c_name), filename(_filename), + namespaces(_namespaces), documentation(_documentation), return_documentation(_return_documentation), property_documentation(_property_documentation), @@ -587,7 +591,7 @@ struct function_def is_beta(_is_beta), is_protected(_is_protected), unit(unit) {} - function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit) + function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Typedecl const* tp, Eolian_Unit const* unit) : return_type(void_), unit(unit) { Eolian_Type const* r_type = ::eolian_function_return_type_get(function, type); @@ -648,6 +652,14 @@ struct function_def else { filename = ""; + + if (tp) + { + for (efl::eina::iterator ns_iterator(::eolian_typedecl_namespaces_get(tp)), ns_last; + ns_iterator != ns_last; + ns_iterator++) + namespaces.push_back(&*ns_iterator); + } } is_beta = eolian_function_is_beta(function); is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED; @@ -967,19 +979,19 @@ struct klass_def try { if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_GET) && ::eolian_function_scope_get(function, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_PROP_GET, unit}); + functions.push_back({function, EOLIAN_PROP_GET, NULL, unit}); } catch(std::exception const&) {} try { if(! ::eolian_function_is_legacy_only(function, EOLIAN_PROP_SET) && ::eolian_function_scope_get(function, EOLIAN_PROP_SET) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_PROP_SET, unit}); + functions.push_back({function, EOLIAN_PROP_SET, NULL, unit}); } catch(std::exception const&) {} } else try { if(! ::eolian_function_is_legacy_only(function, func_type) && ::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, func_type, unit}); + functions.push_back({function, func_type, NULL, unit}); } catch(std::exception const&) {} } for(efl::eina::iterator eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD)) @@ -990,7 +1002,7 @@ struct klass_def Eolian_Function_Type func_type = eolian_function_type_get(function); if(! ::eolian_function_is_legacy_only(function, EOLIAN_METHOD) && ::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE) - functions.push_back({function, EOLIAN_METHOD, unit}); + functions.push_back({function, EOLIAN_METHOD, NULL, unit}); } catch(std::exception const&) {} } for(efl::eina::iterator inherit_iterator ( ::eolian_class_inherits_get(klass)) diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs index c9cf1e980c..d6992ade55 100644 --- a/src/tests/efl_mono/Eo.cs +++ b/src/tests/efl_mono/Eo.cs @@ -186,7 +186,7 @@ class TestEoParent Test.AssertEquals(parent, child.GetParent()); - test.Testing parent_from_cast = test.TestingInherit.static_cast(child.GetParent()); + test.Testing parent_from_cast = test.TestingConcrete.static_cast(child.GetParent()); Test.AssertEquals(parent, parent_from_cast); } }