THRIFT-2449 Enhance typedef structure to distinguish between forwards and real typedefs
Client: General Compiler, Delphi
Patch: Jens Geyer
diff --git a/compiler/cpp/src/generate/t_delphi_generator.cc b/compiler/cpp/src/generate/t_delphi_generator.cc
index 1a51e83..4ecc269 100644
--- a/compiler/cpp/src/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/generate/t_delphi_generator.cc
@@ -85,6 +85,7 @@
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 @@
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 @@
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 @@
bool register_types_;
bool constprefix_;
bool events_;
- bool xmldoc_;
+ bool xmldoc_;
void indent_up_impl(){
++indent_impl_;
};
@@ -268,7 +270,7 @@
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 @@
if( xmldoc_) {
if (field->get_type()->is_enum()) {
string combined_message = xmldoc_encode( field->get_doc())
- + "\n<seealso cref=\""
+ + "\n<seealso cref=\""
+ xmldoc_encode( type_name(field->get_type()))
+ "\"/>";
generate_delphi_docstring_comment(out, combined_message);
@@ -553,6 +555,7 @@
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 @@
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 @@
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 @@
typedefs_pending.push_back( ttypedef);
return;
}
-
+
indent_up();
generate_delphi_doc(s_struct, ttypedef);
indent(s_struct) <<
@@ -821,7 +842,7 @@
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 @@
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::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 1bea4c9..52a7567 100644
--- a/compiler/cpp/src/parse/t_typedef.h
+++ b/compiler/cpp/src/parse/t_typedef.h
@@ -36,6 +36,7 @@
t_type(program, symbolic),
type_(type),
symbolic_(symbolic),
+ forward_(false),
seen_(false) {}
/**
@@ -43,10 +44,11 @@
* 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 @@
return symbolic_;
}
+ bool is_forward_typedef() const {
+ return forward_;
+ }
+
bool is_typedef() const {
return true;
}
@@ -81,6 +87,7 @@
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 e2467df..edb05f9 100644
--- a/compiler/cpp/src/thrifty.yy
+++ b/compiler/cpp/src/thrifty.yy
@@ -1092,7 +1092,7 @@
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);
}
}
}