Skip to content

Commit 4e159be

Browse files
committed
Implement DefinitionBuilder
1 parent 7518a3b commit 4e159be

File tree

10 files changed

+129
-8
lines changed

10 files changed

+129
-8
lines changed

lib/rbs/ast/ruby/members.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,19 @@ def overloads
3737
block: nil,
3838
location: nil
3939
)
40-
40+
4141
[
4242
Overload.new(method_type: method_type, annotations: [])
4343
]
4444
end
45+
46+
def overloading?
47+
false
48+
end
49+
50+
def annotations
51+
[]
52+
end
4553
end
4654
end
4755
end

lib/rbs/definition.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ def hash
6262
end
6363

6464
def comment
65-
member.comment
65+
case member
66+
when AST::Members::Base
67+
member.comment
68+
when AST::Ruby::Members::Base
69+
nil
70+
end
6671
end
6772

6873
def update(type: self.type, member: self.member, defined_in: self.defined_in, implemented_in: self.implemented_in)

lib/rbs/definition_builder.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,37 @@ def define_method(methods, definition, method, subst, self_type_methods, defined
766766
)
767767

768768
method_definition.annotations.replace(original.annotations)
769+
when AST::Ruby::Members::DefMember
770+
if duplicated_method = methods[method.name]
771+
raise DuplicatedMethodDefinitionError.new(
772+
type: definition.self_type,
773+
method_name: method.name,
774+
members: [original, *duplicated_method.members]
775+
)
776+
end
777+
778+
defs = original.overloads.map do |overload|
779+
Definition::Method::TypeDef.new(
780+
type: subst.empty? ? overload.method_type : overload.method_type.sub(subst),
781+
member: original,
782+
defined_in: defined_in,
783+
implemented_in: implemented_in
784+
).tap do |type_def|
785+
# Keep the original annotations given to overloads.
786+
type_def.overload_annotations.replace(overload.annotations)
787+
end
788+
end
789+
790+
method_definition = Definition::Method.new(
791+
super_method: existing_method,
792+
defs: defs,
793+
accessibility: :public,
794+
alias_of: nil,
795+
alias_member: nil
796+
)
797+
798+
method_definition.annotations.replace([])
799+
769800
when nil
770801
# Overloading method definition only
771802

lib/rbs/definition_builder/method_builder.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def build_instance(type_name)
105105
Methods.new(type: type).tap do |methods|
106106
entry.each_decl do |decl|
107107
subst = Substitution.build(decl.type_params.each.map(&:name), args)
108-
if decl.is_a?(AST::Declarations::Base)
108+
case decl
109+
when AST::Declarations::Base
109110
each_rbs_member_with_accessibility(decl.members) do |member, accessibility|
110111
case member
111112
when AST::Members::MethodDefinition
@@ -138,6 +139,18 @@ def build_instance(type_name)
138139
end
139140
end
140141
end
142+
when AST::Ruby::Declarations::Base
143+
decl.members.each do |member|
144+
case member
145+
when AST::Ruby::Members::DefMember
146+
build_method(
147+
methods,
148+
type,
149+
member: member,
150+
accessibility: :public
151+
)
152+
end
153+
end
141154
end
142155
end
143156
end.validate!

sig/ast/ruby/members.rbs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ module RBS
2323
def location: () -> Location
2424

2525
def overloads: () -> Array[Overload]
26+
27+
def overloading?: () -> bool
28+
29+
def annotations: () -> Array[AST::Annotation]
2630
end
2731
end
2832
end

sig/definition.rbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module RBS
2121

2222
class Method
2323
type method_member = AST::Members::MethodDefinition | AST::Members::AttrReader | AST::Members::AttrAccessor | AST::Members::AttrWriter
24+
| AST::Ruby::Members::DefMember
2425

2526
class TypeDef
2627
attr_reader type: MethodType

sig/errors.rbs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,14 @@ module RBS
226226
class InvalidOverloadMethodError < DefinitionError
227227
include DetailedMessageable
228228

229+
type member = AST::Members::MethodDefinition | AST::Ruby::Members::DefMember
230+
229231
attr_reader type_name: TypeName
230232
attr_reader method_name: Symbol
231233
attr_reader kind: :instance | :singleton
232-
attr_reader members: Array[AST::Members::MethodDefinition]
234+
attr_reader members: Array[member]
233235

234-
def initialize: (type_name: TypeName, method_name: Symbol, kind: :instance | :singleton, members: Array[AST::Members::MethodDefinition]) -> void
236+
def initialize: (type_name: TypeName, method_name: Symbol, kind: :instance | :singleton, members: Array[member]) -> void
235237

236238
def location: () -> AST::Members::MethodDefinition::loc?
237239
end

sig/method_builder.rbs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,19 @@ module RBS
1616
#
1717
class Definition
1818
type original = AST::Members::MethodDefinition | AST::Members::Alias | AST::Members::AttrAccessor | AST::Members::AttrWriter | AST::Members::AttrReader
19+
| AST::Ruby::Members::DefMember
20+
21+
type overloading_definition = AST::Members::MethodDefinition | AST::Ruby::Members::DefMember
1922

2023
type accessibility = RBS::Definition::accessibility
2124

2225
attr_reader name: Symbol
2326
attr_reader type: instance_type
2427
attr_reader originals: Array[original]
25-
attr_reader overloads: Array[AST::Members::MethodDefinition]
28+
attr_reader overloads: Array[overloading_definition]
2629
attr_reader accessibilities: Array[accessibility]
2730

28-
def initialize: (name: Symbol, type: instance_type, originals: Array[original], overloads: Array[AST::Members::MethodDefinition], accessibilities: Array[accessibility]) -> void
31+
def initialize: (name: Symbol, type: instance_type, originals: Array[original], overloads: Array[overloading_definition], accessibilities: Array[accessibility]) -> void
2932

3033
def original: () -> original?
3134

@@ -74,7 +77,7 @@ module RBS
7477

7578
def build_attribute: (Methods, Methods::instance_type, member: AST::Members::AttrAccessor | AST::Members::AttrReader | AST::Members::AttrWriter, accessibility: Definition::accessibility) -> void
7679

77-
def build_method: (Methods, Methods::instance_type, member: AST::Members::MethodDefinition, accessibility: Definition::accessibility) -> void
80+
def build_method: (Methods, Methods::instance_type, member: AST::Members::MethodDefinition | AST::Ruby::Members::DefMember, accessibility: Definition::accessibility) -> void
7881

7982
def each_rbs_member_with_accessibility: (Array[AST::Members::t | AST::Declarations::t], ?accessibility: Definition::accessibility) { (AST::Members::t | AST::Declarations::t, Definition::accessibility) -> void } -> void
8083

test/rbs/definition_builder_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,4 +3200,30 @@ module A
32003200
end
32013201
end
32023202
end
3203+
3204+
def test_inline_decl__class_def
3205+
SignatureManager.new do |manager|
3206+
manager.add_ruby_file("inherited.rbs", <<~RUBY)
3207+
class A
3208+
def hello(x) = 123
3209+
end
3210+
RUBY
3211+
3212+
manager.build do |env|
3213+
builder = DefinitionBuilder.new(env: env)
3214+
3215+
builder.build_instance(type_name("::A")).tap do |definition|
3216+
definition.methods[:hello].tap do |method|
3217+
assert_equal type_name("::A"), method.defined_in
3218+
assert_equal type_name("::A"), method.implemented_in
3219+
3220+
assert_equal [parse_method_type("(?) -> untyped")], method.method_types
3221+
assert_equal [parse_method_type("(?) -> untyped")], method.defs.map(&:type)
3222+
3223+
assert_equal [], method.annotations
3224+
end
3225+
end
3226+
end
3227+
end
3228+
end
32033229
end

test/rbs/method_builder_test.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,32 @@ class Foo[A, B]
380380
end
381381
end
382382
end
383+
384+
def test_methods__inline
385+
SignatureManager.new(system_builtin: true) do |manager|
386+
manager.ruby_files[Pathname("foo.rb")] = <<EOF
387+
class Foo
388+
def foo(x, y)
389+
return x + y
390+
end
391+
end
392+
EOF
393+
manager.build do |env|
394+
builder = MethodBuilder.new(env: env)
395+
396+
builder.build_instance(type_name("::Foo")).tap do |methods|
397+
assert_equal parse_type("::Foo"), methods.type
398+
399+
methods.methods[:foo].tap do |foo|
400+
assert_instance_of MethodBuilder::Methods::Definition, foo
401+
402+
assert_instance_of AST::Ruby::Members::DefMember, foo.original
403+
assert_equal [parse_method_type("(?) -> untyped")], foo.original.overloads.map(&:method_type)
404+
405+
assert_equal :public, foo.accessibility
406+
end
407+
end
408+
end
409+
end
410+
end
383411
end

0 commit comments

Comments
 (0)