You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "charles giardina (JIRA)" <ji...@apache.org> on 2018/09/12 16:35:00 UTC

[jira] [Created] (THRIFT-4631) Codegen Creates Invalid Ruby for Recursive Structs

charles giardina created THRIFT-4631:
----------------------------------------

             Summary: Codegen Creates Invalid Ruby for Recursive Structs
                 Key: THRIFT-4631
                 URL: https://issues.apache.org/jira/browse/THRIFT-4631
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Compiler, Ruby - Library
    Affects Versions: 0.11.0
            Reporter: charles giardina


Though thrift supports defining recursive structs, it appears that the Ruby codegen does not generate valid Ruby for for recursive structs.

e.g. Here's an example of what I'm seeing and how to recreate it using Recursive.thrift in the Thrift test suite.
 * add {{$(THRIFT) --gen rb ../Recursive.thrift}} to {{test/rb/Makefile.am}}
 * and add {{require "recursive_types"}} to {{test/rb/generation/test_struct.rb}}
 * run {{make -k check}} from {{test/rb}}
 * this ends up raising the following exception:
{code:java}
thrift/test/rb/gen-rb/recursive_types.rb:50:in `<class:CoRec>': uninitialized constant CoRec2 (NameError)
Did you mean?  CoRec
	from thrift/test/rb/gen-rb/recursive_types.rb:45:in `<top (required)>'
	from thrift/test/rb/generation/test_struct.rb:22:in `require'
	from thrift/test/rb/generation/test_struct.rb:22:in `<top (required)>'
	from test_suite.rb:20:in `require'
	from test_suite.rb:20:in `block in <main>'
	from test_suite.rb:20:in `each'
	from test_suite.rb:20:in `<main>'
make: *** [check] Error 1
{code}

 

I've copied the generated code below. But essentially the issue appears to be that recursive structs are referencing constants or classes that have not yet been declared. I have some ideas on how to address this and can post a proposed solution.

 

generated code:
{code:java}
#
# Autogenerated by Thrift Compiler (0.11.0)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#

require 'thrift'

module RecursiveExample
  class Node < ::Thrift::Union
    include ::Thrift::Struct_Union
    class << self
      def inner_node(val)
        Node.new(:inner_node, val)
      end

      def leaf_node(val)
        Node.new(:leaf_node, val)
      end
    end

    INNER_NODE = 1
    LEAF_NODE = 2

    FIELDS = {
      INNER_NODE => {:type => ::Thrift::Types::STRUCT, :name => 'inner_node', :class => ::RecursiveExample::InnerNode, :optional => true},
      LEAF_NODE => {:type => ::Thrift::Types::STRUCT, :name => 'leaf_node', :class => ::RecursiveExample::LeafNode, :optional => true}
    }

    def struct_fields; FIELDS; end

    def validate
      raise(StandardError, 'Union fields are not set.') if get_set_field.nil? || get_value.nil?
    end

    ::Thrift::Union.generate_accessors self
  end

  class InnerNode
    include ::Thrift::Struct, ::Thrift::Struct_Union
    NODE = 1

    FIELDS = {
      NODE => {:type => ::Thrift::Types::STRUCT, :name => 'node', :class => ::RecursiveExample::Node}
    }

    def struct_fields; FIELDS; end

    def validate
      raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Required field node is unset!') unless @node    end

    ::Thrift::Struct.generate_accessors self
  end

  class LeafNode
    include ::Thrift::Struct, ::Thrift::Struct_Union

    FIELDS = {

    }

    def struct_fields; FIELDS; end

    def validate
    end

    ::Thrift::Struct.generate_accessors self
  end

end
{code}
 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)