This is an automated email from the ASF dual-hosted git repository. jking pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/thrift.git
The following commit(s) were added to refs/heads/master by this push: new 1808888 THRIFT-4631 Fix Ruby codegen to gen valid ruby for recursive structs 1808888 is described below commit 180888820aa7d48485364718eeabbcfe8cba4edf Author: Charles Giardina <cgiard...@liveramp.com> AuthorDate: Tue Sep 11 15:58:42 2018 -0700 THRIFT-4631 Fix Ruby codegen to gen valid ruby for recursive structs --- compiler/cpp/src/thrift/generate/t_rb_generator.cc | 25 +++++++++++++++++++ test/rb/Makefile.am | 1 + .../{Makefile.am => generation/test_recursive.rb} | 28 +++++++++++++++------- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc index 3f2b78e..13ea249 100644 --- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc @@ -113,6 +113,7 @@ public: void generate_enum(t_enum* tenum); void generate_const(t_const* tconst); void generate_struct(t_struct* tstruct); + void generate_forward_declaration(t_struct* tstruct); void generate_union(t_struct* tunion); void generate_xception(t_struct* txception); void generate_service(t_service* tservice); @@ -123,6 +124,7 @@ public: * Struct generation code */ + void generate_rb_struct_declaration(t_rb_ofstream& out, t_struct* tstruct, bool is_exception); void generate_rb_struct(t_rb_ofstream& out, t_struct* tstruct, bool is_exception); void generate_rb_struct_required_validator(t_rb_ofstream& out, t_struct* tstruct); void generate_rb_union(t_rb_ofstream& out, t_struct* tstruct, bool is_exception); @@ -529,6 +531,29 @@ void t_rb_generator::generate_struct(t_struct* tstruct) { } } + +/** + * Generates the "forward declarations" for ruby structs. + * These are simply a declaration of each class with proper inheritance. + * The rest of the struct is still generated in generate_struct as has + * always been the case. These declarations allow thrift to generate valid + * ruby in cases where thrift structs rely on recursive definitions. + */ +void t_rb_generator::generate_forward_declaration(t_struct* tstruct) { + generate_rb_struct_declaration(f_types_, tstruct, tstruct->is_xception()); +} + +void t_rb_generator::generate_rb_struct_declaration(t_rb_ofstream& out, t_struct* tstruct, bool is_exception) { + out.indent() << "class " << type_name(tstruct); + if (tstruct->is_union()) { + out << " < ::Thrift::Union"; + } + if (is_exception) { + out << " < ::Thrift::Exception"; + } + out << "; end" << endl << endl; +} + /** * Generates a struct definition for a thrift exception. Basically the same * as a struct but extends the Exception class. diff --git a/test/rb/Makefile.am b/test/rb/Makefile.am index 4bd4704..cfdc149 100644 --- a/test/rb/Makefile.am +++ b/test/rb/Makefile.am @@ -20,6 +20,7 @@ stubs: $(THRIFT) ../ThriftTest.thrift ../SmallTest.thrift $(THRIFT) --gen rb ../ThriftTest.thrift $(THRIFT) --gen rb ../SmallTest.thrift + $(THRIFT) --gen rb ../Recursive.thrift precross: stubs diff --git a/test/rb/Makefile.am b/test/rb/generation/test_recursive.rb similarity index 55% copy from test/rb/Makefile.am copy to test/rb/generation/test_recursive.rb index 4bd4704..e912f72 100644 --- a/test/rb/Makefile.am +++ b/test/rb/generation/test_recursive.rb @@ -17,15 +17,25 @@ # under the License. # -stubs: $(THRIFT) ../ThriftTest.thrift ../SmallTest.thrift - $(THRIFT) --gen rb ../ThriftTest.thrift - $(THRIFT) --gen rb ../SmallTest.thrift +require File.join(File.dirname(__FILE__), '../test_helper') +require 'recursive_types' -precross: stubs +class TestRecursiveGeneration < Test::Unit::TestCase + CHILD_ITEM = "child item" + PARENT_ITEM = "parent item" -check: stubs -if HAVE_BUNDLER - $(BUNDLER) install - $(BUNDLER) exec $(RUBY) -I. test_suite.rb -endif + def test_can_create_recursive_tree + child_tree = RecTree.new + child_tree.item = CHILD_ITEM + + parent_tree = RecTree.new + parent_tree.item = PARENT_ITEM + parent_tree.children = [child_tree] + + assert_equal(PARENT_ITEM, parent_tree.item) + assert_equal(1, parent_tree.children.length) + assert_equal(CHILD_ITEM, parent_tree.children.first.item) + assert_nil(parent_tree.children.first.children) + end +end