steep 0.36.0 → 0.37.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 +4 -0
- data/lib/steep.rb +2 -0
- data/lib/steep/ast/types/factory.rb +112 -53
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +32 -812
- data/lib/steep/subtyping/check.rb +19 -16
- data/lib/steep/subtyping/variable_occurrence.rb +2 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +76 -50
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3d9186b6988081611f8bf060700ad97eb408ab605ab11ab32b717b9a0e9b8b9
|
4
|
+
data.tar.gz: 6f308f7bd551472237d5857614b765468782290733514793b2dfe35a3ac232cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fee308a7783a6e54c974c71c78189492c0f557528bccb0da530927cfdb4e4a16f4ff6cd2ec9f8c3292dd9839bb1637f68fd3aff9da0fef6783e3f4b5d838984
|
7
|
+
data.tar.gz: 7cd72caf879d339e5fec0bed219957befd40d5dc2466b345435f4b523c8028a9264404b1d9c695c11ca638b8e6bbeb1d1ad8f600367cd87bf9b3c4fade99eeaa
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.37.0 (2020-12-06)
|
6
|
+
|
7
|
+
* Update to RBS 0.20.0 with _singleton attribute_ syntax and _proc types with blocks_. ([#264](https://github.com/soutaro/steep/pull/264))
|
8
|
+
|
5
9
|
## 0.36.0 (2020-11-16)
|
6
10
|
|
7
11
|
* Flow-sensitive typing improvements with `||` and `&&` ([#260](https://github.com/soutaro/steep/pull/260))
|
data/lib/steep.rb
CHANGED
@@ -42,6 +42,8 @@ require "steep/ast/annotation/collection"
|
|
42
42
|
require "steep/ast/builtin"
|
43
43
|
require "steep/ast/types/factory"
|
44
44
|
|
45
|
+
require "steep/interface/function"
|
46
|
+
require "steep/interface/block"
|
45
47
|
require "steep/interface/method_type"
|
46
48
|
require "steep/interface/substitution"
|
47
49
|
require "steep/interface/interface"
|
@@ -75,9 +75,23 @@ module Steep
|
|
75
75
|
end
|
76
76
|
Record.new(elements: elements, location: nil)
|
77
77
|
when RBS::Types::Proc
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
func = Interface::Function.new(
|
79
|
+
params: params(type.type),
|
80
|
+
return_type: type(type.type.return_type),
|
81
|
+
location: type.location
|
82
|
+
)
|
83
|
+
block = if type.block
|
84
|
+
Interface::Block.new(
|
85
|
+
type: Interface::Function.new(
|
86
|
+
params: params(type.block.type),
|
87
|
+
return_type: type(type.block.type.return_type),
|
88
|
+
location: type.location
|
89
|
+
),
|
90
|
+
optional: !type.block.required
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
Proc.new(type: func, block: block)
|
81
95
|
else
|
82
96
|
raise "Unexpected type given: #{type}"
|
83
97
|
end
|
@@ -145,8 +159,15 @@ module Steep
|
|
145
159
|
end
|
146
160
|
RBS::Types::Record.new(fields: fields, location: nil)
|
147
161
|
when Proc
|
162
|
+
block = if type.block
|
163
|
+
RBS::Types::Block.new(
|
164
|
+
type: function_1(type.block.type),
|
165
|
+
required: !type.block.optional?
|
166
|
+
)
|
167
|
+
end
|
148
168
|
RBS::Types::Proc.new(
|
149
|
-
type: function_1(type.
|
169
|
+
type: function_1(type.type),
|
170
|
+
block: block,
|
150
171
|
location: nil
|
151
172
|
)
|
152
173
|
when Logic::Base
|
@@ -156,7 +177,10 @@ module Steep
|
|
156
177
|
end
|
157
178
|
end
|
158
179
|
|
159
|
-
def function_1(
|
180
|
+
def function_1(func)
|
181
|
+
params = func.params
|
182
|
+
return_type = func.return_type
|
183
|
+
|
160
184
|
RBS::Types::Function.new(
|
161
185
|
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
162
186
|
optional_positionals: params.optional.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
@@ -170,7 +194,7 @@ module Steep
|
|
170
194
|
end
|
171
195
|
|
172
196
|
def params(type)
|
173
|
-
Interface::Params.new(
|
197
|
+
Interface::Function::Params.new(
|
174
198
|
required: type.required_positionals.map {|param| type(param.type) },
|
175
199
|
optional: type.optional_positionals.map {|param| type(param.type) },
|
176
200
|
rest: type.rest_positionals&.yield_self {|param| type(param.type) },
|
@@ -202,13 +226,19 @@ module Steep
|
|
202
226
|
|
203
227
|
type = Interface::MethodType.new(
|
204
228
|
type_params: type_params,
|
205
|
-
|
206
|
-
|
229
|
+
type: Interface::Function.new(
|
230
|
+
params: params(method_type.type).subst(subst),
|
231
|
+
return_type: type(method_type.type.return_type).subst(subst),
|
232
|
+
location: method_type.location
|
233
|
+
),
|
207
234
|
block: method_type.block&.yield_self do |block|
|
208
235
|
Interface::Block.new(
|
209
236
|
optional: !block.required,
|
210
|
-
type:
|
211
|
-
|
237
|
+
type: Interface::Function.new(
|
238
|
+
params: params(block.type).subst(subst),
|
239
|
+
return_type: type(block.type.return_type).subst(subst),
|
240
|
+
location: nil
|
241
|
+
)
|
212
242
|
)
|
213
243
|
end,
|
214
244
|
method_decls: method_decls
|
@@ -242,12 +272,12 @@ module Steep
|
|
242
272
|
|
243
273
|
type = RBS::MethodType.new(
|
244
274
|
type_params: type_params,
|
245
|
-
type: function_1(method_type.
|
275
|
+
type: function_1(method_type.type.subst(subst)),
|
246
276
|
block: method_type.block&.yield_self do |block|
|
247
277
|
block_type = block.type.subst(subst)
|
248
278
|
|
249
|
-
RBS::
|
250
|
-
type: function_1(block_type
|
279
|
+
RBS::Types::Block.new(
|
280
|
+
type: function_1(block_type),
|
251
281
|
required: !block.optional
|
252
282
|
)
|
253
283
|
end,
|
@@ -354,7 +384,9 @@ module Steep
|
|
354
384
|
when :is_a?, :kind_of?, :instance_of?
|
355
385
|
if defined_in == RBS::BuiltinNames::Object.name && member.instance?
|
356
386
|
return method_type.with(
|
357
|
-
|
387
|
+
type: method_type.type.with(
|
388
|
+
return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.type.return_type.location)
|
389
|
+
)
|
358
390
|
)
|
359
391
|
end
|
360
392
|
|
@@ -363,7 +395,9 @@ module Steep
|
|
363
395
|
when RBS::BuiltinNames::Object.name,
|
364
396
|
NilClassName
|
365
397
|
return method_type.with(
|
366
|
-
|
398
|
+
type: method_type.type.with(
|
399
|
+
return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.type.return_type.location)
|
400
|
+
)
|
367
401
|
)
|
368
402
|
end
|
369
403
|
|
@@ -373,7 +407,9 @@ module Steep
|
|
373
407
|
RBS::BuiltinNames::TrueClass.name,
|
374
408
|
RBS::BuiltinNames::FalseClass.name
|
375
409
|
return method_type.with(
|
376
|
-
|
410
|
+
type: method_type.type.with(
|
411
|
+
return_type: AST::Types::Logic::Not.new(location: method_type.type.return_type.location)
|
412
|
+
)
|
377
413
|
)
|
378
414
|
end
|
379
415
|
|
@@ -381,7 +417,9 @@ module Steep
|
|
381
417
|
case defined_in
|
382
418
|
when RBS::BuiltinNames::Module.name
|
383
419
|
return method_type.with(
|
384
|
-
|
420
|
+
type: method_type.type.with(
|
421
|
+
return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.type.return_type.location)
|
422
|
+
)
|
385
423
|
)
|
386
424
|
end
|
387
425
|
end
|
@@ -572,14 +610,17 @@ module Steep
|
|
572
610
|
method_types: type.types.map.with_index {|elem_type, index|
|
573
611
|
Interface::MethodType.new(
|
574
612
|
type_params: [],
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
613
|
+
type: Interface::Function.new(
|
614
|
+
params: Interface::Function::Params.new(required: [AST::Types::Literal.new(value: index)],
|
615
|
+
optional: [],
|
616
|
+
rest: nil,
|
617
|
+
required_keywords: {},
|
618
|
+
optional_keywords: {},
|
619
|
+
rest_keywords: nil),
|
620
|
+
return_type: elem_type,
|
621
|
+
location: nil
|
622
|
+
),
|
581
623
|
block: nil,
|
582
|
-
return_type: elem_type,
|
583
624
|
method_decls: Set[]
|
584
625
|
)
|
585
626
|
} + aref.method_types
|
@@ -591,14 +632,17 @@ module Steep
|
|
591
632
|
method_types: type.types.map.with_index {|elem_type, index|
|
592
633
|
Interface::MethodType.new(
|
593
634
|
type_params: [],
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
635
|
+
type: Interface::Function.new(
|
636
|
+
params: Interface::Function::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
637
|
+
optional: [],
|
638
|
+
rest: nil,
|
639
|
+
required_keywords: {},
|
640
|
+
optional_keywords: {},
|
641
|
+
rest_keywords: nil),
|
642
|
+
return_type: elem_type,
|
643
|
+
location: nil
|
644
|
+
),
|
600
645
|
block: nil,
|
601
|
-
return_type: elem_type,
|
602
646
|
method_decls: Set[]
|
603
647
|
)
|
604
648
|
} + update.method_types
|
@@ -610,9 +654,12 @@ module Steep
|
|
610
654
|
method_types: [
|
611
655
|
Interface::MethodType.new(
|
612
656
|
type_params: [],
|
613
|
-
|
657
|
+
type: Interface::Function.new(
|
658
|
+
params: Interface::Function::Params.empty,
|
659
|
+
return_type: type.types[0] || AST::Builtin.nil_type,
|
660
|
+
location: nil
|
661
|
+
),
|
614
662
|
block: nil,
|
615
|
-
return_type: type.types[0] || AST::Builtin.nil_type,
|
616
663
|
method_decls: Set[]
|
617
664
|
)
|
618
665
|
]
|
@@ -624,9 +671,12 @@ module Steep
|
|
624
671
|
method_types: [
|
625
672
|
Interface::MethodType.new(
|
626
673
|
type_params: [],
|
627
|
-
|
674
|
+
type: Interface::Function.new(
|
675
|
+
params: Interface::Function::Params.empty,
|
676
|
+
return_type: type.types.last || AST::Builtin.nil_type,
|
677
|
+
location: nil
|
678
|
+
),
|
628
679
|
block: nil,
|
629
|
-
return_type: type.types.last || AST::Builtin.nil_type,
|
630
680
|
method_decls: Set[]
|
631
681
|
)
|
632
682
|
]
|
@@ -651,14 +701,17 @@ module Steep
|
|
651
701
|
|
652
702
|
Interface::MethodType.new(
|
653
703
|
type_params: [],
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
704
|
+
type: Interface::Function.new(
|
705
|
+
params: Interface::Function::Params.new(required: [key_type],
|
706
|
+
optional: [],
|
707
|
+
rest: nil,
|
708
|
+
required_keywords: {},
|
709
|
+
optional_keywords: {},
|
710
|
+
rest_keywords: nil),
|
711
|
+
return_type: value_type,
|
712
|
+
location: nil
|
713
|
+
),
|
660
714
|
block: nil,
|
661
|
-
return_type: value_type,
|
662
715
|
method_decls: Set[]
|
663
716
|
)
|
664
717
|
} + ref.method_types
|
@@ -671,14 +724,16 @@ module Steep
|
|
671
724
|
key_type = Literal.new(value: key_value, location: nil)
|
672
725
|
Interface::MethodType.new(
|
673
726
|
type_params: [],
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
727
|
+
type: Interface::Function.new(
|
728
|
+
params: Interface::Function::Params.new(required: [key_type, value_type],
|
729
|
+
optional: [],
|
730
|
+
rest: nil,
|
731
|
+
required_keywords: {},
|
732
|
+
optional_keywords: {},
|
733
|
+
rest_keywords: nil),
|
734
|
+
return_type: value_type,
|
735
|
+
location: nil),
|
680
736
|
block: nil,
|
681
|
-
return_type: value_type,
|
682
737
|
method_decls: Set[]
|
683
738
|
)
|
684
739
|
} + update.method_types
|
@@ -691,14 +746,18 @@ module Steep
|
|
691
746
|
interface(Builtin::Proc.instance_type, private: private, self_type: self_type).tap do |interface|
|
692
747
|
method_type = Interface::MethodType.new(
|
693
748
|
type_params: [],
|
694
|
-
|
695
|
-
|
696
|
-
block: nil,
|
749
|
+
type: type.type,
|
750
|
+
block: type.block,
|
697
751
|
method_decls: Set[]
|
698
752
|
)
|
699
753
|
|
700
|
-
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
|
701
754
|
interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
|
755
|
+
|
756
|
+
if type.block_required?
|
757
|
+
interface.methods.delete(:[])
|
758
|
+
else
|
759
|
+
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type.with(block: nil)])
|
760
|
+
end
|
702
761
|
end
|
703
762
|
|
704
763
|
when Logic::Base
|
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -3,68 +3,76 @@ module Steep
|
|
3
3
|
module Types
|
4
4
|
class Proc
|
5
5
|
attr_reader :location
|
6
|
-
attr_reader :
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :type
|
7
|
+
attr_reader :block
|
8
8
|
|
9
|
-
def initialize(
|
9
|
+
def initialize(type:, block:, location: type.location)
|
10
|
+
@type = type
|
11
|
+
@block = block
|
10
12
|
@location = location
|
11
|
-
@params = params
|
12
|
-
@return_type = return_type
|
13
13
|
end
|
14
14
|
|
15
15
|
def ==(other)
|
16
|
-
other.is_a?(self.class) &&
|
17
|
-
other.params == params &&
|
18
|
-
other.return_type == return_type
|
16
|
+
other.is_a?(self.class) && other.type == type && other.block == block
|
19
17
|
end
|
20
18
|
|
21
19
|
def hash
|
22
|
-
self.class.hash
|
20
|
+
self.class.hash ^ type.hash ^ block.hash
|
23
21
|
end
|
24
22
|
|
25
23
|
alias eql? ==
|
26
24
|
|
27
25
|
def subst(s)
|
28
26
|
self.class.new(
|
29
|
-
|
30
|
-
|
27
|
+
type: type.subst(s),
|
28
|
+
block: block&.subst(s),
|
31
29
|
location: location
|
32
30
|
)
|
33
31
|
end
|
34
32
|
|
35
33
|
def to_s
|
36
|
-
|
34
|
+
if block
|
35
|
+
"^#{type.params} #{block} -> #{type.return_type}"
|
36
|
+
else
|
37
|
+
"^#{type.params} -> #{type.return_type}"
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
39
41
|
def free_variables()
|
40
|
-
@fvs ||= Set.
|
41
|
-
|
42
|
-
|
42
|
+
@fvs ||= Set[].tap do |fvs|
|
43
|
+
fvs.merge(type.free_variables)
|
44
|
+
fvs.merge(block.free_variables) if block
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
48
|
def level
|
47
|
-
children = params.each_type.to_a + [return_type]
|
49
|
+
children = type.params.each_type.to_a + [type.return_type]
|
50
|
+
if block
|
51
|
+
children.push(*block.type.params.each_type.to_a)
|
52
|
+
children.push(block.type.return_type)
|
53
|
+
end
|
48
54
|
[0] + level_of_children(children)
|
49
55
|
end
|
50
56
|
|
51
57
|
def closed?
|
52
|
-
|
58
|
+
type.closed? && (block.nil? || block.closed?)
|
53
59
|
end
|
54
60
|
|
55
61
|
def with_location(new_location)
|
56
|
-
self.class.new(location: new_location,
|
62
|
+
self.class.new(location: new_location, block: block, type: type)
|
57
63
|
end
|
58
64
|
|
59
65
|
def map_type(&block)
|
60
66
|
self.class.new(
|
61
|
-
|
62
|
-
|
67
|
+
type: type.map_type(&block),
|
68
|
+
block: self.block&.map_type(&block),
|
63
69
|
location: location
|
64
70
|
)
|
65
71
|
end
|
66
72
|
|
67
73
|
def one_arg?
|
74
|
+
params = type.params
|
75
|
+
|
68
76
|
params.required.size == 1 &&
|
69
77
|
params.optional.empty? &&
|
70
78
|
!params.rest &&
|
@@ -78,6 +86,10 @@ module Steep
|
|
78
86
|
args: [],
|
79
87
|
location: location)
|
80
88
|
end
|
89
|
+
|
90
|
+
def block_required?
|
91
|
+
block && !block.optional?
|
92
|
+
end
|
81
93
|
end
|
82
94
|
end
|
83
95
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Steep
|
2
|
+
module Interface
|
3
|
+
class Block
|
4
|
+
attr_reader :type
|
5
|
+
attr_reader :optional
|
6
|
+
|
7
|
+
def initialize(type:, optional:)
|
8
|
+
@type = type
|
9
|
+
@optional = optional
|
10
|
+
end
|
11
|
+
|
12
|
+
def optional?
|
13
|
+
@optional
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_optional
|
17
|
+
self.class.new(
|
18
|
+
type: type,
|
19
|
+
optional: true
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
other.is_a?(self.class) && other.type == type && other.optional == optional
|
25
|
+
end
|
26
|
+
|
27
|
+
alias eql? ==
|
28
|
+
|
29
|
+
def hash
|
30
|
+
type.hash ^ optional.hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def closed?
|
34
|
+
type.closed?
|
35
|
+
end
|
36
|
+
|
37
|
+
def subst(s)
|
38
|
+
ty = type.subst(s)
|
39
|
+
if ty == type
|
40
|
+
self
|
41
|
+
else
|
42
|
+
self.class.new(
|
43
|
+
type: ty,
|
44
|
+
optional: optional
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def free_variables()
|
50
|
+
@fvs ||= type.free_variables
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
"#{optional? ? "?" : ""}{ #{type.params} -> #{type.return_type} }"
|
55
|
+
end
|
56
|
+
|
57
|
+
def map_type(&block)
|
58
|
+
self.class.new(
|
59
|
+
type: type.map_type(&block),
|
60
|
+
optional: optional
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def +(other)
|
65
|
+
optional = self.optional? || other.optional?
|
66
|
+
type = Function.new(
|
67
|
+
params: self.type.params + other.type.params,
|
68
|
+
return_type: AST::Types::Union.build(types: [self.type.return_type, other.type.return_type]),
|
69
|
+
location: nil
|
70
|
+
)
|
71
|
+
|
72
|
+
self.class.new(
|
73
|
+
type: type,
|
74
|
+
optional: optional
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|