From 343c61d6a7f06e65de8087499675d7b8295e41b2 Mon Sep 17 00:00:00 2001 From: Jake Farrell Date: Fri, 9 Dec 2011 02:29:56 +0000 Subject: [PATCH] Thrift-1441: Generate constructor with parameters for exception class to let it update message property automatically. Client:delphi Patch: Kenjiro Fukumitsu Add the function to delphi generator that generates constructor with parameters to initialize members,if the class is exception and have more than zero parameters. git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1212226 13f79535-47bb-0310-9956-ffa450edef68 --- .../cpp/src/generate/t_delphi_generator.cc | 91 +++++++++++++++++-- lib/delphi/test/TestServer.pas | 17 +--- 2 files changed, 86 insertions(+), 22 deletions(-) diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc index 4b602e50..bb00ea71 100644 --- a/compiler/cpp/src/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/generate/t_delphi_generator.cc @@ -136,9 +136,11 @@ class t_delphi_generator : public t_oop_generator std::string declare_field(t_field* tfield, bool init=false, std::string prefix="", bool is_xception_class = false); std::string function_signature(t_function* tfunction, std::string full_cls="", bool is_xception = false); std::string argument_list(t_struct* tstruct); + std::string constructor_argument_list(t_struct* tstruct, std::string current_indent); std::string type_to_enum(t_type* ttype); std::string prop_name(t_field* tfield, bool is_xception = false); std::string prop_name(std::string name, bool is_xception = false); + std::string constructor_param_name(string name); void write_enum(std::string line); void write_forward_decr(std::string line); @@ -664,7 +666,7 @@ void t_delphi_generator::print_const_def_value(std::ostream& vars, std::ostream& throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string(); } string val = render_const_value( vars, out, name, field_type, v_iter->second); - indent_impl(out) << cls_prefix << normalize_name(name) << "." << normalize_name( v_iter->first->get_string()) << " := " << val << ";" << endl; + indent_impl(out) << cls_prefix << normalize_name(name) << "." << prop_name( v_iter->first->get_string(), type->is_xception()) << " := " << val << ";" << endl; } } else if (type->is_map()) { t_type* ktype = ((t_map*)type)->get_key_type(); @@ -716,11 +718,10 @@ void t_delphi_generator::print_const_value( std::ostream& vars, std::ostream& ou indent_impl(out) << name << " := " << type_name(type) << "(" << value->get_integer() << ");" << endl; } else { string typname; - typname = type_name(type,!type->is_xception()); + typname = type_name( type, true, false, type->is_xception(), type->is_xception()); indent_impl(out) << name << " := " << typname << ".Create;" << endl; print_const_def_value( vars, out, name, type, value); } - } void t_delphi_generator::initialize_field(std::ostream& vars, std::ostream& out, string name, t_type* type, t_const_value* value) { @@ -843,10 +844,10 @@ void t_delphi_generator::generate_delphi_struct_impl( ostream& out, string cls_p } indent_down_impl(); - indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." << "Create;" << endl; if ( ! vars.str().empty()) { + out << "var" << endl; out << vars.str(); } @@ -866,6 +867,21 @@ void t_delphi_generator::generate_delphi_struct_impl( ostream& out, string cls_p indent_down_impl(); indent_impl(out) << "end;" << endl << endl; + if ((members.size() > 0) && is_exception && (!is_x_factory)) { + indent_impl(out) << "constructor " << cls_prefix << cls_nm << "." << "Create(" << constructor_argument_list( tstruct, indent_impl()) << ");" << endl; + indent_impl(out) << "begin" << endl; + indent_up_impl(); + indent_impl(out) << "Create;" << endl; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + string propname = prop_name((*m_iter)->get_name(), is_exception); + string param_name = constructor_param_name( (*m_iter)->get_name()); + indent_impl(out) << propname << " := " << param_name << ";" << endl; + } + indent_impl(out) << "UpdateMessageProperty;" << endl; + indent_down_impl(); + indent_impl(out) << "end;" << endl << endl; + } + indent_impl(out) << "destructor " << cls_prefix << cls_nm << "." << "Destroy;" << endl; indent_impl(out) << "begin" << endl; indent_up_impl(); @@ -1035,7 +1051,13 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream &out, t_struc indent(out) << "public" << endl; indent_up(); - indent(out) << "constructor Create;" << endl; + if ((members.size() > 0) && is_exception && (! is_x_factory)) { + indent(out) << "constructor Create; overload;" << endl; + indent(out) << "constructor Create(" << constructor_argument_list( tstruct, indent()) << "); overload;" << endl; + } else { + indent(out) << "constructor Create;" << endl; + } + indent(out) << "destructor Destroy; override;" << endl; out << endl; @@ -1078,9 +1100,7 @@ void t_delphi_generator::generate_delphi_struct_definition(ostream &out, t_struc } indent_down(); - indent(out) << "end;" << endl; - - indent(out) << endl; + indent(out) << "end;" << endl << endl; } void t_delphi_generator::generate_service(t_service* tservice) { @@ -1998,6 +2018,13 @@ std::string t_delphi_generator::prop_name(string name, bool is_xception) { return normalize_name( ret, true, is_xception); } +std::string t_delphi_generator::constructor_param_name(string name) { + string ret = name; + ret[0] = toupper(ret[0]); + ret = "A" + ret; + return normalize_name( ret, false, false); +} + string t_delphi_generator::normalize_clsnm(string clsnm, string prefix, bool b_no_check_keyword) { if (clsnm.size() > 0) { clsnm[0] = toupper(clsnm[0]); @@ -2154,6 +2181,54 @@ string t_delphi_generator::argument_list(t_struct* tstruct) { return result; } +string t_delphi_generator::constructor_argument_list(t_struct* tstruct, string current_indent) { + ostringstream result; + const vector& fields = tstruct->get_members(); + vector::const_iterator f_iter; + bool first = true; + t_type* tt; + string line = ""; + string newline_indent = current_indent + " "; + + bool firstline = true; + + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if (first) { + first = false; + } else { + line += ";"; + } + + if (line.size() > 80) { + if ( firstline ) { + result << endl << newline_indent; + firstline = false; + } + result << line << endl; + line = newline_indent; + } else if ( line.size() > 0) { + line += " "; + } + + tt = (*f_iter)->get_type(); + line += constructor_param_name((*f_iter)->get_name()) + ": " + type_name( tt, false, true, tt->is_xception(), true); + } + + if ( line.size() > 0) { + result << line; + } + + string result_str; + + if (firstline) { + result_str = " " + result.str(); + } else { + result_str = result.str(); + } + + return result_str; +} + string t_delphi_generator::type_to_enum(t_type* type) { while (type->is_typedef()) { type = ((t_typedef*)type)->get_type(); diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas index 26d49d2c..8f890dac 100644 --- a/lib/delphi/test/TestServer.pas +++ b/lib/delphi/test/TestServer.pas @@ -106,17 +106,11 @@ begin end; procedure TTestServer.TTestHandlerImpl.testException(arg: string); -var - x : TXception; begin Console.WriteLine('testException(' + arg + ')'); if ( arg = 'Xception') then begin - x := TXception.Create; - x.ErrorCode := 1001; - x.Message_ := 'This is an Xception'; - x.UpdateMessageProperty; - raise x; + raise TXception.Create( 1001, 'This is an Xception'); end; end; @@ -272,21 +266,16 @@ end; function TTestServer.TTestHandlerImpl.testMultiException(arg0, arg1: string): IXtruct; var - x : TXception; x2 : TXception2; begin Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')'); if ( arg0 = 'Xception') then begin - x := TXception.Create; - x.ErrorCode := 1001; - x.Message_ := 'This is an Xception'; - x.UpdateMessageProperty; - raise x; + raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR end else if ( arg0 = 'Xception2') then begin - x2 := TXception2.Create; + x2 := TXception2.Create; // the old way still works too? x2.ErrorCode := 2002; x2.Struct_thing := TXtructImpl.Create; x2.Struct_thing.String_thing := 'This is an Xception2'; -- 2.17.1