rbi 0.1.13 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/lib/rbi/formatter.rb +4 -16
- data/lib/rbi/index.rb +1 -1
- data/lib/rbi/model.rb +38 -36
- data/lib/rbi/parser.rb +90 -53
- data/lib/rbi/printer.rb +512 -611
- data/lib/rbi/rewriters/attr_to_methods.rb +169 -0
- data/lib/rbi/rewriters/flatten_singleton_methods.rb +65 -0
- data/lib/rbi/rewriters/flatten_visibilities.rb +65 -0
- data/lib/rbi/rewriters/group_nodes.rb +46 -47
- data/lib/rbi/rewriters/merge_trees.rb +15 -45
- data/lib/rbi/rewriters/{nest_non_public_methods.rb → nest_non_public_members.rb} +4 -4
- data/lib/rbi/rewriters/nest_top_level_members.rb +68 -0
- data/lib/rbi/type.rb +765 -0
- data/lib/rbi/type_parser.rb +320 -0
- data/lib/rbi/type_visitor.rb +112 -0
- data/lib/rbi/version.rb +1 -1
- data/lib/rbi/visitor.rb +228 -2
- data/lib/rbi.rb +15 -1
- metadata +19 -18
@@ -0,0 +1,169 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RBI
|
5
|
+
class UnexpectedMultipleSigsError < Error
|
6
|
+
sig { returns(Node) }
|
7
|
+
attr_reader :node
|
8
|
+
|
9
|
+
sig { params(node: Node).void }
|
10
|
+
def initialize(node)
|
11
|
+
super(<<~MSG)
|
12
|
+
This declaration cannot have more than one sig.
|
13
|
+
|
14
|
+
#{node.string.chomp}
|
15
|
+
MSG
|
16
|
+
|
17
|
+
@node = node
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Rewriters
|
22
|
+
class AttrToMethods < Visitor
|
23
|
+
extend T::Sig
|
24
|
+
|
25
|
+
sig { override.params(node: T.nilable(Node)).void }
|
26
|
+
def visit(node)
|
27
|
+
case node
|
28
|
+
when Tree
|
29
|
+
visit_all(node.nodes.dup)
|
30
|
+
|
31
|
+
when Attr
|
32
|
+
replace(node, with: node.convert_to_methods)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
sig { params(node: Node, with: T::Array[Node]).void }
|
39
|
+
def replace(node, with:)
|
40
|
+
tree = node.parent_tree
|
41
|
+
raise ReplaceNodeError, "Can't replace #{self} without a parent tree" unless tree
|
42
|
+
|
43
|
+
node.detach
|
44
|
+
with.each { |node| tree << node }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Tree
|
50
|
+
extend T::Sig
|
51
|
+
|
52
|
+
sig { void }
|
53
|
+
def replace_attributes_with_methods!
|
54
|
+
visitor = Rewriters::AttrToMethods.new
|
55
|
+
visitor.visit(self)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Attr
|
60
|
+
sig { abstract.returns(T::Array[Method]) }
|
61
|
+
def convert_to_methods; end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
sig(:final) { returns([T.nilable(Sig), T.nilable(T.any(Type, String))]) }
|
66
|
+
def parse_sig
|
67
|
+
raise UnexpectedMultipleSigsError, self if 1 < sigs.count
|
68
|
+
|
69
|
+
sig = sigs.first
|
70
|
+
return [nil, nil] unless sig
|
71
|
+
|
72
|
+
attribute_type = case self
|
73
|
+
when AttrReader, AttrAccessor then sig.return_type
|
74
|
+
when AttrWriter then sig.params.first&.type
|
75
|
+
end
|
76
|
+
|
77
|
+
[sig, attribute_type]
|
78
|
+
end
|
79
|
+
|
80
|
+
sig do
|
81
|
+
params(
|
82
|
+
name: String,
|
83
|
+
sig: T.nilable(Sig),
|
84
|
+
visibility: Visibility,
|
85
|
+
loc: T.nilable(Loc),
|
86
|
+
comments: T::Array[Comment],
|
87
|
+
).returns(Method)
|
88
|
+
end
|
89
|
+
def create_getter_method(name, sig, visibility, loc, comments)
|
90
|
+
Method.new(
|
91
|
+
name,
|
92
|
+
params: [],
|
93
|
+
visibility: visibility,
|
94
|
+
sigs: sig ? [sig] : [],
|
95
|
+
loc: loc,
|
96
|
+
comments: comments,
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
sig do
|
101
|
+
params(
|
102
|
+
name: String,
|
103
|
+
sig: T.nilable(Sig),
|
104
|
+
attribute_type: T.nilable(T.any(Type, String)),
|
105
|
+
visibility: Visibility,
|
106
|
+
loc: T.nilable(Loc),
|
107
|
+
comments: T::Array[Comment],
|
108
|
+
).returns(Method)
|
109
|
+
end
|
110
|
+
def create_setter_method(name, sig, attribute_type, visibility, loc, comments) # rubocop:disable Metrics/ParameterLists
|
111
|
+
sig = if sig # Modify the original sig to correct the name, and remove the return type
|
112
|
+
params = attribute_type ? [SigParam.new(name, attribute_type)] : []
|
113
|
+
|
114
|
+
Sig.new(
|
115
|
+
params: params,
|
116
|
+
return_type: "void",
|
117
|
+
is_abstract: sig.is_abstract,
|
118
|
+
is_override: sig.is_override,
|
119
|
+
is_overridable: sig.is_overridable,
|
120
|
+
is_final: sig.is_final,
|
121
|
+
type_params: sig.type_params,
|
122
|
+
checked: sig.checked,
|
123
|
+
loc: sig.loc,
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
Method.new(
|
128
|
+
"#{name}=",
|
129
|
+
params: [ReqParam.new(name)],
|
130
|
+
visibility: visibility,
|
131
|
+
sigs: sig ? [sig] : [],
|
132
|
+
loc: loc,
|
133
|
+
comments: comments,
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class AttrAccessor
|
139
|
+
sig { override.returns(T::Array[Method]) }
|
140
|
+
def convert_to_methods
|
141
|
+
sig, attribute_type = parse_sig
|
142
|
+
|
143
|
+
names.flat_map do |name|
|
144
|
+
[
|
145
|
+
create_getter_method(name.to_s, sig, visibility, loc, comments),
|
146
|
+
create_setter_method(name.to_s, sig, attribute_type, visibility, loc, comments),
|
147
|
+
]
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class AttrReader
|
153
|
+
sig { override.returns(T::Array[Method]) }
|
154
|
+
def convert_to_methods
|
155
|
+
sig, _ = parse_sig
|
156
|
+
|
157
|
+
names.map { |name| create_getter_method(name.to_s, sig, visibility, loc, comments) }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class AttrWriter
|
162
|
+
sig { override.returns(T::Array[Method]) }
|
163
|
+
def convert_to_methods
|
164
|
+
sig, attribute_type = parse_sig
|
165
|
+
|
166
|
+
names.map { |name| create_setter_method(name.to_s, sig, attribute_type, visibility, loc, comments) }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RBI
|
5
|
+
module Rewriters
|
6
|
+
# Rewrite non-singleton methods inside singleton classes to singleton methods
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# ~~~rb
|
10
|
+
# class << self
|
11
|
+
# def m1; end
|
12
|
+
# def self.m2; end
|
13
|
+
#
|
14
|
+
# class << self
|
15
|
+
# def m3; end
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
# ~~~
|
19
|
+
#
|
20
|
+
# will be rewritten to:
|
21
|
+
#
|
22
|
+
# ~~~rb
|
23
|
+
# def self.m1; end
|
24
|
+
#
|
25
|
+
# class << self
|
26
|
+
# def self.m2; end
|
27
|
+
# def self.m3; end
|
28
|
+
# end
|
29
|
+
# ~~~
|
30
|
+
class FlattenSingletonMethods < Visitor
|
31
|
+
extend T::Sig
|
32
|
+
|
33
|
+
sig { override.params(node: T.nilable(Node)).void }
|
34
|
+
def visit(node)
|
35
|
+
return unless node
|
36
|
+
|
37
|
+
case node
|
38
|
+
when SingletonClass
|
39
|
+
node.nodes.dup.each do |child|
|
40
|
+
visit(child)
|
41
|
+
next unless child.is_a?(Method) && !child.is_singleton
|
42
|
+
|
43
|
+
child.detach
|
44
|
+
child.is_singleton = true
|
45
|
+
T.must(node.parent_tree) << child
|
46
|
+
end
|
47
|
+
|
48
|
+
node.detach if node.nodes.empty?
|
49
|
+
when Tree
|
50
|
+
visit_all(node.nodes)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Tree
|
57
|
+
extend T::Sig
|
58
|
+
|
59
|
+
sig { void }
|
60
|
+
def flatten_singleton_methods!
|
61
|
+
visitor = Rewriters::FlattenSingletonMethods.new
|
62
|
+
visitor.visit(self)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RBI
|
5
|
+
module Rewriters
|
6
|
+
# Flattens visibility nodes into method nodes
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# ~~~rb
|
10
|
+
# class A
|
11
|
+
# def m1; end
|
12
|
+
# private
|
13
|
+
# def m2; end
|
14
|
+
# def m3; end
|
15
|
+
# end
|
16
|
+
# ~~~
|
17
|
+
#
|
18
|
+
# will be transformed into:
|
19
|
+
#
|
20
|
+
# ~~~rb
|
21
|
+
# class A
|
22
|
+
# def m1; end
|
23
|
+
# private def m2; end
|
24
|
+
# private def m3; end
|
25
|
+
# end
|
26
|
+
# ~~~
|
27
|
+
class FlattenVisibilities < Visitor
|
28
|
+
extend T::Sig
|
29
|
+
|
30
|
+
sig { void }
|
31
|
+
def initialize
|
32
|
+
super
|
33
|
+
|
34
|
+
@current_visibility = T.let([Public.new], T::Array[Visibility])
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { override.params(node: T.nilable(Node)).void }
|
38
|
+
def visit(node)
|
39
|
+
return unless node
|
40
|
+
|
41
|
+
case node
|
42
|
+
when Public, Protected, Private
|
43
|
+
@current_visibility[-1] = node
|
44
|
+
node.detach
|
45
|
+
when Tree
|
46
|
+
@current_visibility << Public.new
|
47
|
+
visit_all(node.nodes.dup)
|
48
|
+
@current_visibility.pop
|
49
|
+
when Attr, Method
|
50
|
+
node.visibility = T.must(@current_visibility.last)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Tree
|
57
|
+
extend T::Sig
|
58
|
+
|
59
|
+
sig { void }
|
60
|
+
def flatten_visibilities!
|
61
|
+
visitor = Rewriters::FlattenVisibilities.new
|
62
|
+
visitor.visit(self)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RBI
|
5
|
+
class GroupNodesError < Error; end
|
6
|
+
|
5
7
|
module Rewriters
|
6
8
|
class GroupNodes < Visitor
|
7
9
|
extend T::Sig
|
@@ -12,8 +14,7 @@ module RBI
|
|
12
14
|
|
13
15
|
case node
|
14
16
|
when Tree
|
15
|
-
kinds = node.nodes.map(
|
16
|
-
kinds.compact!
|
17
|
+
kinds = node.nodes.map { |child| group_kind(child) }
|
17
18
|
kinds.uniq!
|
18
19
|
|
19
20
|
groups = {}
|
@@ -22,12 +23,54 @@ module RBI
|
|
22
23
|
node.nodes.dup.each do |child|
|
23
24
|
visit(child)
|
24
25
|
child.detach
|
25
|
-
groups[child
|
26
|
+
groups[group_kind(child)] << child
|
26
27
|
end
|
27
28
|
|
28
29
|
groups.each { |_, group| node << group }
|
29
30
|
end
|
30
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
sig { params(node: Node).returns(Group::Kind) }
|
36
|
+
def group_kind(node)
|
37
|
+
case node
|
38
|
+
when Group
|
39
|
+
node.kind
|
40
|
+
when Include, Extend
|
41
|
+
Group::Kind::Mixins
|
42
|
+
when RequiresAncestor
|
43
|
+
Group::Kind::RequiredAncestors
|
44
|
+
when Helper
|
45
|
+
Group::Kind::Helpers
|
46
|
+
when TypeMember
|
47
|
+
Group::Kind::TypeMembers
|
48
|
+
when MixesInClassMethods
|
49
|
+
Group::Kind::MixesInClassMethods
|
50
|
+
when Send
|
51
|
+
Group::Kind::Sends
|
52
|
+
when Attr
|
53
|
+
Group::Kind::Attrs
|
54
|
+
when TStructField
|
55
|
+
Group::Kind::TStructFields
|
56
|
+
when TEnumBlock
|
57
|
+
Group::Kind::TEnums
|
58
|
+
when VisibilityGroup
|
59
|
+
Group::Kind::Methods
|
60
|
+
when Method
|
61
|
+
if node.name == "initialize"
|
62
|
+
Group::Kind::Inits
|
63
|
+
else
|
64
|
+
Group::Kind::Methods
|
65
|
+
end
|
66
|
+
when SingletonClass
|
67
|
+
Group::Kind::SingletonClasses
|
68
|
+
when Scope, Const
|
69
|
+
Group::Kind::Consts
|
70
|
+
else
|
71
|
+
raise GroupNodesError, "Unknown group for #{self}"
|
72
|
+
end
|
73
|
+
end
|
31
74
|
end
|
32
75
|
end
|
33
76
|
|
@@ -41,50 +84,6 @@ module RBI
|
|
41
84
|
end
|
42
85
|
end
|
43
86
|
|
44
|
-
class Node
|
45
|
-
extend T::Sig
|
46
|
-
|
47
|
-
sig { returns(Group::Kind) }
|
48
|
-
def group_kind
|
49
|
-
case self
|
50
|
-
when Group
|
51
|
-
kind
|
52
|
-
when Include, Extend
|
53
|
-
Group::Kind::Mixins
|
54
|
-
when RequiresAncestor
|
55
|
-
Group::Kind::RequiredAncestors
|
56
|
-
when Helper
|
57
|
-
Group::Kind::Helpers
|
58
|
-
when TypeMember
|
59
|
-
Group::Kind::TypeMembers
|
60
|
-
when MixesInClassMethods
|
61
|
-
Group::Kind::MixesInClassMethods
|
62
|
-
when Send
|
63
|
-
Group::Kind::Sends
|
64
|
-
when Attr
|
65
|
-
Group::Kind::Attrs
|
66
|
-
when TStructField
|
67
|
-
Group::Kind::TStructFields
|
68
|
-
when TEnumBlock
|
69
|
-
Group::Kind::TEnums
|
70
|
-
when VisibilityGroup
|
71
|
-
Group::Kind::Methods
|
72
|
-
when Method
|
73
|
-
if name == "initialize"
|
74
|
-
Group::Kind::Inits
|
75
|
-
else
|
76
|
-
Group::Kind::Methods
|
77
|
-
end
|
78
|
-
when SingletonClass
|
79
|
-
Group::Kind::SingletonClasses
|
80
|
-
when Scope, Const
|
81
|
-
Group::Kind::Consts
|
82
|
-
else
|
83
|
-
raise "Unknown group for #{self}"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
87
|
class Group < Tree
|
89
88
|
extend T::Sig
|
90
89
|
|
@@ -348,6 +348,8 @@ module RBI
|
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
351
|
+
class DuplicateNodeError < Error; end
|
352
|
+
|
351
353
|
class Scope
|
352
354
|
extend T::Sig
|
353
355
|
|
@@ -357,6 +359,12 @@ module RBI
|
|
357
359
|
case self
|
358
360
|
when Module
|
359
361
|
Module.new(name, loc: loc, comments: comments)
|
362
|
+
when TEnum
|
363
|
+
TEnum.new(name, loc: loc, comments: comments)
|
364
|
+
when TEnumBlock
|
365
|
+
TEnumBlock.new(loc: loc, comments: comments)
|
366
|
+
when TStruct
|
367
|
+
TStruct.new(name, loc: loc, comments: comments)
|
360
368
|
when Class
|
361
369
|
Class.new(name, superclass_name: superclass_name, loc: loc, comments: comments)
|
362
370
|
when Struct
|
@@ -364,7 +372,7 @@ module RBI
|
|
364
372
|
when SingletonClass
|
365
373
|
SingletonClass.new(loc: loc, comments: comments)
|
366
374
|
else
|
367
|
-
raise "Can't duplicate node #{self}"
|
375
|
+
raise DuplicateNodeError, "Can't duplicate node #{self}"
|
368
376
|
end
|
369
377
|
end
|
370
378
|
end
|
@@ -549,20 +557,6 @@ module RBI
|
|
549
557
|
end
|
550
558
|
end
|
551
559
|
|
552
|
-
class TEnumBlock
|
553
|
-
extend T::Sig
|
554
|
-
|
555
|
-
sig { override.params(other: Node).void }
|
556
|
-
def merge_with(other)
|
557
|
-
return unless other.is_a?(TEnumBlock)
|
558
|
-
|
559
|
-
super
|
560
|
-
other.names.each do |name|
|
561
|
-
names << name unless names.include?(name)
|
562
|
-
end
|
563
|
-
end
|
564
|
-
end
|
565
|
-
|
566
560
|
class TStructProp
|
567
561
|
extend T::Sig
|
568
562
|
|
@@ -592,6 +586,9 @@ module RBI
|
|
592
586
|
sig { returns(Tree) }
|
593
587
|
attr_reader :left, :right
|
594
588
|
|
589
|
+
sig { returns(String) }
|
590
|
+
attr_reader :left_name, :right_name
|
591
|
+
|
595
592
|
sig { params(left_name: String, right_name: String).void }
|
596
593
|
def initialize(left_name: "left", right_name: "right")
|
597
594
|
super()
|
@@ -602,15 +599,6 @@ module RBI
|
|
602
599
|
@right = T.let(Tree.new, Tree)
|
603
600
|
@right.parent_tree = self
|
604
601
|
end
|
605
|
-
|
606
|
-
sig { override.params(v: Printer).void }
|
607
|
-
def accept_printer(v)
|
608
|
-
v.printl("<<<<<<< #{@left_name}")
|
609
|
-
v.visit(left)
|
610
|
-
v.printl("=======")
|
611
|
-
v.visit(right)
|
612
|
-
v.printl(">>>>>>> #{@right_name}")
|
613
|
-
end
|
614
602
|
end
|
615
603
|
|
616
604
|
# A conflict between two scope headers
|
@@ -631,6 +619,9 @@ module RBI
|
|
631
619
|
sig { returns(Scope) }
|
632
620
|
attr_reader :left, :right
|
633
621
|
|
622
|
+
sig { returns(String) }
|
623
|
+
attr_reader :left_name, :right_name
|
624
|
+
|
634
625
|
sig do
|
635
626
|
params(
|
636
627
|
left: Scope,
|
@@ -646,26 +637,5 @@ module RBI
|
|
646
637
|
@left_name = left_name
|
647
638
|
@right_name = right_name
|
648
639
|
end
|
649
|
-
|
650
|
-
sig { override.params(v: Printer).void }
|
651
|
-
def accept_printer(v)
|
652
|
-
previous_node = v.previous_node
|
653
|
-
v.printn if previous_node && (!previous_node.oneline? || !oneline?)
|
654
|
-
|
655
|
-
v.printl("# #{loc}") if loc && v.print_locs
|
656
|
-
v.visit_all(comments)
|
657
|
-
|
658
|
-
v.printl("<<<<<<< #{@left_name}")
|
659
|
-
left.print_header(v)
|
660
|
-
v.printl("=======")
|
661
|
-
right.print_header(v)
|
662
|
-
v.printl(">>>>>>> #{@right_name}")
|
663
|
-
left.print_body(v)
|
664
|
-
end
|
665
|
-
|
666
|
-
sig { override.returns(T::Boolean) }
|
667
|
-
def oneline?
|
668
|
-
left.oneline?
|
669
|
-
end
|
670
640
|
end
|
671
641
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
module RBI
|
5
5
|
module Rewriters
|
6
|
-
class
|
6
|
+
class NestNonPublicMembers < Visitor
|
7
7
|
extend T::Sig
|
8
8
|
|
9
9
|
sig { override.params(node: T.nilable(Node)).void }
|
@@ -18,7 +18,7 @@ module RBI
|
|
18
18
|
|
19
19
|
node.nodes.dup.each do |child|
|
20
20
|
visit(child)
|
21
|
-
next unless child.is_a?(Method)
|
21
|
+
next unless child.is_a?(Attr) || child.is_a?(Method)
|
22
22
|
|
23
23
|
child.detach
|
24
24
|
case child.visibility
|
@@ -43,8 +43,8 @@ module RBI
|
|
43
43
|
extend T::Sig
|
44
44
|
|
45
45
|
sig { void }
|
46
|
-
def
|
47
|
-
visitor = Rewriters::
|
46
|
+
def nest_non_public_members!
|
47
|
+
visitor = Rewriters::NestNonPublicMembers.new
|
48
48
|
visitor.visit(self)
|
49
49
|
end
|
50
50
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RBI
|
5
|
+
module Rewriters
|
6
|
+
# This rewriter moves top-level members into a top-level Object class
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# ~~~rb
|
10
|
+
# def foo; end
|
11
|
+
# attr_reader :bar
|
12
|
+
# ~~~
|
13
|
+
#
|
14
|
+
# will be rewritten to:
|
15
|
+
#
|
16
|
+
# ~~~rb
|
17
|
+
# class Object
|
18
|
+
# def foo; end
|
19
|
+
# attr_reader :bar
|
20
|
+
# end
|
21
|
+
# ~~~
|
22
|
+
class NestTopLevelMembers < Visitor
|
23
|
+
extend T::Sig
|
24
|
+
|
25
|
+
sig { void }
|
26
|
+
def initialize
|
27
|
+
super
|
28
|
+
|
29
|
+
@top_level_object_class = T.let(nil, T.nilable(Class))
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { override.params(node: T.nilable(Node)).void }
|
33
|
+
def visit(node)
|
34
|
+
return unless node
|
35
|
+
|
36
|
+
case node
|
37
|
+
when Tree
|
38
|
+
visit_all(node.nodes.dup)
|
39
|
+
else
|
40
|
+
scope = node.parent_scope
|
41
|
+
unless scope
|
42
|
+
parent = node.parent_tree
|
43
|
+
raise unless parent
|
44
|
+
|
45
|
+
node.detach
|
46
|
+
|
47
|
+
unless @top_level_object_class
|
48
|
+
@top_level_object_class = Class.new("Object")
|
49
|
+
parent.nodes << @top_level_object_class
|
50
|
+
end
|
51
|
+
|
52
|
+
@top_level_object_class << node
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Tree
|
60
|
+
extend T::Sig
|
61
|
+
|
62
|
+
sig { void }
|
63
|
+
def nest_top_level_members!
|
64
|
+
visitor = Rewriters::NestTopLevelMembers.new
|
65
|
+
visitor.visit(self)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|