diff --git a/src/bin/eolian_js/eolian/js/format.hh b/src/bin/eolian_js/eolian/js/format.hh index a07d541e14..e1f02c30a6 100644 --- a/src/bin/eolian_js/eolian/js/format.hh +++ b/src/bin/eolian_js/eolian/js/format.hh @@ -11,24 +11,175 @@ namespace eolian { namespace js { namespace format { -std::string generic(std::string const& in) +const char* verbs[] = + { + "add", + "get", + "is", + "del", + "thaw", + "freeze", + "save", + "wait", + "eject", + "raise", + "lower", + "load", + "dup", + "reset", + "unload", + "close", + "set", + "interpolate", + "has", + "grab", + "check", + "find", + "ungrab", + "unset", + "clear", + "pop", + "new", + "peek", + "push", + "update", + "show", + "move", + "hide", + "calculate", + "resize", + "attach", + "pack", + "unpack", + "emit" + }; + +const char* not_verbs[] = + { + "below", + "above", + "name", + "unfreezable", + "value", + "r", + "g", + "b", + "a", + "finalize", + "destructor", + "to", + "circle", + "rect", + "path", + "commands", + "type", + "colorspace" + "op", + "type", + "properties", + "status", + "status", + "relative", + "ptr", + "pair", + "pos", + "end" + }; + +std::string format_method(std::string const& in) { - std::string s = in; - auto i = s.find('_'); - while (i != std::string::npos) + std::string r; + std::string::const_iterator current = in.begin(), last = in.end(); + do { - if (i <= 0 || i+1 >= s.size() || - !::isalnum(s[i-1]) || !::isalnum(s[i+1])) - { - EINA_CXX_DOM_LOG_WARN(eolian::js::domain) << "Entity '" << in - << "' can't be conveniently converted to a JavaScript name."; - return in; - } - s[i+1] = static_cast(::toupper(s[i+1])); - s.erase(i, 1); - i = s.find('_', i); + std::string::const_iterator word_end = std::find(current, last, '_'); + if(word_end == last) + { + bool found_verb = false, found_not_verb = false; + std::string v(current, word_end); + for(const char** verb = &format::verbs[0]; verb != &format::verbs + [sizeof(format::verbs)/sizeof(format::verbs[0])]; ++verb) + { + if(!std::lexicographical_compare + (current, word_end, *verb, *verb + std::strlen(*verb)) + && !std::lexicographical_compare + (*verb, *verb + std::strlen(*verb), current, word_end)) + { + found_verb = true; + } + } + if(!found_verb) + { + for(const char** not_verb = &format::not_verbs[0]; not_verb != &format::not_verbs + [sizeof(format::not_verbs)/sizeof(format::not_verbs[0])]; ++not_verb) + { + if(!std::lexicographical_compare + (current, word_end, *not_verb, *not_verb + std::strlen(*not_verb)) + && !std::lexicographical_compare + (*not_verb, *not_verb + std::strlen(*not_verb), current, word_end)) + { + found_not_verb = true; + } + } + if(!found_not_verb) + EINA_CXX_DOM_LOG_WARN(eolian::js::domain) + << "Last word is NOT a not-verb " << v << std::endl; + } + if(found_verb || !found_not_verb) + r = v + r; + else + { + v[0] = std::toupper(v[0]); + r += v; + r[0] = std::tolower(r[0]); + } + current = last; + } + else + { + r += std::toupper(*current++); + std::copy(current, word_end, std::back_inserter(r)); + current = word_end + 1; + } } - return s; + while(current != last); + + EINA_CXX_DOM_LOG_DBG(eolian::js::domain) + << "Formatted method " << r << " with input " << in << std::endl; + + return r; +} + +std::string format_field(std::string const& in) +{ + return format_method(in); +} + +std::string format_class(std::string const& in) +{ + std::string r; + std::string::const_iterator current = in.begin(), last = in.end(); + std::copy_if(current, last, std::back_insert_iterator(r), + [] (char c) + { + return c != '_'; + }); + return r; +} + +std::string format_namespace(std::string const& in) +{ + return format_class(in); +} + +std::string format_struct(std::string const& in) +{ + return format_class(in); +} + +std::string format_enum(std::string const& in) +{ + return format_class(in); } std::string constant(std::string in) diff --git a/src/bin/eolian_js/main.cc b/src/bin/eolian_js/main.cc index bc575fdf8e..b144a45ca4 100644 --- a/src/bin/eolian_js/main.cc +++ b/src/bin/eolian_js/main.cc @@ -647,7 +647,7 @@ int main(int argc, char** argv) { k = "::efl::eina::js::nonclass_cls_name_getter"; } - ss << " prototype_->SetAccessor(::efl::eina::js::compatibility_new(isolate_, \"" << format::generic(field_name) << "\"),\n"; + ss << " prototype_->SetAccessor(::efl::eina::js::compatibility_new(isolate_, \"" << format::format_field(field_name) << "\"),\n"; 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"; } @@ -659,11 +659,11 @@ int main(int argc, char** argv) if (comma) ss << ", "; comma = true; - ss << '"' << format::generic(&*ns_it) << '"'; + ss << '"' << format::format_namespace(&*ns_it) << '"'; } ss << "}, isolate, global);\n"; ss << " ::efl::eo::js::register_struct<" << struct_c_name << ">(isolate, \"" - << format::generic(struct_name) << "\", \"" << struct_type_full_name << "\", to_export, fields_func);\n"; + << format::format_struct(struct_name) << "\", \"" << struct_type_full_name << "\", to_export, fields_func);\n"; ss << " }\n"; structs_ss << ss.str(); @@ -717,10 +717,10 @@ int main(int argc, char** argv) member_name = eolian_function_name_get(function); break; case EOLIAN_PROP_SET: - member_name = std::string("set_") + eolian_function_name_get(function); + member_name = eolian_function_name_get(function) + std::string("_set"); break; case EOLIAN_PROP_GET: - member_name = std::string("get_") + eolian_function_name_get(function); + member_name = eolian_function_name_get(function) + std::string("_get"); break; case EOLIAN_PROPERTY: EINA_CXX_DOM_LOG_ERR(eolian::js::domain) << "EOLIAN_PROPERTY function type is invalid at this point"; @@ -739,7 +739,7 @@ int main(int argc, char** argv) { if(! ::eolian_function_is_constructor(function, klass)) ss << " prototype->Set( ::efl::eina::js::compatibility_new(isolate, \"" - << format::generic(name) << "\")\n" + << format::format_method(name) << "\")\n" << " , ::efl::eina::js::compatibility_new(isolate, &efl::eo::js::call_function\n" << " , efl::eo::js::call_function_data<\n" << " ::efl::eina::_mpl::tuple_cSetClassName( ::efl::eina::js::compatibility_new(isolate, \"" - << format::generic(class_name) + << format::format_class(class_name) << "\"));\n"; os << " auto to_export = ::efl::eo::js::get_namespace({"; @@ -1017,13 +1017,13 @@ int main(int argc, char** argv) if (comma) os << ", "; comma = true; - os << '"' << format::generic(&*ns_it) << '"'; + os << '"' << format::format_namespace(&*ns_it) << '"'; } } os << "}, isolate, global);\n"; os << " to_export->Set( ::efl::eina::js::compatibility_new(isolate, \"" - << format::generic(class_name) << "\")" + << format::format_class(class_name) << "\")" << ", constructor->GetFunction());\n"; @@ -1031,7 +1031,7 @@ int main(int argc, char** argv) os << " v8::Handle constructor = ::efl::eina::js::compatibility_new\n"; os << " (isolate, &efl::eo::js::construct_from_eo);\n"; os << " constructor->SetClassName( ::efl::eina::js::compatibility_new(isolate, \"" - << format::generic(class_name) + << format::format_class(class_name) << "\"));\n"; os << " v8::Local instance = " << "register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n"; @@ -1058,12 +1058,12 @@ int main(int argc, char** argv) if (comma) os << ", "; comma = true; - os << '"' << format::generic(&*ns_it) << '"'; + os << '"' << format::format_namespace(&*ns_it) << '"'; } os << "}, isolate, global);\n"; os << " v8::Handle enum_obj = efl::eina::js::compatibility_new(isolate);\n"; os << " to_export->Set(efl::eina::js::compatibility_new(isolate, \"" - << format::generic(enum_name) << "\"), enum_obj);\n"; + << format::format_enum(enum_name) << "\"), enum_obj);\n"; for (efl::eina::iterator ef(::eolian_type_enum_fields_get(tp)) , ef_end; ef != ef_end; ++ef) {