rbi 0.0.17 → 0.1.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 +1 -1
- data/lib/rbi/loc.rb +15 -0
- data/lib/rbi/parser.rb +596 -545
- data/lib/rbi/version.rb +1 -1
- metadata +7 -35
data/lib/rbi/parser.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require "
|
4
|
+
require "yarp"
|
5
5
|
|
6
6
|
module RBI
|
7
7
|
class ParseError < StandardError
|
@@ -53,19 +53,6 @@ module RBI
|
|
53
53
|
class Parser
|
54
54
|
extend T::Sig
|
55
55
|
|
56
|
-
# opt-in to most recent AST format
|
57
|
-
::Parser::Builders::Default.emit_lambda = true
|
58
|
-
::Parser::Builders::Default.emit_procarg0 = true
|
59
|
-
::Parser::Builders::Default.emit_encoding = true
|
60
|
-
::Parser::Builders::Default.emit_index = true
|
61
|
-
::Parser::Builders::Default.emit_arg_inside_procarg0 = true
|
62
|
-
|
63
|
-
sig { void }
|
64
|
-
def initialize
|
65
|
-
# Delay load unparser and only if it has not been loaded already.
|
66
|
-
require "unparser" unless defined?(::Unparser)
|
67
|
-
end
|
68
|
-
|
69
56
|
class << self
|
70
57
|
extend T::Sig
|
71
58
|
|
@@ -104,22 +91,24 @@ module RBI
|
|
104
91
|
|
105
92
|
private
|
106
93
|
|
107
|
-
sig { params(
|
108
|
-
def parse(
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
94
|
+
sig { params(source: String, file: String).returns(Tree) }
|
95
|
+
def parse(source, file:)
|
96
|
+
result = YARP.parse(source)
|
97
|
+
unless result.success?
|
98
|
+
raise ParseError.new(result.errors.map(&:message).join(" "), Loc.from_yarp(file, result.errors.first.location))
|
99
|
+
end
|
100
|
+
|
101
|
+
visitor = TreeBuilder.new(source, comments: result.comments, file: file)
|
102
|
+
visitor.visit(result.value)
|
103
|
+
visitor.tree
|
104
|
+
rescue YARP::ParseError => e
|
105
|
+
raise ParseError.new(e.message, Loc.from_yarp(file, e.location))
|
117
106
|
rescue ParseError => e
|
118
107
|
raise e
|
119
108
|
rescue => e
|
120
|
-
last_node =
|
109
|
+
last_node = visitor&.last_node
|
121
110
|
last_location = if last_node
|
122
|
-
Loc.
|
111
|
+
Loc.from_yarp(file, last_node.location)
|
123
112
|
else
|
124
113
|
Loc.new(file: file)
|
125
114
|
end
|
@@ -128,630 +117,692 @@ module RBI
|
|
128
117
|
exception.print_debug
|
129
118
|
raise exception
|
130
119
|
end
|
131
|
-
end
|
132
120
|
|
133
|
-
|
134
|
-
|
135
|
-
extend T::Sig
|
121
|
+
class Visitor < YARP::Visitor
|
122
|
+
extend T::Sig
|
136
123
|
|
137
|
-
|
124
|
+
sig { params(source: String, file: String).void }
|
125
|
+
def initialize(source, file:)
|
126
|
+
super()
|
138
127
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
128
|
+
@source = source
|
129
|
+
@file = file
|
130
|
+
end
|
143
131
|
|
144
|
-
|
145
|
-
def visit(node); end
|
132
|
+
private
|
146
133
|
|
147
|
-
|
134
|
+
sig { params(node: YARP::Node).returns(Loc) }
|
135
|
+
def node_loc(node)
|
136
|
+
Loc.from_yarp(@file, node.location)
|
137
|
+
end
|
148
138
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
139
|
+
sig { params(node: T.nilable(YARP::Node)).returns(T.nilable(String)) }
|
140
|
+
def node_string(node)
|
141
|
+
return unless node
|
153
142
|
|
154
|
-
|
155
|
-
|
156
|
-
|
143
|
+
node.slice
|
144
|
+
end
|
145
|
+
|
146
|
+
sig { params(node: YARP::Node).returns(String) }
|
147
|
+
def node_string!(node)
|
148
|
+
T.must(node_string(node))
|
149
|
+
end
|
157
150
|
end
|
158
|
-
end
|
159
151
|
|
160
|
-
|
161
|
-
|
152
|
+
class TreeBuilder < Visitor
|
153
|
+
extend T::Sig
|
162
154
|
|
163
|
-
|
164
|
-
|
155
|
+
sig { returns(Tree) }
|
156
|
+
attr_reader :tree
|
165
157
|
|
166
|
-
|
167
|
-
|
158
|
+
sig { returns(T.nilable(YARP::Node)) }
|
159
|
+
attr_reader :last_node
|
168
160
|
|
169
|
-
|
170
|
-
|
171
|
-
file:
|
172
|
-
comments: T::Array[::Parser::Source::Comment],
|
173
|
-
nodes_comments_assoc: T::Hash[::Parser::Source::Map, T::Array[::Parser::Source::Comment]],
|
174
|
-
).void
|
175
|
-
end
|
176
|
-
def initialize(file:, comments: [], nodes_comments_assoc: {})
|
177
|
-
super()
|
178
|
-
@file = file
|
179
|
-
@comments = comments
|
180
|
-
@nodes_comments_assoc = nodes_comments_assoc
|
181
|
-
@tree = T.let(Tree.new, Tree)
|
182
|
-
@scopes_stack = T.let([@tree], T::Array[Tree])
|
183
|
-
@last_node = T.let(nil, T.nilable(::AST::Node))
|
184
|
-
@last_sigs = T.let([], T::Array[RBI::Sig])
|
185
|
-
@last_sigs_comments = T.let([], T::Array[Comment])
|
186
|
-
|
187
|
-
separate_header_comments
|
188
|
-
end
|
161
|
+
sig { params(source: String, comments: T::Array[YARP::Comment], file: String).void }
|
162
|
+
def initialize(source, comments:, file:)
|
163
|
+
super(source, file: file)
|
189
164
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
165
|
+
@comments_by_line = T.let(comments.to_h { |c| [c.location.start_line, c] }, T::Hash[Integer, YARP::Comment])
|
166
|
+
@tree = T.let(Tree.new, Tree)
|
167
|
+
|
168
|
+
@scopes_stack = T.let([@tree], T::Array[Tree])
|
169
|
+
@last_node = T.let(nil, T.nilable(YARP::Node))
|
170
|
+
@last_sigs = T.let([], T::Array[RBI::Sig])
|
171
|
+
@last_sigs_comments = T.let([], T::Array[Comment])
|
172
|
+
end
|
173
|
+
|
174
|
+
sig { override.params(node: T.nilable(YARP::Node)).void }
|
175
|
+
def visit(node)
|
176
|
+
return unless node
|
195
177
|
|
196
|
-
|
197
|
-
|
198
|
-
|
178
|
+
@last_node = node
|
179
|
+
super
|
180
|
+
end
|
199
181
|
|
200
|
-
|
182
|
+
sig { override.params(node: YARP::ClassNode).void }
|
183
|
+
def visit_class_node(node)
|
184
|
+
scope = Class.new(
|
185
|
+
node_string!(node.constant_path),
|
186
|
+
superclass_name: node_string(node.superclass),
|
187
|
+
loc: node_loc(node),
|
188
|
+
comments: node_comments(node),
|
189
|
+
)
|
201
190
|
|
202
|
-
case node.type
|
203
|
-
when :module, :class, :sclass
|
204
|
-
scope = parse_scope(node)
|
205
191
|
current_scope << scope
|
206
192
|
@scopes_stack << scope
|
207
|
-
|
193
|
+
visit(node.body)
|
194
|
+
collect_dangling_comments(node)
|
208
195
|
@scopes_stack.pop
|
209
|
-
when :casgn
|
210
|
-
current_scope << parse_const_assign(node)
|
211
|
-
when :def, :defs
|
212
|
-
current_scope << parse_def(node)
|
213
|
-
when :send
|
214
|
-
node = parse_send(node)
|
215
|
-
current_scope << node if node
|
216
|
-
when :block
|
217
|
-
rbi_node = parse_block(node)
|
218
|
-
if rbi_node.is_a?(Sig)
|
219
|
-
@last_sigs << rbi_node
|
220
|
-
@last_sigs_comments.concat(node_comments(node))
|
221
|
-
elsif rbi_node
|
222
|
-
current_scope << rbi_node
|
223
|
-
end
|
224
|
-
else
|
225
|
-
visit_all(node.children)
|
226
196
|
end
|
227
197
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
private
|
232
|
-
|
233
|
-
sig { params(node: AST::Node).returns(Scope) }
|
234
|
-
def parse_scope(node)
|
235
|
-
loc = node_loc(node)
|
236
|
-
comments = node_comments(node)
|
237
|
-
|
238
|
-
case node.type
|
239
|
-
when :module
|
240
|
-
name = parse_name(node.children[0])
|
241
|
-
Module.new(name, loc: loc, comments: comments)
|
242
|
-
when :class
|
243
|
-
name = parse_name(node.children[0])
|
244
|
-
superclass_name = ConstBuilder.visit(node.children[1])
|
245
|
-
Class.new(name, superclass_name: superclass_name, loc: loc, comments: comments)
|
246
|
-
when :sclass
|
247
|
-
SingletonClass.new(loc: loc, comments: comments)
|
248
|
-
else
|
249
|
-
raise ParseError.new("Unsupported scope node type `#{node.type}`", loc)
|
198
|
+
sig { override.params(node: YARP::ConstantWriteNode).void }
|
199
|
+
def visit_constant_write_node(node)
|
200
|
+
visit_constant_assign(node)
|
250
201
|
end
|
251
|
-
end
|
252
202
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
if struct_definition?(node_value)
|
257
|
-
parse_struct(node)
|
258
|
-
elsif type_variable_definition?(node_value)
|
259
|
-
parse_type_variable(node)
|
260
|
-
else
|
261
|
-
name = parse_name(node)
|
262
|
-
value = parse_expr(node_value)
|
263
|
-
loc = node_loc(node)
|
264
|
-
comments = node_comments(node)
|
265
|
-
Const.new(name, value, loc: loc, comments: comments)
|
203
|
+
sig { override.params(node: YARP::ConstantPathWriteNode).void }
|
204
|
+
def visit_constant_path_write_node(node)
|
205
|
+
visit_constant_assign(node)
|
266
206
|
end
|
267
|
-
end
|
268
207
|
|
269
|
-
|
270
|
-
|
271
|
-
|
208
|
+
sig { params(node: T.any(YARP::ConstantWriteNode, YARP::ConstantPathWriteNode)).void }
|
209
|
+
def visit_constant_assign(node)
|
210
|
+
struct = parse_struct(node)
|
211
|
+
|
212
|
+
current_scope << if struct
|
213
|
+
struct
|
214
|
+
elsif type_variable_definition?(node.value)
|
215
|
+
TypeMember.new(
|
216
|
+
case node
|
217
|
+
when YARP::ConstantWriteNode
|
218
|
+
node.name
|
219
|
+
when YARP::ConstantPathWriteNode
|
220
|
+
node_string!(node.target)
|
221
|
+
end,
|
222
|
+
node_string!(node.value),
|
223
|
+
loc: node_loc(node),
|
224
|
+
comments: node_comments(node),
|
225
|
+
)
|
226
|
+
else
|
227
|
+
Const.new(
|
228
|
+
case node
|
229
|
+
when YARP::ConstantWriteNode
|
230
|
+
node.name
|
231
|
+
when YARP::ConstantPathWriteNode
|
232
|
+
node_string!(node.target)
|
233
|
+
end,
|
234
|
+
node_string!(node.value),
|
235
|
+
loc: node_loc(node),
|
236
|
+
comments: node_comments(node),
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
272
240
|
|
273
|
-
|
274
|
-
|
275
|
-
Method.new(
|
276
|
-
node.
|
277
|
-
params: node.
|
241
|
+
sig { override.params(node: YARP::DefNode).void }
|
242
|
+
def visit_def_node(node)
|
243
|
+
current_scope << Method.new(
|
244
|
+
node.name,
|
245
|
+
params: parse_params(node.parameters),
|
278
246
|
sigs: current_sigs,
|
279
|
-
loc:
|
247
|
+
loc: node_loc(node),
|
280
248
|
comments: current_sigs_comments + node_comments(node),
|
249
|
+
is_singleton: !!node.receiver,
|
281
250
|
)
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
loc:
|
289
|
-
comments:
|
251
|
+
end
|
252
|
+
|
253
|
+
sig { override.params(node: YARP::ModuleNode).void }
|
254
|
+
def visit_module_node(node)
|
255
|
+
scope = Module.new(
|
256
|
+
node_string!(node.constant_path),
|
257
|
+
loc: node_loc(node),
|
258
|
+
comments: node_comments(node),
|
290
259
|
)
|
291
|
-
|
292
|
-
|
260
|
+
|
261
|
+
current_scope << scope
|
262
|
+
@scopes_stack << scope
|
263
|
+
visit(node.body)
|
264
|
+
collect_dangling_comments(node)
|
265
|
+
@scopes_stack.pop
|
293
266
|
end
|
294
|
-
end
|
295
267
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
when :arg
|
304
|
-
ReqParam.new(name, loc: loc, comments: comments)
|
305
|
-
when :optarg
|
306
|
-
value = parse_expr(node.children[1])
|
307
|
-
OptParam.new(name, value, loc: loc, comments: comments)
|
308
|
-
when :restarg
|
309
|
-
RestParam.new(name, loc: loc, comments: comments)
|
310
|
-
when :kwarg
|
311
|
-
KwParam.new(name, loc: loc, comments: comments)
|
312
|
-
when :kwoptarg
|
313
|
-
value = parse_expr(node.children[1])
|
314
|
-
KwOptParam.new(name, value, loc: loc, comments: comments)
|
315
|
-
when :kwrestarg
|
316
|
-
KwRestParam.new(name, loc: loc, comments: comments)
|
317
|
-
when :blockarg
|
318
|
-
BlockParam.new(name, loc: loc, comments: comments)
|
319
|
-
else
|
320
|
-
raise ParseError.new("Unsupported param node type `#{node.type}`", loc)
|
268
|
+
sig { override.params(node: YARP::ProgramNode).void }
|
269
|
+
def visit_program_node(node)
|
270
|
+
super
|
271
|
+
|
272
|
+
collect_orphan_comments
|
273
|
+
separate_header_comments
|
274
|
+
set_root_tree_loc
|
321
275
|
end
|
322
|
-
end
|
323
276
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
AttrReader.new(*symbols, sigs: current_sigs, loc: loc, comments: current_sigs_comments + comments)
|
337
|
-
when :attr_writer
|
338
|
-
symbols = node.children[2..-1].map { |child| child.children[0] }
|
339
|
-
AttrWriter.new(*symbols, sigs: current_sigs, loc: loc, comments: current_sigs_comments + comments)
|
340
|
-
when :attr_accessor
|
341
|
-
symbols = node.children[2..-1].map { |child| child.children[0] }
|
342
|
-
AttrAccessor.new(*symbols, sigs: current_sigs, loc: loc, comments: current_sigs_comments + comments)
|
343
|
-
when :include
|
344
|
-
names = node.children[2..-1].map { |child| parse_expr(child) }
|
345
|
-
Include.new(*names, loc: loc, comments: comments)
|
346
|
-
when :extend
|
347
|
-
names = node.children[2..-1].map { |child| parse_expr(child) }
|
348
|
-
Extend.new(*names, loc: loc, comments: comments)
|
349
|
-
when :abstract!, :sealed!, :interface!
|
350
|
-
Helper.new(method_name.to_s.delete_suffix("!"), loc: loc, comments: comments)
|
351
|
-
when :mixes_in_class_methods
|
352
|
-
names = node.children[2..-1].map { |child| parse_name(child) }
|
353
|
-
MixesInClassMethods.new(*names, loc: loc, comments: comments)
|
354
|
-
when :public, :protected, :private
|
355
|
-
visibility = case method_name
|
356
|
-
when :protected
|
357
|
-
Protected.new(loc: loc)
|
358
|
-
when :private
|
359
|
-
Private.new(loc: loc)
|
360
|
-
else
|
361
|
-
Public.new(loc: loc)
|
362
|
-
end
|
363
|
-
nested_node = node.children[2]
|
364
|
-
case nested_node&.type
|
365
|
-
when :def, :defs
|
366
|
-
method = parse_def(nested_node)
|
367
|
-
method.visibility = visibility
|
368
|
-
method
|
369
|
-
when :send
|
370
|
-
snode = parse_send(nested_node)
|
371
|
-
raise ParseError.new("Unexpected token `private` before `#{nested_node.type}`", loc) unless snode.is_a?(Attr)
|
372
|
-
|
373
|
-
snode.visibility = visibility
|
374
|
-
snode
|
375
|
-
when nil
|
376
|
-
visibility
|
377
|
-
else
|
378
|
-
raise ParseError.new("Unexpected token `private` before `#{nested_node.type}`", loc)
|
379
|
-
end
|
380
|
-
when :prop
|
381
|
-
name, type, default_value = parse_tstruct_prop(node)
|
382
|
-
TStructProp.new(name, type, default: default_value, loc: loc, comments: comments)
|
383
|
-
when :const
|
384
|
-
name, type, default_value = parse_tstruct_prop(node)
|
385
|
-
TStructConst.new(name, type, default: default_value, loc: loc, comments: comments)
|
386
|
-
else
|
387
|
-
args = parse_send_args(node)
|
388
|
-
Send.new(method_name.to_s, args, loc: loc, comments: comments)
|
277
|
+
sig { override.params(node: YARP::SingletonClassNode).void }
|
278
|
+
def visit_singleton_class_node(node)
|
279
|
+
scope = SingletonClass.new(
|
280
|
+
loc: node_loc(node),
|
281
|
+
comments: node_comments(node),
|
282
|
+
)
|
283
|
+
|
284
|
+
current_scope << scope
|
285
|
+
@scopes_stack << scope
|
286
|
+
visit(node.body)
|
287
|
+
collect_dangling_comments(node)
|
288
|
+
@scopes_stack.pop
|
389
289
|
end
|
390
|
-
end
|
391
290
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
291
|
+
sig { params(node: YARP::CallNode).void }
|
292
|
+
def visit_call_node(node)
|
293
|
+
message = node.name
|
294
|
+
case message
|
295
|
+
when "abstract!", "sealed!", "interface!"
|
296
|
+
current_scope << Helper.new(
|
297
|
+
message.delete_suffix("!"),
|
298
|
+
loc: node_loc(node),
|
299
|
+
comments: node_comments(node),
|
300
|
+
)
|
301
|
+
when "attr_reader"
|
302
|
+
args = node.arguments
|
303
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
304
|
+
|
305
|
+
current_scope << AttrReader.new(
|
306
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg).delete_prefix(":").to_sym }),
|
307
|
+
sigs: current_sigs,
|
308
|
+
loc: node_loc(node),
|
309
|
+
comments: current_sigs_comments + node_comments(node),
|
310
|
+
)
|
311
|
+
when "attr_writer"
|
312
|
+
args = node.arguments
|
313
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
314
|
+
|
315
|
+
current_scope << AttrWriter.new(
|
316
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg).delete_prefix(":").to_sym }),
|
317
|
+
sigs: current_sigs,
|
318
|
+
loc: node_loc(node),
|
319
|
+
comments: current_sigs_comments + node_comments(node),
|
320
|
+
)
|
321
|
+
when "attr_accessor"
|
322
|
+
args = node.arguments
|
323
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
324
|
+
|
325
|
+
current_scope << AttrAccessor.new(
|
326
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg).delete_prefix(":").to_sym }),
|
327
|
+
sigs: current_sigs,
|
328
|
+
loc: node_loc(node),
|
329
|
+
comments: current_sigs_comments + node_comments(node),
|
330
|
+
)
|
331
|
+
when "enums"
|
332
|
+
block = node.block
|
333
|
+
return unless block.is_a?(YARP::BlockNode)
|
334
|
+
|
335
|
+
body = block.body
|
336
|
+
return unless body.is_a?(YARP::StatementsNode)
|
337
|
+
|
338
|
+
current_scope << TEnumBlock.new(
|
339
|
+
body.body.map { |stmt| T.cast(stmt, YARP::ConstantWriteNode).name },
|
340
|
+
loc: node_loc(node),
|
341
|
+
comments: node_comments(node),
|
342
|
+
)
|
343
|
+
when "extend"
|
344
|
+
args = node.arguments
|
345
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
346
|
+
|
347
|
+
current_scope << Extend.new(
|
348
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg) }),
|
349
|
+
loc: node_loc(node),
|
350
|
+
comments: node_comments(node),
|
351
|
+
)
|
352
|
+
when "include"
|
353
|
+
args = node.arguments
|
354
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
355
|
+
|
356
|
+
current_scope << Include.new(
|
357
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg) }),
|
358
|
+
loc: node_loc(node),
|
359
|
+
comments: node_comments(node),
|
360
|
+
)
|
361
|
+
when "mixes_in_class_methods"
|
362
|
+
args = node.arguments
|
363
|
+
return unless args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
364
|
+
|
365
|
+
current_scope << MixesInClassMethods.new(
|
366
|
+
*T.unsafe(args.arguments.map { |arg| node_string!(arg) }),
|
367
|
+
loc: node_loc(node),
|
368
|
+
comments: node_comments(node),
|
369
|
+
)
|
370
|
+
when "private", "protected", "public"
|
371
|
+
args = node.arguments
|
372
|
+
if args.is_a?(YARP::ArgumentsNode) && args.arguments.any?
|
373
|
+
visit(node.arguments)
|
374
|
+
last_node = @scopes_stack.last&.nodes&.last
|
375
|
+
case last_node
|
376
|
+
when Method, Attr
|
377
|
+
last_node.visibility = parse_visibility(node.name, node)
|
378
|
+
else
|
379
|
+
raise ParseError.new(
|
380
|
+
"Unexpected token `#{node.message}` before `#{last_node&.string&.strip}`",
|
381
|
+
node_loc(node),
|
382
|
+
)
|
383
|
+
end
|
384
|
+
else
|
385
|
+
current_scope << parse_visibility(node.name, node)
|
401
386
|
end
|
387
|
+
when "prop", "const"
|
388
|
+
parse_tstruct_field(node)
|
389
|
+
when "requires_ancestor"
|
390
|
+
block = node.block
|
391
|
+
return unless block.is_a?(YARP::BlockNode)
|
392
|
+
|
393
|
+
body = block.body
|
394
|
+
return unless body.is_a?(YARP::StatementsNode)
|
395
|
+
|
396
|
+
current_scope << RequiresAncestor.new(
|
397
|
+
node_string!(body),
|
398
|
+
loc: node_loc(node),
|
399
|
+
comments: node_comments(node),
|
400
|
+
)
|
401
|
+
when "sig"
|
402
|
+
@last_sigs << parse_sig(node)
|
402
403
|
else
|
403
|
-
|
404
|
+
current_scope << Send.new(
|
405
|
+
message,
|
406
|
+
parse_send_args(node.arguments),
|
407
|
+
loc: node_loc(node),
|
408
|
+
comments: node_comments(node),
|
409
|
+
)
|
404
410
|
end
|
405
411
|
end
|
406
|
-
args
|
407
|
-
end
|
408
412
|
|
409
|
-
|
410
|
-
def parse_block(node)
|
411
|
-
name = node.children[0].children[1]
|
412
|
-
|
413
|
-
case name
|
414
|
-
when :sig
|
415
|
-
parse_sig(node)
|
416
|
-
when :enums
|
417
|
-
parse_enum(node)
|
418
|
-
when :requires_ancestor
|
419
|
-
parse_requires_ancestor(node)
|
420
|
-
else
|
421
|
-
raise ParseError.new("Unsupported block node type `#{name}`", node_loc(node))
|
422
|
-
end
|
423
|
-
end
|
413
|
+
private
|
424
414
|
|
425
|
-
|
426
|
-
|
427
|
-
(node
|
428
|
-
|
429
|
-
|
415
|
+
# Collect all the remaining comments within a node
|
416
|
+
sig { params(node: YARP::Node).void }
|
417
|
+
def collect_dangling_comments(node)
|
418
|
+
first_line = node.location.start_line
|
419
|
+
last_line = node.location.end_line
|
430
420
|
|
431
|
-
|
432
|
-
def parse_struct(node)
|
433
|
-
name = parse_name(node)
|
434
|
-
loc = node_loc(node)
|
435
|
-
comments = node_comments(node)
|
421
|
+
last_node_last_line = node.child_nodes.last&.location&.end_line
|
436
422
|
|
437
|
-
|
438
|
-
|
423
|
+
last_line.downto(first_line) do |line|
|
424
|
+
comment = @comments_by_line[line]
|
425
|
+
next unless comment
|
426
|
+
break if last_node_last_line && line <= last_node_last_line
|
439
427
|
|
440
|
-
|
441
|
-
|
442
|
-
body = send.children[2].children
|
443
|
-
else
|
444
|
-
body << send.children[2]
|
428
|
+
current_scope << parse_comment(comment)
|
429
|
+
@comments_by_line.delete(line)
|
445
430
|
end
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
if
|
457
|
-
|
431
|
+
end
|
432
|
+
|
433
|
+
# Collect all the remaining comments after visiting the tree
|
434
|
+
sig { void }
|
435
|
+
def collect_orphan_comments
|
436
|
+
last_line = T.let(nil, T.nilable(Integer))
|
437
|
+
last_node_end = @tree.nodes.last&.loc&.end_line
|
438
|
+
|
439
|
+
@comments_by_line.each do |line, comment|
|
440
|
+
# Associate the comment either with the header or the file or as a dangling comment at the end
|
441
|
+
recv = if last_node_end && line >= last_node_end
|
442
|
+
@tree
|
443
|
+
else
|
444
|
+
@tree.comments
|
458
445
|
end
|
446
|
+
|
447
|
+
# Preserve blank lines in comments
|
448
|
+
if last_line && line > last_line + 1
|
449
|
+
recv << BlankLine.new(loc: Loc.from_yarp(@file, comment.location))
|
450
|
+
end
|
451
|
+
|
452
|
+
recv << parse_comment(comment)
|
453
|
+
last_line = line
|
459
454
|
end
|
460
455
|
end
|
461
456
|
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
struct
|
468
|
-
end
|
457
|
+
sig { returns(Tree) }
|
458
|
+
def current_scope
|
459
|
+
T.must(@scopes_stack.last) # Should never be nil since we create a Tree as the root
|
460
|
+
end
|
469
461
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
462
|
+
sig { returns(T::Array[Sig]) }
|
463
|
+
def current_sigs
|
464
|
+
sigs = @last_sigs.dup
|
465
|
+
@last_sigs.clear
|
466
|
+
sigs
|
467
|
+
end
|
476
468
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
469
|
+
sig { returns(T::Array[Comment]) }
|
470
|
+
def current_sigs_comments
|
471
|
+
comments = @last_sigs_comments.dup
|
472
|
+
@last_sigs_comments.clear
|
473
|
+
comments
|
474
|
+
end
|
482
475
|
|
483
|
-
|
476
|
+
sig { params(node: YARP::Node).returns(T::Array[Comment]) }
|
477
|
+
def node_comments(node)
|
478
|
+
comments = []
|
484
479
|
|
485
|
-
|
486
|
-
|
480
|
+
start_line = node.location.start_line
|
481
|
+
start_line -= 1 unless @comments_by_line.key?(start_line)
|
487
482
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
type = parse_expr(node.children[3])
|
492
|
-
has_default = node.children[4]
|
493
|
-
&.children&.fetch(0, nil)
|
494
|
-
&.children&.fetch(0, nil)
|
495
|
-
&.children&.fetch(0, nil) == :default
|
496
|
-
default_value = if has_default
|
497
|
-
parse_expr(node.children.fetch(4, nil)
|
498
|
-
&.children&.fetch(0, nil)
|
499
|
-
&.children&.fetch(1, nil))
|
500
|
-
end
|
501
|
-
[name, type, default_value]
|
502
|
-
end
|
483
|
+
start_line.downto(1) do |line|
|
484
|
+
comment = @comments_by_line[line]
|
485
|
+
break unless comment
|
503
486
|
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
sig.loc = node_loc(node)
|
508
|
-
sig
|
509
|
-
end
|
487
|
+
comments.unshift(parse_comment(comment))
|
488
|
+
@comments_by_line.delete(line)
|
489
|
+
end
|
510
490
|
|
511
|
-
|
512
|
-
|
513
|
-
enum = TEnumBlock.new
|
491
|
+
comments
|
492
|
+
end
|
514
493
|
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
[node.children[2]]
|
494
|
+
sig { params(node: YARP::Comment).returns(Comment) }
|
495
|
+
def parse_comment(node)
|
496
|
+
Comment.new(node.location.slice.gsub(/^# ?/, "").rstrip, loc: Loc.from_yarp(@file, node.location))
|
519
497
|
end
|
520
498
|
|
521
|
-
|
522
|
-
|
499
|
+
sig { params(node: T.nilable(YARP::Node)).returns(T::Array[Arg]) }
|
500
|
+
def parse_send_args(node)
|
501
|
+
args = T.let([], T::Array[Arg])
|
502
|
+
return args unless node.is_a?(YARP::ArgumentsNode)
|
503
|
+
|
504
|
+
node.arguments.each do |arg|
|
505
|
+
case arg
|
506
|
+
when YARP::KeywordHashNode
|
507
|
+
arg.elements.each do |assoc|
|
508
|
+
next unless assoc.is_a?(YARP::AssocNode)
|
509
|
+
|
510
|
+
args << KwArg.new(
|
511
|
+
node_string!(assoc.key).delete_suffix(":"),
|
512
|
+
T.must(node_string(assoc.value)),
|
513
|
+
)
|
514
|
+
end
|
515
|
+
else
|
516
|
+
args << Arg.new(T.must(node_string(arg)))
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
args
|
523
521
|
end
|
524
|
-
enum.loc = node_loc(node)
|
525
|
-
enum
|
526
|
-
end
|
527
522
|
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
ra.loc = node_loc(node)
|
533
|
-
ra
|
534
|
-
end
|
523
|
+
sig { params(node: T.nilable(YARP::Node)).returns(T::Array[Param]) }
|
524
|
+
def parse_params(node)
|
525
|
+
params = []
|
526
|
+
return params unless node.is_a?(YARP::ParametersNode)
|
535
527
|
|
536
|
-
|
537
|
-
|
538
|
-
Loc.from_ast_loc(@file, node.location)
|
539
|
-
end
|
528
|
+
node.requireds.each do |param|
|
529
|
+
next unless param.is_a?(YARP::RequiredParameterNode)
|
540
530
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
531
|
+
params << ReqParam.new(
|
532
|
+
param.name.to_s,
|
533
|
+
loc: node_loc(param),
|
534
|
+
comments: node_comments(param),
|
535
|
+
)
|
536
|
+
end
|
545
537
|
|
546
|
-
|
547
|
-
|
548
|
-
loc = Loc.from_ast_loc(@file, comment.location)
|
549
|
-
Comment.new(text, loc: loc)
|
550
|
-
end
|
551
|
-
end
|
538
|
+
node.optionals.each do |param|
|
539
|
+
next unless param.is_a?(YARP::OptionalParameterNode)
|
552
540
|
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
541
|
+
params << OptParam.new(
|
542
|
+
param.name.to_s,
|
543
|
+
node_string!(param.value),
|
544
|
+
loc: node_loc(param),
|
545
|
+
comments: node_comments(param),
|
546
|
+
)
|
547
|
+
end
|
557
548
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
549
|
+
rest = node.rest
|
550
|
+
if rest.is_a?(YARP::RestParameterNode)
|
551
|
+
params << RestParam.new(
|
552
|
+
rest.name || "*args",
|
553
|
+
loc: node_loc(rest),
|
554
|
+
comments: node_comments(rest),
|
555
|
+
)
|
556
|
+
end
|
564
557
|
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
558
|
+
node.keywords.each do |param|
|
559
|
+
next unless param.is_a?(YARP::KeywordParameterNode)
|
560
|
+
|
561
|
+
value = param.value
|
562
|
+
params << if value
|
563
|
+
KwOptParam.new(
|
564
|
+
param.name.delete_suffix(":"),
|
565
|
+
node_string!(value),
|
566
|
+
loc: node_loc(param),
|
567
|
+
comments: node_comments(param),
|
568
|
+
)
|
569
|
+
else
|
570
|
+
KwParam.new(
|
571
|
+
param.name.delete_suffix(":"),
|
572
|
+
loc: node_loc(param),
|
573
|
+
comments: node_comments(param),
|
574
|
+
)
|
575
|
+
end
|
576
|
+
end
|
571
577
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
if last_line && comment_line > last_line + 1
|
581
|
-
# Preserve empty lines in file headers
|
582
|
-
tree.comments << BlankLine.new(loc: loc)
|
578
|
+
rest_kw = node.keyword_rest
|
579
|
+
if rest_kw.is_a?(YARP::KeywordRestParameterNode)
|
580
|
+
params << KwRestParam.new(
|
581
|
+
rest_kw.name || "**kwargs",
|
582
|
+
loc: node_loc(rest_kw),
|
583
|
+
comments: node_comments(rest_kw),
|
584
|
+
)
|
583
585
|
end
|
584
586
|
|
585
|
-
|
586
|
-
|
587
|
+
block = node.block
|
588
|
+
if block.is_a?(YARP::BlockParameterNode)
|
589
|
+
params << BlockParam.new(
|
590
|
+
block.name || "&block",
|
591
|
+
loc: node_loc(block),
|
592
|
+
comments: node_comments(block),
|
593
|
+
)
|
594
|
+
end
|
595
|
+
|
596
|
+
params
|
587
597
|
end
|
588
|
-
end
|
589
598
|
|
590
|
-
|
591
|
-
|
592
|
-
|
599
|
+
sig { params(node: YARP::CallNode).returns(Sig) }
|
600
|
+
def parse_sig(node)
|
601
|
+
@last_sigs_comments = node_comments(node)
|
593
602
|
|
594
|
-
|
595
|
-
|
596
|
-
|
603
|
+
builder = SigBuilder.new(@source, file: @file)
|
604
|
+
builder.current.loc = node_loc(node)
|
605
|
+
builder.visit_call_node(node)
|
606
|
+
builder.current
|
607
|
+
end
|
597
608
|
|
598
|
-
|
599
|
-
|
600
|
-
|
609
|
+
sig { params(node: T.any(YARP::ConstantWriteNode, YARP::ConstantPathWriteNode)).returns(T.nilable(Struct)) }
|
610
|
+
def parse_struct(node)
|
611
|
+
send = node.value
|
612
|
+
return unless send.is_a?(YARP::CallNode)
|
613
|
+
return unless send.message == "new"
|
614
|
+
|
615
|
+
recv = send.receiver
|
616
|
+
return unless recv
|
617
|
+
return unless node_string(recv) =~ /(::)?Struct/
|
618
|
+
|
619
|
+
members = []
|
620
|
+
keyword_init = T.let(false, T::Boolean)
|
621
|
+
|
622
|
+
args = send.arguments
|
623
|
+
if args.is_a?(YARP::ArgumentsNode)
|
624
|
+
args.arguments.each do |arg|
|
625
|
+
case arg
|
626
|
+
when YARP::SymbolNode
|
627
|
+
members << arg.value
|
628
|
+
when YARP::KeywordHashNode
|
629
|
+
arg.elements.each do |assoc|
|
630
|
+
next unless assoc.is_a?(YARP::AssocNode)
|
631
|
+
|
632
|
+
key = node_string!(assoc.key)
|
633
|
+
val = node_string(assoc.value)
|
634
|
+
|
635
|
+
keyword_init = val == "true" if key == "keyword_init:"
|
636
|
+
end
|
637
|
+
else
|
638
|
+
raise ParseError.new("Unexpected node type `#{arg.class}`", node_loc(arg))
|
639
|
+
end
|
640
|
+
end
|
641
|
+
end
|
601
642
|
|
602
|
-
|
603
|
-
|
643
|
+
name = case node
|
644
|
+
when YARP::ConstantWriteNode
|
645
|
+
node.name
|
646
|
+
when YARP::ConstantPathWriteNode
|
647
|
+
node_string!(node.target)
|
648
|
+
end
|
604
649
|
|
605
|
-
|
606
|
-
|
650
|
+
loc = node_loc(node)
|
651
|
+
comments = node_comments(node)
|
652
|
+
struct = Struct.new(name, members: members, keyword_init: keyword_init, loc: loc, comments: comments)
|
653
|
+
@scopes_stack << struct
|
654
|
+
visit(send.block)
|
655
|
+
@scopes_stack.pop
|
656
|
+
struct
|
607
657
|
end
|
608
658
|
|
609
|
-
|
610
|
-
|
659
|
+
sig { params(send: YARP::CallNode).void }
|
660
|
+
def parse_tstruct_field(send)
|
661
|
+
args = send.arguments
|
662
|
+
return unless args.is_a?(YARP::ArgumentsNode)
|
611
663
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
last_loc = tree.nodes.last&.loc
|
616
|
-
|
617
|
-
@tree.loc = Loc.new(
|
618
|
-
file: @file,
|
619
|
-
begin_line: first_loc&.begin_line || 0,
|
620
|
-
begin_column: first_loc&.begin_column || 0,
|
621
|
-
end_line: last_loc&.end_line || 0,
|
622
|
-
end_column: last_loc&.end_column || 0,
|
623
|
-
)
|
624
|
-
end
|
625
|
-
end
|
664
|
+
name_arg, type_arg, *rest = args.arguments
|
665
|
+
return unless name_arg
|
666
|
+
return unless type_arg
|
626
667
|
|
627
|
-
|
628
|
-
|
668
|
+
name = node_string!(name_arg).delete_prefix(":")
|
669
|
+
type = node_string!(type_arg)
|
670
|
+
loc = node_loc(send)
|
671
|
+
comments = node_comments(send)
|
672
|
+
default_value = T.let(nil, T.nilable(String))
|
629
673
|
|
630
|
-
|
631
|
-
|
674
|
+
rest&.each do |arg|
|
675
|
+
next unless arg.is_a?(YARP::KeywordHashNode)
|
632
676
|
|
633
|
-
|
634
|
-
|
635
|
-
super
|
636
|
-
@names = T.let([], T::Array[String])
|
637
|
-
end
|
677
|
+
arg.elements.each do |assoc|
|
678
|
+
next unless assoc.is_a?(YARP::AssocNode)
|
638
679
|
|
639
|
-
|
640
|
-
|
680
|
+
if node_string(assoc.key) == "default:"
|
681
|
+
default_value = node_string(assoc.value)
|
682
|
+
end
|
683
|
+
end
|
684
|
+
end
|
641
685
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
686
|
+
current_scope << case send.message
|
687
|
+
when "const"
|
688
|
+
TStructConst.new(name, type, default: default_value, loc: loc, comments: comments)
|
689
|
+
when "prop"
|
690
|
+
TStructProp.new(name, type, default: default_value, loc: loc, comments: comments)
|
691
|
+
else
|
692
|
+
raise ParseError.new("Unexpected message `#{send.message}`", loc)
|
693
|
+
end
|
694
|
+
end
|
647
695
|
|
648
|
-
|
696
|
+
sig { params(name: String, node: YARP::Node).returns(Visibility) }
|
697
|
+
def parse_visibility(name, node)
|
698
|
+
case name
|
699
|
+
when "public"
|
700
|
+
Public.new(loc: node_loc(node))
|
701
|
+
when "protected"
|
702
|
+
Protected.new(loc: node_loc(node))
|
703
|
+
when "private"
|
704
|
+
Private.new(loc: node_loc(node))
|
705
|
+
else
|
706
|
+
raise ParseError.new("Unexpected visibility `#{name}`", node_loc(node))
|
707
|
+
end
|
649
708
|
end
|
650
|
-
end
|
651
709
|
|
652
|
-
|
653
|
-
|
654
|
-
|
710
|
+
sig { void }
|
711
|
+
def separate_header_comments
|
712
|
+
current_scope.nodes.dup.each do |child_node|
|
713
|
+
break unless child_node.is_a?(Comment) || child_node.is_a?(BlankLine)
|
655
714
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
@names << node.children[1].to_s
|
660
|
-
when :cbase
|
661
|
-
@names << ""
|
662
|
-
when :sym
|
663
|
-
@names << ":#{node.children[0]}"
|
715
|
+
current_scope.comments << child_node
|
716
|
+
child_node.detach
|
717
|
+
end
|
664
718
|
end
|
665
|
-
end
|
666
|
-
end
|
667
719
|
|
668
|
-
|
669
|
-
|
720
|
+
sig { void }
|
721
|
+
def set_root_tree_loc
|
722
|
+
first_loc = tree.nodes.first&.loc
|
723
|
+
last_loc = tree.nodes.last&.loc
|
724
|
+
|
725
|
+
@tree.loc = Loc.new(
|
726
|
+
file: @file,
|
727
|
+
begin_line: first_loc&.begin_line || 0,
|
728
|
+
begin_column: first_loc&.begin_column || 0,
|
729
|
+
end_line: last_loc&.end_line || 0,
|
730
|
+
end_column: last_loc&.end_column || 0,
|
731
|
+
)
|
732
|
+
end
|
670
733
|
|
671
|
-
|
672
|
-
|
734
|
+
sig { params(node: T.nilable(YARP::Node)).returns(T::Boolean) }
|
735
|
+
def type_variable_definition?(node)
|
736
|
+
return false unless node.is_a?(YARP::CallNode)
|
737
|
+
return false unless node.block
|
673
738
|
|
674
|
-
|
675
|
-
|
676
|
-
super
|
677
|
-
@current = T.let(Sig.new, Sig)
|
739
|
+
node.message == "type_member" || node.message == "type_template"
|
740
|
+
end
|
678
741
|
end
|
679
742
|
|
680
|
-
class
|
743
|
+
class SigBuilder < Visitor
|
681
744
|
extend T::Sig
|
682
745
|
|
683
|
-
sig {
|
684
|
-
|
685
|
-
v = SigBuilder.new
|
686
|
-
v.visit_all(node.children)
|
687
|
-
v.current
|
688
|
-
end
|
689
|
-
end
|
746
|
+
sig { returns(Sig) }
|
747
|
+
attr_accessor :current
|
690
748
|
|
691
|
-
|
692
|
-
|
693
|
-
|
749
|
+
sig { params(content: String, file: String).void }
|
750
|
+
def initialize(content, file:)
|
751
|
+
super
|
694
752
|
|
695
|
-
|
696
|
-
when :send
|
697
|
-
visit_send(node)
|
753
|
+
@current = T.let(Sig.new, Sig)
|
698
754
|
end
|
699
|
-
end
|
700
755
|
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
@current.is_abstract = true
|
711
|
-
when :override
|
712
|
-
@current.is_override = true
|
713
|
-
when :overridable
|
714
|
-
@current.is_overridable = true
|
715
|
-
when :checked
|
716
|
-
if node.children.length >= 3
|
717
|
-
@current.checked = node.children[2].children[0]
|
718
|
-
end
|
719
|
-
when :type_parameters
|
720
|
-
node.children[2..-1].each do |child|
|
721
|
-
@current.type_params << child.children[0].to_s
|
722
|
-
end
|
723
|
-
when :params
|
724
|
-
if node.children.length >= 3
|
725
|
-
node.children[2].children.each do |child|
|
726
|
-
name = child.children[0].children[0].to_s
|
727
|
-
type = parse_expr(child.children[1])
|
728
|
-
@current << SigParam.new(name, type)
|
756
|
+
sig { override.params(node: YARP::CallNode).void }
|
757
|
+
def visit_call_node(node)
|
758
|
+
case node.message
|
759
|
+
when "sig"
|
760
|
+
args = node.arguments
|
761
|
+
if args.is_a?(YARP::ArgumentsNode)
|
762
|
+
args.arguments.each do |arg|
|
763
|
+
@current.is_final = node_string(arg) == ":final"
|
764
|
+
end
|
729
765
|
end
|
766
|
+
when "abstract"
|
767
|
+
@current.is_abstract = true
|
768
|
+
when "checked"
|
769
|
+
args = node.arguments
|
770
|
+
if args.is_a?(YARP::ArgumentsNode)
|
771
|
+
arg = node_string(args.arguments.first)
|
772
|
+
@current.checked = arg&.delete_prefix(":")&.to_sym
|
773
|
+
end
|
774
|
+
when "override"
|
775
|
+
@current.is_override = true
|
776
|
+
when "overridable"
|
777
|
+
@current.is_overridable = true
|
778
|
+
when "params"
|
779
|
+
visit(node.arguments)
|
780
|
+
when "returns"
|
781
|
+
args = node.arguments
|
782
|
+
if args.is_a?(YARP::ArgumentsNode)
|
783
|
+
first = args.arguments.first
|
784
|
+
@current.return_type = node_string!(first) if first
|
785
|
+
end
|
786
|
+
when "type_parameters"
|
787
|
+
args = node.arguments
|
788
|
+
if args.is_a?(YARP::ArgumentsNode)
|
789
|
+
args.arguments.each do |arg|
|
790
|
+
@current.type_params << node_string!(arg).delete_prefix(":")
|
791
|
+
end
|
792
|
+
end
|
793
|
+
when "void"
|
794
|
+
@current.return_type = nil
|
730
795
|
end
|
731
|
-
when :returns
|
732
|
-
if node.children.length >= 3
|
733
|
-
@current.return_type = parse_expr(node.children[2])
|
734
|
-
end
|
735
|
-
when :void
|
736
|
-
@current.return_type = nil
|
737
|
-
else
|
738
|
-
raise "#{node.location.line}: Unhandled #{name}"
|
739
|
-
end
|
740
|
-
end
|
741
|
-
end
|
742
796
|
|
743
|
-
|
744
|
-
|
745
|
-
|
797
|
+
visit(node.receiver)
|
798
|
+
visit(node.block)
|
799
|
+
end
|
746
800
|
|
747
|
-
sig { params(
|
748
|
-
def
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
begin_column: ast_loc.column,
|
753
|
-
end_line: ast_loc.last_line,
|
754
|
-
end_column: ast_loc.last_column,
|
801
|
+
sig { override.params(node: YARP::AssocNode).void }
|
802
|
+
def visit_assoc_node(node)
|
803
|
+
@current.params << SigParam.new(
|
804
|
+
node_string!(node.key).delete_suffix(":"),
|
805
|
+
node_string!(T.must(node.value)),
|
755
806
|
)
|
756
807
|
end
|
757
808
|
end
|