rbi 0.2.2 → 0.3.3
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 -1
- data/lib/rbi/formatter.rb +9 -20
- data/lib/rbi/index.rb +49 -43
- data/lib/rbi/loc.rb +7 -19
- data/lib/rbi/model.rb +246 -584
- data/lib/rbi/parser.rb +227 -98
- data/lib/rbi/printer.rb +173 -108
- data/lib/rbi/rbs/method_type_translator.rb +120 -0
- data/lib/rbi/rbs/type_translator.rb +181 -0
- data/lib/rbi/rbs_printer.rb +273 -150
- data/lib/rbi/rewriters/add_sig_templates.rb +7 -10
- data/lib/rbi/rewriters/annotate.rb +6 -9
- data/lib/rbi/rewriters/attr_to_methods.rb +16 -32
- data/lib/rbi/rewriters/deannotate.rb +5 -8
- data/lib/rbi/rewriters/filter_versions.rb +7 -12
- data/lib/rbi/rewriters/flatten_singleton_methods.rb +5 -7
- data/lib/rbi/rewriters/flatten_visibilities.rb +6 -9
- data/lib/rbi/rewriters/group_nodes.rb +6 -11
- data/lib/rbi/rewriters/merge_trees.rb +84 -132
- data/lib/rbi/rewriters/nest_non_public_members.rb +5 -10
- data/lib/rbi/rewriters/nest_singleton_methods.rb +3 -6
- data/lib/rbi/rewriters/nest_top_level_members.rb +5 -8
- data/lib/rbi/rewriters/remove_known_definitions.rb +13 -23
- data/lib/rbi/rewriters/sort_nodes.rb +10 -11
- data/lib/rbi/rewriters/translate_rbs_sigs.rb +87 -0
- data/lib/rbi/type.rb +135 -137
- data/lib/rbi/type_parser.rb +51 -27
- data/lib/rbi/type_visitor.rb +19 -21
- data/lib/rbi/version.rb +1 -1
- data/lib/rbi/visitor.rb +55 -46
- data/lib/rbi.rb +7 -3
- data/rbi/rbi.rbi +3686 -0
- metadata +21 -7
data/lib/rbi/parser.rb
CHANGED
@@ -5,12 +5,10 @@ require "prism"
|
|
5
5
|
|
6
6
|
module RBI
|
7
7
|
class ParseError < Error
|
8
|
-
|
9
|
-
|
10
|
-
sig { returns(Loc) }
|
8
|
+
#: Loc
|
11
9
|
attr_reader :location
|
12
10
|
|
13
|
-
|
11
|
+
#: (String message, Loc location) -> void
|
14
12
|
def initialize(message, location)
|
15
13
|
super(message)
|
16
14
|
@location = location
|
@@ -18,19 +16,17 @@ module RBI
|
|
18
16
|
end
|
19
17
|
|
20
18
|
class UnexpectedParserError < Error
|
21
|
-
|
22
|
-
|
23
|
-
sig { returns(Loc) }
|
19
|
+
#: Loc
|
24
20
|
attr_reader :last_location
|
25
21
|
|
26
|
-
|
22
|
+
#: (Exception parent_exception, Loc last_location) -> void
|
27
23
|
def initialize(parent_exception, last_location)
|
28
24
|
super(parent_exception)
|
29
25
|
set_backtrace(parent_exception.backtrace)
|
30
26
|
@last_location = last_location
|
31
27
|
end
|
32
28
|
|
33
|
-
|
29
|
+
#: (?io: (IO | StringIO)) -> void
|
34
30
|
def print_debug(io: $stderr)
|
35
31
|
io.puts ""
|
36
32
|
io.puts "##################################"
|
@@ -51,47 +47,43 @@ module RBI
|
|
51
47
|
end
|
52
48
|
|
53
49
|
class Parser
|
54
|
-
extend T::Sig
|
55
|
-
|
56
50
|
class << self
|
57
|
-
|
58
|
-
|
59
|
-
sig { params(string: String).returns(Tree) }
|
51
|
+
#: (String string) -> Tree
|
60
52
|
def parse_string(string)
|
61
53
|
Parser.new.parse_string(string)
|
62
54
|
end
|
63
55
|
|
64
|
-
|
56
|
+
#: (String path) -> Tree
|
65
57
|
def parse_file(path)
|
66
58
|
Parser.new.parse_file(path)
|
67
59
|
end
|
68
60
|
|
69
|
-
|
61
|
+
#: (Array[String] paths) -> Array[Tree]
|
70
62
|
def parse_files(paths)
|
71
63
|
parser = Parser.new
|
72
64
|
paths.map { |path| parser.parse_file(path) }
|
73
65
|
end
|
74
66
|
|
75
|
-
|
67
|
+
#: (Array[String] strings) -> Array[Tree]
|
76
68
|
def parse_strings(strings)
|
77
69
|
parser = Parser.new
|
78
70
|
strings.map { |string| parser.parse_string(string) }
|
79
71
|
end
|
80
72
|
end
|
81
73
|
|
82
|
-
|
74
|
+
#: (String string) -> Tree
|
83
75
|
def parse_string(string)
|
84
76
|
parse(string, file: "-")
|
85
77
|
end
|
86
78
|
|
87
|
-
|
79
|
+
#: (String path) -> Tree
|
88
80
|
def parse_file(path)
|
89
81
|
parse(::File.read(path), file: path)
|
90
82
|
end
|
91
83
|
|
92
84
|
private
|
93
85
|
|
94
|
-
|
86
|
+
#: (String source, file: String) -> Tree
|
95
87
|
def parse(source, file:)
|
96
88
|
result = Prism.parse(source)
|
97
89
|
unless result.success?
|
@@ -120,9 +112,7 @@ module RBI
|
|
120
112
|
end
|
121
113
|
|
122
114
|
class Visitor < Prism::Visitor
|
123
|
-
|
124
|
-
|
125
|
-
sig { params(source: String, file: String).void }
|
115
|
+
#: (String source, file: String) -> void
|
126
116
|
def initialize(source, file:)
|
127
117
|
super()
|
128
118
|
|
@@ -132,46 +122,66 @@ module RBI
|
|
132
122
|
|
133
123
|
private
|
134
124
|
|
135
|
-
|
125
|
+
#: (Prism::Node node) -> Loc
|
136
126
|
def node_loc(node)
|
137
127
|
Loc.from_prism(@file, node.location)
|
138
128
|
end
|
139
129
|
|
140
|
-
|
130
|
+
#: (Prism::Node? node) -> String?
|
141
131
|
def node_string(node)
|
142
132
|
return unless node
|
143
133
|
|
144
134
|
node.slice
|
145
135
|
end
|
146
136
|
|
147
|
-
|
137
|
+
#: (Prism::Node node) -> String
|
148
138
|
def node_string!(node)
|
149
|
-
|
139
|
+
node_string(node) #: as !nil
|
140
|
+
end
|
141
|
+
|
142
|
+
#: (Prism::Node node) -> Prism::Location
|
143
|
+
def adjust_prism_location_for_heredoc(node)
|
144
|
+
visitor = HeredocLocationVisitor.new(
|
145
|
+
node.location.send(:source),
|
146
|
+
node.location.start_offset,
|
147
|
+
node.location.end_offset,
|
148
|
+
)
|
149
|
+
visitor.visit(node)
|
150
|
+
visitor.location
|
151
|
+
end
|
152
|
+
|
153
|
+
#: (Prism::Node? node) -> bool
|
154
|
+
def self?(node)
|
155
|
+
node.is_a?(Prism::SelfNode)
|
156
|
+
end
|
157
|
+
|
158
|
+
#: (Prism::Node? node) -> bool
|
159
|
+
def t_sig_without_runtime?(node)
|
160
|
+
!!(node.is_a?(Prism::ConstantPathNode) && node_string(node) =~ /(::)?T::Sig::WithoutRuntime/)
|
150
161
|
end
|
151
162
|
end
|
152
163
|
|
153
164
|
class TreeBuilder < Visitor
|
154
|
-
|
155
|
-
|
156
|
-
sig { returns(Tree) }
|
165
|
+
#: Tree
|
157
166
|
attr_reader :tree
|
158
167
|
|
159
|
-
|
168
|
+
#: Prism::Node?
|
160
169
|
attr_reader :last_node
|
161
170
|
|
162
|
-
|
171
|
+
#: (String source, comments: Array[Prism::Comment], file: String) -> void
|
163
172
|
def initialize(source, comments:, file:)
|
164
173
|
super(source, file: file)
|
165
174
|
|
166
|
-
@comments_by_line =
|
167
|
-
@tree =
|
175
|
+
@comments_by_line = comments.to_h { |c| [c.location.start_line, c] } #: Hash[Integer, Prism::Comment]
|
176
|
+
@tree = Tree.new #: Tree
|
168
177
|
|
169
|
-
@scopes_stack =
|
170
|
-
@last_node =
|
171
|
-
@last_sigs =
|
178
|
+
@scopes_stack = [@tree] #: Array[Tree]
|
179
|
+
@last_node = nil #: Prism::Node?
|
180
|
+
@last_sigs = [] #: Array[RBI::Sig]
|
172
181
|
end
|
173
182
|
|
174
|
-
|
183
|
+
# @override
|
184
|
+
#: (Prism::ClassNode node) -> void
|
175
185
|
def visit_class_node(node)
|
176
186
|
@last_node = node
|
177
187
|
superclass_name = node_string(node.superclass)
|
@@ -206,54 +216,78 @@ module RBI
|
|
206
216
|
@last_node = nil
|
207
217
|
end
|
208
218
|
|
209
|
-
|
219
|
+
# @override
|
220
|
+
#: (Prism::ConstantWriteNode node) -> void
|
210
221
|
def visit_constant_write_node(node)
|
211
222
|
@last_node = node
|
212
223
|
visit_constant_assign(node)
|
213
224
|
@last_node = nil
|
214
225
|
end
|
215
226
|
|
216
|
-
|
227
|
+
# @override
|
228
|
+
#: (Prism::ConstantPathWriteNode node) -> void
|
217
229
|
def visit_constant_path_write_node(node)
|
218
230
|
@last_node = node
|
219
231
|
visit_constant_assign(node)
|
220
232
|
@last_node = nil
|
221
233
|
end
|
222
234
|
|
223
|
-
|
235
|
+
#: ((Prism::ConstantWriteNode | Prism::ConstantPathWriteNode) node) -> void
|
224
236
|
def visit_constant_assign(node)
|
225
237
|
struct = parse_struct(node)
|
226
238
|
|
227
239
|
current_scope << if struct
|
228
240
|
struct
|
229
|
-
elsif
|
230
|
-
|
241
|
+
elsif t_enum_value?(node)
|
242
|
+
TEnumValue.new(
|
231
243
|
case node
|
232
244
|
when Prism::ConstantWriteNode
|
233
245
|
node.name.to_s
|
234
246
|
when Prism::ConstantPathWriteNode
|
235
247
|
node_string!(node.target)
|
236
248
|
end,
|
237
|
-
node_string!(node.value),
|
238
249
|
loc: node_loc(node),
|
239
250
|
comments: node_comments(node),
|
240
251
|
)
|
241
252
|
else
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
end,
|
249
|
-
node_string!(node.value),
|
250
|
-
loc: node_loc(node),
|
251
|
-
comments: node_comments(node),
|
253
|
+
adjusted_node_location = adjust_prism_location_for_heredoc(node)
|
254
|
+
|
255
|
+
adjusted_value_location = Prism::Location.new(
|
256
|
+
node.value.location.send(:source),
|
257
|
+
node.value.location.start_offset,
|
258
|
+
adjusted_node_location.end_offset - node.value.location.start_offset,
|
252
259
|
)
|
260
|
+
|
261
|
+
if type_variable_definition?(node.value)
|
262
|
+
TypeMember.new(
|
263
|
+
case node
|
264
|
+
when Prism::ConstantWriteNode
|
265
|
+
node.name.to_s
|
266
|
+
when Prism::ConstantPathWriteNode
|
267
|
+
node_string!(node.target)
|
268
|
+
end,
|
269
|
+
adjusted_value_location.slice,
|
270
|
+
loc: Loc.from_prism(@file, adjusted_node_location),
|
271
|
+
comments: node_comments(node),
|
272
|
+
)
|
273
|
+
else
|
274
|
+
Const.new(
|
275
|
+
case node
|
276
|
+
when Prism::ConstantWriteNode
|
277
|
+
node.name.to_s
|
278
|
+
when Prism::ConstantPathWriteNode
|
279
|
+
node_string!(node.target)
|
280
|
+
end,
|
281
|
+
adjusted_value_location.slice,
|
282
|
+
loc: Loc.from_prism(@file, adjusted_node_location),
|
283
|
+
comments: node_comments(node),
|
284
|
+
)
|
285
|
+
end
|
253
286
|
end
|
254
287
|
end
|
255
288
|
|
256
|
-
|
289
|
+
# @override
|
290
|
+
#: (Prism::DefNode node) -> void
|
257
291
|
def visit_def_node(node)
|
258
292
|
@last_node = node
|
259
293
|
|
@@ -274,7 +308,8 @@ module RBI
|
|
274
308
|
@last_node = nil
|
275
309
|
end
|
276
310
|
|
277
|
-
|
311
|
+
# @override
|
312
|
+
#: (Prism::ModuleNode node) -> void
|
278
313
|
def visit_module_node(node)
|
279
314
|
@last_node = node
|
280
315
|
scope = Module.new(
|
@@ -292,7 +327,8 @@ module RBI
|
|
292
327
|
@last_node = nil
|
293
328
|
end
|
294
329
|
|
295
|
-
|
330
|
+
# @override
|
331
|
+
#: (Prism::ProgramNode node) -> void
|
296
332
|
def visit_program_node(node)
|
297
333
|
@last_node = node
|
298
334
|
super
|
@@ -303,7 +339,8 @@ module RBI
|
|
303
339
|
@last_node = nil
|
304
340
|
end
|
305
341
|
|
306
|
-
|
342
|
+
# @override
|
343
|
+
#: (Prism::SingletonClassNode node) -> void
|
307
344
|
def visit_singleton_class_node(node)
|
308
345
|
@last_node = node
|
309
346
|
scope = SingletonClass.new(
|
@@ -320,7 +357,7 @@ module RBI
|
|
320
357
|
@last_node = nil
|
321
358
|
end
|
322
359
|
|
323
|
-
|
360
|
+
#: (Prism::CallNode node) -> void
|
324
361
|
def visit_call_node(node)
|
325
362
|
@last_node = node
|
326
363
|
message = node.name.to_s
|
@@ -451,11 +488,6 @@ module RBI
|
|
451
488
|
loc: node_loc(node),
|
452
489
|
comments: node_comments(node),
|
453
490
|
)
|
454
|
-
else
|
455
|
-
raise ParseError.new(
|
456
|
-
"Unexpected token `#{node.message}` before `#{last_node&.string&.strip}`",
|
457
|
-
node_loc(node),
|
458
|
-
)
|
459
491
|
end
|
460
492
|
else
|
461
493
|
current_scope << parse_visibility(node.name.to_s, node)
|
@@ -483,6 +515,10 @@ module RBI
|
|
483
515
|
comments: node_comments(node),
|
484
516
|
)
|
485
517
|
when "sig"
|
518
|
+
unless node.receiver.nil? || self?(node.receiver) || t_sig_without_runtime?(node.receiver)
|
519
|
+
@last_node = nil
|
520
|
+
return
|
521
|
+
end
|
486
522
|
@last_sigs << parse_sig(node)
|
487
523
|
else
|
488
524
|
current_scope << Send.new(
|
@@ -499,7 +535,7 @@ module RBI
|
|
499
535
|
private
|
500
536
|
|
501
537
|
# Collect all the remaining comments within a node
|
502
|
-
|
538
|
+
#: (Prism::Node node) -> void
|
503
539
|
def collect_dangling_comments(node)
|
504
540
|
first_line = node.location.start_line
|
505
541
|
last_line = node.location.end_line
|
@@ -517,9 +553,9 @@ module RBI
|
|
517
553
|
end
|
518
554
|
|
519
555
|
# Collect all the remaining comments after visiting the tree
|
520
|
-
|
556
|
+
#: -> void
|
521
557
|
def collect_orphan_comments
|
522
|
-
last_line =
|
558
|
+
last_line = nil #: Integer?
|
523
559
|
last_node_end = @tree.nodes.last&.loc&.end_line
|
524
560
|
|
525
561
|
@comments_by_line.each do |line, comment|
|
@@ -540,21 +576,21 @@ module RBI
|
|
540
576
|
end
|
541
577
|
end
|
542
578
|
|
543
|
-
|
579
|
+
#: -> Tree
|
544
580
|
def current_scope
|
545
|
-
|
581
|
+
@scopes_stack.last #: as !nil # Should never be nil since we create a Tree as the root
|
546
582
|
end
|
547
583
|
|
548
|
-
|
584
|
+
#: -> Array[Sig]
|
549
585
|
def current_sigs
|
550
586
|
sigs = @last_sigs.dup
|
551
587
|
@last_sigs.clear
|
552
588
|
sigs
|
553
589
|
end
|
554
590
|
|
555
|
-
|
591
|
+
#: (Array[Sig] sigs) -> Array[Comment]
|
556
592
|
def detach_comments_from_sigs(sigs)
|
557
|
-
comments =
|
593
|
+
comments = [] #: Array[Comment]
|
558
594
|
|
559
595
|
sigs.each do |sig|
|
560
596
|
comments += sig.comments.dup
|
@@ -564,7 +600,7 @@ module RBI
|
|
564
600
|
comments
|
565
601
|
end
|
566
602
|
|
567
|
-
|
603
|
+
#: (Prism::Node node) -> Array[Comment]
|
568
604
|
def node_comments(node)
|
569
605
|
comments = []
|
570
606
|
|
@@ -582,14 +618,22 @@ module RBI
|
|
582
618
|
comments
|
583
619
|
end
|
584
620
|
|
585
|
-
|
621
|
+
#: (Prism::Comment node) -> Comment
|
586
622
|
def parse_comment(node)
|
587
|
-
|
623
|
+
loc = Loc.from_prism(@file, node.location)
|
624
|
+
string = node.location.slice
|
625
|
+
# We also ignore RDoc directives such as `:nodoc:`
|
626
|
+
# See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives
|
627
|
+
if string.start_with?("#:") && !(string =~ /^#:[a-z_]+:/)
|
628
|
+
RBSComment.new(string.gsub(/^#: ?/, "").rstrip, loc: loc)
|
629
|
+
else
|
630
|
+
Comment.new(string.gsub(/^# ?/, "").rstrip, loc: loc)
|
631
|
+
end
|
588
632
|
end
|
589
633
|
|
590
|
-
|
634
|
+
#: (Prism::Node? node) -> Array[Arg]
|
591
635
|
def parse_send_args(node)
|
592
|
-
args =
|
636
|
+
args = [] #: Array[Arg]
|
593
637
|
return args unless node.is_a?(Prism::ArgumentsNode)
|
594
638
|
|
595
639
|
node.arguments.each do |arg|
|
@@ -600,18 +644,20 @@ module RBI
|
|
600
644
|
|
601
645
|
args << KwArg.new(
|
602
646
|
node_string!(assoc.key).delete_suffix(":"),
|
603
|
-
|
647
|
+
node_string(assoc.value), #: as !nil
|
604
648
|
)
|
605
649
|
end
|
606
650
|
else
|
607
|
-
args << Arg.new(
|
651
|
+
args << Arg.new(
|
652
|
+
node_string(arg), #: as !nil
|
653
|
+
)
|
608
654
|
end
|
609
655
|
end
|
610
656
|
|
611
657
|
args
|
612
658
|
end
|
613
659
|
|
614
|
-
|
660
|
+
#: (Prism::Node? node) -> Array[Param]
|
615
661
|
def parse_params(node)
|
616
662
|
params = []
|
617
663
|
return params unless node.is_a?(Prism::ParametersNode)
|
@@ -685,7 +731,7 @@ module RBI
|
|
685
731
|
params
|
686
732
|
end
|
687
733
|
|
688
|
-
|
734
|
+
#: (Prism::CallNode node) -> Sig
|
689
735
|
def parse_sig(node)
|
690
736
|
builder = SigBuilder.new(@source, file: @file)
|
691
737
|
builder.current.loc = node_loc(node)
|
@@ -694,7 +740,7 @@ module RBI
|
|
694
740
|
builder.current
|
695
741
|
end
|
696
742
|
|
697
|
-
|
743
|
+
#: ((Prism::ConstantWriteNode | Prism::ConstantPathWriteNode) node) -> Struct?
|
698
744
|
def parse_struct(node)
|
699
745
|
send = node.value
|
700
746
|
return unless send.is_a?(Prism::CallNode)
|
@@ -705,7 +751,7 @@ module RBI
|
|
705
751
|
return unless node_string(recv) =~ /(::)?Struct/
|
706
752
|
|
707
753
|
members = []
|
708
|
-
keyword_init =
|
754
|
+
keyword_init = false #: bool
|
709
755
|
|
710
756
|
args = send.arguments
|
711
757
|
if args.is_a?(Prism::ArgumentsNode)
|
@@ -722,8 +768,6 @@ module RBI
|
|
722
768
|
|
723
769
|
keyword_init = val == "true" if key == "keyword_init:"
|
724
770
|
end
|
725
|
-
else
|
726
|
-
raise ParseError.new("Unexpected node type `#{arg.class}`", node_loc(arg))
|
727
771
|
end
|
728
772
|
end
|
729
773
|
end
|
@@ -744,7 +788,7 @@ module RBI
|
|
744
788
|
struct
|
745
789
|
end
|
746
790
|
|
747
|
-
|
791
|
+
#: (Prism::CallNode send) -> void
|
748
792
|
def parse_tstruct_field(send)
|
749
793
|
args = send.arguments
|
750
794
|
return unless args.is_a?(Prism::ArgumentsNode)
|
@@ -757,7 +801,7 @@ module RBI
|
|
757
801
|
type = node_string!(type_arg)
|
758
802
|
loc = node_loc(send)
|
759
803
|
comments = node_comments(send)
|
760
|
-
default_value =
|
804
|
+
default_value = nil #: String?
|
761
805
|
|
762
806
|
rest.each do |arg|
|
763
807
|
next unless arg.is_a?(Prism::KeywordHashNode)
|
@@ -781,7 +825,7 @@ module RBI
|
|
781
825
|
end
|
782
826
|
end
|
783
827
|
|
784
|
-
|
828
|
+
#: (String name, Prism::Node node) -> Visibility
|
785
829
|
def parse_visibility(name, node)
|
786
830
|
case name
|
787
831
|
when "public"
|
@@ -795,7 +839,7 @@ module RBI
|
|
795
839
|
end
|
796
840
|
end
|
797
841
|
|
798
|
-
|
842
|
+
#: -> void
|
799
843
|
def separate_header_comments
|
800
844
|
current_scope.nodes.dup.each do |child_node|
|
801
845
|
break unless child_node.is_a?(Comment) || child_node.is_a?(BlankLine)
|
@@ -805,7 +849,7 @@ module RBI
|
|
805
849
|
end
|
806
850
|
end
|
807
851
|
|
808
|
-
|
852
|
+
#: -> void
|
809
853
|
def set_root_tree_loc
|
810
854
|
first_loc = tree.nodes.first&.loc
|
811
855
|
last_loc = tree.nodes.last&.loc
|
@@ -819,29 +863,43 @@ module RBI
|
|
819
863
|
)
|
820
864
|
end
|
821
865
|
|
822
|
-
|
866
|
+
#: (Prism::Node? node) -> bool
|
823
867
|
def type_variable_definition?(node)
|
824
868
|
node.is_a?(Prism::CallNode) && (node.message == "type_member" || node.message == "type_template")
|
825
869
|
end
|
870
|
+
|
871
|
+
#: (Prism::Node? node) -> bool
|
872
|
+
def t_enum_value?(node)
|
873
|
+
return false unless current_scope.is_a?(TEnumBlock)
|
874
|
+
|
875
|
+
return false unless node.is_a?(Prism::ConstantWriteNode)
|
876
|
+
|
877
|
+
value = node.value
|
878
|
+
return false unless value.is_a?(Prism::CallNode)
|
879
|
+
return false unless value.message == "new"
|
880
|
+
|
881
|
+
true
|
882
|
+
end
|
826
883
|
end
|
827
884
|
|
828
885
|
class SigBuilder < Visitor
|
829
|
-
|
830
|
-
|
831
|
-
sig { returns(Sig) }
|
886
|
+
#: Sig
|
832
887
|
attr_reader :current
|
833
888
|
|
834
|
-
|
889
|
+
#: (String content, file: String) -> void
|
835
890
|
def initialize(content, file:)
|
836
891
|
super
|
837
892
|
|
838
|
-
@current =
|
893
|
+
@current = Sig.new #: Sig
|
839
894
|
end
|
840
895
|
|
841
|
-
|
896
|
+
# @override
|
897
|
+
#: (Prism::CallNode node) -> void
|
842
898
|
def visit_call_node(node)
|
843
899
|
case node.message
|
844
900
|
when "sig"
|
901
|
+
@current.without_runtime = t_sig_without_runtime?(node.receiver)
|
902
|
+
|
845
903
|
args = node.arguments
|
846
904
|
if args.is_a?(Prism::ArgumentsNode)
|
847
905
|
args.arguments.each do |arg|
|
@@ -858,6 +916,22 @@ module RBI
|
|
858
916
|
end
|
859
917
|
when "override"
|
860
918
|
@current.is_override = true
|
919
|
+
|
920
|
+
args = node.arguments&.arguments
|
921
|
+
|
922
|
+
keywords_hash = args
|
923
|
+
&.grep(Prism::KeywordHashNode)
|
924
|
+
&.first
|
925
|
+
|
926
|
+
allow_incompatible_override = keywords_hash
|
927
|
+
&.elements
|
928
|
+
&.any? do |assoc|
|
929
|
+
assoc.is_a?(Prism::AssocNode) &&
|
930
|
+
node_string(assoc.key) == "allow_incompatible:" &&
|
931
|
+
node_string(assoc.value) == "true"
|
932
|
+
end
|
933
|
+
|
934
|
+
@current.allow_incompatible_override = !!allow_incompatible_override
|
861
935
|
when "overridable"
|
862
936
|
@current.is_overridable = true
|
863
937
|
when "params"
|
@@ -883,7 +957,8 @@ module RBI
|
|
883
957
|
visit(node.block)
|
884
958
|
end
|
885
959
|
|
886
|
-
|
960
|
+
# @override
|
961
|
+
#: (Prism::AssocNode node) -> void
|
887
962
|
def visit_assoc_node(node)
|
888
963
|
@current.params << SigParam.new(
|
889
964
|
node_string!(node.key).delete_suffix(":"),
|
@@ -891,5 +966,59 @@ module RBI
|
|
891
966
|
)
|
892
967
|
end
|
893
968
|
end
|
969
|
+
|
970
|
+
class HeredocLocationVisitor < Prism::Visitor
|
971
|
+
#: (Prism::Source source, Integer begin_offset, Integer end_offset) -> void
|
972
|
+
def initialize(source, begin_offset, end_offset)
|
973
|
+
super()
|
974
|
+
@source = source
|
975
|
+
@begin_offset = begin_offset
|
976
|
+
@end_offset = end_offset
|
977
|
+
@offset_last_newline = false #: bool
|
978
|
+
end
|
979
|
+
|
980
|
+
# @override
|
981
|
+
#: (Prism::StringNode node) -> void
|
982
|
+
def visit_string_node(node)
|
983
|
+
return unless node.heredoc?
|
984
|
+
|
985
|
+
closing_loc = node.closing_loc
|
986
|
+
return unless closing_loc
|
987
|
+
|
988
|
+
handle_string_node(node)
|
989
|
+
end
|
990
|
+
|
991
|
+
# @override
|
992
|
+
#: (Prism::InterpolatedStringNode node) -> void
|
993
|
+
def visit_interpolated_string_node(node)
|
994
|
+
return super unless node.heredoc?
|
995
|
+
|
996
|
+
closing_loc = node.closing_loc
|
997
|
+
return super unless closing_loc
|
998
|
+
|
999
|
+
handle_string_node(node)
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
#: -> Prism::Location
|
1003
|
+
def location
|
1004
|
+
Prism::Location.new(
|
1005
|
+
@source,
|
1006
|
+
@begin_offset,
|
1007
|
+
@end_offset - @begin_offset - (@offset_last_newline ? 1 : 0),
|
1008
|
+
)
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
private
|
1012
|
+
|
1013
|
+
#: (Prism::StringNode | Prism::InterpolatedStringNode node) -> void
|
1014
|
+
def handle_string_node(node)
|
1015
|
+
closing_loc = node.closing_loc #: as !nil
|
1016
|
+
|
1017
|
+
if closing_loc.end_offset > @end_offset
|
1018
|
+
@end_offset = closing_loc.end_offset
|
1019
|
+
@offset_last_newline = true if node.closing_loc&.slice&.end_with?("\n")
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
end
|
894
1023
|
end
|
895
1024
|
end
|