eolian-js: Modified formating to replace verb position in method names

Formatting now checks if the last function is a known verb and changes
its position to the first word of the method if it is. Making the
method use the same coding standard as node.js.
This commit is contained in:
Felipe Magno de Almeida 2016-01-17 14:09:55 -02:00
parent 23c7900eec
commit 05e204c96b
2 changed files with 173 additions and 27 deletions

View File

@ -11,24 +11,170 @@ 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"
};
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"
};
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<char>(::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);
v[0] = std::toupper(v[0]);
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
r += v;
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<std::string>(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)

View File

@ -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<v8::String>(isolate_, \"" << format::generic(field_name) << "\"),\n";
ss << " prototype_->SetAccessor(::efl::eina::js::compatibility_new<v8::String>(isolate_, \"" << format::format_field(field_name) << "\"),\n";
ss << " static_cast<v8::AccessorGetterCallback>(&::efl::eo::js::get_struct_member<" << struct_c_name << ", decltype(" << member_ref << "), &" << member_ref << ", " << k << ">),\n";
ss << " static_cast<v8::AccessorSetterCallback>(&::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<v8::String>(isolate, \""
<< format::generic(name) << "\")\n"
<< format::format_method(name) << "\")\n"
<< " , ::efl::eina::js::compatibility_new<v8::FunctionTemplate>(isolate, &efl::eo::js::call_function\n"
<< " , efl::eo::js::call_function_data<\n"
<< " ::efl::eina::_mpl::tuple_c<std::size_t";
@ -1005,7 +1005,7 @@ int main(int argc, char** argv)
os << " register_" << lower_case_class_name << "_from_constructor(isolate, constructor, &constructor_from_eo);\n";
os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(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<v8::String>(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<v8::FunctionTemplate> constructor = ::efl::eina::js::compatibility_new<v8::FunctionTemplate>\n";
os << " (isolate, &efl::eo::js::construct_from_eo);\n";
os << " constructor->SetClassName( ::efl::eina::js::compatibility_new<v8::String>(isolate, \""
<< format::generic(class_name)
<< format::format_class(class_name)
<< "\"));\n";
os << " v8::Local<v8::ObjectTemplate> 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<v8::Object> enum_obj = efl::eina::js::compatibility_new<v8::Object>(isolate);\n";
os << " to_export->Set(efl::eina::js::compatibility_new<v8::String>(isolate, \""
<< format::generic(enum_name) << "\"), enum_obj);\n";
<< format::format_enum(enum_name) << "\"), enum_obj);\n";
for (efl::eina::iterator<Eolian_Enum_Type_Field> ef(::eolian_type_enum_fields_get(tp))
, ef_end; ef != ef_end; ++ef)
{