Client: Ruby
re: https://issues.apache.org/jira/browse/THRIFT-4631
The goal of this PR is to alter the thrift ruby code generator so that in cases
where we define structs that rely on recursion, it generates valid ruby.
The codegen include a `generate_forward_declaration` method which gets called
before `generate_struct`. It allows us to eagerly declare ruby classes so that
all classes are declared before any of the recursion within the classes
executes. Without implementing something like this you get an `uninitialized
constant` exception.
I've added tests to catch the original issue as well.
The delta caused by the this change is adding class declarations at the top of
the generated files. Here's the delta alone. Full copies of the before / after
below.
```
class RecTree; end
class RecList; end
class CoRec; end
class CoRec2; end
class VectorTest; end
```
What gets generated now for Recursive.thrift
```
#
# Autogenerated by Thrift Compiler (1.0.0-dev)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
require 'thrift'
class RecTree
include ::Thrift::Struct, ::Thrift::Struct_Union
CHILDREN = 1
ITEM = 2
FIELDS = {
CHILDREN => {:type => ::Thrift::Types::LIST, :name => 'children', :element
=> {:type => ::Thrift::Types::STRUCT, :class => ::RecTree}},
ITEM => {:type => ::Thrift::Types::I16, :name => 'item'}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class RecList
include ::Thrift::Struct, ::Thrift::Struct_Union
NEXTITEM = 1
ITEM = 3
FIELDS = {
NEXTITEM => {:type => ::Thrift::Types::STRUCT, :name => 'nextitem', :class
=> ::RecList},
ITEM => {:type => ::Thrift::Types::I16, :name => 'item'}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class CoRec
include ::Thrift::Struct, ::Thrift::Struct_Union
OTHER = 1
FIELDS = {
OTHER => {:type => ::Thrift::Types::STRUCT, :name => 'other', :class =>
::CoRec2}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class CoRec2
include ::Thrift::Struct, ::Thrift::Struct_Union
OTHER = 1
FIELDS = {
OTHER => {:type => ::Thrift::Types::STRUCT, :name => 'other', :class =>
::CoRec}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class VectorTest
include ::Thrift::Struct, ::Thrift::Struct_Union
LISTER = 1
FIELDS = {
LISTER => {:type => ::Thrift::Types::LIST, :name => 'lister', :element =>
{:type => ::Thrift::Types::STRUCT, :class => ::RecList}}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
```
What is generated using this PR:
```
#
# Autogenerated by Thrift Compiler (1.0.0-dev)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
require 'thrift'
class RecTree; end
class RecList; end
class CoRec; end
class CoRec2; end
class VectorTest; end
class RecTree
include ::Thrift::Struct, ::Thrift::Struct_Union
CHILDREN = 1
ITEM = 2
FIELDS = {
CHILDREN => {:type => ::Thrift::Types::LIST, :name => 'children', :element
=> {:type => ::Thrift::Types::STRUCT, :class => ::RecTree}},
ITEM => {:type => ::Thrift::Types::I16, :name => 'item'}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class RecList
include ::Thrift::Struct, ::Thrift::Struct_Union
NEXTITEM = 1
ITEM = 3
FIELDS = {
NEXTITEM => {:type => ::Thrift::Types::STRUCT, :name => 'nextitem', :class
=> ::RecList},
ITEM => {:type => ::Thrift::Types::I16, :name => 'item'}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class CoRec
include ::Thrift::Struct, ::Thrift::Struct_Union
OTHER = 1
FIELDS = {
OTHER => {:type => ::Thrift::Types::STRUCT, :name => 'other', :class =>
::CoRec2}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class CoRec2
include ::Thrift::Struct, ::Thrift::Struct_Union
OTHER = 1
FIELDS = {
OTHER => {:type => ::Thrift::Types::STRUCT, :name => 'other', :class =>
::CoRec}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
class VectorTest
include ::Thrift::Struct, ::Thrift::Struct_Union
LISTER = 1
FIELDS = {
LISTER => {:type => ::Thrift::Types::LIST, :name => 'lister', :element =>
{:type => ::Thrift::Types::STRUCT, :class => ::RecList}}
}
def struct_fields; FIELDS; end
def validate
end
::Thrift::Struct.generate_accessors self
end
```
[ Full content available at: https://github.com/apache/thrift/pull/1592 ]
This message was relayed via gitbox.apache.org for [email protected]