mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-07 10:48:51 +00:00
Default values and nullification for thrift code
Summary: All things are null now, unless you specify a default value! Reviewed By: marc git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664963 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
29cbeb6235
commit
7ff3245bfa
@ -373,29 +373,53 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
|
||||
vector<t_field*>::const_iterator m_iter;
|
||||
const vector<t_field*>& members = tstruct->get_members();
|
||||
|
||||
// Default constructor
|
||||
bool init_ctor = false;
|
||||
if (!pointers) {
|
||||
// Default constructor
|
||||
indent(out) <<
|
||||
tstruct->get_name() << "()";
|
||||
|
||||
bool init_ctor = false;
|
||||
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
t_type* t = (*m_iter)->get_type();
|
||||
while (t->is_typedef()) {
|
||||
t = ((t_typedef*)t)->get_type();
|
||||
}
|
||||
if (t->is_base_type() &&
|
||||
((t_base_type*)t)->get_base() != t_base_type::TYPE_STRING) {
|
||||
if (t->is_base_type() || t->is_enum()) {
|
||||
string dval;
|
||||
if (t->is_enum()) {
|
||||
dval += "(" + t->get_name() + ")";
|
||||
}
|
||||
dval += t->is_string() ? "\"\"" : "0";
|
||||
t_const_value* cv = (*m_iter)->get_value();
|
||||
if (cv != NULL) {
|
||||
dval = render_const_value(out, (*m_iter)->get_name(), t, cv);
|
||||
}
|
||||
if (!init_ctor) {
|
||||
init_ctor = true;
|
||||
indent(out) <<
|
||||
tstruct->get_name() << "() : ";
|
||||
out << (*m_iter)->get_name() << "(0)";
|
||||
out << " : ";
|
||||
out << (*m_iter)->get_name() << "(" << dval << ")";
|
||||
} else {
|
||||
out << ", " << (*m_iter)->get_name() << "(0)";
|
||||
out << ", " << (*m_iter)->get_name() << "(" << dval << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (init_ctor) {
|
||||
out << " {} " << endl;
|
||||
out << " {" << endl;
|
||||
indent_up();
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
t_type* t = (*m_iter)->get_type();
|
||||
while (t->is_typedef()) {
|
||||
t = ((t_typedef*)t)->get_type();
|
||||
}
|
||||
if (!t->is_base_type()) {
|
||||
t_const_value* cv = (*m_iter)->get_value();
|
||||
if (cv != NULL) {
|
||||
print_const_value(out, (*m_iter)->get_name(), t, cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
indent_down();
|
||||
indent(out) << "} " << endl;
|
||||
}
|
||||
|
||||
out <<
|
||||
@ -1696,6 +1720,7 @@ void t_cpp_generator::generate_deserialize_container(ofstream& out,
|
||||
string etype = tmp("_etype");
|
||||
|
||||
indent(out) <<
|
||||
prefix << ".clear();" << endl <<
|
||||
"uint32_t " << size << ";" << endl;
|
||||
|
||||
// Declare variables, read header
|
||||
|
@ -146,23 +146,25 @@ void t_java_generator::generate_consts(std::vector<t_const*> consts) {
|
||||
* is NOT performed in this function as it is always run beforehand using the
|
||||
* validate_types method in main.cc
|
||||
*/
|
||||
void t_java_generator::print_const_value(ofstream& out, string name, t_type* type, t_const_value* value, bool in_static) {
|
||||
void t_java_generator::print_const_value(std::ofstream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval) {
|
||||
|
||||
indent(out);
|
||||
if (!defval) {
|
||||
out <<
|
||||
(in_static ? "" : "public static final ") <<
|
||||
type_name(type) << " ";
|
||||
}
|
||||
if (type->is_base_type()) {
|
||||
string v2 = render_const_value(out, name, type, value);
|
||||
indent(out) << "public static final " << type_name(type) << " " << name << " = " << v2 << ";" << endl <<
|
||||
endl;
|
||||
out << name << " = " << v2 << ";" << endl << endl;
|
||||
} else if (type->is_enum()) {
|
||||
indent(out) << "public static final int " << name << " = " << value->get_integer() << ";" << endl <<
|
||||
endl;
|
||||
out << name << " = " << 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*>& val = value->get_map();
|
||||
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
||||
indent(out) <<
|
||||
(in_static ? "" : "public static final ") <<
|
||||
type_name(type) << " " << name <<
|
||||
" = new " << type_name(type) << "();" << endl;
|
||||
out << name << " = new " << type_name(type) << "();" << endl;
|
||||
if (!in_static) {
|
||||
indent(out) << "static {" << endl;
|
||||
indent_up();
|
||||
@ -187,9 +189,7 @@ void t_java_generator::print_const_value(ofstream& out, string name, t_type* typ
|
||||
}
|
||||
out << endl;
|
||||
} else if (type->is_map()) {
|
||||
indent(out) <<
|
||||
(in_static ? "" : "public static final ") <<
|
||||
type_name(type, true, true) << " " << name << " = new " << type_name(type, true, true) << "();" << endl;
|
||||
out << name << " = new " << type_name(type, true, true) << "();" << endl;
|
||||
if (!in_static) {
|
||||
indent(out) << "static {" << endl;
|
||||
indent_up();
|
||||
@ -209,9 +209,7 @@ void t_java_generator::print_const_value(ofstream& out, string name, t_type* typ
|
||||
}
|
||||
out << endl;
|
||||
} else if (type->is_list() || type->is_set()) {
|
||||
indent(out) <<
|
||||
(in_static ? "" : "public static final ") <<
|
||||
type_name(type) << " " << name << " = new " << type_name(type) << "();" << endl;
|
||||
out << name << " = new " << type_name(type) << "();" << endl;
|
||||
if (!in_static) {
|
||||
indent(out) << "static {" << endl;
|
||||
indent_up();
|
||||
@ -348,7 +346,7 @@ void t_java_generator::generate_java_struct_definition(ofstream &out,
|
||||
vector<t_field*>::const_iterator m_iter;
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
indent(out) <<
|
||||
"public " << declare_field(*m_iter, true) << endl;
|
||||
"public " << declare_field(*m_iter, false) << endl;
|
||||
}
|
||||
|
||||
// Inner Isset class
|
||||
@ -368,6 +366,22 @@ void t_java_generator::generate_java_struct_definition(ofstream &out,
|
||||
endl;
|
||||
}
|
||||
|
||||
// Default constructor
|
||||
indent(out) <<
|
||||
"public " << tstruct->get_name() << "() {" << endl;
|
||||
indent_up();
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
t_type* t = (*m_iter)->get_type();
|
||||
while (t->is_typedef()) {
|
||||
t = ((t_typedef*)t)->get_type();
|
||||
}
|
||||
if (!t->is_base_type() && (*m_iter)->get_value() != NULL) {
|
||||
print_const_value(out, "this." + (*m_iter)->get_name(), t, (*m_iter)->get_value(), true, true);
|
||||
}
|
||||
}
|
||||
indent_down();
|
||||
indent(out) << "}" << endl << endl;
|
||||
|
||||
generate_java_struct_reader(out, tstruct);
|
||||
if (is_result) {
|
||||
generate_java_struct_result_writer(out, tstruct);
|
||||
@ -1202,6 +1216,8 @@ void t_java_generator::generate_deserialize_container(ofstream& out,
|
||||
obj = tmp("_list");
|
||||
}
|
||||
|
||||
indent(out) << prefix << " = new " << type_name(ttype, false, true) << "(); // from me" << endl;
|
||||
|
||||
// Declare variables, read header
|
||||
if (ttype->is_map()) {
|
||||
out <<
|
||||
@ -1214,7 +1230,6 @@ void t_java_generator::generate_deserialize_container(ofstream& out,
|
||||
indent() << "TList " << obj << " = iprot.readListBegin();" << endl;
|
||||
}
|
||||
|
||||
|
||||
// For loop iterates over elements
|
||||
string i = tmp("_i");
|
||||
indent(out) <<
|
||||
@ -1259,9 +1274,9 @@ void t_java_generator::generate_deserialize_map_element(ofstream& out,
|
||||
t_field fval(tmap->get_val_type(), val);
|
||||
|
||||
indent(out) <<
|
||||
declare_field(&fkey, true) << endl;
|
||||
declare_field(&fkey) << endl;
|
||||
indent(out) <<
|
||||
declare_field(&fval, true) << endl;
|
||||
declare_field(&fval) << endl;
|
||||
|
||||
generate_deserialize_field(out, &fkey);
|
||||
generate_deserialize_field(out, &fval);
|
||||
@ -1597,13 +1612,15 @@ string t_java_generator::declare_field(t_field* tfield, bool init) {
|
||||
while (ttype->is_typedef()) {
|
||||
ttype = ((t_typedef*)ttype)->get_type();
|
||||
}
|
||||
if (ttype->is_base_type()) {
|
||||
if (ttype->is_base_type() && tfield->get_value() != NULL) {
|
||||
ofstream dummy;
|
||||
result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
|
||||
} else if (ttype->is_base_type()) {
|
||||
t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
|
||||
switch (tbase) {
|
||||
case t_base_type::TYPE_VOID:
|
||||
throw "NO T_VOID CONSTRUCT";
|
||||
case t_base_type::TYPE_STRING:
|
||||
// result += " = \"\"";
|
||||
result += " = null";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
@ -1625,7 +1642,7 @@ string t_java_generator::declare_field(t_field* tfield, bool init) {
|
||||
} else if (ttype->is_container()) {
|
||||
result += " = new " + type_name(ttype, false, true) + "()";
|
||||
} else {
|
||||
result += " = null";
|
||||
result += " = new " + type_name(ttype, false, true) + "()";;
|
||||
}
|
||||
}
|
||||
return result + ";";
|
||||
|
@ -40,7 +40,7 @@ class t_java_generator : public t_oop_generator {
|
||||
void generate_xception(t_struct* txception);
|
||||
void generate_service (t_service* tservice);
|
||||
|
||||
void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value, bool in_static);
|
||||
void print_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value, bool in_static, bool defval=false);
|
||||
std::string render_const_value(std::ofstream& out, std::string name, t_type* type, t_const_value* value);
|
||||
|
||||
/**
|
||||
@ -138,7 +138,7 @@ class t_java_generator : public t_oop_generator {
|
||||
ttype->is_container() ||
|
||||
ttype->is_struct() ||
|
||||
ttype->is_xception() ||
|
||||
(ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));
|
||||
ttype->is_string();
|
||||
}
|
||||
|
||||
|
||||
|
@ -123,7 +123,7 @@ void t_php_generator::generate_const(t_const* tconst) {
|
||||
t_const_value* value = tconst->get_value();
|
||||
|
||||
f_consts_ << "$GLOBALS['" << program_name_ << "_CONSTANTS']['" << name << "'] = ";
|
||||
print_const_value(type, value);
|
||||
f_consts_ << render_const_value(type, value);
|
||||
f_consts_ << ";" << endl << endl;
|
||||
}
|
||||
|
||||
@ -132,36 +132,40 @@ void t_php_generator::generate_const(t_const* tconst) {
|
||||
* is NOT performed in this function as it is always run beforehand using the
|
||||
* validate_types method in main.cc
|
||||
*/
|
||||
void t_php_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
string t_php_generator::render_const_value(t_type* type, t_const_value* value) {
|
||||
std::ostringstream out;
|
||||
while (type->is_typedef()) {
|
||||
type = ((t_typedef*)type)->get_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:
|
||||
f_consts_ << "'" << value->get_string() << "'";
|
||||
out << "'" << value->get_string() << "'";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
f_consts_ << (value->get_integer() > 0 ? "true" : "false");
|
||||
out << (value->get_integer() > 0 ? "true" : "false");
|
||||
break;
|
||||
case t_base_type::TYPE_BYTE:
|
||||
case t_base_type::TYPE_I16:
|
||||
case t_base_type::TYPE_I32:
|
||||
case t_base_type::TYPE_I64:
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
break;
|
||||
case t_base_type::TYPE_DOUBLE:
|
||||
if (value->get_type() == t_const_value::CV_INTEGER) {
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
} else {
|
||||
f_consts_ << value->get_double();
|
||||
out << value->get_double();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw "compiler error: no const of base type " + tbase;
|
||||
}
|
||||
} else if (type->is_enum()) {
|
||||
indent(f_consts_) << value->get_integer();
|
||||
indent(out) << value->get_integer();
|
||||
} else if (type->is_struct() || type->is_xception()) {
|
||||
f_consts_ << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl;
|
||||
out << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl;
|
||||
indent_up();
|
||||
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
|
||||
vector<t_field*>::const_iterator f_iter;
|
||||
@ -177,30 +181,30 @@ void t_php_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
if (field_type == NULL) {
|
||||
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
|
||||
}
|
||||
f_consts_ << indent();
|
||||
print_const_value(g_type_string, v_iter->first);
|
||||
f_consts_ << " => ";
|
||||
print_const_value(field_type, v_iter->second);
|
||||
f_consts_ << endl;
|
||||
out << indent();
|
||||
out << render_const_value(g_type_string, v_iter->first);
|
||||
out << " => ";
|
||||
out << render_const_value(field_type, v_iter->second);
|
||||
out << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "))";
|
||||
indent(out) << "))";
|
||||
} else if (type->is_map()) {
|
||||
t_type* ktype = ((t_map*)type)->get_key_type();
|
||||
t_type* vtype = ((t_map*)type)->get_val_type();
|
||||
f_consts_ << "array(" << endl;
|
||||
out << "array(" << endl;
|
||||
indent_up();
|
||||
const map<t_const_value*, t_const_value*>& val = value->get_map();
|
||||
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
||||
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(ktype, v_iter->first);
|
||||
f_consts_ << " => ";
|
||||
print_const_value(vtype, v_iter->second);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(ktype, v_iter->first);
|
||||
out << " => ";
|
||||
out << render_const_value(vtype, v_iter->second);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << ")";
|
||||
indent(out) << ")";
|
||||
} else if (type->is_list() || type->is_set()) {
|
||||
t_type* etype;
|
||||
if (type->is_list()) {
|
||||
@ -208,21 +212,22 @@ void t_php_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
} else {
|
||||
etype = ((t_set*)type)->get_elem_type();
|
||||
}
|
||||
f_consts_ << "array(" << endl;
|
||||
out << "array(" << endl;
|
||||
indent_up();
|
||||
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) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(etype, *v_iter);
|
||||
out << indent();
|
||||
out << render_const_value(etype, *v_iter);
|
||||
if (type->is_set()) {
|
||||
f_consts_ << " => true";
|
||||
out << " => true";
|
||||
}
|
||||
f_consts_ << "," << endl;
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << ")";
|
||||
indent(out) << ")";
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,8 +278,16 @@ void t_php_generator::generate_php_struct_definition(ofstream& out,
|
||||
indent_up();
|
||||
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
string dval = "null";
|
||||
t_type* t = (*m_iter)->get_type();
|
||||
while (t->is_typedef()) {
|
||||
t = ((t_typedef*)t)->get_type();
|
||||
}
|
||||
if ((*m_iter)->get_value() != NULL && !(t->is_struct() || t->is_xception())) {
|
||||
dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value());
|
||||
}
|
||||
indent(out) <<
|
||||
"public $" << (*m_iter)->get_name() << " = null;" << endl;
|
||||
"public $" << (*m_iter)->get_name() << " = " << dval << ";" << endl;
|
||||
}
|
||||
|
||||
out << endl;
|
||||
@ -284,6 +297,17 @@ void t_php_generator::generate_php_struct_definition(ofstream& out,
|
||||
out <<
|
||||
indent() << "public function __construct($vals=null) {" << endl;
|
||||
indent_up();
|
||||
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
t_type* t = (*m_iter)->get_type();
|
||||
while (t->is_typedef()) {
|
||||
t = ((t_typedef*)t)->get_type();
|
||||
}
|
||||
if ((*m_iter)->get_value() != NULL && (t->is_struct() || t->is_xception())) {
|
||||
indent(out) << "$this->" << (*m_iter)->get_name() << " = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
out <<
|
||||
indent() << "if (is_array($vals)) {" << endl;
|
||||
indent_up();
|
||||
@ -821,7 +845,7 @@ void t_php_generator::generate_service_rest(t_service* tservice) {
|
||||
"class " << service_name_ << "Rest" << extends_if << " {" << endl;
|
||||
indent_up();
|
||||
f_service_ <<
|
||||
indent() << "var $impl_;" << endl <<
|
||||
indent() << "private $impl_;" << endl <<
|
||||
endl <<
|
||||
indent() << "public function __construct($impl) {" << endl <<
|
||||
indent() << " $this->impl_ = $impl;" << endl <<
|
||||
|
@ -43,7 +43,7 @@ class t_php_generator : public t_oop_generator {
|
||||
void generate_xception (t_struct* txception);
|
||||
void generate_service (t_service* tservice);
|
||||
|
||||
void print_const_value (t_type* type, t_const_value* value);
|
||||
std::string render_const_value(t_type* type, t_const_value* value);
|
||||
|
||||
/**
|
||||
* Structs!
|
||||
|
@ -123,8 +123,7 @@ void t_py_generator::generate_const(t_const* tconst) {
|
||||
string name = tconst->get_name();
|
||||
t_const_value* value = tconst->get_value();
|
||||
|
||||
indent(f_consts_) << name << " = ";
|
||||
print_const_value(type, value);
|
||||
indent(f_consts_) << name << " = " << render_const_value(type, value);
|
||||
f_consts_ << endl << endl;
|
||||
}
|
||||
|
||||
@ -133,36 +132,38 @@ void t_py_generator::generate_const(t_const* tconst) {
|
||||
* is NOT performed in this function as it is always run beforehand using the
|
||||
* validate_types method in main.cc
|
||||
*/
|
||||
void t_py_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
string t_py_generator::render_const_value(t_type* type, t_const_value* value) {
|
||||
std::ostringstream out;
|
||||
|
||||
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:
|
||||
f_consts_ << "'" << value->get_string() << "'";
|
||||
out << "'" << value->get_string() << "'";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
f_consts_ << (value->get_integer() > 0 ? "True" : "False");
|
||||
out << (value->get_integer() > 0 ? "True" : "False");
|
||||
break;
|
||||
case t_base_type::TYPE_BYTE:
|
||||
case t_base_type::TYPE_I16:
|
||||
case t_base_type::TYPE_I32:
|
||||
case t_base_type::TYPE_I64:
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
break;
|
||||
case t_base_type::TYPE_DOUBLE:
|
||||
if (value->get_type() == t_const_value::CV_INTEGER) {
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
} else {
|
||||
f_consts_ << value->get_double();
|
||||
out << value->get_double();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw "compiler error: no const of base type " + tbase;
|
||||
}
|
||||
} else if (type->is_enum()) {
|
||||
indent(f_consts_) << value->get_integer();
|
||||
indent(out) << value->get_integer();
|
||||
} else if (type->is_struct() || type->is_xception()) {
|
||||
f_consts_ << type->get_name() << "({" << endl;
|
||||
out << type->get_name() << "({" << endl;
|
||||
indent_up();
|
||||
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
|
||||
vector<t_field*>::const_iterator f_iter;
|
||||
@ -178,30 +179,30 @@ void t_py_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
if (field_type == NULL) {
|
||||
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
|
||||
}
|
||||
f_consts_ << indent();
|
||||
print_const_value(g_type_string, v_iter->first);
|
||||
f_consts_ << " : ";
|
||||
print_const_value(field_type, v_iter->second);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(g_type_string, v_iter->first);
|
||||
out << " : ";
|
||||
out << render_const_value(field_type, v_iter->second);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "})";
|
||||
indent(out) << "})";
|
||||
} else if (type->is_map()) {
|
||||
t_type* ktype = ((t_map*)type)->get_key_type();
|
||||
t_type* vtype = ((t_map*)type)->get_val_type();
|
||||
f_consts_ << "{" << endl;
|
||||
out << "{" << endl;
|
||||
indent_up();
|
||||
const map<t_const_value*, t_const_value*>& val = value->get_map();
|
||||
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
||||
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(ktype, v_iter->first);
|
||||
f_consts_ << " : ";
|
||||
print_const_value(vtype, v_iter->second);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(ktype, v_iter->first);
|
||||
out << " : ";
|
||||
out << render_const_value(vtype, v_iter->second);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "}";
|
||||
indent(out) << "}";
|
||||
} else if (type->is_list() || type->is_set()) {
|
||||
t_type* etype;
|
||||
if (type->is_list()) {
|
||||
@ -210,23 +211,25 @@ void t_py_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
etype = ((t_set*)type)->get_elem_type();
|
||||
}
|
||||
if (type->is_set()) {
|
||||
f_consts_ << "set(";
|
||||
out << "set(";
|
||||
}
|
||||
f_consts_ << "[" << endl;
|
||||
out << "[" << endl;
|
||||
indent_up();
|
||||
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) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(etype, *v_iter);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(etype, *v_iter);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "]";
|
||||
indent(out) << "]";
|
||||
if (type->is_set()) {
|
||||
f_consts_ << ")";
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,14 +291,9 @@ void t_py_generator::generate_py_struct_definition(ofstream& out,
|
||||
"pass" <<endl;
|
||||
} else {
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
if (is_result) {
|
||||
indent(out) <<
|
||||
"self." << (*m_iter)->get_name() << " = None" << endl;
|
||||
} else {
|
||||
// This fills in default values, as opposed to nulls
|
||||
indent(out) <<
|
||||
declare_field(*m_iter, true) << endl;
|
||||
}
|
||||
// This fills in default values, as opposed to nulls
|
||||
indent(out) <<
|
||||
declare_field(*m_iter) << endl;
|
||||
}
|
||||
|
||||
indent(out) <<
|
||||
@ -1393,51 +1391,16 @@ void t_py_generator::generate_serialize_list_element(ofstream &out,
|
||||
*
|
||||
* @param ttype The type
|
||||
*/
|
||||
string t_py_generator::declare_field(t_field* tfield, bool init, bool obj) {
|
||||
string t_py_generator::declare_field(t_field* tfield) {
|
||||
string result = "self." + tfield->get_name();
|
||||
if (init) {
|
||||
t_type* type = tfield->get_type();
|
||||
while (type->is_typedef()) {
|
||||
type = ((t_typedef*)type)->get_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_VOID:
|
||||
break;
|
||||
case t_base_type::TYPE_STRING:
|
||||
result += " = ''";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
result += " = False";
|
||||
break;
|
||||
case t_base_type::TYPE_BYTE:
|
||||
case t_base_type::TYPE_I16:
|
||||
case t_base_type::TYPE_I32:
|
||||
case t_base_type::TYPE_I64:
|
||||
result += " = 0";
|
||||
break;
|
||||
case t_base_type::TYPE_DOUBLE:
|
||||
result += " = 0.0";
|
||||
break;
|
||||
default:
|
||||
throw "compiler error: no PHP initializer for base type " + tbase;
|
||||
}
|
||||
} else if (type->is_enum()) {
|
||||
result += " = 0";
|
||||
} else if (type->is_container()) {
|
||||
if (type->is_map()) {
|
||||
result += " = {}";
|
||||
} else {
|
||||
result += " = []";
|
||||
}
|
||||
} else if (type->is_struct() || type->is_xception()) {
|
||||
if (obj) {
|
||||
result += " = " + type_name((t_struct*)type) + "()";
|
||||
} else {
|
||||
result += " = None";
|
||||
}
|
||||
}
|
||||
t_type* type = tfield->get_type();
|
||||
while (type->is_typedef()) {
|
||||
type = ((t_typedef*)type)->get_type();
|
||||
}
|
||||
if (tfield->get_value() != NULL) {
|
||||
result += " = " + render_const_value(type, tfield->get_value());
|
||||
} else {
|
||||
result += " = None";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class t_py_generator : public t_oop_generator {
|
||||
void generate_xception (t_struct* txception);
|
||||
void generate_service (t_service* tservice);
|
||||
|
||||
void print_const_value (t_type* type, t_const_value* value);
|
||||
std::string render_const_value(t_type* type, t_const_value* value);
|
||||
|
||||
/**
|
||||
* Struct generation code
|
||||
@ -122,7 +122,7 @@ class t_py_generator : public t_oop_generator {
|
||||
std::string py_autogen_comment();
|
||||
std::string py_imports();
|
||||
std::string render_includes();
|
||||
std::string declare_field(t_field* tfield, bool init=false, bool obj=false);
|
||||
std::string declare_field(t_field* tfield);
|
||||
std::string type_name(t_type* ttype);
|
||||
std::string function_signature(t_function* tfunction, std::string prefix="");
|
||||
std::string argument_list(t_struct* tstruct);
|
||||
|
@ -132,8 +132,7 @@ void t_rb_generator::generate_const(t_const* tconst) {
|
||||
|
||||
name[0] = toupper(name[0]);
|
||||
|
||||
indent(f_consts_) << name << " = ";
|
||||
print_const_value(type, value);
|
||||
indent(f_consts_) << name << " = " << render_const_value(type, value);
|
||||
f_consts_ << endl << endl;
|
||||
}
|
||||
|
||||
@ -142,36 +141,37 @@ void t_rb_generator::generate_const(t_const* tconst) {
|
||||
* is NOT performed in this function as it is always run beforehand using the
|
||||
* validate_types method in main.cc
|
||||
*/
|
||||
void t_rb_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
string t_rb_generator::render_const_value(t_type* type, t_const_value* value) {
|
||||
std::ostringstream out;
|
||||
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:
|
||||
f_consts_ << "'" << value->get_string() << "'";
|
||||
out << "'" << value->get_string() << "'";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
f_consts_ << (value->get_integer() > 0 ? "true" : "false");
|
||||
out << (value->get_integer() > 0 ? "true" : "false");
|
||||
break;
|
||||
case t_base_type::TYPE_BYTE:
|
||||
case t_base_type::TYPE_I16:
|
||||
case t_base_type::TYPE_I32:
|
||||
case t_base_type::TYPE_I64:
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
break;
|
||||
case t_base_type::TYPE_DOUBLE:
|
||||
if (value->get_type() == t_const_value::CV_INTEGER) {
|
||||
f_consts_ << value->get_integer();
|
||||
out << value->get_integer();
|
||||
} else {
|
||||
f_consts_ << value->get_double();
|
||||
out << value->get_double();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw "compiler error: no const of base type " + tbase;
|
||||
}
|
||||
} else if (type->is_enum()) {
|
||||
indent(f_consts_) << value->get_integer();
|
||||
indent(out) << value->get_integer();
|
||||
} else if (type->is_struct() || type->is_xception()) {
|
||||
f_consts_ << type->get_name() << "({" << endl;
|
||||
out << type->get_name() << "({" << endl;
|
||||
indent_up();
|
||||
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
|
||||
vector<t_field*>::const_iterator f_iter;
|
||||
@ -187,30 +187,30 @@ void t_rb_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
if (field_type == NULL) {
|
||||
throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
|
||||
}
|
||||
f_consts_ << indent();
|
||||
print_const_value(g_type_string, v_iter->first);
|
||||
f_consts_ << " => ";
|
||||
print_const_value(field_type, v_iter->second);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(g_type_string, v_iter->first);
|
||||
out << " => ";
|
||||
out << render_const_value(field_type, v_iter->second);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "})";
|
||||
indent(out) << "})";
|
||||
} else if (type->is_map()) {
|
||||
t_type* ktype = ((t_map*)type)->get_key_type();
|
||||
t_type* vtype = ((t_map*)type)->get_val_type();
|
||||
f_consts_ << "{" << endl;
|
||||
out << "{" << endl;
|
||||
indent_up();
|
||||
const map<t_const_value*, t_const_value*>& val = value->get_map();
|
||||
map<t_const_value*, t_const_value*>::const_iterator v_iter;
|
||||
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(ktype, v_iter->first);
|
||||
f_consts_ << " =>x ";
|
||||
print_const_value(vtype, v_iter->second);
|
||||
f_consts_ << "," << endl;
|
||||
out << indent();
|
||||
out << render_const_value(ktype, v_iter->first);
|
||||
out << " => ";
|
||||
out << render_const_value(vtype, v_iter->second);
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
indent(f_consts_) << "}";
|
||||
indent(out) << "}";
|
||||
} else if (type->is_list() || type->is_set()) {
|
||||
t_type* etype;
|
||||
if (type->is_list()) {
|
||||
@ -219,28 +219,29 @@ void t_rb_generator::print_const_value(t_type* type, t_const_value* value) {
|
||||
etype = ((t_set*)type)->get_elem_type();
|
||||
}
|
||||
if (type->is_set()) {
|
||||
f_consts_ << "{";
|
||||
out << "{";
|
||||
} else {
|
||||
f_consts_ << "[" << endl;
|
||||
out << "[" << endl;
|
||||
}
|
||||
indent_up();
|
||||
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) {
|
||||
f_consts_ << indent();
|
||||
print_const_value(etype, *v_iter);
|
||||
out << indent();
|
||||
out << render_const_value(etype, *v_iter);
|
||||
if (type->is_set()) {
|
||||
f_consts_ << " => true";
|
||||
out << " => true";
|
||||
}
|
||||
f_consts_ << "," << endl;
|
||||
out << "," << endl;
|
||||
}
|
||||
indent_down();
|
||||
if (type->is_set()) {
|
||||
indent(f_consts_) << "}";
|
||||
indent(out) << "}";
|
||||
} else {
|
||||
indent(f_consts_) << "]";
|
||||
indent(out) << "]";
|
||||
}
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,6 +324,11 @@ void t_rb_generator::generate_rb_struct_definition(ofstream& out,
|
||||
indent_up();
|
||||
|
||||
if (members.size() > 0) {
|
||||
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
|
||||
if ((*m_iter)->get_value() != NULL) {
|
||||
indent(out) << declare_field(*m_iter) << endl;
|
||||
}
|
||||
}
|
||||
indent(out) <<
|
||||
"if (d != nil)" << endl;
|
||||
indent_up();
|
||||
@ -1435,51 +1441,16 @@ void t_rb_generator::generate_serialize_list_element(ofstream &out,
|
||||
*
|
||||
* @param ttype The type
|
||||
*/
|
||||
string t_rb_generator::declare_field(t_field* tfield, bool init, bool obj) {
|
||||
string t_rb_generator::declare_field(t_field* tfield) {
|
||||
string result = "@" + tfield->get_name();
|
||||
if (init) {
|
||||
t_type* type = tfield->get_type();
|
||||
while (type->is_typedef()) {
|
||||
type = ((t_typedef*)type)->get_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_VOID:
|
||||
break;
|
||||
case t_base_type::TYPE_STRING:
|
||||
result += " = ''";
|
||||
break;
|
||||
case t_base_type::TYPE_BOOL:
|
||||
result += " = false";
|
||||
break;
|
||||
case t_base_type::TYPE_BYTE:
|
||||
case t_base_type::TYPE_I16:
|
||||
case t_base_type::TYPE_I32:
|
||||
case t_base_type::TYPE_I64:
|
||||
result += " = 0";
|
||||
break;
|
||||
case t_base_type::TYPE_DOUBLE:
|
||||
result += " = 0.0";
|
||||
break;
|
||||
default:
|
||||
throw "compiler error: no PHP initializer for base type " + tbase;
|
||||
}
|
||||
} else if (type->is_enum()) {
|
||||
result += " = 0";
|
||||
} else if (type->is_container()) {
|
||||
if (type->is_map() || type->is_set()) {
|
||||
result += " = {}";
|
||||
} else {
|
||||
result += " = []";
|
||||
}
|
||||
} else if (type->is_struct() || type->is_xception()) {
|
||||
if (obj) {
|
||||
result += " = " + type_name((t_struct*)type) + "()";
|
||||
} else {
|
||||
result += " = nil";
|
||||
}
|
||||
}
|
||||
t_type* type = tfield->get_type();
|
||||
while (type->is_typedef()) {
|
||||
type = ((t_typedef*)type)->get_type();
|
||||
}
|
||||
if (tfield->get_value() != NULL) {
|
||||
result += " = " + render_const_value(type, tfield->get_value());
|
||||
} else {
|
||||
result += " = nil";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class t_rb_generator : public t_oop_generator {
|
||||
void generate_xception (t_struct* txception);
|
||||
void generate_service (t_service* tservice);
|
||||
|
||||
void print_const_value (t_type* type, t_const_value* value);
|
||||
std::string render_const_value(t_type* type, t_const_value* value);
|
||||
|
||||
/**
|
||||
* Struct generation code
|
||||
@ -122,7 +122,7 @@ class t_rb_generator : public t_oop_generator {
|
||||
std::string rb_autogen_comment();
|
||||
std::string rb_imports();
|
||||
std::string render_includes();
|
||||
std::string declare_field(t_field* tfield, bool init=false, bool obj=false);
|
||||
std::string declare_field(t_field* tfield);
|
||||
std::string type_name(t_type* ttype);
|
||||
std::string function_signature(t_function* tfunction, std::string prefix="");
|
||||
std::string argument_list(t_struct* tstruct);
|
||||
|
@ -414,6 +414,13 @@ void validate_const_type(t_const* c) {
|
||||
validate_const_rec(c->get_name(), c->get_type(), c->get_value());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the type of a default value assigned to a field.
|
||||
*/
|
||||
void validate_field_value(t_field* field, t_const_value* cv) {
|
||||
validate_const_rec(field->get_name(), field->get_type(), cv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a program
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include "parse/t_const.h"
|
||||
#include "parse/t_field.h"
|
||||
|
||||
/**
|
||||
* Defined in the flex library
|
||||
@ -37,6 +38,11 @@ void failure(const char* fmt, ...);
|
||||
*/
|
||||
void validate_const_type(t_const* c);
|
||||
|
||||
/**
|
||||
* Check constant types
|
||||
*/
|
||||
void validate_field_value(t_field* field, t_const_value* cv);
|
||||
|
||||
/**
|
||||
* Converts a string filename into a thrift program name
|
||||
*/
|
||||
|
@ -15,12 +15,14 @@ class t_field {
|
||||
type_(type),
|
||||
name_(name),
|
||||
key_(0),
|
||||
value_(NULL),
|
||||
xsd_optional_(false) {}
|
||||
|
||||
t_field(t_type* type, std::string name, int32_t key) :
|
||||
type_(type),
|
||||
name_(name),
|
||||
key_(key),
|
||||
value_(NULL),
|
||||
xsd_optional_(false) {}
|
||||
|
||||
~t_field() {}
|
||||
@ -45,10 +47,19 @@ class t_field {
|
||||
return xsd_optional_;
|
||||
}
|
||||
|
||||
void set_value(t_const_value* value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
t_const_value* get_value() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
t_type* type_;
|
||||
std::string name_;
|
||||
int32_t key_;
|
||||
t_const_value* value_;
|
||||
|
||||
bool xsd_optional_;
|
||||
|
||||
|
@ -123,7 +123,9 @@ int y_field_val = -1;
|
||||
%type<ttype> DefinitionType
|
||||
|
||||
%type<tfield> Field
|
||||
%type<iconst> FieldIdentifier
|
||||
%type<ttype> FieldType
|
||||
%type<tconstv> FieldValue
|
||||
%type<tstruct> FieldList
|
||||
|
||||
%type<tenum> Enum
|
||||
@ -575,32 +577,46 @@ FieldList:
|
||||
}
|
||||
|
||||
Field:
|
||||
tok_int_constant ':' FieldType tok_identifier XsdOptional CommaOrSemicolonOptional
|
||||
FieldIdentifier FieldType tok_identifier FieldValue XsdOptional CommaOrSemicolonOptional
|
||||
{
|
||||
pdebug("tok_int_constant : Field -> FieldType tok_identifier");
|
||||
if ($1 <= 0) {
|
||||
pwarning(1, "Nonpositive value (%d) not allowed as a field key for '%s'.\n", $1, $4);
|
||||
$1 = y_field_val--;
|
||||
if ($1 < 0) {
|
||||
pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $3);
|
||||
}
|
||||
$$ = new t_field($2, $3, $1);
|
||||
if ($4 != NULL) {
|
||||
validate_field_value($$, $4);
|
||||
$$->set_value($4);
|
||||
}
|
||||
$$ = new t_field($3, $4, $1);
|
||||
$$->set_xsd_optional($5);
|
||||
}
|
||||
| FieldType tok_identifier XsdOptional CommaOrSemicolonOptional
|
||||
|
||||
FieldIdentifier:
|
||||
tok_int_constant ':'
|
||||
{
|
||||
pdebug("Field -> FieldType tok_identifier");
|
||||
pwarning(2, "No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", $2);
|
||||
$$ = new t_field($1, $2, y_field_val--);
|
||||
$$->set_xsd_optional($3);
|
||||
}
|
||||
| FieldType tok_identifier '=' tok_int_constant CommaOrSemicolonOptional
|
||||
{
|
||||
pwarning(1, "Trailing = id notation is deprecated. Use 'Id: Type Name' notation instead");
|
||||
pdebug("Field -> FieldType tok_identifier = tok_int_constant");
|
||||
if ($4 <= 0) {
|
||||
pwarning(1, "Nonpositive value (%d) not allowed as a field key for '%s'.\n", $4, $2);
|
||||
$4 = y_field_val--;
|
||||
if ($1 <= 0) {
|
||||
pwarning(1, "Nonpositive value (%d) not allowed as a field key.\n", $1);
|
||||
$1 = y_field_val--;
|
||||
}
|
||||
$$ = new t_field($1, $2, $4);
|
||||
$$ = $1;
|
||||
}
|
||||
|
|
||||
{
|
||||
$$ = y_field_val--;
|
||||
}
|
||||
|
||||
FieldValue:
|
||||
'=' ConstValue
|
||||
{
|
||||
if (g_parse_mode == PROGRAM) {
|
||||
$$ = $2;
|
||||
} else {
|
||||
$$ = NULL;
|
||||
}
|
||||
}
|
||||
|
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
|
||||
DefinitionType:
|
||||
|
Loading…
Reference in New Issue
Block a user