From e6dd831f7ea57bc4717f364141be1bf197da3cc8 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Thu, 23 Nov 2017 21:47:25 -0300 Subject: [PATCH] eolian_cxx: Many changes for the C# bindings - Added helper function to get all methods of a given class (local and inherited methods) - Add filename information to klass - Added new defs: enum, value (currently only integers), struct - Generator refactoring - Eolian C compatibility --- src/lib/eolian_cxx/grammar/address_of.hpp | 2 + src/lib/eolian_cxx/grammar/alternative.hpp | 2 + .../grammar/attribute_conditional.hpp | 15 +- .../eolian_cxx/grammar/attribute_reorder.hpp | 2 + .../eolian_cxx/grammar/attribute_replace.hpp | 9 +- .../grammar/base_class_definition.hpp | 2 + src/lib/eolian_cxx/grammar/c_type.hpp | 6 +- src/lib/eolian_cxx/grammar/case.hpp | 4 + .../eolian_cxx/grammar/class_declaration.hpp | 2 + .../eolian_cxx/grammar/class_definition.hpp | 2 + .../grammar/class_implementation.hpp | 2 + src/lib/eolian_cxx/grammar/context.hpp | 20 ++ .../grammar/converting_argument.hpp | 2 + src/lib/eolian_cxx/grammar/eps.hpp | 2 + .../grammar/function_declaration.hpp | 2 + .../grammar/function_definition.hpp | 4 +- src/lib/eolian_cxx/grammar/generator.hpp | 4 +- src/lib/eolian_cxx/grammar/header_guards.hpp | 2 + .../grammar/header_include_directive.hpp | 2 + .../implementation_include_directive.hpp | 2 + src/lib/eolian_cxx/grammar/indentation.hpp | 2 + src/lib/eolian_cxx/grammar/integral.hpp | 88 ++++++ src/lib/eolian_cxx/grammar/klass_def.hpp | 265 ++++++++++++++++-- src/lib/eolian_cxx/grammar/kleene.hpp | 2 + src/lib/eolian_cxx/grammar/list.hpp | 2 + src/lib/eolian_cxx/grammar/namespace.hpp | 2 + src/lib/eolian_cxx/grammar/parameter.hpp | 4 + src/lib/eolian_cxx/grammar/sequence.hpp | 2 + src/lib/eolian_cxx/grammar/string.hpp | 38 +-- src/lib/eolian_cxx/grammar/type.hpp | 4 +- 30 files changed, 448 insertions(+), 49 deletions(-) create mode 100644 src/lib/eolian_cxx/grammar/integral.hpp diff --git a/src/lib/eolian_cxx/grammar/address_of.hpp b/src/lib/eolian_cxx/grammar/address_of.hpp index 3fa48b0d5d..6c6b977ca3 100644 --- a/src/lib/eolian_cxx/grammar/address_of.hpp +++ b/src/lib/eolian_cxx/grammar/address_of.hpp @@ -61,6 +61,8 @@ struct address_of_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/alternative.hpp b/src/lib/eolian_cxx/grammar/alternative.hpp index 3ad3e6af67..844f3d208d 100644 --- a/src/lib/eolian_cxx/grammar/alternative.hpp +++ b/src/lib/eolian_cxx/grammar/alternative.hpp @@ -30,6 +30,8 @@ struct alternative_generator template struct is_eager_generator > : std::true_type {}; +template +struct is_generator > : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp index 2803f9fc48..5934564014 100644 --- a/src/lib/eolian_cxx/grammar/attribute_conditional.hpp +++ b/src/lib/eolian_cxx/grammar/attribute_conditional.hpp @@ -21,9 +21,6 @@ struct functional_attribute_conditional_generator G g; }; -template -struct is_eager_generator> : std::true_type {}; - template struct functional_attribute_conditional_directive { @@ -42,9 +39,6 @@ struct functional_attribute_conditional_directive F f; }; -template -struct is_eager_generator> : std::true_type {}; - struct attribute_conditional_terminal { template @@ -54,6 +48,15 @@ struct attribute_conditional_terminal } } const attribute_conditional = {}; +template +struct is_eager_generator> : std::true_type {}; +template +struct is_eager_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; + namespace type_traits { template struct attributes_needed> diff --git a/src/lib/eolian_cxx/grammar/attribute_reorder.hpp b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp index b3f8b3196b..a14e3a9203 100644 --- a/src/lib/eolian_cxx/grammar/attribute_reorder.hpp +++ b/src/lib/eolian_cxx/grammar/attribute_reorder.hpp @@ -66,6 +66,8 @@ struct attribute_reorder_generator template struct is_eager_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; template attribute_reorder_generator attribute_reorder(G g) diff --git a/src/lib/eolian_cxx/grammar/attribute_replace.hpp b/src/lib/eolian_cxx/grammar/attribute_replace.hpp index e45fb9f710..fee7328488 100644 --- a/src/lib/eolian_cxx/grammar/attribute_replace.hpp +++ b/src/lib/eolian_cxx/grammar/attribute_replace.hpp @@ -18,9 +18,6 @@ struct functional_attribute_replace_generator G g; }; -template -struct is_eager_generator> : std::true_type {}; - template struct functional_attribute_replace_directive { @@ -39,8 +36,14 @@ struct functional_attribute_replace_directive F f; }; +template +struct is_eager_generator> : std::true_type {}; template struct is_eager_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; struct attribute_replace_terminal { diff --git a/src/lib/eolian_cxx/grammar/base_class_definition.hpp b/src/lib/eolian_cxx/grammar/base_class_definition.hpp index 5a4a219529..aa61334020 100644 --- a/src/lib/eolian_cxx/grammar/base_class_definition.hpp +++ b/src/lib/eolian_cxx/grammar/base_class_definition.hpp @@ -101,6 +101,8 @@ struct base_class_definition_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/c_type.hpp b/src/lib/eolian_cxx/grammar/c_type.hpp index 6d814f80a4..e680b38835 100644 --- a/src/lib/eolian_cxx/grammar/c_type.hpp +++ b/src/lib/eolian_cxx/grammar/c_type.hpp @@ -35,10 +35,10 @@ inline std::string c_type(parameter_def const& param) switch(param.direction) { case parameter_direction::in: - return param.type.original_type.visit(c_type_visitor{¶m.c_type}); + return param.type.original_type.visit(c_type_visitor{¶m.type.c_type}); case parameter_direction::out: case parameter_direction::inout: - return param.type.original_type.visit(c_type_visitor{¶m.c_type}) + "*"; + return param.type.original_type.visit(c_type_visitor{¶m.type.c_type}) + "*"; default: throw std::runtime_error("Unknown parameter direction"); }; @@ -63,6 +63,8 @@ struct c_type_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/case.hpp b/src/lib/eolian_cxx/grammar/case.hpp index 86421363ac..c18d4ab565 100644 --- a/src/lib/eolian_cxx/grammar/case.hpp +++ b/src/lib/eolian_cxx/grammar/case.hpp @@ -55,6 +55,10 @@ template struct is_eager_generator> : std::true_type {}; template struct is_eager_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/class_declaration.hpp b/src/lib/eolian_cxx/grammar/class_declaration.hpp index d448c31074..de9c4a69d6 100644 --- a/src/lib/eolian_cxx/grammar/class_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/class_declaration.hpp @@ -73,6 +73,8 @@ struct class_declaration_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/class_definition.hpp b/src/lib/eolian_cxx/grammar/class_definition.hpp index 54df3301a6..13349d4007 100644 --- a/src/lib/eolian_cxx/grammar/class_definition.hpp +++ b/src/lib/eolian_cxx/grammar/class_definition.hpp @@ -212,6 +212,8 @@ struct class_definition_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/class_implementation.hpp b/src/lib/eolian_cxx/grammar/class_implementation.hpp index 3e9174f936..0731e3d591 100644 --- a/src/lib/eolian_cxx/grammar/class_implementation.hpp +++ b/src/lib/eolian_cxx/grammar/class_implementation.hpp @@ -53,6 +53,8 @@ struct class_implementation_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp index 9b5e164470..79e54178e0 100644 --- a/src/lib/eolian_cxx/grammar/context.hpp +++ b/src/lib/eolian_cxx/grammar/context.hpp @@ -40,6 +40,26 @@ template struct tag_check : std::false_type {}; template struct tag_check> : tag_check {}; + +template +Tag const& context_find_tag(context_cons const& context + , typename std::enable_if::value>::type* = nullptr) +{ + return context.tag; +} + +template +Tag const& context_find_tag(context_cons const& context + , typename std::enable_if::value>::type* = nullptr) +{ + return context_find_tag(context.tail); +} + +template +Tag const& context_find_tag(context_null const& context) +{ + throw std::logic_error("Context for generation not available"); +} } } } diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp index 07255800ca..230608ffc3 100644 --- a/src/lib/eolian_cxx/grammar/converting_argument.hpp +++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp @@ -68,6 +68,8 @@ struct converting_argument_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/eps.hpp b/src/lib/eolian_cxx/grammar/eps.hpp index 900df90e1a..d396cbf0b3 100644 --- a/src/lib/eolian_cxx/grammar/eps.hpp +++ b/src/lib/eolian_cxx/grammar/eps.hpp @@ -16,6 +16,8 @@ struct eps_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; eps_generator const eps = {}; diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp index 431b4a21da..e98fbf0a3a 100644 --- a/src/lib/eolian_cxx/grammar/function_declaration.hpp +++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp @@ -57,6 +57,8 @@ struct function_declaration_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp index 1c7cf25a16..50bd9970c5 100644 --- a/src/lib/eolian_cxx/grammar/function_definition.hpp +++ b/src/lib/eolian_cxx/grammar/function_definition.hpp @@ -88,7 +88,7 @@ struct function_definition_generator if(!as_generator(scope_tab).generate(sink, attributes::unused, ctx)) return false; if(f.return_type != attributes::void_ - && !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, "", f.return_type.c_type}) + && !as_generator(attributes::c_type({attributes::parameter_direction::in, f.return_type, ""}) << " __return_value = " ).generate(sink, attributes::unused, ctx)) return false; @@ -154,6 +154,8 @@ struct function_definition_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/generator.hpp b/src/lib/eolian_cxx/grammar/generator.hpp index 1100befddf..130ee6859c 100644 --- a/src/lib/eolian_cxx/grammar/generator.hpp +++ b/src/lib/eolian_cxx/grammar/generator.hpp @@ -38,8 +38,8 @@ template struct is_generator : is_generator {}; template struct is_eager_generator : is_eager_generator {}; -template -struct is_generator : is_eager_generator {}; +// template +// struct is_generator : is_eager_generator {}; template ::value>::type> G as_generator(G&& g) { return g; } diff --git a/src/lib/eolian_cxx/grammar/header_guards.hpp b/src/lib/eolian_cxx/grammar/header_guards.hpp index eab596d91e..a5a353bb4b 100644 --- a/src/lib/eolian_cxx/grammar/header_guards.hpp +++ b/src/lib/eolian_cxx/grammar/header_guards.hpp @@ -56,6 +56,8 @@ struct header_guards_generator template struct is_eager_generator > : std::true_type {}; +template +struct is_generator > : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/header_include_directive.hpp b/src/lib/eolian_cxx/grammar/header_include_directive.hpp index 8fbc0eb4fa..6b717b685a 100644 --- a/src/lib/eolian_cxx/grammar/header_include_directive.hpp +++ b/src/lib/eolian_cxx/grammar/header_include_directive.hpp @@ -21,6 +21,8 @@ struct header_include_directive_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp index f82d84b9ea..1fe50df6f7 100644 --- a/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp +++ b/src/lib/eolian_cxx/grammar/implementation_include_directive.hpp @@ -32,6 +32,8 @@ struct implementation_include_directive_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> diff --git a/src/lib/eolian_cxx/grammar/indentation.hpp b/src/lib/eolian_cxx/grammar/indentation.hpp index 615842e87b..897be03c3b 100644 --- a/src/lib/eolian_cxx/grammar/indentation.hpp +++ b/src/lib/eolian_cxx/grammar/indentation.hpp @@ -28,6 +28,8 @@ struct scope_tab_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; struct scope_tab_terminal { diff --git a/src/lib/eolian_cxx/grammar/integral.hpp b/src/lib/eolian_cxx/grammar/integral.hpp new file mode 100644 index 0000000000..95cb2f0740 --- /dev/null +++ b/src/lib/eolian_cxx/grammar/integral.hpp @@ -0,0 +1,88 @@ +#ifndef EOLIAN_CXX_INTEGRAL_HH +#define EOLIAN_CXX_INTEGRAL_HH + +#include +#include + +#include "grammar/generator.hpp" +#include "grammar/attributes.hpp" +#include "grammar/case.hpp" + +namespace efl { namespace eolian { namespace grammar { + +namespace detail { + +template +void generate_integral(OutputIterator sink, T integer) +{ + std::stringstream stm; + stm << integer; + std::string string = stm.str(); + std::copy(string.begin(), string.end(), sink); +} + +} + +// literal +template +struct literal_integral_generator +{ + T integral; + + template + bool generate(OutputIterator sink, Attribute const&, Context const&) const + { + detail::generate_integral(sink, integral); + return true; + } +}; + +template ::value>::type> +literal_integral_generator as_generator(T&& literal) { return {std::forward(literal)}; } +literal_integral_generator as_generator(std::size_t literal) { return {literal}; } + +struct integral_terminal { + template + literal_integral_generator operator()(T literal) const + { + return {literal}; + } +} const int_ = {}; + +struct integral_generator +{ + template + bool generate(OutputIterator sink, Attribute const& attribute, Context const&) const + { + detail::generate_integral(sink, attribute); + return true; + } +}; + +integral_generator as_generator(integral_terminal) { return {}; } + +template +struct is_eager_generator> : std::true_type {}; +template <> +struct is_eager_generator : std::true_type {}; +template +struct is_generator> : std::true_type {}; +template <> +struct is_generator : std::true_type {}; +template +struct is_generator::value>::type> : std::true_type {}; +template <> +struct is_generator : std::true_type {}; + +namespace type_traits { +template +struct attributes_needed> : std::integral_constant {}; +template <> +struct attributes_needed : std::integral_constant {}; +template <> +struct attributes_needed : std::integral_constant {}; +} + +} } } + +#endif diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp index 146bfbe861..edfadc05bb 100644 --- a/src/lib/eolian_cxx/grammar/klass_def.hpp +++ b/src/lib/eolian_cxx/grammar/klass_def.hpp @@ -212,16 +212,19 @@ struct type_def typedef eina::variant variant_type; variant_type original_type; std::string c_type; + bool has_own; + bool is_ptr; type_def() {} - type_def(variant_type original_type, std::string c_type) - : original_type(original_type), c_type(c_type) {} + type_def(variant_type original_type, std::string c_type, bool has_own) + : original_type(original_type), c_type(c_type), has_own(has_own) {} type_def(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype) { set(eolian_type, unit, ctype); } void set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype); + void set(Eolian_Expression_Type eolian_exp_type); }; struct get_qualifier_visitor @@ -247,17 +250,19 @@ inline bool operator!=(type_def const& lhs, type_def const& rhs) return !(lhs == rhs); } -type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void"}; +type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}, false}, "void", false}; inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype) { c_type = ::eolian_type_c_type_get(eolian_type, ctype); // ::eina_stringshare_del(stringshare); // this crashes Eolian_Type const* stp = eolian_type_base_type_get(eolian_type); + has_own = !!::eolian_type_is_owned(eolian_type); + is_ptr = !!::eolian_type_is_ptr(eolian_type); switch( ::eolian_type_type_get(eolian_type)) { case EOLIAN_TYPE_VOID: - original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}}; + original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}, false}; break; case EOLIAN_TYPE_REGULAR: if (!stp) @@ -305,6 +310,22 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni } } +inline void type_def::set(Eolian_Expression_Type eolian_exp_type) +{ + switch(eolian_exp_type) + { + case EOLIAN_EXPR_INT: + original_type = attributes::regular_type_def{"int", {{}, {}}, {}, false}; + c_type = "int"; + break; + default: + // FIXME implement the remaining types + EINA_LOG_ERR("Unsupported expression type"); + std::abort(); + break; + } +} + enum class parameter_direction { in, inout, out @@ -331,26 +352,23 @@ struct parameter_def parameter_direction direction; type_def type; std::string param_name; - std::string c_type; friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs) { return lhs.direction == rhs.direction && lhs.type == rhs.type - && lhs.param_name == rhs.param_name - && lhs.c_type == rhs.c_type; + && lhs.param_name == rhs.param_name; } friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs) { return !(lhs == rhs); } - parameter_def(parameter_direction direction, type_def type, std::string param_name, std::string c_type) - : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), c_type(std::move(c_type)) {} + parameter_def(parameter_direction direction, type_def type, std::string param_name) + : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)) {} parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit) : type( ::eolian_parameter_type_get(param), unit, EOLIAN_C_TYPE_PARAM) , param_name( ::eolian_parameter_name_get(param)) - , c_type( ::eolian_type_c_type_get(::eolian_parameter_type_get(param), EOLIAN_C_TYPE_PARAM)) { Eolian_Parameter_Dir direction = ::eolian_parameter_direction_get(param); switch(direction) @@ -396,8 +414,8 @@ template <> struct tuple_element<3ul, parameter_def> { typedef std::string type; - static type const& get(parameter_def const& p) { return p.c_type; } - static type& get(parameter_def& p) { return p.c_type; } + static type const& get(parameter_def const& p) { return p.type.c_type; } + static type& get(parameter_def& p) { return p.type.c_type; } }; template typename tuple_element::type const& get(parameter_def const& p) @@ -412,6 +430,7 @@ struct function_def std::string name; std::vector parameters; std::string c_name; + std::string filename; bool is_beta; bool is_protected; @@ -421,6 +440,7 @@ struct function_def && lhs.name == rhs.name && lhs.parameters == rhs.parameters && lhs.c_name == rhs.c_name + && lhs.filename == rhs.filename && lhs.is_beta == rhs.is_beta && lhs.is_protected == rhs.is_protected; } @@ -430,8 +450,8 @@ struct function_def } function_def(type_def return_type, std::string name, std::vector parameters - , std::string c_name, bool is_beta) - : return_type(return_type), name(name), parameters(parameters), c_name(c_name), is_beta(is_beta) {} + , std::string c_name, std::string filename, bool is_beta) + : return_type(return_type), name(name), parameters(parameters), c_name(c_name), filename(filename), is_beta(is_beta) {} function_def() = default; function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Unit const* unit) : return_type(void_) @@ -440,7 +460,7 @@ struct function_def name = ::eolian_function_name_get(function); if(r_type) return_type.set(r_type, unit, EOLIAN_C_TYPE_RETURN); - if(type == EOLIAN_METHOD) + if(type == EOLIAN_METHOD || type == EOLIAN_FUNCTION_POINTER) { for(efl::eina::iterator param_iterator ( ::eolian_function_parameters_get(function)) , param_last; param_iterator != param_last; ++param_iterator) @@ -484,8 +504,18 @@ struct function_def parameters.insert(parameters.end(), values.begin(), values.end()); } c_name = eolian_function_full_c_name_get(function, type, EINA_FALSE); + if (type != EOLIAN_FUNCTION_POINTER) + { + const Eolian_Class *klass = eolian_function_class_get(function); + filename = eolian_class_file_get(klass); + } + else + { + filename = ""; + } is_beta = eolian_function_is_beta(function); is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED; + is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED; } }; @@ -606,20 +636,25 @@ auto get(event_def& def) -> decltype(tuple_element::get(def)) return tuple_element::get(def); } +inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit); + struct klass_def { std::string eolian_name; std::string cxx_name; + std::string filename; std::vector namespaces; std::vector functions; std::set inherits; class_type type; std::vector events; + std::set immediate_inherits; friend inline bool operator==(klass_def const& lhs, klass_def const& rhs) { return lhs.eolian_name == rhs.eolian_name && lhs.cxx_name == rhs.cxx_name + && lhs.filename == lhs.filename && lhs.namespaces == rhs.namespaces && lhs.functions == rhs.functions && lhs.inherits == rhs.inherits @@ -631,14 +666,16 @@ struct klass_def return !(lhs == rhs); } - klass_def(std::string eolian_name, std::string cxx_name + klass_def(std::string eolian_name, std::string cxx_name, std::string filename , std::vector namespaces , std::vector functions , std::set inherits - , class_type type) - : eolian_name(eolian_name), cxx_name(cxx_name) + , class_type type + , std::set immediate_inherits) + : eolian_name(eolian_name), cxx_name(cxx_name), filename(filename) , namespaces(namespaces) , functions(functions), inherits(inherits), type(type) + , immediate_inherits(immediate_inherits) {} klass_def(Eolian_Class const* klass, Eolian_Unit const* unit) { @@ -648,6 +685,7 @@ struct klass_def this->namespaces.push_back(&*namespace_iterator); } cxx_name = eolian_name = eolian_class_name_get(klass); + filename = eolian_class_file_get(klass); for(efl::eina::iterator eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY)) , functions_last; eolian_functions != functions_last; ++eolian_functions) { @@ -684,6 +722,12 @@ struct klass_def functions.push_back({function, EOLIAN_METHOD, unit}); } catch(std::exception const&) {} } + for(efl::eina::iterator inherit_iterator ( ::eolian_class_inherits_get(klass)) + , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) + { + Eolian_Class const* inherit = &*inherit_iterator; + immediate_inherits.insert({inherit, {}}); + } std::function inherit_algo = [&] (Eolian_Class const* klass) { @@ -722,6 +766,117 @@ struct klass_def } } + // TODO memoize the return? + std::vector get_all_methods() const + { + std::vector ret; + + std::copy(functions.cbegin(), functions.cend(), std::back_inserter(ret)); + + for (auto inherit : inherits) + { + klass_def klass(get_klass(inherit, NULL), NULL); + std::copy(klass.functions.cbegin(), klass.functions.cend(), + std::back_inserter(ret)); + } + + return ret; + } +}; + +struct value_def +{ + typedef eina::variant variant_type; // FIXME support other types + variant_type value; + std::string literal; + type_def type; + + value_def() {} + value_def(Eolian_Value value_obj) + { + type.set(value_obj.type); + value = value_obj.value.i; + literal = eolian_expression_value_to_literal(&value_obj); + } +}; + +struct enum_value_def +{ + value_def value; + std::string name; + std::string c_name; + + enum_value_def(Eolian_Enum_Type_Field const* enum_field) + { + name = eolian_typedecl_enum_field_name_get(enum_field); + c_name = eolian_typedecl_enum_field_c_name_get(enum_field); + auto exp = eolian_typedecl_enum_field_value_get(enum_field, EINA_TRUE); + value = eolian_expression_eval(NULL, exp, EOLIAN_MASK_INT); // FIXME hardcoded int + } +}; + +struct enum_def +{ + std::string eolian_name; + std::string cxx_name; + std::vector namespaces; + std::vector fields; + + enum_def(Eolian_Typedecl const* enum_obj) + { + for(efl::eina::iterator namespace_iterator( ::eolian_typedecl_namespaces_get(enum_obj)) + , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) + { + this->namespaces.push_back((&*namespace_iterator)); + } + cxx_name = eolian_name = eolian_typedecl_name_get(enum_obj); + + for (efl::eina::iterator field_iterator(::eolian_typedecl_enum_fields_get(enum_obj)) + , field_last; field_iterator != field_last; ++field_iterator) + { + // Fill the types + this->fields.push_back(&*field_iterator); + } + } +}; + +struct struct_field_def +{ + type_def type; + std::string name; + + struct_field_def(Eolian_Struct_Type_Field const* struct_field) + { + name = eolian_typedecl_struct_field_name_get(struct_field); + try { + type.set(eolian_typedecl_struct_field_type_get(struct_field), NULL, EOLIAN_C_TYPE_DEFAULT); + } catch(std::runtime_error const&) { /* Silently skip pointer fields*/ } + } + +}; + +struct struct_def +{ + std::string eolian_name; + std::string cxx_name; + std::vector namespaces; + std::vector fields; + + struct_def(Eolian_Typedecl const* struct_obj) + { + for(efl::eina::iterator namespace_iterator( ::eolian_typedecl_namespaces_get(struct_obj)) + , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) + { + this->namespaces.push_back((&*namespace_iterator)); + } + cxx_name = eolian_name = eolian_typedecl_name_get(struct_obj); + + for(efl::eina::iterator field_iterator(::eolian_typedecl_struct_fields_get(struct_obj)) + , field_last; field_iterator != field_last; ++field_iterator) + { + this->fields.push_back(&*field_iterator); + } + } }; inline klass_name get_klass_name(klass_def const& klass) @@ -748,6 +903,80 @@ inline std::vector cpp_namespaces(std::vector namespac return namespaces; } +inline bool has_events(klass_def const &klass) +{ + for (auto&& e : klass.events) + { + (void)e; + return true; + } + + for (auto&& c : klass.inherits) + { + attributes::klass_def parent(get_klass(c, NULL), NULL); + for (auto&& e : parent.events) + { + (void)e; + return true; + } + } + + return false; +} + +template +inline bool has_type_return(klass_def const &klass, T visitor) +{ + for (auto&& f : klass.functions) + { + if (f.return_type.original_type.visit(visitor)) + return true; + } + + for (auto&& c : klass.inherits) + { + attributes::klass_def parent(get_klass(c, NULL), NULL); + if (has_type_return(parent, visitor)) + return true; + } + + return false; +} + +struct string_return_visitor +{ + typedef string_return_visitor visitor_type; + typedef bool result_type; + template + bool operator()(T const&) const { return false; } + bool operator()(regular_type_def const& regular) const + { + return regular.base_type == "string"; + } +}; + +struct stringshare_return_visitor +{ + typedef stringshare_return_visitor visitor_type; + typedef bool result_type; + template + bool operator()(T const&) const { return false; } + bool operator()(regular_type_def const& regular) const + { + return regular.base_type == "stringshare"; + } +}; + +inline bool has_string_return(klass_def const &klass) +{ + return has_type_return(klass, string_return_visitor{}); +} + +inline bool has_stringshare_return(klass_def const &klass) +{ + return has_type_return(klass, stringshare_return_visitor{}); +} + } namespace type_traits { diff --git a/src/lib/eolian_cxx/grammar/kleene.hpp b/src/lib/eolian_cxx/grammar/kleene.hpp index 8c3088fb03..0aff2bae20 100644 --- a/src/lib/eolian_cxx/grammar/kleene.hpp +++ b/src/lib/eolian_cxx/grammar/kleene.hpp @@ -29,6 +29,8 @@ struct kleene_generator template struct is_eager_generator > : std::true_type {}; +template +struct is_generator > : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/list.hpp b/src/lib/eolian_cxx/grammar/list.hpp index c8d96240d8..f87a771b66 100644 --- a/src/lib/eolian_cxx/grammar/list.hpp +++ b/src/lib/eolian_cxx/grammar/list.hpp @@ -34,6 +34,8 @@ struct list_generator template struct is_eager_generator > : std::true_type {}; +template +struct is_generator > : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/namespace.hpp b/src/lib/eolian_cxx/grammar/namespace.hpp index 5cef9ecfe8..e16edca8f1 100644 --- a/src/lib/eolian_cxx/grammar/namespace.hpp +++ b/src/lib/eolian_cxx/grammar/namespace.hpp @@ -54,6 +54,8 @@ struct namespaces_directive template struct is_eager_generator> : std::true_type {}; +template +struct is_generator> : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp index b29805e24a..f9e625a514 100644 --- a/src/lib/eolian_cxx/grammar/parameter.hpp +++ b/src/lib/eolian_cxx/grammar/parameter.hpp @@ -35,6 +35,8 @@ struct parameter_type_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {}; @@ -53,6 +55,8 @@ struct parameter_generator template <> struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; namespace type_traits { template <> struct attributes_needed : std::integral_constant {}; diff --git a/src/lib/eolian_cxx/grammar/sequence.hpp b/src/lib/eolian_cxx/grammar/sequence.hpp index 96fb467af2..dfffbf3394 100644 --- a/src/lib/eolian_cxx/grammar/sequence.hpp +++ b/src/lib/eolian_cxx/grammar/sequence.hpp @@ -115,6 +115,8 @@ struct sequence_generator template struct is_eager_generator > : std::true_type {}; +template +struct is_generator > : std::true_type {}; namespace type_traits { template diff --git a/src/lib/eolian_cxx/grammar/string.hpp b/src/lib/eolian_cxx/grammar/string.hpp index 77507ce2a0..df4ae8f2cb 100644 --- a/src/lib/eolian_cxx/grammar/string.hpp +++ b/src/lib/eolian_cxx/grammar/string.hpp @@ -26,15 +26,6 @@ struct literal_generator const char* string; }; -template <> -struct is_eager_generator : std::true_type {}; - -template <> -struct is_generator : std::true_type {}; - -template -struct is_generator : std::true_type {}; - literal_generator as_generator(char const* literal) { return literal; } struct { @@ -130,13 +121,6 @@ struct string_replace_generator char from, to; }; -template <> -struct is_eager_generator : std::true_type {}; -template <> -struct is_eager_generator : std::true_type {}; -template <> -struct is_eager_generator : std::true_type {}; - struct string_generator_terminal { specific_string_generator operator[](std::string string) const @@ -153,6 +137,28 @@ struct string_replace_terminal } } const string_replace = {}; +template <> +struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; + +template +struct is_generator : std::true_type {}; +template <> +struct is_eager_generator : std::true_type {}; +template <> +struct is_eager_generator : std::true_type {}; +template <> +struct is_eager_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; +template <> +struct is_generator : std::true_type {}; + template <> struct is_generator : std::true_type {}; template <> diff --git a/src/lib/eolian_cxx/grammar/type.hpp b/src/lib/eolian_cxx/grammar/type.hpp index 8a09b6e199..61e0e55fba 100644 --- a/src/lib/eolian_cxx/grammar/type.hpp +++ b/src/lib/eolian_cxx/grammar/type.hpp @@ -23,7 +23,7 @@ struct type_generator template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { - return param.type.original_type.visit(visitor_generate{sink, &context, param.c_type + return param.type.original_type.visit(visitor_generate{sink, &context, param.type.c_type , param.direction != attributes::parameter_direction::in, false}); } @@ -46,6 +46,8 @@ type_generator const as_generator(type_terminal) template <> struct is_eager_generator : std::true_type {}; template <> +struct is_generator : std::true_type {}; +template <> struct is_generator : std::true_type {}; namespace type_traits {