Skip to content

Commit

Permalink
Support RBS attribute definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
akouryy committed May 22, 2024
1 parent 8896eec commit 13ed851
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/typeprof/core/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ def self.create_rbs_member(raw_decl, lenv)
when RBS::AST::Members::Private
when RBS::AST::Members::Alias
SigAliasNode.new(raw_decl, lenv)
when RBS::AST::Members::AttrReader
SigAttrReaderNode.new(raw_decl, lenv)
when RBS::AST::Members::AttrWriter
SigAttrWriterNode.new(raw_decl, lenv)
when RBS::AST::Members::AttrAccessor
SigAttrAccessorNode.new(raw_decl, lenv)
when RBS::AST::Declarations::Base
self.create_rbs_decl(raw_decl, lenv)
else
Expand Down
77 changes: 77 additions & 0 deletions lib/typeprof/core/ast/sig_decl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,83 @@ def install0(genv)
end
end

class SigAttrReaderNode < Node
def initialize(raw_decl, lenv)
super(raw_decl, lenv)
@mid = raw_decl.name
rbs_method_type = RBS::MethodType.new(
type: RBS::Types::Function.empty(raw_decl.type),
type_params: [],
block: nil,
location: raw_decl.type.location,
)
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
end

attr_reader :mid, :method_type

def subnodes = { method_type: }
def attrs = { mid: }

def install0(genv)
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, [@method_type], false)
Source.new
end
end

class SigAttrWriterNode < Node
def initialize(raw_decl, lenv)
super(raw_decl, lenv)
@mid = :"#{raw_decl.name}="

# (raw_decl.type) -> raw_decl.type
rbs_method_type = RBS::MethodType.new(
type: RBS::Types::Function.new(
required_positionals: [RBS::Types::Function::Param.new(name: nil, type: raw_decl.type, location: raw_decl.type.location)],
optional_positionals: [],
rest_positionals: nil,
trailing_positionals: [],
required_keywords: {},
optional_keywords: {},
rest_keywords: nil,
return_type: raw_decl.type,
),
type_params: [],
block: nil,
location: raw_decl.type.location,
)
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
end

attr_reader :mid, :method_type

def subnodes = { method_type: }
def attrs = { mid: }

def install0(genv)
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, [@method_type], false)
Source.new
end
end

class SigAttrAccessorNode < Node
def initialize(raw_decl, lenv)
super(raw_decl, lenv)
@reader = SigAttrReaderNode.new(raw_decl, lenv)
@writer = SigAttrWriterNode.new(raw_decl, lenv)
end

attr_reader :reader, :writer

def subnodes = { reader:, writer: }

def install0(genv)
@reader.install0(genv)
@writer.install0(genv)
Source.new
end
end

class SigConstNode < Node
def initialize(raw_decl, lenv)
super(raw_decl, lenv)
Expand Down
38 changes: 38 additions & 0 deletions scenario/rbs/attr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## update: test.rbs
class A
attr_reader foo: Integer
attr_writer foo: Integer | Float

attr_accessor bar: String
end

## update: test.rb
def test1
a = A.new
a.foo = 42.0
a.foo
end

def test2
a = A.new
a.bar = "foo"
a.bar
end

## assert: test.rb
class Object
def test1: -> Integer
def test2: -> String
end

## hover: test.rb:3:4
A#foo= : (::Integer | ::Float) -> ::Integer | ::Float

## hover: test.rb:4:4
A#foo : -> ::Integer

## hover: test.rb:9:4
A#bar= : (::String) -> ::String

## hover: test.rb:10:4
A#bar : -> ::String

0 comments on commit 13ed851

Please sign in to comment.