steep 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|