steep 0.4.0 → 0.5.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/CHANGELOG.md +12 -0
- data/LICENSE +21 -0
- data/bin/smoke_runner.rb +3 -0
- data/lib/steep/ast/annotation/collection.rb +120 -43
- data/lib/steep/ast/annotation.rb +5 -10
- data/lib/steep/ast/location.rb +1 -1
- data/lib/steep/ast/method_type.rb +3 -1
- data/lib/steep/ast/signature/alias.rb +19 -0
- data/lib/steep/ast/signature/env.rb +9 -0
- data/lib/steep/ast/signature/members.rb +4 -0
- data/lib/steep/ast/types/proc.rb +79 -0
- data/lib/steep/ast/types/void.rb +4 -0
- data/lib/steep/cli.rb +2 -1
- data/lib/steep/drivers/check.rb +4 -1
- data/lib/steep/errors.rb +13 -0
- data/lib/steep/interface/builder.rb +90 -47
- data/lib/steep/interface/instantiated.rb +1 -1
- data/lib/steep/interface/method.rb +8 -0
- data/lib/steep/interface/method_type.rb +40 -13
- data/lib/steep/parser.rb +1098 -1043
- data/lib/steep/parser.y +94 -36
- data/lib/steep/source.rb +5 -6
- data/lib/steep/subtyping/check.rb +162 -47
- data/lib/steep/subtyping/variable_occurrence.rb +2 -2
- data/lib/steep/subtyping/variable_variance.rb +3 -3
- data/lib/steep/type_construction.rb +630 -300
- data/lib/steep/type_inference/block_params.rb +186 -35
- data/lib/steep/type_inference/send_args.rb +12 -3
- data/lib/steep/type_inference/type_env.rb +10 -4
- data/lib/steep/type_name.rb +6 -0
- data/lib/steep/typing.rb +21 -2
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +2 -0
- data/smoke/alias/a.rb +19 -0
- data/smoke/alias/a.rbi +10 -0
- data/smoke/alias/b.rb +7 -0
- data/smoke/alias/c.rb +10 -0
- data/smoke/array/c.rb +7 -0
- data/smoke/block/c.rb +10 -0
- data/smoke/block/c.rbi +3 -0
- data/smoke/block/d.rb +15 -0
- data/smoke/class/c.rb +1 -1
- data/smoke/class/e.rb +1 -1
- data/smoke/class/h.rb +15 -0
- data/smoke/class/h.rbi +7 -0
- data/smoke/class/i.rb +17 -0
- data/smoke/class/i.rbi +9 -0
- data/smoke/extension/a.rbi +4 -0
- data/smoke/extension/d.rb +2 -0
- data/smoke/hash/a.rb +17 -0
- data/smoke/hash/b.rb +7 -0
- data/smoke/implements/a.rb +2 -2
- data/smoke/initialize/a.rb +1 -1
- data/smoke/lambda/a.rb +11 -0
- data/smoke/literal/b.rb +9 -0
- data/smoke/literal/literal_methods.rbi +4 -0
- data/smoke/method/c.rb +5 -0
- data/smoke/regression/array.rb +7 -0
- data/smoke/regression/hash.rb +7 -0
- data/smoke/regression/set_divide.rb +16 -0
- data/smoke/self/a.rb +2 -2
- data/stdlib/builtin.rbi +151 -1
- data/steep.gemspec +1 -0
- metadata +30 -4
data/lib/steep/parser.y
CHANGED
@@ -92,17 +92,22 @@ optional_keyword: QUESTION keyword COLON type { result = [val[0].location + val[
|
|
92
92
|
val[3]] }
|
93
93
|
|
94
94
|
block_opt: { result = nil }
|
95
|
-
| LBRACE RBRACE {
|
95
|
+
| block_optional LBRACE RBRACE {
|
96
96
|
result = AST::MethodType::Block.new(params: nil,
|
97
97
|
return_type: nil,
|
98
|
-
location: val[0].location + val[
|
98
|
+
location: (val[0] || val[1]).location + val[2].location,
|
99
|
+
optional: val[0]&.value || false)
|
99
100
|
}
|
100
|
-
| LBRACE block_params ARROW type RBRACE {
|
101
|
-
result = AST::MethodType::Block.new(params: val[
|
102
|
-
return_type: val[
|
103
|
-
location: val[0].location + val[
|
101
|
+
| block_optional LBRACE block_params ARROW type RBRACE {
|
102
|
+
result = AST::MethodType::Block.new(params: val[2],
|
103
|
+
return_type: val[4],
|
104
|
+
location: (val[0] || val[1]).location + val[5].location,
|
105
|
+
optional: val[0]&.value || false)
|
104
106
|
}
|
105
107
|
|
108
|
+
block_optional: { result = nil }
|
109
|
+
| QUESTION { result = LocatedValue.new(location: val[0].location, value: true) }
|
110
|
+
|
106
111
|
block_params: { result = nil }
|
107
112
|
| LPAREN block_params0 RPAREN {
|
108
113
|
result = val[1]
|
@@ -139,7 +144,7 @@ block_params2: { result = nil }
|
|
139
144
|
simple_type: type_name {
|
140
145
|
result = AST::Types::Name.new(name: val[0].value, location: val[0].location, args: [])
|
141
146
|
}
|
142
|
-
|
|
147
|
+
| application_type_name LT type_seq GT {
|
143
148
|
loc = val[0].location + val[3].location
|
144
149
|
name = val[0].value
|
145
150
|
args = val[2]
|
@@ -175,16 +180,20 @@ simple_type: type_name {
|
|
175
180
|
paren_type: LPAREN type RPAREN { result = val[1].with_location(val[0].location + val[2].location) }
|
176
181
|
| simple_type
|
177
182
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
183
|
+
application_type_name: module_name {
|
184
|
+
result = LocatedValue.new(value: TypeName::Instance.new(name: val[0].value),
|
185
|
+
location: val[0].location)
|
186
|
+
}
|
187
|
+
| INTERFACE_NAME {
|
188
|
+
result = LocatedValue.new(value: TypeName::Interface.new(name: val[0].value),
|
189
|
+
location: val[0].location)
|
190
|
+
}
|
191
|
+
| LIDENT {
|
192
|
+
result = LocatedValue.new(value: TypeName::Alias.new(name: val[0].value),
|
193
|
+
location: val[0].location)
|
194
|
+
}
|
195
|
+
|
196
|
+
type_name: application_type_name
|
188
197
|
| module_name DOT CLASS constructor {
|
189
198
|
loc = val[0].location + (val[3] || val[2]).location
|
190
199
|
result = LocatedValue.new(value: TypeName::Class.new(name: val[0].value, constructor: val[3]&.value),
|
@@ -197,14 +206,30 @@ type_name: instance_type_name
|
|
197
206
|
}
|
198
207
|
|
199
208
|
constructor: { result = nil }
|
200
|
-
| CONSTRUCTOR
|
201
|
-
| NOCONSTRUCTOR
|
209
|
+
| CONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: true) }
|
210
|
+
| NOCONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: false) }
|
202
211
|
|
203
212
|
type: paren_type
|
204
213
|
| union_seq {
|
205
214
|
loc = val[0].first.location + val[0].last.location
|
206
215
|
result = AST::Types::Union.build(types: val[0], location: loc)
|
207
216
|
}
|
217
|
+
| HAT LPAREN lambda_params RPAREN ARROW paren_type {
|
218
|
+
loc = val[0].location + val[5].location
|
219
|
+
result = AST::Types::Proc.new(params: val[2], return_type: val[5], location: loc)
|
220
|
+
}
|
221
|
+
|
222
|
+
lambda_params: lambda_params1
|
223
|
+
| paren_type { result = Interface::Params.empty.update(required: [val[0]]) }
|
224
|
+
| paren_type COMMA lambda_params {
|
225
|
+
result = val[2].update(required: [val[0]] + val[2].required)
|
226
|
+
}
|
227
|
+
|
228
|
+
lambda_params1: { result = Interface::Params.empty }
|
229
|
+
| STAR paren_type { result = Interface::Params.empty.update(rest: val[1]) }
|
230
|
+
| QUESTION paren_type { result = Interface::Params.empty.update(optional: [val[1]]) }
|
231
|
+
| QUESTION paren_type COMMA lambda_params1 { result = val[3].update(optional: [val[1]] + val[3].optional) }
|
232
|
+
|
208
233
|
|
209
234
|
type_seq: type { result = [val[0]] }
|
210
235
|
| type COMMA type_seq { result = [val[0]] + val[2] }
|
@@ -212,7 +237,7 @@ type_seq: type { result = [val[0]] }
|
|
212
237
|
union_seq: simple_type BAR simple_type { result = [val[0], val[2]] }
|
213
238
|
| simple_type BAR union_seq { result = [val[0]] + val[2] }
|
214
239
|
|
215
|
-
keyword:
|
240
|
+
keyword: LIDENT
|
216
241
|
| MODULE_NAME
|
217
242
|
| INTERFACE_NAME
|
218
243
|
| ANY
|
@@ -223,6 +248,7 @@ keyword: IDENT
|
|
223
248
|
| INCLUDE
|
224
249
|
| IVAR
|
225
250
|
| SELF
|
251
|
+
| TYPE
|
226
252
|
|
227
253
|
signatures: { result = [] }
|
228
254
|
| interface signatures { result = [val[0]] + val[1] }
|
@@ -231,6 +257,7 @@ signatures: { result = [] }
|
|
231
257
|
| extension_decl signatures { result = [val[0]] + val[1] }
|
232
258
|
| const_decl signatures { result = [val[0]] + val[1] }
|
233
259
|
| gvar_decl signatures { result = [val[0]] + val[1] }
|
260
|
+
| alias_decl signatures { result = [val[0]] + val[1] }
|
234
261
|
|
235
262
|
gvar_decl: GVAR COLON type {
|
236
263
|
loc = val.first.location + val.last.location
|
@@ -285,6 +312,14 @@ extension_decl: EXTENSION module_name type_params LPAREN UIDENT RPAREN class_mem
|
|
285
312
|
members: val[6])
|
286
313
|
}
|
287
314
|
|
315
|
+
alias_decl: TYPE LIDENT type_params EQ type {
|
316
|
+
loc = val[0].location + val[4].location
|
317
|
+
result = AST::Signature::Alias.new(location: loc,
|
318
|
+
name: val[1].value,
|
319
|
+
params: val[2],
|
320
|
+
type: val[4])
|
321
|
+
}
|
322
|
+
|
288
323
|
self_type_opt: { result = nil }
|
289
324
|
| COLON type { result = val[1] }
|
290
325
|
|
@@ -326,34 +361,34 @@ ivar_member: IVAR_NAME COLON type {
|
|
326
361
|
)
|
327
362
|
}
|
328
363
|
|
329
|
-
instance_method_member: DEF
|
364
|
+
instance_method_member: DEF method_annotations method_name COLON method_type_union {
|
330
365
|
loc = val.first.location + val.last.last.location
|
331
366
|
result = AST::Signature::Members::Method.new(
|
332
367
|
name: val[2].value,
|
333
368
|
types: val[4],
|
334
369
|
kind: :instance,
|
335
370
|
location: loc,
|
336
|
-
attributes:
|
371
|
+
attributes: val[1] || []
|
337
372
|
)
|
338
373
|
}
|
339
|
-
module_method_member: DEF
|
374
|
+
module_method_member: DEF method_annotations SELF DOT method_name COLON method_type_union {
|
340
375
|
loc = val.first.location + val.last.last.location
|
341
376
|
result = AST::Signature::Members::Method.new(
|
342
377
|
name: val[4].value,
|
343
378
|
types: val[6],
|
344
379
|
kind: :module,
|
345
380
|
location: loc,
|
346
|
-
attributes:
|
381
|
+
attributes: val[1] || []
|
347
382
|
)
|
348
383
|
}
|
349
|
-
module_instance_method_member: DEF
|
384
|
+
module_instance_method_member: DEF method_annotations SELFQ DOT method_name COLON method_type_union {
|
350
385
|
loc = val.first.location + val.last.last.location
|
351
386
|
result = AST::Signature::Members::Method.new(
|
352
387
|
name: val[4].value,
|
353
388
|
types: val[6],
|
354
389
|
kind: :module_instance,
|
355
390
|
location: loc,
|
356
|
-
attributes:
|
391
|
+
attributes: val[1] || []
|
357
392
|
)
|
358
393
|
}
|
359
394
|
include_member: INCLUDE module_name {
|
@@ -389,8 +424,14 @@ attr_ivar_opt: { result = nil }
|
|
389
424
|
| LPAREN RPAREN { result = false }
|
390
425
|
| LPAREN IVAR_NAME RPAREN { result = val[1].value }
|
391
426
|
|
392
|
-
|
393
|
-
| LPAREN
|
427
|
+
method_annotations: { result = nil }
|
428
|
+
| LPAREN method_annotation_seq RPAREN { result = val[1] }
|
429
|
+
|
430
|
+
method_annotation_seq: method_annotation_keyword { result = [val[0]] }
|
431
|
+
| method_annotation_keyword COMMA method_annotation_seq { result = [val[0]] + val[2] }
|
432
|
+
|
433
|
+
method_annotation_keyword: CONSTRUCTOR { result = val[0].value }
|
434
|
+
| INCOMPATIBLE { result = val[0].value }
|
394
435
|
|
395
436
|
super_opt: { result = nil }
|
396
437
|
| LTCOLON super_class { result = val[1] }
|
@@ -428,6 +469,7 @@ method_name: method_name0
|
|
428
469
|
| STAR | STAR2
|
429
470
|
| PERCENT | MINUS
|
430
471
|
| LT | GT
|
472
|
+
| UMINUS
|
431
473
|
| BAR { result = LocatedValue.new(location: val[0].location, value: :|) }
|
432
474
|
| method_name0 EQ {
|
433
475
|
raise ParseError, "\nunexpected method name #{val[0].to_s} =" unless val[0].location.pred?(val[1].location)
|
@@ -448,8 +490,13 @@ method_name: method_name0
|
|
448
490
|
raise ParseError, "\nunexpected method name > >" unless val[0].location.pred?(val[1].location)
|
449
491
|
result = LocatedValue.new(location: val[0].location + val[1].location, value: :>>)
|
450
492
|
}
|
493
|
+
| NIL QUESTION {
|
494
|
+
raise ParseError, "\nunexpected method name #{val[0].to_s} ?" unless val[0].location.pred?(val[1].location)
|
495
|
+
result = LocatedValue.new(location: val[0].location + val[1].location,
|
496
|
+
value: :"nil?")
|
497
|
+
}
|
451
498
|
|
452
|
-
method_name0:
|
499
|
+
method_name0: LIDENT
|
453
500
|
| UIDENT
|
454
501
|
| MODULE_NAME
|
455
502
|
| INTERFACE_NAME
|
@@ -463,15 +510,18 @@ method_name0: IDENT
|
|
463
510
|
| EXTEND
|
464
511
|
| INCLUDE
|
465
512
|
| OPERATOR
|
513
|
+
| HAT
|
466
514
|
| BANG
|
467
515
|
| BLOCK
|
468
516
|
| BREAK
|
469
517
|
| METHOD
|
470
518
|
| BOOL
|
519
|
+
| TYPE
|
471
520
|
| CONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :constructor) }
|
472
521
|
| NOCONSTRUCTOR { result = LocatedValue.new(location: val[0].location, value: :noconstructor) }
|
473
522
|
| ATTR_READER
|
474
523
|
| ATTR_ACCESSOR
|
524
|
+
| INCOMPATIBLE
|
475
525
|
|
476
526
|
annotation: AT_TYPE VAR subject COLON type {
|
477
527
|
loc = val.first.location + val.last.location
|
@@ -545,7 +595,7 @@ dynamic_name: method_name {
|
|
545
595
|
result = AST::Annotation::Dynamic::Name.new(name: val[2].value, location: loc, kind: :module_instance)
|
546
596
|
}
|
547
597
|
|
548
|
-
subject:
|
598
|
+
subject: LIDENT { result = val[0] }
|
549
599
|
|
550
600
|
end
|
551
601
|
|
@@ -624,7 +674,7 @@ def next_token
|
|
624
674
|
when input.scan(/\?/)
|
625
675
|
new_token(:QUESTION)
|
626
676
|
when input.scan(/!/)
|
627
|
-
new_token(:BANG)
|
677
|
+
new_token(:BANG, :!)
|
628
678
|
when input.scan(/\(/)
|
629
679
|
new_token(:LPAREN, nil)
|
630
680
|
when input.scan(/\)/)
|
@@ -651,7 +701,9 @@ def next_token
|
|
651
701
|
new_token(:DOT)
|
652
702
|
when input.scan(/<:/)
|
653
703
|
new_token(:LTCOLON)
|
654
|
-
when input.scan(
|
704
|
+
when input.scan(/\^/)
|
705
|
+
new_token(:HAT, :"^")
|
706
|
+
when input.scan(/(\[\]=)|(\[\])|===|==|!=|<<|=~/)
|
655
707
|
new_token(:OPERATOR, input.matched.to_sym)
|
656
708
|
when input.scan(/\[/)
|
657
709
|
new_token(:LBRACKET, nil)
|
@@ -675,12 +727,18 @@ def next_token
|
|
675
727
|
new_token(:ANY, :any)
|
676
728
|
when input.scan(/void\b/)
|
677
729
|
new_token(:VOID, :void)
|
730
|
+
when input.scan(/type\b/)
|
731
|
+
new_token(:TYPE, :type)
|
678
732
|
when input.scan(/interface\b/)
|
679
733
|
new_token(:INTERFACE, :interface)
|
734
|
+
when input.scan(/incompatible\b/)
|
735
|
+
new_token(:INCOMPATIBLE, :incompatible)
|
680
736
|
when input.scan(/end\b/)
|
681
737
|
new_token(:END, :end)
|
682
738
|
when input.scan(/\|/)
|
683
739
|
new_token(:BAR, :bar)
|
740
|
+
when input.scan(/-@/)
|
741
|
+
new_token(:UMINUS, :"-@")
|
684
742
|
when input.scan(/def\b/)
|
685
743
|
new_token(:DEF)
|
686
744
|
when input.scan(/@type\b/)
|
@@ -738,9 +796,9 @@ def next_token
|
|
738
796
|
when input.scan(/extension\b/)
|
739
797
|
new_token(:EXTENSION, :extension)
|
740
798
|
when input.scan(/constructor\b/)
|
741
|
-
new_token(:CONSTRUCTOR,
|
799
|
+
new_token(:CONSTRUCTOR, :constructor)
|
742
800
|
when input.scan(/noconstructor\b/)
|
743
|
-
new_token(:NOCONSTRUCTOR,
|
801
|
+
new_token(:NOCONSTRUCTOR, :noconstructor)
|
744
802
|
when input.scan(/\$\w+\b/)
|
745
803
|
new_token(:GVAR, input.matched.to_sym)
|
746
804
|
when input.scan(/[A-Z]\w*/)
|
@@ -753,7 +811,7 @@ def next_token
|
|
753
811
|
new_token(:INT, input.matched.to_i)
|
754
812
|
when input.scan(/\"[^\"]*\"/)
|
755
813
|
new_token(:STRING, input.matched[1...-1])
|
756
|
-
when input.scan(
|
757
|
-
new_token(:
|
814
|
+
when input.scan(/[a-z]\w*/)
|
815
|
+
new_token(:LIDENT, input.matched.to_sym)
|
758
816
|
end
|
759
817
|
end
|
data/lib/steep/source.rb
CHANGED
@@ -33,9 +33,8 @@ module Steep
|
|
33
33
|
value(token)
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
36
|
+
self.emit_lambda = true
|
37
|
+
self.emit_procarg0 = true
|
39
38
|
end
|
40
39
|
|
41
40
|
def self.parser
|
@@ -243,7 +242,7 @@ module Steep
|
|
243
242
|
|
244
243
|
associated_annotations = annotations.select do |annot|
|
245
244
|
case node.type
|
246
|
-
when :def, :module, :class, :block, :ensure
|
245
|
+
when :def, :module, :class, :block, :ensure, :defs
|
247
246
|
loc = node.loc
|
248
247
|
loc.line <= annot.line && annot.line < loc.last_line
|
249
248
|
|
@@ -275,8 +274,8 @@ module Steep
|
|
275
274
|
end
|
276
275
|
end
|
277
276
|
|
278
|
-
def annotations(block:)
|
279
|
-
AST::Annotation::Collection.new(annotations: mapping[block.__id__] || [])
|
277
|
+
def annotations(block:, builder:, current_module:)
|
278
|
+
AST::Annotation::Collection.new(annotations: mapping[block.__id__] || [], builder: builder, current_module: current_module)
|
280
279
|
end
|
281
280
|
|
282
281
|
def each_annotation
|
@@ -39,6 +39,10 @@ module Steep
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def alias?(type)
|
43
|
+
type.is_a?(AST::Types::Name) && type.name.is_a?(TypeName::Alias)
|
44
|
+
end
|
45
|
+
|
42
46
|
def cacheable?(relation)
|
43
47
|
relation.sub_type.free_variables.empty? && relation.super_type.free_variables.empty?
|
44
48
|
end
|
@@ -59,29 +63,33 @@ module Steep
|
|
59
63
|
when relation.sub_type.is_a?(AST::Types::Any) || relation.super_type.is_a?(AST::Types::Any)
|
60
64
|
success(constraints: constraints)
|
61
65
|
|
66
|
+
when relation.super_type.is_a?(AST::Types::Void)
|
67
|
+
success(constraints: constraints)
|
68
|
+
|
62
69
|
when relation.super_type.is_a?(AST::Types::Top)
|
63
70
|
success(constraints: constraints)
|
64
71
|
|
65
72
|
when relation.sub_type.is_a?(AST::Types::Bot)
|
66
73
|
success(constraints: constraints)
|
67
74
|
|
68
|
-
when relation.super_type.is_a?(AST::Types::
|
69
|
-
|
70
|
-
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
71
|
-
success(constraints: constraints)
|
72
|
-
else
|
73
|
-
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
74
|
-
trace: trace)
|
75
|
-
end
|
75
|
+
when relation.super_type.is_a?(AST::Types::Boolean)
|
76
|
+
success(constraints: constraints)
|
76
77
|
|
77
|
-
when relation.sub_type.is_a?(AST::Types::
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
when relation.sub_type.is_a?(AST::Types::Name) && relation.sub_type.name.is_a?(TypeName::Alias)
|
79
|
+
check0(
|
80
|
+
Relation.new(sub_type: expand_alias(relation.sub_type), super_type: relation.super_type),
|
81
|
+
assumption: assumption,
|
82
|
+
trace: trace,
|
83
|
+
constraints: constraints
|
84
|
+
)
|
85
|
+
|
86
|
+
when relation.super_type.is_a?(AST::Types::Name) && relation.super_type.name.is_a?(TypeName::Alias)
|
87
|
+
check0(
|
88
|
+
Relation.new(super_type: expand_alias(relation.super_type), sub_type: relation.sub_type),
|
89
|
+
assumption: assumption,
|
90
|
+
trace: trace,
|
91
|
+
constraints: constraints
|
92
|
+
)
|
85
93
|
|
86
94
|
when relation.sub_type.is_a?(AST::Types::Literal)
|
87
95
|
check0(
|
@@ -139,8 +147,27 @@ module Steep
|
|
139
147
|
results.find(&:failure?)
|
140
148
|
end
|
141
149
|
|
150
|
+
when relation.super_type.is_a?(AST::Types::Var)
|
151
|
+
if constraints.unknown?(relation.super_type.name)
|
152
|
+
constraints.add(relation.super_type.name, sub_type: relation.sub_type)
|
153
|
+
success(constraints: constraints)
|
154
|
+
else
|
155
|
+
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
156
|
+
trace: trace)
|
157
|
+
end
|
158
|
+
|
159
|
+
when relation.sub_type.is_a?(AST::Types::Var)
|
160
|
+
if constraints.unknown?(relation.sub_type.name)
|
161
|
+
constraints.add(relation.sub_type.name, super_type: relation.super_type)
|
162
|
+
success(constraints: constraints)
|
163
|
+
else
|
164
|
+
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
165
|
+
trace: trace)
|
166
|
+
end
|
167
|
+
|
142
168
|
when relation.sub_type.is_a?(AST::Types::Name) && relation.super_type.is_a?(AST::Types::Name)
|
143
|
-
|
169
|
+
case
|
170
|
+
when relation.sub_type.name == relation.super_type.name && relation.sub_type.args.size == relation.super_type.args.size
|
144
171
|
results = relation.sub_type.args.zip(relation.super_type.args).flat_map do |(sub, sup)|
|
145
172
|
Relation.new(sub_type: sub, super_type: sup).yield_self do |rel|
|
146
173
|
[rel, rel.flip]
|
@@ -164,9 +191,32 @@ module Steep
|
|
164
191
|
check_interface(sub_interface, super_interface, assumption: assumption, trace: trace, constraints: constraints)
|
165
192
|
end
|
166
193
|
|
194
|
+
when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
|
195
|
+
check_method_params(:__proc__,
|
196
|
+
relation.sub_type.params, relation.super_type.params,
|
197
|
+
assumption: assumption,
|
198
|
+
trace: trace,
|
199
|
+
constraints: constraints).then do
|
200
|
+
check0(Relation.new(sub_type: relation.sub_type.return_type, super_type: relation.super_type.return_type),
|
201
|
+
assumption: assumption,
|
202
|
+
trace: trace,
|
203
|
+
constraints: constraints)
|
204
|
+
end
|
205
|
+
|
167
206
|
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
|
168
|
-
if relation.sub_type.types
|
169
|
-
|
207
|
+
if relation.sub_type.types.size >= relation.super_type.types.size
|
208
|
+
pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
|
209
|
+
results = pairs.flat_map do |t1, t2|
|
210
|
+
relation = Relation.new(sub_type: t1, super_type: t2)
|
211
|
+
[check0(relation, assumption: assumption, trace: trace, constraints: constraints),
|
212
|
+
check0(relation.flip, assumption: assumption, trace: trace, constraints: constraints)]
|
213
|
+
end
|
214
|
+
|
215
|
+
if results.all?(&:success?)
|
216
|
+
success(constraints: constraints)
|
217
|
+
else
|
218
|
+
results.find(&:failure?)
|
219
|
+
end
|
170
220
|
else
|
171
221
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
172
222
|
trace: trace)
|
@@ -331,7 +381,9 @@ module Steep
|
|
331
381
|
case
|
332
382
|
when !super_block && !sub_block
|
333
383
|
success(constraints: constraints)
|
334
|
-
when super_block && sub_block
|
384
|
+
when super_block && sub_block && super_block.optional? == sub_block.optional?
|
385
|
+
success(constraints: constraints)
|
386
|
+
when sub_block&.optional?
|
335
387
|
success(constraints: constraints)
|
336
388
|
else
|
337
389
|
failure(
|
@@ -371,10 +423,10 @@ module Steep
|
|
371
423
|
# No block required and given
|
372
424
|
|
373
425
|
when super_type.block && sub_type.block
|
374
|
-
match_params(name, super_type.block.params, sub_type.block.params, trace: trace).yield_self do |block_result|
|
426
|
+
match_params(name, super_type.block.type.params, sub_type.block.type.params, trace: trace).yield_self do |block_result|
|
375
427
|
return block_result unless block_result.is_a?(Array)
|
376
428
|
pairs.push(*block_result)
|
377
|
-
pairs.push [super_type.block.return_type, sub_type.block.return_type]
|
429
|
+
pairs.push [super_type.block.type.return_type, sub_type.block.type.return_type]
|
378
430
|
end
|
379
431
|
|
380
432
|
else
|
@@ -478,10 +530,10 @@ module Steep
|
|
478
530
|
end
|
479
531
|
|
480
532
|
def check_block_params(name, sub_block, super_block, assumption:, trace:, constraints:)
|
481
|
-
if sub_block
|
533
|
+
if sub_block && super_block
|
482
534
|
check_method_params(name,
|
483
|
-
super_block.params,
|
484
|
-
sub_block.params,
|
535
|
+
super_block.type.params,
|
536
|
+
sub_block.type.params,
|
485
537
|
assumption: assumption,
|
486
538
|
trace: trace,
|
487
539
|
constraints: constraints)
|
@@ -491,9 +543,9 @@ module Steep
|
|
491
543
|
end
|
492
544
|
|
493
545
|
def check_block_return(sub_block, super_block, assumption:, trace:, constraints:)
|
494
|
-
if sub_block
|
495
|
-
relation = Relation.new(sub_type: super_block.return_type,
|
496
|
-
super_type: sub_block.return_type)
|
546
|
+
if sub_block && super_block
|
547
|
+
relation = Relation.new(sub_type: super_block.type.return_type,
|
548
|
+
super_type: sub_block.type.return_type)
|
497
549
|
check(relation, assumption: assumption, trace: trace, constraints: constraints)
|
498
550
|
else
|
499
551
|
success(constraints: constraints)
|
@@ -561,24 +613,29 @@ module Steep
|
|
561
613
|
module_type: module_type,
|
562
614
|
with_initialize: with_initialize)
|
563
615
|
when AST::Types::Name
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
616
|
+
case type.name
|
617
|
+
when TypeName::Alias
|
618
|
+
resolve(expand_alias(type), self_type: self_type, instance_type: instance_type, module_type: module_type, with_initialize: with_initialize)
|
619
|
+
else
|
620
|
+
builder.build(type.name, with_initialize: with_initialize).yield_self do |abstract|
|
621
|
+
case type.name
|
622
|
+
when TypeName::Instance, TypeName::Interface
|
623
|
+
abstract.instantiate(
|
624
|
+
type: self_type,
|
625
|
+
args: type.args,
|
626
|
+
instance_type: type,
|
627
|
+
module_type: module_type || module_type(type)
|
628
|
+
)
|
629
|
+
when TypeName::Class, TypeName::Module
|
630
|
+
signature = builder.signatures.find_class_or_module(type.name.name)
|
631
|
+
args = signature.params&.variables&.map {|var| AST::Types::Var.new(name: var) } || []
|
632
|
+
abstract.instantiate(
|
633
|
+
type: self_type,
|
634
|
+
args: [],
|
635
|
+
instance_type: AST::Types::Name.new_instance(name: type.name.name, args: args),
|
636
|
+
module_type: module_type || module_type(type)
|
637
|
+
)
|
638
|
+
end
|
582
639
|
end
|
583
640
|
end
|
584
641
|
when AST::Types::Union
|
@@ -691,9 +748,13 @@ module Steep
|
|
691
748
|
end
|
692
749
|
end
|
693
750
|
|
751
|
+
ivar_chains = interfaces.each.with_object({}) do |interface, chains|
|
752
|
+
chains.merge!(interface.ivar_chains)
|
753
|
+
end
|
754
|
+
|
694
755
|
Interface::Instantiated.new(type: type,
|
695
756
|
methods: methods,
|
696
|
-
ivar_chains:
|
757
|
+
ivar_chains: ivar_chains)
|
697
758
|
when AST::Types::Void
|
698
759
|
Interface::Instantiated.new(type: type,
|
699
760
|
methods: {},
|
@@ -744,6 +805,60 @@ module Steep
|
|
744
805
|
|
745
806
|
array_interface
|
746
807
|
end
|
808
|
+
|
809
|
+
when AST::Types::Proc
|
810
|
+
yield_self do
|
811
|
+
proc_interface = resolve(type.back_type, self_type: self_type, with_initialize: with_initialize)
|
812
|
+
apply_type = Interface::MethodType.new(
|
813
|
+
type_params: [],
|
814
|
+
params: type.params,
|
815
|
+
block: nil,
|
816
|
+
return_type: type.return_type,
|
817
|
+
location: nil
|
818
|
+
)
|
819
|
+
|
820
|
+
proc_interface.methods[:[]] = proc_interface.methods[:[]].yield_self do |aref|
|
821
|
+
aref.with_types([apply_type])
|
822
|
+
end
|
823
|
+
proc_interface.methods[:call] = proc_interface.methods[:call].yield_self do |aref|
|
824
|
+
aref.with_types([apply_type])
|
825
|
+
end
|
826
|
+
|
827
|
+
proc_interface
|
828
|
+
end
|
829
|
+
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
def expand_alias(type)
|
834
|
+
expanded = case type
|
835
|
+
when AST::Types::Union
|
836
|
+
AST::Types::Union.build(
|
837
|
+
types: type.types.map {|ty| expand_alias(ty) },
|
838
|
+
location: type.location
|
839
|
+
)
|
840
|
+
when AST::Types::Intersection
|
841
|
+
AST::Types::Intersection.build(
|
842
|
+
types: type.types.map {|ty| expand_alias(ty) },
|
843
|
+
location: type.location
|
844
|
+
)
|
845
|
+
when AST::Types::Name
|
846
|
+
if type.name.is_a?(TypeName::Alias)
|
847
|
+
a = builder.signatures.find_alias(type.name.name) or raise "Unknown alias name: #{type.name.name}"
|
848
|
+
args = type.args.map {|ty| expand_alias(ty) }
|
849
|
+
s = Interface::Substitution.build(a.params&.variables || [], args)
|
850
|
+
expand_alias(a.type.subst(s))
|
851
|
+
else
|
852
|
+
type
|
853
|
+
end
|
854
|
+
else
|
855
|
+
type
|
856
|
+
end
|
857
|
+
|
858
|
+
if block_given?
|
859
|
+
yield expanded
|
860
|
+
else
|
861
|
+
expanded
|
747
862
|
end
|
748
863
|
end
|
749
864
|
end
|
@@ -20,12 +20,12 @@ module Steep
|
|
20
20
|
end
|
21
21
|
|
22
22
|
method_type.block&.yield_self do |block|
|
23
|
-
block.params.each_type do |type|
|
23
|
+
block.type.params.each_type do |type|
|
24
24
|
each_var(type) do |var|
|
25
25
|
params << var
|
26
26
|
end
|
27
27
|
end
|
28
|
-
each_var(block.return_type) do |var|
|
28
|
+
each_var(block.type.return_type) do |var|
|
29
29
|
returns << var
|
30
30
|
end
|
31
31
|
end
|
@@ -28,9 +28,9 @@ module Steep
|
|
28
28
|
add_params(method_type.params, block: false, contravariants: contravariants, covariants: covariants)
|
29
29
|
add_type(method_type.return_type, variance: :covariant, covariants: covariants, contravariants: contravariants)
|
30
30
|
|
31
|
-
method_type.block&.yield_self do |
|
32
|
-
add_params(
|
33
|
-
add_type(
|
31
|
+
method_type.block&.type&.yield_self do |proc|
|
32
|
+
add_params(proc.params, block: true, contravariants: contravariants, covariants: covariants)
|
33
|
+
add_type(proc.return_type, variance: :contravariant, covariants: covariants, contravariants: contravariants)
|
34
34
|
end
|
35
35
|
|
36
36
|
new(covariants: covariants, contravariants: contravariants)
|