Skip to content

Commit

Permalink
Support ruby v3.1 and v3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ksss committed Oct 17, 2023
1 parent 568985c commit af735c2
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 81 deletions.
4 changes: 2 additions & 2 deletions lib/rbs/prototype/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ def generate_class(mod)
unless decl
if mod < Struct
decl = StructGenerator.new(mod).build_decl
elsif mod < Data
elsif RUBY_VERSION >= '3.2' && mod < Data
decl = DataGenerator.new(mod).build_decl
else
decl = AST::Declarations::Class.new(
Expand All @@ -511,7 +511,7 @@ def generate_class(mod)

generate_mixin(mod, decl, type_name, type_name_absolute)

unless mod < Struct || mod < Data
unless mod < Struct || (RUBY_VERSION >= '3.2' && mod < Data)
generate_methods(mod, type_name, decl.members) unless outline
end

Expand Down
8 changes: 6 additions & 2 deletions lib/rbs/prototype/runtime/value_object_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def build_member_accessors(ast_members_class)
end

class StructGenerator < ValueObjectBase
CAN_CALL_KEYWORD_INIT_P = Struct.new(:tmp).respond_to?(:keyword_init?)

def build_super_class
AST::Declarations::Class::Super.new(name: TypeName("::Struct"), args: [untyped], location: nil)
end
Expand All @@ -102,7 +104,7 @@ def build_s_new
[:new, :[]].map do |name|
new_overloads = []

if @target_class.keyword_init? == false || @target_class.keyword_init? == nil
if CAN_CALL_KEYWORD_INIT_P ? (@target_class.keyword_init? == false || @target_class.keyword_init? == nil) : true
new_overloads << AST::Members::MethodDefinition::Overload.new(
annotations: [],
method_type: MethodType.new(
Expand All @@ -115,7 +117,7 @@ def build_s_new
)
)
end
if @target_class.keyword_init? == true || @target_class.keyword_init? == nil
if CAN_CALL_KEYWORD_INIT_P ? (@target_class.keyword_init? == true || @target_class.keyword_init? == nil) : true
new_overloads << AST::Members::MethodDefinition::Overload.new(
annotations: [],
method_type: MethodType.new(
Expand Down Expand Up @@ -144,6 +146,8 @@ def build_s_new

# def self.keyword_init?: () -> bool?
def build_s_keyword_init_p
return [] unless CAN_CALL_KEYWORD_INIT_P

return_type = @target_class.keyword_init?.nil? \
? Types::Bases::Nil.new(location: nil)
: Types::Literal.new(literal: @target_class.keyword_init?, location: nil)
Expand Down
228 changes: 151 additions & 77 deletions test/rbs/runtime_prototype_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -701,131 +701,205 @@ def test_struct
SignatureManager.new do |manager|
manager.build do |env|
p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::StructInheritWithNil"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructInheritWithNil < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped foo, ?bar: untyped bar) -> instance
if Runtime::StructGenerator::CAN_CALL_KEYWORD_INIT_P
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructInheritWithNil < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped foo, ?bar: untyped bar) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.keyword_init?: () -> nil
def self.keyword_init?: () -> nil
def self.members: () -> [ :foo, :bar ]
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor foo: untyped
attr_accessor bar: untyped
attr_accessor bar: untyped
end
end
end
end
RBS
RBS
else
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructInheritWithNil < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor bar: untyped
end
end
end
RBS
end

p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::StructKeywordInitTrue"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitTrue < ::Struct[untyped]
def self.new: (?foo: untyped foo, ?bar: untyped bar) -> instance
if Runtime::StructGenerator::CAN_CALL_KEYWORD_INIT_P
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitTrue < ::Struct[untyped]
def self.new: (?foo: untyped, ?bar: untyped) -> instance
def self.[]: (?foo: untyped foo, ?bar: untyped bar) -> instance
def self.[]: (?foo: untyped, ?bar: untyped) -> instance
def self.keyword_init?: () -> true
def self.keyword_init?: () -> true
def self.members: () -> [ :foo, :bar ]
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor foo: untyped
attr_accessor bar: untyped
attr_accessor bar: untyped
end
end
end
end
RBS
RBS
else
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitTrue < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor bar: untyped
end
end
end
RBS
end

p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::StructKeywordInitFalse"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitFalse < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
if Runtime::StructGenerator::CAN_CALL_KEYWORD_INIT_P
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitFalse < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
def self.keyword_init?: () -> false
def self.keyword_init?: () -> false
def self.members: () -> [ :foo, :bar ]
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor foo: untyped
attr_accessor bar: untyped
attr_accessor bar: untyped
end
end
end
end
RBS
RBS
else
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class StructKeywordInitFalse < ::Struct[untyped]
def self.new: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.[]: (?untyped foo, ?untyped bar) -> instance
| (?foo: untyped, ?bar: untyped) -> instance
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_accessor foo: untyped
attr_accessor bar: untyped
end
end
end
RBS
end
end
end
end

class DataInherit < Data.define(:foo, :bar)
end
DataConst = Data.define(:foo, :bar)
if RUBY_VERSION >= '3.2'
class DataInherit < Data.define(:foo, :bar)
end
DataConst = Data.define(:foo, :bar)

def test_data
SignatureManager.new do |manager|
manager.build do |env|
p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::DataInherit"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class DataInherit < ::Data
def self.new: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def test_data
SignatureManager.new do |manager|
manager.build do |env|
p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::DataInherit"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class DataInherit < ::Data
def self.new: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.[]: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.[]: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.members: () -> [ :foo, :bar ]
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_reader foo: untyped
attr_reader foo: untyped
attr_reader bar: untyped
attr_reader bar: untyped
end
end
end
end
RBS
RBS

p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::DataConst"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class DataConst < ::Data
def self.new: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
p = Runtime.new(patterns: ["RBS::RuntimePrototypeTest::DataConst"], env: env, merge: false)
assert_write p.decls, <<~RBS
module RBS
class RuntimePrototypeTest < ::Test::Unit::TestCase
class DataConst < ::Data
def self.new: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.[]: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.[]: (untyped foo, untyped bar) -> instance
| (foo: untyped, bar: untyped) -> instance
def self.members: () -> [ :foo, :bar ]
def self.members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
def members: () -> [ :foo, :bar ]
attr_reader foo: untyped
attr_reader foo: untyped
attr_reader bar: untyped
attr_reader bar: untyped
end
end
end
end
RBS
RBS
end
end
end
end
Expand Down

0 comments on commit af735c2

Please sign in to comment.