From 966d51bf28e101ca9f26d37a4a62511d11574856 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Wed, 29 Jun 2016 15:06:01 -0300 Subject: [PATCH] eolian_js: Several fixes * Update after scope api change. * Add missing type mapping for new eolian types * Avoid generating protected properties We select the get/set as one (through TYPE_PROPERTY) in the first check for visibility. After 375179b47 it is possible to have different scopes for getters and setters. * Add pointer to complex tp and classes e984e5a removed the explicit pointer from classes and complex types in the eo files, handling them implicitly. * Avoid generating functions with void* Until further notice, they will not be automatically generated. * Avoid generating ref stuff from eo_base.eo * Warn when there are methods with the same name. --- src/bin/eolian_js/main.cc | 133 +++++++++++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 32 deletions(-) diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc index 5497d6db7d..c5786080e8 100644 --- a/src/bin/eolian_js/main.cc +++ b/src/bin/eolian_js/main.cc @@ -154,7 +154,11 @@ _eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller {"iterator", "Eina_Iterator"}, {"hash", "Eina_Hash"}, {"list", "Eina_List"}, - {"promise", "Eina_Promise"} + {"promise", "Eina_Promise"}, + {"string", "const char*"}, + {"void_ptr", "void *"}, + {"stringshare", "Eina_Stringshare*"} + }; std::string type_name = eolian_type_name_get(tp); @@ -163,11 +167,43 @@ _eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller type_name = it->second; result += type_name; + if (tpt == EOLIAN_TYPE_CLASS || tpt == EOLIAN_TYPE_COMPLEX) + result += "*"; // Implied pointer + auto tpd = eolian_type_typedecl_get(tp); if (tpd && eolian_typedecl_type_get(tpd) == EOLIAN_TYPEDECL_STRUCT) { result = "efl::eina::js::make_struct_tag<" + result + ">"; } + + if (tpt == EOLIAN_TYPE_COMPLEX) + { + result = "efl::eina::js::make_complex_tag<" + result; + + bool has_subtypes = false; + const Eolian_Type *subtype = eolian_type_base_type_get(tp); + while (subtype) + { + auto t = _eolian_type_cpp_type_named_get(subtype, caller_class_prefix, need_name_getter); + auto k = type_class_name(subtype); + if (!k.empty()) + { + result += ", " + t + ", " + _class_name_getter(caller_class_prefix, k); + need_name_getter.insert(k); + } + else + { + result += ", " + t + ", ::efl::eina::js::nonclass_cls_name_getter"; + } + has_subtypes = true; + subtype = eolian_type_next_type_get(subtype); + } + + if (!has_subtypes) + throw eolian::js::incomplete_complex_type_error("Incomplete complex type"); + + result += ">"; + } } else if (tpt == EOLIAN_TYPE_VOID) result += "void"; @@ -175,7 +211,6 @@ _eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller { auto btp = eolian_type_base_type_get(tp); result += _eolian_type_cpp_type_named_get(btp, caller_class_prefix, need_name_getter); - const auto base_is_const = eolian_type_is_const(btp); Eolian_Type_Type btpt = EOLIAN_TYPE_UNKNOWN_TYPE; @@ -201,35 +236,6 @@ _eolian_type_cpp_type_named_get(const Eolian_Type *tp, std::string const& caller result += '*'; if (is_const) result += " const"; } - - if (btpt == EOLIAN_TYPE_COMPLEX) - { - result = "efl::eina::js::make_complex_tag<" + result; - - bool has_subtypes = false; - const Eolian_Type *subtype = eolian_type_base_type_get(btp); - while (subtype) - { - auto t = _eolian_type_cpp_type_named_get(subtype, caller_class_prefix, need_name_getter); - auto k = type_class_name(subtype); - if (!k.empty()) - { - result += ", " + t + ", " + _class_name_getter(caller_class_prefix, k); - need_name_getter.insert(k); - } - else - { - result += ", " + t + ", ::efl::eina::js::nonclass_cls_name_getter"; - } - has_subtypes = true; - subtype = eolian_type_next_type_get(subtype); - } - - if (!has_subtypes) - throw eolian::js::incomplete_complex_type_error("Incomplete complex type"); - - result += ">"; - } } else { @@ -286,6 +292,51 @@ _function_return_is_missing(Eolian_Function const* func, Eolian_Function_Type fu return !type; } +bool +_type_is_generatable(const Eolian_Type *tp, bool add_pointer) +{ + std::string c_type = eolian_type_c_type_get(tp); + + if (add_pointer) + c_type += " *"; + + return c_type.find("void *") == std::string::npos; +} + +bool +_function_belongs_to(const Eolian_Function *function, std::string klass) +{ + const Eolian_Class *cl = eolian_function_class_get(function); + const std::string name = cl ? eolian_class_full_name_get(cl) : ""; + return name.find(klass) == 0; +} + +bool +_function_is_generatable(const Eolian_Function *function, Eolian_Function_Type ftp) +{ + const auto key_params = _eolian_function_keys_get(function, ftp); + const auto parameters = _eolian_function_parameters_get(function, ftp); + std::vector full_params; + + full_params.insert(std::end(full_params), std::begin(key_params), std::end(key_params)); + full_params.insert(std::end(full_params), std::begin(parameters), std::end(parameters)); + + for (auto parameter : full_params) + { + auto tp = ::eolian_parameter_type_get(parameter); + bool add_pointer = eolian_parameter_direction_get(parameter) != EOLIAN_IN_PARAM; + if (!_type_is_generatable(tp, add_pointer)) + return false; + + if (eolian_type_is_ref(tp) && _function_belongs_to(function, "Eo.Base")) + return false; + } + + auto rtp = ::eolian_function_return_type_get(function, ftp); + + return rtp ? _type_is_generatable(rtp, false) : true; +} + void separate_functions(Eolian_Class const* klass, Eolian_Function_Type t, bool ignore_constructors, std::vector& constructor_functions, std::vector& normal_functions) @@ -295,7 +346,7 @@ void separate_functions(Eolian_Class const* klass, Eolian_Function_Type t, bool for(; first != last; ++first) { Eolian_Function const* function = &*first; - if(eolian_function_scope_get(function) == EOLIAN_SCOPE_PUBLIC) + if(eolian_function_scope_get(function, t) == EOLIAN_SCOPE_PUBLIC) { EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << ::eolian_function_full_c_name_get(function, t, EINA_FALSE); if(strcmp("elm_obj_entry_input_panel_imdata_get", ::eolian_function_full_c_name_get(function, t, EINA_FALSE)) != 0 && @@ -604,6 +655,9 @@ int main(int argc, char** argv) , last; first != last; ++first) { std::stringstream ss; + bool should_reject_ref = file_basename == "eo_base.eo"; + bool has_ref_field = false; + auto tpd = &*first; if (!tpd || ::eolian_typedecl_type_get(tpd) == EOLIAN_TYPEDECL_STRUCT_OPAQUE) continue; @@ -632,6 +686,11 @@ int main(int argc, char** argv) EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Could not get struct field name"; continue; } + if (should_reject_ref && eolian_type_is_ref(field_type)) + { + has_ref_field = true; + break; + } std::string field_type_tag_name; try { @@ -660,6 +719,9 @@ int main(int argc, char** argv) ss << " static_cast(&::efl::eo::js::get_struct_member<" << struct_c_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">),\n"; ss << " static_cast(&::efl::eo::js::set_struct_member<" << struct_c_name << ", " << field_type_tag_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">));\n"; } + + if (should_reject_ref && has_ref_field) + continue; ss << " };\n"; ss << " auto to_export = ::efl::eo::js::get_namespace({"; bool comma = false; @@ -717,6 +779,8 @@ int main(int argc, char** argv) // generate function registration for (const auto function_type : function_types) { + if (eolian_function_scope_get(function, function_type) != EOLIAN_SCOPE_PUBLIC || !_function_is_generatable(function, function_type)) + continue; // Some properties may have public 'get' but protected 'set'. try { std::string member_name; @@ -920,6 +984,11 @@ int main(int argc, char** argv) // Write function to functions stream functions_ss << ss.str(); } + else + { + EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "Duplicate member function found in class: " << + eolian_class_full_name_get(klass) << ": '" << member_name << "'"; + } } catch(eolian::js::incomplete_complex_type_error const& e) {