summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorJens Geyer <jensg@apache.org>2022-06-11 14:24:33 +0200
committerJens Geyer <jensg@apache.org>2022-06-13 23:05:02 +0200
commit7628392dff65d747a026fd5183466c4460047c92 (patch)
tree93bf9a9ee298720d608267034bf5d807ecc7b356 /compiler
parente3eb9afb20a0535d44c203a4195db9822f8861fc (diff)
downloadthrift-7628392dff65d747a026fd5183466c4460047c92.tar.gz
THRIFT-5590 Haxe complex inits
Client: hx Patch: Jens Geyer This closes #2622
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cpp/src/thrift/generate/t_haxe_generator.cc310
1 files changed, 166 insertions, 144 deletions
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<t_const*> 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<t_const*> 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<t_field*>& fields = ((t_struct*)type)->get_members();
- vector<t_field*>::const_iterator f_iter;
- const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::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<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::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<t_const_value*>& val = value->get_list();
- vector<t_const_value*>::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<t_field*>& fields = ((t_struct*)type)->get_members();
+ vector<t_field*>::const_iterator f_iter;
+ const map<t_const_value*, t_const_value*, t_const_value::value_compare>& values = value->get_map();
+ map<t_const_value*, t_const_value*, t_const_value::value_compare>::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<t_const_value*, t_const_value*, t_const_value::value_compare>& values = value->get_map();
+ map<t_const_value*, t_const_value*, t_const_value::value_compare>::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<t_const_value*>& values = value->get_list();
+ vector<t_const_value*>::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<t_const_value*>& values = value->get_list();
+ vector<t_const_value*>::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) {