steep 1.2.0 → 1.3.0.pre.1
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/CHANGELOG.md +23 -2
- data/Gemfile.lock +14 -4
- data/Gemfile.steep +2 -2
- data/Gemfile.steep.lock +17 -5
- data/Steepfile +7 -9
- data/lib/steep/annotation_parser.rb +34 -28
- data/lib/steep/ast/annotation.rb +16 -5
- data/lib/steep/ast/node/type_application.rb +74 -0
- data/lib/steep/ast/node/type_assertion.rb +56 -0
- data/lib/steep/ast/types/factory.rb +5 -1
- data/lib/steep/diagnostic/helper.rb +2 -1
- data/lib/steep/diagnostic/lsp_formatter.rb +3 -1
- data/lib/steep/diagnostic/ruby.rb +70 -5
- data/lib/steep/diagnostic/signature.rb +21 -8
- data/lib/steep/drivers/check.rb +1 -1
- data/lib/steep/drivers/checkfile.rb +1 -1
- data/lib/steep/drivers/langserver.rb +2 -2
- data/lib/steep/drivers/stats.rb +1 -1
- data/lib/steep/drivers/watch.rb +1 -1
- data/lib/steep/drivers/worker.rb +0 -1
- data/lib/steep/server/lsp_formatter.rb +13 -3
- data/lib/steep/server/master.rb +4 -1
- data/lib/steep/server/worker_process.rb +86 -14
- data/lib/steep/services/hover_provider/rbs.rb +7 -7
- data/lib/steep/services/hover_provider/ruby.rb +19 -4
- data/lib/steep/services/signature_service.rb +7 -4
- data/lib/steep/signature/validator.rb +36 -13
- data/lib/steep/source.rb +189 -71
- data/lib/steep/type_construction.rb +232 -126
- data/lib/steep/type_inference/logic_type_interpreter.rb +31 -5
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +2 -0
- data/rbs_collection.steep.lock.yaml +52 -11
- data/rbs_collection.steep.yaml +1 -1
- data/sig/shims/exception.rbs +4 -0
- data/sig/shims/parser/comment.rbs +33 -0
- data/sig/shims/parser.rbs +30 -2
- data/sig/steep/annotation_parser.rbs +59 -0
- data/sig/steep/ast/annotation.rbs +21 -26
- data/sig/steep/ast/node/type_application.rbs +31 -0
- data/sig/steep/ast/node/type_assertion.rbs +26 -0
- data/sig/steep/ast/types/factory.rbs +0 -2
- data/sig/steep/diagnostic/helper.rbs +9 -3
- data/sig/steep/diagnostic/lsp_formatter.rbs +12 -8
- data/sig/steep/diagnostic/ruby.rbs +62 -8
- data/sig/steep/diagnostic/signature.rbs +118 -85
- data/sig/steep/drivers/worker.rbs +11 -13
- data/sig/steep/range_extension.rbs +7 -0
- data/sig/steep/server/lsp_formatter.rbs +14 -7
- data/sig/steep/server/worker_process.rbs +74 -12
- data/sig/steep/services/hover_provider/rbs.rbs +27 -7
- data/sig/steep/services/hover_provider/ruby.rbs +18 -4
- data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
- data/sig/steep/signature/validator.rbs +76 -0
- data/sig/steep/source.rbs +54 -30
- data/sig/steep/type_construction.rbs +85 -27
- data/sig/steep/type_inference/method_call.rbs +1 -1
- data/smoke/diagnostics-rbs/inherit-module.rbs +2 -0
- data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
- data/steep.gemspec +6 -1
- metadata +86 -6
@@ -20,7 +20,7 @@ module Steep
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def each_error(&block)
|
23
|
-
if
|
23
|
+
if block
|
24
24
|
@errors.each(&block)
|
25
25
|
else
|
26
26
|
enum_for :each_error
|
@@ -64,6 +64,8 @@ module Steep
|
|
64
64
|
)
|
65
65
|
|
66
66
|
type_params.zip(type_args).each do |param, arg|
|
67
|
+
arg or raise
|
68
|
+
|
67
69
|
if param.upper_bound
|
68
70
|
upper_bound_type = factory.type(param.upper_bound).subst(subst)
|
69
71
|
arg_type = factory.type(arg)
|
@@ -121,7 +123,7 @@ module Steep
|
|
121
123
|
|
122
124
|
if name && type_params && type_args
|
123
125
|
if !type_params.empty? && !type_args.empty?
|
124
|
-
validate_type_application_constraints(
|
126
|
+
validate_type_application_constraints(name, type_params, type_args, location: type.location)
|
125
127
|
end
|
126
128
|
end
|
127
129
|
|
@@ -156,19 +158,21 @@ module Steep
|
|
156
158
|
end
|
157
159
|
|
158
160
|
def mixin_constraints(definition, mixin_ancestors, immediate_self_types:)
|
161
|
+
# @type var relations: Array[[Subtyping::Relation[AST::Types::t], RBS::Definition::Ancestor::Instance]]
|
159
162
|
relations = []
|
160
163
|
|
161
164
|
self_type = checker.factory.type(definition.self_type)
|
162
165
|
if immediate_self_types && !immediate_self_types.empty?
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
)
|
166
|
+
# @type var sts: Array[AST::Types::t]
|
167
|
+
sts = immediate_self_types.map {|st| ancestor_to_type(st) }
|
168
|
+
self_type = AST::Types::Intersection.build(types: sts.push(self_type), location: nil)
|
167
169
|
end
|
168
170
|
|
169
171
|
mixin_ancestors.each do |ancestor|
|
170
172
|
args = ancestor.args.map {|type| checker.factory.type(type) }
|
171
173
|
ancestor_ancestors = builder.ancestor_builder.one_instance_ancestors(ancestor.name)
|
174
|
+
ancestor_ancestors.self_types or raise
|
175
|
+
ancestor_ancestors.params or raise
|
172
176
|
self_constraints = ancestor_ancestors.self_types.map do |self_ancestor|
|
173
177
|
s = Interface::Substitution.build(ancestor_ancestors.params, args)
|
174
178
|
ancestor_to_type(self_ancestor).subst(s)
|
@@ -263,7 +267,7 @@ module Steep
|
|
263
267
|
end
|
264
268
|
|
265
269
|
ancestors = builder.ancestor_builder.one_instance_ancestors(name)
|
266
|
-
mixin_constraints(definition, ancestors.included_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
270
|
+
mixin_constraints(definition, ancestors.included_modules || raise, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
267
271
|
checker.check(
|
268
272
|
relation,
|
269
273
|
self_type: AST::Types::Self.new,
|
@@ -271,6 +275,8 @@ module Steep
|
|
271
275
|
class_type: AST::Types::Class.new,
|
272
276
|
constraints: Subtyping::Constraints.empty
|
273
277
|
).else do
|
278
|
+
raise if ancestor.source.is_a?(Symbol)
|
279
|
+
|
274
280
|
@errors << Diagnostic::Signature::ModuleSelfTypeError.new(
|
275
281
|
name: name,
|
276
282
|
location: ancestor.source&.location || raise,
|
@@ -292,6 +298,14 @@ module Steep
|
|
292
298
|
end
|
293
299
|
|
294
300
|
builder.build_singleton(name).tap do |definition|
|
301
|
+
entry =
|
302
|
+
case definition.entry
|
303
|
+
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
304
|
+
definition.entry
|
305
|
+
else
|
306
|
+
raise
|
307
|
+
end
|
308
|
+
|
295
309
|
definition.instance_variables.each do |name, var|
|
296
310
|
if parent = var.parent_variable
|
297
311
|
var_type = checker.factory.type(var.type)
|
@@ -327,7 +341,7 @@ module Steep
|
|
327
341
|
definition.class_variables.each do |name, var|
|
328
342
|
if var.declared_in == definition.type_name
|
329
343
|
if (parent = var.parent_variable) && var.declared_in != parent.declared_in
|
330
|
-
class_var =
|
344
|
+
class_var = entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
|
331
345
|
member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
|
332
346
|
end
|
333
347
|
|
@@ -336,7 +350,7 @@ module Steep
|
|
336
350
|
class_name: definition.type_name,
|
337
351
|
other_class_name: parent.declared_in,
|
338
352
|
variable_name: name,
|
339
|
-
location: class_var.location[:name
|
353
|
+
location: class_var.location&.[](:name)
|
340
354
|
)
|
341
355
|
end
|
342
356
|
end
|
@@ -344,6 +358,7 @@ module Steep
|
|
344
358
|
end
|
345
359
|
|
346
360
|
ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
|
361
|
+
ancestors.extended_modules or raise
|
347
362
|
mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
348
363
|
checker.check(
|
349
364
|
relation,
|
@@ -352,6 +367,8 @@ module Steep
|
|
352
367
|
class_type: AST::Types::Class.new,
|
353
368
|
constraints: Subtyping::Constraints.empty
|
354
369
|
).else do
|
370
|
+
raise if ancestor.source.is_a?(Symbol)
|
371
|
+
|
355
372
|
@errors << Diagnostic::Signature::ModuleSelfTypeError.new(
|
356
373
|
name: name,
|
357
374
|
location: ancestor.source&.location || raise,
|
@@ -381,19 +398,23 @@ module Steep
|
|
381
398
|
builder.build_instance(ancestor.name)
|
382
399
|
when ancestor.name.interface?
|
383
400
|
builder.build_interface(ancestor.name)
|
401
|
+
else
|
402
|
+
raise
|
384
403
|
end
|
385
404
|
|
386
405
|
location =
|
387
|
-
|
406
|
+
case ancestor.source
|
407
|
+
when :super
|
388
408
|
primary_decl = env.class_decls[name].primary.decl
|
409
|
+
primary_decl.is_a?(RBS::AST::Declarations::Class) or raise
|
389
410
|
if super_class = primary_decl.super_class
|
390
411
|
super_class.location
|
391
412
|
else
|
392
413
|
# Implicit super class (Object): this can be skipped in fact...
|
393
|
-
primary_decl.location
|
414
|
+
primary_decl.location&.aref(:name)
|
394
415
|
end
|
395
416
|
else
|
396
|
-
ancestor.source
|
417
|
+
ancestor.source&.location
|
397
418
|
end
|
398
419
|
|
399
420
|
validate_type_application_constraints(
|
@@ -423,12 +444,14 @@ module Steep
|
|
423
444
|
case ancestor
|
424
445
|
when RBS::Definition::Ancestor::Instance
|
425
446
|
# Interface ancestor cannot be other than Interface
|
447
|
+
ancestor.source.is_a?(Symbol) and raise
|
448
|
+
|
426
449
|
defn = builder.build_interface(ancestor.name)
|
427
450
|
validate_type_application_constraints(
|
428
451
|
ancestor.name,
|
429
452
|
defn.type_params_decl,
|
430
453
|
ancestor.args,
|
431
|
-
location: ancestor.source
|
454
|
+
location: ancestor.source&.location || raise
|
432
455
|
)
|
433
456
|
end
|
434
457
|
end
|
data/lib/steep/source.rb
CHANGED
@@ -1,27 +1,11 @@
|
|
1
1
|
module Steep
|
2
2
|
class Source
|
3
|
-
class LocatedAnnotation
|
4
|
-
attr_reader :line
|
5
|
-
attr_reader :annotation
|
6
|
-
attr_reader :source
|
7
|
-
|
8
|
-
def initialize(line:, source:, annotation:)
|
9
|
-
@line = line
|
10
|
-
@source = source
|
11
|
-
@annotation = annotation
|
12
|
-
end
|
13
|
-
|
14
|
-
def ==(other)
|
15
|
-
other.is_a?(LocatedAnnotation) &&
|
16
|
-
other.line == line &&
|
17
|
-
other.annotation == annotation
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
3
|
attr_reader :path
|
22
4
|
attr_reader :node
|
23
5
|
attr_reader :mapping
|
24
6
|
|
7
|
+
extend NodeHelper
|
8
|
+
|
25
9
|
def initialize(path:, node:, mapping:)
|
26
10
|
@path = path
|
27
11
|
@node = node
|
@@ -47,46 +31,61 @@ module Steep
|
|
47
31
|
|
48
32
|
def self.parse(source_code, path:, factory:)
|
49
33
|
buffer = ::Parser::Source::Buffer.new(path.to_s, 1, source: source_code)
|
50
|
-
node = new_parser().
|
34
|
+
node, comments = new_parser().parse_with_comments(buffer)
|
51
35
|
|
36
|
+
# @type var annotations: Array[AST::Annotation::t]
|
52
37
|
annotations = []
|
53
|
-
|
54
|
-
|
55
|
-
buffer = ::Parser::Source::Buffer.new(path.to_s, 1, source: source_code)
|
56
|
-
new_parser().tokenize(buffer)
|
57
|
-
end
|
38
|
+
# @type var type_comments: Hash[Integer, type_comment]
|
39
|
+
type_comments = {}
|
58
40
|
|
59
41
|
buffer = RBS::Buffer.new(name: path, content: source_code)
|
42
|
+
annotation_parser = AnnotationParser.new(factory: factory)
|
60
43
|
|
61
44
|
comments.each do |comment|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
45
|
+
if comment.inline?
|
46
|
+
content = comment.text.delete_prefix('#')
|
47
|
+
content.lstrip!
|
48
|
+
prefix = comment.text.size - content.size
|
49
|
+
content.rstrip!
|
50
|
+
suffix = comment.text.size - content.size - prefix
|
51
|
+
|
52
|
+
location = RBS::Location.new(
|
53
|
+
buffer: buffer,
|
54
|
+
start_pos: comment.location.expression.begin_pos + prefix,
|
55
|
+
end_pos: comment.location.expression.end_pos - suffix
|
56
|
+
)
|
57
|
+
|
58
|
+
case
|
59
|
+
when annotation = annotation_parser.parse(content, location: location)
|
60
|
+
annotations << annotation
|
61
|
+
when assertion = AST::Node::TypeAssertion.parse(location)
|
62
|
+
type_comments[assertion.line] = assertion
|
63
|
+
when tapp = AST::Node::TypeApplication.parse(location)
|
64
|
+
type_comments[tapp.line] = tapp
|
65
|
+
end
|
69
66
|
end
|
70
67
|
end
|
71
68
|
|
72
|
-
|
69
|
+
map = {}
|
70
|
+
map.compare_by_identity
|
73
71
|
|
74
72
|
if node
|
75
|
-
|
73
|
+
node = insert_type_node(node, type_comments)
|
74
|
+
construct_mapping(node: node, annotations: annotations, mapping: map)
|
76
75
|
end
|
77
76
|
|
78
77
|
annotations.each do |annot|
|
79
|
-
|
80
|
-
|
78
|
+
map[node] ||= []
|
79
|
+
map[node] << annot
|
81
80
|
end
|
82
81
|
|
83
|
-
new(path: path, node: node, mapping:
|
82
|
+
new(path: path, node: node, mapping: map)
|
84
83
|
end
|
85
84
|
|
86
85
|
def self.construct_mapping(node:, annotations:, mapping:, line_range: nil)
|
87
86
|
case node.type
|
88
87
|
when :if
|
89
|
-
if node.loc.
|
88
|
+
if node.loc.respond_to?(:question)
|
90
89
|
# Skip ternary operator
|
91
90
|
each_child_node node do |child|
|
92
91
|
construct_mapping(node: child, annotations: annotations, mapping: mapping, line_range: nil)
|
@@ -200,7 +199,7 @@ module Steep
|
|
200
199
|
last_cond = node.children[-2]
|
201
200
|
body = node.children.last
|
202
201
|
|
203
|
-
node.children.take(node.children.size-1) do |child|
|
202
|
+
node.children.take(node.children.size-1).each do |child|
|
204
203
|
construct_mapping(node: child, annotations: annotations, mapping: mapping, line_range: nil)
|
205
204
|
end
|
206
205
|
|
@@ -235,7 +234,7 @@ module Steep
|
|
235
234
|
end
|
236
235
|
end
|
237
236
|
|
238
|
-
associated_annotations = annotations.
|
237
|
+
associated_annotations, other_annotations = annotations.partition do |annot|
|
239
238
|
case node.type
|
240
239
|
when :def, :module, :class, :block, :ensure, :defs
|
241
240
|
loc = node.loc
|
@@ -257,33 +256,34 @@ module Steep
|
|
257
256
|
associated_annotations.each do |annot|
|
258
257
|
mapping[node] ||= []
|
259
258
|
mapping[node] << annot
|
260
|
-
annotations.delete annot
|
261
259
|
end
|
262
|
-
end
|
263
260
|
|
264
|
-
|
265
|
-
node.children.each do |child|
|
266
|
-
if child.is_a?(::AST::Node)
|
267
|
-
yield child
|
268
|
-
end
|
269
|
-
end
|
261
|
+
annotations.replace(other_annotations)
|
270
262
|
end
|
271
263
|
|
272
|
-
def self.
|
264
|
+
def self.map_child_node(node, type = nil, skip: nil)
|
273
265
|
children = node.children.map do |child|
|
274
|
-
if child.is_a?(::AST::Node)
|
275
|
-
|
266
|
+
if child.is_a?(Parser::AST::Node)
|
267
|
+
if skip
|
268
|
+
if skip.member?(child)
|
269
|
+
child
|
270
|
+
else
|
271
|
+
yield child
|
272
|
+
end
|
273
|
+
else
|
274
|
+
yield child
|
275
|
+
end
|
276
276
|
else
|
277
277
|
child
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
-
node.updated(
|
281
|
+
node.updated(type, children)
|
282
282
|
end
|
283
283
|
|
284
284
|
def annotations(block:, factory:, context:)
|
285
285
|
AST::Annotation::Collection.new(
|
286
|
-
annotations: (mapping[block] || [])
|
286
|
+
annotations: (mapping[block] || []),
|
287
287
|
factory: factory,
|
288
288
|
context: context
|
289
289
|
)
|
@@ -292,7 +292,7 @@ module Steep
|
|
292
292
|
def each_annotation(&block)
|
293
293
|
if block_given?
|
294
294
|
mapping.each do |node, annots|
|
295
|
-
yield node, annots
|
295
|
+
yield [node, annots]
|
296
296
|
end
|
297
297
|
else
|
298
298
|
enum_for :each_annotation
|
@@ -301,9 +301,11 @@ module Steep
|
|
301
301
|
|
302
302
|
def each_heredoc_node(node = self.node, parents = [], &block)
|
303
303
|
if block
|
304
|
+
return unless node
|
305
|
+
|
304
306
|
case node.type
|
305
307
|
when :dstr, :str
|
306
|
-
if node.location.
|
308
|
+
if node.location.respond_to?(:heredoc_body)
|
307
309
|
yield [node, *parents]
|
308
310
|
end
|
309
311
|
end
|
@@ -344,7 +346,9 @@ module Steep
|
|
344
346
|
parents.unshift node
|
345
347
|
|
346
348
|
Source.each_child_node(node) do |child|
|
347
|
-
ns = find_nodes_loc(child, position, parents)
|
349
|
+
if ns = find_nodes_loc(child, position, parents)
|
350
|
+
return ns
|
351
|
+
end
|
348
352
|
end
|
349
353
|
|
350
354
|
parents
|
@@ -359,12 +363,14 @@ module Steep
|
|
359
363
|
node.location.expression.source_buffer.source_line(i+1).size + 1
|
360
364
|
end + column
|
361
365
|
|
362
|
-
if
|
363
|
-
Source.each_child_node(
|
364
|
-
find_nodes_loc(child, position,
|
366
|
+
if heredoc_nodes = find_heredoc_nodes(line, column, position)
|
367
|
+
Source.each_child_node(heredoc_nodes[0]) do |child|
|
368
|
+
if nodes = find_nodes_loc(child, position, heredoc_nodes)
|
369
|
+
return nodes
|
370
|
+
end
|
365
371
|
end
|
366
372
|
|
367
|
-
|
373
|
+
return heredoc_nodes
|
368
374
|
else
|
369
375
|
find_nodes_loc(node, position, [])
|
370
376
|
end
|
@@ -385,7 +391,7 @@ module Steep
|
|
385
391
|
delete_defs(node.children[0], allow_list)
|
386
392
|
end
|
387
393
|
else
|
388
|
-
|
394
|
+
map_child_node(node) do |child|
|
389
395
|
delete_defs(child, allow_list)
|
390
396
|
end
|
391
397
|
end
|
@@ -398,7 +404,9 @@ module Steep
|
|
398
404
|
|
399
405
|
node_ = Source.delete_defs(node, defs)
|
400
406
|
|
401
|
-
mapping
|
407
|
+
# @type var mapping: Hash[Parser::AST::Node, Array[AST::Annotation::t]]
|
408
|
+
mapping = {}
|
409
|
+
mapping.compare_by_identity
|
402
410
|
|
403
411
|
annotations = self.mapping.values.flatten
|
404
412
|
Source.construct_mapping(node: node_, annotations: annotations, mapping: mapping)
|
@@ -414,19 +422,129 @@ module Steep
|
|
414
422
|
end
|
415
423
|
end
|
416
424
|
|
417
|
-
def
|
418
|
-
|
419
|
-
|
420
|
-
node.
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
425
|
+
def self.insert_type_node(node, comments)
|
426
|
+
if node.location.expression
|
427
|
+
first_line = node.location.expression.first_line
|
428
|
+
last_line = node.location.expression.last_line
|
429
|
+
last_comment = comments[last_line]
|
430
|
+
|
431
|
+
if (first_line..last_line).none? {|l| comments.key?(l) }
|
432
|
+
return node
|
433
|
+
end
|
434
|
+
|
435
|
+
case
|
436
|
+
when last_comment.is_a?(AST::Node::TypeAssertion)
|
437
|
+
case node.type
|
438
|
+
when :lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn
|
439
|
+
# Skip
|
440
|
+
when :masgn
|
441
|
+
lhs, rhs = node.children
|
442
|
+
node = node.updated(nil, [lhs, insert_type_node(rhs, comments)])
|
443
|
+
return adjust_location(node)
|
444
|
+
when :return, :break, :next
|
445
|
+
# Skip
|
446
|
+
when :begin
|
447
|
+
if node.loc.begin
|
448
|
+
# paren
|
449
|
+
child_assertions = comments.except(last_line)
|
450
|
+
node = map_child_node(node) {|child| insert_type_node(child, child_assertions) }
|
451
|
+
node = adjust_location(node)
|
452
|
+
return assertion_node(node, last_comment)
|
453
|
+
end
|
454
|
+
else
|
455
|
+
child_assertions = comments.except(last_line)
|
456
|
+
node = map_child_node(node) {|child| insert_type_node(child, child_assertions) }
|
457
|
+
node = adjust_location(node)
|
458
|
+
return assertion_node(node, last_comment)
|
459
|
+
end
|
460
|
+
when selector_line = sendish_node?(node)
|
461
|
+
if (comment = comments[selector_line]).is_a?(AST::Node::TypeApplication)
|
462
|
+
child_assertions = comments.except(selector_line)
|
463
|
+
case node.type
|
464
|
+
when :block
|
465
|
+
send, *children = node.children
|
466
|
+
node = node.updated(
|
467
|
+
nil,
|
468
|
+
[
|
469
|
+
map_child_node(send) {|child| insert_type_node(child, child_assertions) },
|
470
|
+
*children.map {|child| insert_type_node(child, child_assertions) }
|
471
|
+
]
|
472
|
+
)
|
473
|
+
when :numblock
|
474
|
+
send, size, body = node.children
|
475
|
+
node = node.updated(
|
476
|
+
nil,
|
477
|
+
[
|
478
|
+
map_child_node(send) {|child| insert_type_node(child, child_assertions) },
|
479
|
+
size,
|
480
|
+
insert_type_node(body, child_assertions)
|
481
|
+
]
|
482
|
+
)
|
483
|
+
else
|
484
|
+
node = map_child_node(node) {|child| insert_type_node(child, child_assertions) }
|
485
|
+
end
|
486
|
+
node = adjust_location(node)
|
487
|
+
return type_application_node(node, comment)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
adjust_location(
|
493
|
+
map_child_node(node, nil) {|child| insert_type_node(child, comments) }
|
494
|
+
)
|
495
|
+
end
|
496
|
+
|
497
|
+
def self.sendish_node?(node)
|
498
|
+
send_node =
|
499
|
+
case node.type
|
500
|
+
when :send, :csend
|
501
|
+
node
|
502
|
+
when :block, :numblock
|
503
|
+
send = node.children[0]
|
504
|
+
case send.type
|
505
|
+
when :send, :csend
|
506
|
+
send
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
if send_node
|
511
|
+
if send_node.location.dot
|
512
|
+
send_node.location.selector.line
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def self.adjust_location(node)
|
518
|
+
if end_pos = node.location.expression&.end_pos
|
519
|
+
if last_pos = each_child_node(node).map {|node| node.location.expression&.end_pos }.compact.max
|
520
|
+
if last_pos > end_pos
|
521
|
+
props = { location: node.location.with_expression(node.location.expression.with(end_pos: last_pos)) }
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
if props
|
527
|
+
node.updated(nil, nil, props)
|
427
528
|
else
|
428
529
|
node
|
429
530
|
end
|
430
531
|
end
|
532
|
+
|
533
|
+
def self.assertion_node(node, type)
|
534
|
+
map = Parser::Source::Map.new(node.location.expression.with(end_pos: type.location.end_pos))
|
535
|
+
Parser::AST::Node.new(:assertion, [node, type], { location: map })
|
536
|
+
end
|
537
|
+
|
538
|
+
def self.type_application_node(node, tapp)
|
539
|
+
if node.location.expression.end_pos > tapp.location.end_pos
|
540
|
+
map = Parser::Source::Map.new(node.location.expression)
|
541
|
+
else
|
542
|
+
map = Parser::Source::Map.new(node.location.expression.with(end_pos: tapp.location.end_pos))
|
543
|
+
end
|
544
|
+
|
545
|
+
node = Parser::AST::Node.new(:tapp, [node, tapp], { location: map })
|
546
|
+
tapp.set_node(node)
|
547
|
+
node
|
548
|
+
end
|
431
549
|
end
|
432
550
|
end
|