From 7628392dff65d747a026fd5183466c4460047c92 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Sat, 11 Jun 2022 14:24:33 +0200 Subject: THRIFT-5590 Haxe complex inits Client: hx Patch: Jens Geyer This closes #2622 --- .../cpp/src/thrift/generate/t_haxe_generator.cc | 310 +++++++++++---------- 1 file changed, 166 insertions(+), 144 deletions(-) (limited to 'compiler') diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc index 42b41811d..757f207f0 100644 --- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc @@ -91,12 +91,28 @@ public: void print_const_value(std::ostream& out, std::string name, t_type* type, - t_const_value* value, - bool in_static, - bool defval = false); - std::string render_const_value(std::string name, - t_type* type, + t_const_value* value); + + void render_const_value(std::ostream& out, + t_type* type, + t_const_value* value); + + void render_struct_initializer(std::ostream& out, + t_struct* type, t_const_value* value); + void render_map_initializer(std::ostream& out, + t_map* type, + t_const_value* value); + void render_list_initializer(std::ostream& out, + t_list* type, + t_const_value* value); + void render_set_initializer(std::ostream& out, + t_set* type, + t_const_value* value); + + // helper + std::string render_const_value_str( t_type* type, t_const_value* value); + /** * Service-level generation functions @@ -300,6 +316,7 @@ string t_haxe_generator::haxe_type_imports() { + "import haxe.ds.IntMap;\n" + "import haxe.ds.StringMap;\n" + "import haxe.ds.ObjectMap;\n" + + "import org.apache.thrift.helper.ObjectSet;\n" + "\n" + "#if flash\n" + "import flash.errors.ArgumentError;\n" @@ -480,8 +497,7 @@ void t_haxe_generator::generate_consts(std::vector consts) { print_const_value(f_consts, (*c_iter)->get_name(), (*c_iter)->get_type(), - (*c_iter)->get_value(), - false); + (*c_iter)->get_value()); } indent_down(); indent(f_consts) << "}" << endl; @@ -491,179 +507,185 @@ void t_haxe_generator::generate_consts(std::vector consts) { void t_haxe_generator::print_const_value(std::ostream& out, string name, t_type* type, - t_const_value* value, - bool in_static, - bool defval) { + t_const_value* value) { type = get_true_type(type); + bool complex = type->is_struct() || type->is_xception() || type->is_map() || type->is_list() || type->is_set(); indent(out); - if (!defval) { - out << (in_static ? "var " : "public static inline var "); + + out << "public static "; + if (!complex) { + out << "inline "; } - if (type->is_base_type()) { - string v2 = render_const_value(name, type, value); - out << name; - if (!defval) { - out << ":" << type_name(type); - } - out << " = " << v2 << ";" << endl << endl; - } else if (type->is_enum()) { - out << name; - if (!defval) { - out << ":" << type_name(type); - } - out << " = " << value->get_integer() << ";" << endl << endl; - } else if (type->is_struct() || type->is_xception()) { - const vector& fields = ((t_struct*)type)->get_members(); - vector::const_iterator f_iter; - const map& val = value->get_map(); - map::const_iterator v_iter; - out << name << ":" << type_name(type) << " = new " << type_name(type, false, true) << "();" - << endl; - if (!in_static) { - indent(out) << "{" << endl; - indent_up(); - indent(out) << "new function() : Void {" << endl; - indent_up(); - } - for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - t_type* field_type = nullptr; - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - if ((*f_iter)->get_name() == v_iter->first->get_string()) { - field_type = (*f_iter)->get_type(); - } - } - if (field_type == nullptr) { - throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); - } - string val = render_const_value(name, field_type, v_iter->second); - indent(out) << name << "."; - out << v_iter->first->get_string() << " = " << val << ";" << endl; - } - if (!in_static) { - indent_down(); - indent(out) << "}();" << endl; - indent_down(); - indent(out) << "}" << endl; - } - out << endl; - } else if (type->is_map()) { - out << name; - if (!defval) { - out << ":" << type_name(type); - } - out << " = new " << type_name(type, false, true) << "();" << endl; - if (!in_static) { - indent(out) << "{" << endl; - indent_up(); - indent(out) << "new function() : Void {" << endl; - indent_up(); - } - t_type* ktype = ((t_map*)type)->get_key_type(); - t_type* vtype = ((t_map*)type)->get_val_type(); - const map& val = value->get_map(); - map::const_iterator v_iter; - for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string key = render_const_value(name, ktype, v_iter->first); - string val = render_const_value(name, vtype, v_iter->second); - indent(out) << name << "[" << key << "] = " << val << ";" << endl; - } - if (!in_static) { - indent_down(); - indent(out) << "}();" << endl; - indent_down(); - indent(out) << "}" << endl; - } - out << endl; - } else if (type->is_list() || type->is_set()) { - out << name; - if (!defval) { - out << ":" << type_name(type); - } - out << " = new " << type_name(type, false, true) << "();" << endl; - if (!in_static) { - indent(out) << "{" << endl; - indent_up(); - indent(out) << "new function() : Void {" << endl; - indent_up(); - } - t_type* etype; - if (type->is_list()) { - etype = ((t_list*)type)->get_elem_type(); - } else { - etype = ((t_set*)type)->get_elem_type(); - } - const vector& val = value->get_list(); - vector::const_iterator v_iter; - for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) { - string val = render_const_value(name, etype, *v_iter); - indent(out) << name << "." << (type->is_list() ? "push" : "add") << "(" << val << ");" - << endl; - } - if (!in_static) { - indent_down(); - indent(out) << "}();" << endl; - indent_down(); - indent(out) << "}" << endl; - } - out << endl; - } else { - throw "compiler error: no const of type " + type->get_name(); + out << "var " << name; + if (complex) { + out << " (default,null)"; } + out << " : " << get_cap_name(type_name(type)) << " = "; + render_const_value(out, type, value); + out << ";" << endl << endl; } -string t_haxe_generator::render_const_value(string name, - t_type* type, - t_const_value* value) { - (void)name; - type = get_true_type(type); +std::string t_haxe_generator::render_const_value_str( t_type* type, t_const_value* value) { std::ostringstream render; + render_const_value(render, type, value); + return render.str(); +} + + +void t_haxe_generator::render_const_value(std::ostream& out, + t_type* type, + t_const_value* value) { + type = get_true_type(type); if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { case t_base_type::TYPE_STRING: - render << '"' << get_escaped_string(value) << '"'; + out << '"' << get_escaped_string(value) << '"'; break; case t_base_type::TYPE_BOOL: - render << ((value->get_integer() > 0) ? "true" : "false"); + out << ((value->get_integer() > 0) ? "true" : "false"); break; case t_base_type::TYPE_I8: - render << "(byte)" << value->get_integer(); + out << "(byte)" << value->get_integer(); break; case t_base_type::TYPE_I16: - render << "(short)" << value->get_integer(); + out << "(short)" << value->get_integer(); break; case t_base_type::TYPE_I32: - render << value->get_integer(); + out << value->get_integer(); break; case t_base_type::TYPE_I64: - render << value->get_integer() << "L"; + out << value->get_integer() << "L"; break; case t_base_type::TYPE_DOUBLE: if (value->get_type() == t_const_value::CV_INTEGER) { - render << "(double)" << value->get_integer(); + out << "(double)" << value->get_integer(); } else { - render << value->get_double(); + out << value->get_double(); } break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - render << value->get_integer(); + out << value->get_integer(); + } else if (type->is_struct() || type->is_xception()) { + render_struct_initializer(out, (t_struct*)type, value); + } else if (type->is_map()) { + render_map_initializer(out, (t_map*)type, value); + } else if (type->is_list()) { + render_list_initializer(out, (t_list*)type, value); + } else if (type->is_set()) { + render_set_initializer(out, (t_set*)type, value); } else { - /* this is badly broken - string t = tmp("tmp"); - print_const_value(out, t, type, value, true); - render << t; - */ - render << "null"; // we fix that later + throw "compiler error: no const of type " + type->get_name(); } +} - return render.str(); +void t_haxe_generator::render_struct_initializer(std::ostream& out, + t_struct* type, + t_const_value* value) { + out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + indent_up(); + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + + const vector& fields = ((t_struct*)type)->get_members(); + vector::const_iterator f_iter; + const map& values = value->get_map(); + map::const_iterator v_iter; + for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { + t_type* field_type = nullptr; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_name() == v_iter->first->get_string()) { + field_type = (*f_iter)->get_type(); + break; + } + } + if (field_type == nullptr) { + throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); + } + indent(out) << "tmp." << v_iter->first->get_string() << " = "; + render_const_value(out, field_type, v_iter->second); + out << ";" << endl; + } + + indent(out) << "return tmp;" << endl; + indent_down(); + indent(out) << "})()"; // no endl } +void t_haxe_generator::render_map_initializer(std::ostream& out, + t_map* type, + t_const_value* value) { + out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + indent_up(); + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + + t_type* key_type = ((t_map*)type)->get_key_type(); + t_type* val_type = ((t_map*)type)->get_val_type(); + + const map& values = value->get_map(); + map::const_iterator v_iter; + for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { + indent(out) << "tmp.set("; + render_const_value(out, key_type, v_iter->first); + out << ", "; + render_const_value(out, val_type, v_iter->second); + out << ");" << endl; + } + + indent(out) << "return tmp;" << endl; + indent_down(); + indent(out) << "})()"; // no endl +} + +void t_haxe_generator::render_list_initializer(std::ostream& out, + t_list* type, + t_const_value* value) { + out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + indent_up(); + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + + t_type* elm_type = type->get_elem_type(); + + const vector& values = value->get_list(); + vector::const_iterator v_iter; + for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { + indent(out) << "tmp.add("; + render_const_value(out, elm_type, *v_iter); + out << ");" << endl; + } + + indent(out) << "return tmp;" << endl; + indent_down(); + indent(out) << "})()"; // no endl +} + +void t_haxe_generator::render_set_initializer(std::ostream& out, + t_set* type, + t_const_value* value) { + out << "(function() : " << get_cap_name(type_name(type)) << " {" << endl; + indent_up(); + indent(out) << "var tmp = new " << get_cap_name(type_name(type)) << "();" << endl; + + t_type* elm_type = type->get_elem_type(); + + const vector& values = value->get_list(); + vector::const_iterator v_iter; + for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) { + indent(out) << "tmp.add("; + render_const_value(out, elm_type, *v_iter); + out << ");" << endl; + } + + indent(out) << "return tmp;" << endl; + indent_down(); + indent(out) << "})()"; // no endl +} + + /** * Generates a struct definition for a thrift data type. This is a class * with data members, read(), write(), and an inner Isset class. @@ -803,7 +825,7 @@ void t_haxe_generator::generate_haxe_struct_definition(ostream& out, for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if ((*m_iter)->get_value() != nullptr) { indent(out) << "this." << (*m_iter)->get_name() << " = "; - out << render_const_value((*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_value()); + render_const_value( out, (*m_iter)->get_type(), (*m_iter)->get_value()); out << ";" << endl; } } @@ -2655,7 +2677,7 @@ string t_haxe_generator::declare_field(t_field* tfield, bool init) { if (init) { t_type* ttype = get_true_type(tfield->get_type()); if (ttype->is_base_type() && tfield->get_value() != nullptr) { - result += " = " + render_const_value(tfield->get_name(), ttype, tfield->get_value()); + result += " = " + render_const_value_str( ttype, tfield->get_value()); } else if (ttype->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base(); switch (tbase) { -- cgit v1.2.1