Skip to content

Commit

Permalink
Add new Attribute#ivar API
Browse files Browse the repository at this point in the history
  • Loading branch information
amomchilov committed Dec 2, 2024
1 parent 5576405 commit e406183
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
15 changes: 15 additions & 0 deletions lib/rbs/ast/members.rb
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,21 @@ def update(name: self.name, type: self.type, ivar_name: self.ivar_name, kind: se
visibility: visibility
)
end

def ivar
@ivar ||= begin
ivar_name = case self.ivar_name
when false
return nil # Skip the instance variable declaration entirely
when nil
:"@#{name}" # Infer the instance variable name from the attribute name
else
self.ivar_name # Use the custom instance variable name given by the user
end

InstanceVariable.new(name: ivar_name, type: type, location: location, comment: comment)
end
end
end

class AttrReader < Base
Expand Down
2 changes: 2 additions & 0 deletions sig/members.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ module RBS
include _HashEqual

def update: (?name: Symbol, ?type: Types::t, ?ivar_name: Symbol | false | nil, ?kind: kind, ?annotations: Array[Annotation], ?location: loc?, ?comment: Comment?, ?visibility: visibility?) -> instance

def ivar: () -> InstanceVariable?
end

class AttrReader < Base
Expand Down
48 changes: 48 additions & 0 deletions test/rbs/signature_parsing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,13 @@ def self?.three: -> bool
assert_equal :a, m.name
assert_nil m.ivar_name
assert_equal parse_type("Integer"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@a, ivar.name # Inferred from the attribute name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[11].yield_self do |m|
Expand All @@ -369,6 +376,13 @@ def self?.three: -> bool
assert_equal :a, m.name
assert_equal :@A, m.ivar_name
assert_equal parse_type("String"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@A, ivar.name # Explicitly given ivar name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[12].yield_self do |m|
Expand All @@ -377,6 +391,8 @@ def self?.three: -> bool
assert_equal :a, m.name
assert_equal false, m.ivar_name
assert_equal parse_type("bool"), m.type

assert_nil m.ivar # The instance variable was explicitly skipped
end

module_decl.members[13].yield_self do |m|
Expand All @@ -385,6 +401,13 @@ def self?.three: -> bool
assert_equal :b, m.name
assert_nil m.ivar_name
assert_equal parse_type("Integer"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@b, ivar.name # Inferred from the attribute name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[14].yield_self do |m|
Expand All @@ -393,6 +416,13 @@ def self?.three: -> bool
assert_equal :b, m.name
assert_equal :@B, m.ivar_name
assert_equal parse_type("String"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@B, ivar.name # Explicitly given ivar name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[15].yield_self do |m|
Expand All @@ -401,6 +431,8 @@ def self?.three: -> bool
assert_equal :b, m.name
assert_equal false, m.ivar_name
assert_equal parse_type("bool"), m.type

assert_nil m.ivar # The instance variable was explicitly skipped
end

module_decl.members[16].yield_self do |m|
Expand All @@ -409,6 +441,13 @@ def self?.three: -> bool
assert_equal :c, m.name
assert_nil m.ivar_name
assert_equal parse_type("Integer"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@c, ivar.name # Inferred from the attribute name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[17].yield_self do |m|
Expand All @@ -417,6 +456,13 @@ def self?.three: -> bool
assert_equal :c, m.name
assert_equal :@C, m.ivar_name
assert_equal parse_type("String"), m.type

ivar = m.ivar
assert_instance_of Members::InstanceVariable, ivar
assert_equal :@C, ivar.name # Explicitly given ivar name
assert_equal m.type, ivar.type
assert_equal m.location, ivar.location
assert_equal m.comment, ivar.comment
end

module_decl.members[18].yield_self do |m|
Expand All @@ -425,6 +471,8 @@ def self?.three: -> bool
assert_equal :c, m.name
assert_equal false, m.ivar_name
assert_equal parse_type("bool"), m.type

assert_nil m.ivar # The instance variable was explicitly skipped
end
end
end
Expand Down

0 comments on commit e406183

Please sign in to comment.