steep 1.2.0 → 1.3.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|