From d000b241a43e50157938e056b9fa0f7d88f099df Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Sun, 13 Apr 2014 21:58:47 +0200 Subject: [PATCH] THRIFT-2449 Enhance typedef structure to distinguish between forwards and real typedefs Client: General Compiler, Delphi Patch: Jens Geyer --- .../cpp/src/generate/t_delphi_generator.cc | 52 +++++++++++++++---- compiler/cpp/src/parse/t_typedef.h | 9 +++- compiler/cpp/src/thrifty.yy | 2 +- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc index 1a51e83e..4ecc2694 100644 --- a/compiler/cpp/src/generate/t_delphi_generator.cc +++ b/compiler/cpp/src/generate/t_delphi_generator.cc @@ -85,6 +85,7 @@ class t_delphi_generator : public t_oop_generator void generate_typedef (t_typedef* ttypedef); void generate_enum (t_enum* tenum); + void generate_forward_declaration(t_struct* tstruct); void generate_struct (t_struct* tstruct); void generate_xception (t_struct* txception); void generate_service (t_service* tservice); @@ -187,7 +188,7 @@ class t_delphi_generator : public t_oop_generator string replace_all( string contents, string search, string replace); string xml_encode( string contents); string xmldoc_encode( string contents); - string xmlattrib_encode( string contents); + string xmlattrib_encode( string contents); void generate_delphi_doc (std::ostream& out, t_field* field); void generate_delphi_doc (std::ostream& out, t_doc* tdoc); void generate_delphi_doc (std::ostream& out, t_function* tdoc); @@ -215,6 +216,7 @@ class t_delphi_generator : public t_oop_generator std::ostringstream s_service_impl; std::ostringstream s_type_factory_registration; std::ostringstream s_type_factory_funcs; + bool has_forward; bool has_enum; bool has_const; std::string namespace_dir_; @@ -237,7 +239,7 @@ class t_delphi_generator : public t_oop_generator bool register_types_; bool constprefix_; bool events_; - bool xmldoc_; + bool xmldoc_; void indent_up_impl(){ ++indent_impl_; }; @@ -268,7 +270,7 @@ string t_delphi_generator::replace_all( string contents, string search, string r size_t found = str.find(search); while( (found != string::npos) && (found < str.length())) { str.replace( found, slen, repl); - found = str.find(search, found+incr); + found = str.find(search, found+incr); } } @@ -324,7 +326,7 @@ void t_delphi_generator::generate_delphi_doc(ostream &out, t_field* field) { if( xmldoc_) { if (field->get_type()->is_enum()) { string combined_message = xmldoc_encode( field->get_doc()) - + "\nget_type())) + "\"/>"; generate_delphi_docstring_comment(out, combined_message); @@ -553,6 +555,7 @@ void t_delphi_generator::add_delphi_uses_list( string unitname){ void t_delphi_generator::init_generator() { indent_impl_ = 0; namespace_name_ = program_->get_namespace("delphi"); + has_forward = false; has_enum = false; has_const = false; create_keywords(); @@ -641,8 +644,11 @@ void t_delphi_generator::close_generator() { indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << ( xmldoc_ ? "True" : "False") << ";" << endl; indent_down(); + f_all << endl; f_all << "type" << endl; - f_all << s_forward_decr.str(); + if(has_forward) { + f_all << s_forward_decr.str() << endl; + } if (has_enum) { indent(f_all) << endl; indent(f_all) << "{$SCOPEDENUMS ON}" << endl << endl; @@ -709,6 +715,21 @@ void t_delphi_generator::delphi_type_usings( ostream& out) { indent_down(); } +void t_delphi_generator::generate_forward_declaration(t_struct* tstruct) { + // Forward declare struct def + has_forward = true; + pverbose("forward declaration of %s\n", type_name(tstruct).c_str()); + + string what = tstruct->is_xception() ? "class" : "interface"; + + indent_up(); + indent(s_forward_decr) << + type_name(tstruct,tstruct->is_xception(),true) << " = " << what << ";" << endl; + indent_down(); + + add_defined_type(tstruct); +} + void t_delphi_generator::generate_typedef(t_typedef* ttypedef) { t_type* type = ttypedef->get_type(); @@ -718,7 +739,7 @@ void t_delphi_generator::generate_typedef(t_typedef* ttypedef) { typedefs_pending.push_back( ttypedef); return; } - + indent_up(); generate_delphi_doc(s_struct, ttypedef); indent(s_struct) << @@ -821,7 +842,7 @@ void t_delphi_generator::generate_enum(t_enum* tenum) { s_enum << ","; s_enum << endl; } - generate_delphi_doc(s_enum, *c_iter); + generate_delphi_doc(s_enum, *c_iter); indent(s_enum) << normalize_name((*c_iter)->get_name()) << " = " << value; } s_enum << endl; @@ -1568,7 +1589,7 @@ void t_delphi_generator::generate_service_interface(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_delphi_doc(s_service, *f_iter); - indent(s_service) << + indent(s_service) << function_signature(*f_iter) << endl; } indent_down(); @@ -2541,9 +2562,18 @@ string t_delphi_generator::normalize_clsnm(string clsnm, string prefix, bool b_n } string t_delphi_generator::type_name( t_type* ttype, bool b_cls, bool b_no_postfix, bool b_exception_factory, bool b_full_exception_factory) { - - if (ttype->is_typedef()) { - return normalize_name( "T"+((t_typedef*)ttype)->get_symbolic()); + + if (ttype->is_typedef()) { + t_typedef* tdef = (t_typedef*)ttype; + if( tdef->is_forward_typedef()) { // forward types according to THRIFT-2421 + if( tdef->get_type() != NULL) { + return type_name( tdef->get_type(), b_cls, b_no_postfix, b_exception_factory, b_full_exception_factory); + } else { + throw "unresolved forward declaration: " + tdef->get_symbolic(); + } + } else { + return normalize_name( "T"+tdef->get_symbolic()); + } } string typ_nm; diff --git a/compiler/cpp/src/parse/t_typedef.h b/compiler/cpp/src/parse/t_typedef.h index 1bea4c98..52a75671 100644 --- a/compiler/cpp/src/parse/t_typedef.h +++ b/compiler/cpp/src/parse/t_typedef.h @@ -36,6 +36,7 @@ class t_typedef : public t_type { t_type(program, symbolic), type_(type), symbolic_(symbolic), + forward_(false), seen_(false) {} /** @@ -43,10 +44,11 @@ class t_typedef : public t_type { * resolved at a later time, like for forward declarations or * recursive types. */ - t_typedef(t_program* program, const std::string& symbolic) : + t_typedef(t_program* program, const std::string& symbolic, bool forward) : t_type(program, symbolic), type_(NULL), symbolic_(symbolic), + forward_(forward), seen_(false) {} ~t_typedef() {} @@ -57,6 +59,10 @@ class t_typedef : public t_type { return symbolic_; } + bool is_forward_typedef() const { + return forward_; + } + bool is_typedef() const { return true; } @@ -81,6 +87,7 @@ class t_typedef : public t_type { private: t_type* type_; std::string symbolic_; + bool forward_; mutable bool seen_; }; diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index e2467dfd..edb05f90 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -1092,7 +1092,7 @@ FieldType: declared. Either way allow it and we'll figure it out during generation. */ - $$ = new t_typedef(g_program, $1); + $$ = new t_typedef(g_program, $1, true); } } } -- 2.17.1