steep 0.20.0 → 0.25.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 +30 -1
- data/Gemfile +7 -0
- data/bin/steep-prof +16 -0
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/ast/types/literal.rb +4 -0
- data/lib/steep/ast/types/union.rb +4 -1
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/project/target.rb +17 -3
- data/lib/steep/server/interaction_worker.rb +3 -3
- data/lib/steep/server/signature_worker.rb +3 -0
- data/lib/steep/signature/errors.rb +28 -0
- data/lib/steep/signature/validator.rb +11 -1
- data/lib/steep/source.rb +2 -1
- data/lib/steep/subtyping/check.rb +224 -52
- data/lib/steep/type_construction.rb +425 -181
- data/lib/steep/type_inference/constant_env.rb +1 -1
- data/lib/steep/type_inference/context.rb +8 -0
- data/lib/steep/type_inference/context_array.rb +4 -3
- data/lib/steep/type_inference/logic.rb +31 -0
- data/lib/steep/typing.rb +7 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/class/a.rbs +1 -2
- data/smoke/class/f.rb +3 -1
- data/steep.gemspec +1 -8
- metadata +7 -96
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c290301da65ed473b092cd6c2ea39eebe02f566124a1fa32e0f420d290513cbf
|
4
|
+
data.tar.gz: ca4fca20e9f3f0b19c57b98d6cdfce0023aeeff8cd0fcd2ee0fc91346e5e0816
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76c3b0c76e303bcc558bf20efeebe3ddaa3caef432f5d325261261f6d8431f5bbd36bc44af9a4a4dd6a90f2db30ac35ca044181b25063890c0e68c5499d7792c
|
7
|
+
data.tar.gz: a5fa8fba718f599806d9d0ad62a66c138261469d41694bb39ebafe1b8736ad255e890c55f0e3b4f180f4e0212f0b65b31b5957b5c337cba42d1129b9e935e577
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,35 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.25.0 (2020-08-18)
|
6
|
+
|
7
|
+
* Improve `op_send` typing ([#186](https://github.com/soutaro/steep/pull/186))
|
8
|
+
* Improve `op_asgn` typing ([#189](https://github.com/soutaro/steep/pull/189))
|
9
|
+
* Better multi-assignment support ([#183](https://github.com/soutaro/steep/pull/183), [#184](https://github.com/soutaro/steep/pull/184))
|
10
|
+
* Support for loop and class variables ([#182](https://github.com/soutaro/steep/pull/182))
|
11
|
+
* Fix tuple typing ([#181](https://github.com/soutaro/steep/pull/181))
|
12
|
+
|
13
|
+
## 0.24.0 (2020-08-11)
|
14
|
+
|
15
|
+
* Update RBS to 0.10 ([#180](https://github.com/soutaro/steep/pull/180))
|
16
|
+
|
17
|
+
## 0.23.0 (2020-08-06)
|
18
|
+
|
19
|
+
* Fix literal typing with hint ([#179](https://github.com/soutaro/steep/pull/179))
|
20
|
+
* Fix literal type subtyping ([#178](https://github.com/soutaro/steep/pull/178))
|
21
|
+
|
22
|
+
## 0.22.0 (2020-08-03)
|
23
|
+
|
24
|
+
* Improve signature validation ([#175](https://github.com/soutaro/steep/pull/175), [#177](https://github.com/soutaro/steep/pull/177))
|
25
|
+
* Fix boolean literal typing ([#172](https://github.com/soutaro/steep/pull/172))
|
26
|
+
* Make exit code success when Steep has unreported type errors ([#171](https://github.com/soutaro/steep/pull/171))
|
27
|
+
* Allow `./` prefix for signature pattern ([#170](https://github.com/soutaro/steep/pull/170))
|
28
|
+
|
29
|
+
## 0.21.0 (2020-07-20)
|
30
|
+
|
31
|
+
* Fix LSP hover ([#168](https://github.com/soutaro/steep/pull/168))
|
32
|
+
* Nominal subtyping ([#167](https://github.com/soutaro/steep/pull/167))
|
33
|
+
|
5
34
|
## 0.20.0 (2020-07-17)
|
6
35
|
|
7
36
|
* Support singleton class definitions ([#166](https://github.com/soutaro/steep/pull/166))
|
@@ -39,7 +68,7 @@
|
|
39
68
|
|
40
69
|
* Fix constant resolution ([#143](https://github.com/soutaro/steep/pull/143))
|
41
70
|
* Fix RBS diagnostics line number in LSP ([#142](https://github.com/soutaro/steep/pull/142))
|
42
|
-
* Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
|
71
|
+
* Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
|
43
72
|
|
44
73
|
## 0.16.0 (2020-05-19)
|
45
74
|
|
data/Gemfile
CHANGED
@@ -5,3 +5,10 @@ gemspec
|
|
5
5
|
|
6
6
|
gem "with_steep_types", path: "test/gems/with_steep_types"
|
7
7
|
gem "without_steep_types", path: "test/gems/without_steep_types"
|
8
|
+
|
9
|
+
gem "rake"
|
10
|
+
gem "minitest", "~> 5.0"
|
11
|
+
gem "racc", "~> 1.4"
|
12
|
+
gem "minitest-reporters"
|
13
|
+
gem "minitest-hooks"
|
14
|
+
gem "stackprof"
|
data/bin/steep-prof
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "stackprof"
|
4
|
+
|
5
|
+
mode = (ENV["STEEP_STACKPROF_MODE"] || :wall).to_sym
|
6
|
+
out = ENV["STEEP_STACKPROF_OUT"] || "tmp/stackprof-#{mode}-steep.dump"
|
7
|
+
|
8
|
+
def exit(*)
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
STDERR.puts "Running profiler: mode=#{mode}, out=#{out}"
|
14
|
+
StackProf.run(mode: mode, out: out) do
|
15
|
+
load File.join(__dir__, "../exe/steep")
|
16
|
+
end
|
data/lib/steep/drivers/check.rb
CHANGED
data/lib/steep/project/target.rb
CHANGED
@@ -79,6 +79,7 @@ module Steep
|
|
79
79
|
def self.test_pattern(patterns, path, ext:)
|
80
80
|
patterns.any? do |pattern|
|
81
81
|
p = pattern.end_with?(File::Separator) ? pattern : pattern + File::Separator
|
82
|
+
p.delete_prefix!('./')
|
82
83
|
(path.to_s.start_with?(p) && path.extname == ext) || File.fnmatch(pattern, path.to_s)
|
83
84
|
end
|
84
85
|
end
|
@@ -160,7 +161,18 @@ module Steep
|
|
160
161
|
else
|
161
162
|
yield env, check, Time.now
|
162
163
|
end
|
164
|
+
rescue RBS::DuplicatedDeclarationError => exn
|
165
|
+
@status = SignatureValidationErrorStatus.new(
|
166
|
+
errors: [
|
167
|
+
Signature::Errors::DuplicatedDefinitionError.new(
|
168
|
+
name: exn.name,
|
169
|
+
location: exn.decls[0].location
|
170
|
+
)
|
171
|
+
],
|
172
|
+
timestamp: Time.now
|
173
|
+
)
|
163
174
|
rescue => exn
|
175
|
+
Steep.log_error exn
|
164
176
|
@status = SignatureOtherErrorStatus.new(error: exn, timestamp: Time.now)
|
165
177
|
end
|
166
178
|
end
|
@@ -183,8 +195,10 @@ module Steep
|
|
183
195
|
type_check_sources = []
|
184
196
|
|
185
197
|
target_sources.each do |file|
|
186
|
-
|
187
|
-
|
198
|
+
Steep.logger.tagged("path=#{file.path}") do
|
199
|
+
if file.type_check(check, timestamp)
|
200
|
+
type_check_sources << file
|
201
|
+
end
|
188
202
|
end
|
189
203
|
end
|
190
204
|
|
@@ -205,7 +219,7 @@ module Steep
|
|
205
219
|
def errors
|
206
220
|
case status
|
207
221
|
when TypeCheckStatus
|
208
|
-
source_files.each_value.flat_map(&:errors)
|
222
|
+
source_files.each_value.flat_map(&:errors).select { |error | options.error_to_report?(error) }
|
209
223
|
else
|
210
224
|
[]
|
211
225
|
end
|
@@ -95,8 +95,8 @@ module Steep
|
|
95
95
|
```
|
96
96
|
HOVER
|
97
97
|
if content.definition
|
98
|
-
if content.definition.
|
99
|
-
string << "\n----\n\n#{content.definition.
|
98
|
+
if content.definition.comments
|
99
|
+
string << "\n----\n\n#{content.definition.comments.map(&:string).join("\n\n")}"
|
100
100
|
end
|
101
101
|
|
102
102
|
string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
|
@@ -111,7 +111,7 @@ def #{content.method_name}: #{content.method_type}
|
|
111
111
|
```
|
112
112
|
HOVER
|
113
113
|
if (comment = content.comment_string)
|
114
|
-
string << "\n----\n\n#{comment
|
114
|
+
string << "\n----\n\n#{comment}\n"
|
115
115
|
end
|
116
116
|
|
117
117
|
if content.definition.method_types.size > 1
|
@@ -112,6 +112,9 @@ module Steep
|
|
112
112
|
target.signature_files.each_key.with_object({}) do |path, hash|
|
113
113
|
hash[path] = []
|
114
114
|
end
|
115
|
+
when Project::Target::SignatureOtherErrorStatus
|
116
|
+
Steep.log_error status.error
|
117
|
+
{}
|
115
118
|
else
|
116
119
|
Steep.logger.info "Unexpected target status: #{status.class}"
|
117
120
|
{}
|
@@ -19,6 +19,19 @@ module Steep
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
class DuplicatedDefinitionError < Base
|
23
|
+
attr_reader :name
|
24
|
+
|
25
|
+
def initialize(name:, location:)
|
26
|
+
@name = name
|
27
|
+
@location = location
|
28
|
+
end
|
29
|
+
|
30
|
+
def puts(io)
|
31
|
+
io.puts "#{loc_to_s}\sDuplicatedDefinitionError: name=#{name}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
22
35
|
class UnknownTypeNameError < Base
|
23
36
|
attr_reader :name
|
24
37
|
|
@@ -48,6 +61,21 @@ module Steep
|
|
48
61
|
io.puts "#{loc_to_s}\tInvalidTypeApplicationError: name=#{name}, expected=[#{params.join(", ")}], actual=[#{args.join(", ")}]"
|
49
62
|
end
|
50
63
|
end
|
64
|
+
|
65
|
+
class InvalidMethodOverloadError < Base
|
66
|
+
attr_reader :class_name
|
67
|
+
attr_reader :method_name
|
68
|
+
|
69
|
+
def initialize(class_name:, method_name:, location:)
|
70
|
+
@class_name = class_name
|
71
|
+
@method_name = method_name
|
72
|
+
@location = location
|
73
|
+
end
|
74
|
+
|
75
|
+
def puts(io)
|
76
|
+
io.puts "#{loc_to_s}\tInvalidMethodOverloadError: class_name=#{class_name}, method_name=#{method_name}"
|
77
|
+
end
|
78
|
+
end
|
51
79
|
end
|
52
80
|
end
|
53
81
|
end
|
@@ -53,6 +53,7 @@ module Steep
|
|
53
53
|
validate_decl
|
54
54
|
validate_const
|
55
55
|
validate_global
|
56
|
+
validate_alias
|
56
57
|
end
|
57
58
|
|
58
59
|
def validate_type(type)
|
@@ -99,6 +100,7 @@ module Steep
|
|
99
100
|
env.constant_decls.each do |name, entry|
|
100
101
|
rescue_validation_errors do
|
101
102
|
Steep.logger.debug "Validating constant `#{name}`..."
|
103
|
+
builder.ensure_namespace!(name.namespace, location: entry.decl.location)
|
102
104
|
validate_type entry.decl.type
|
103
105
|
end
|
104
106
|
end
|
@@ -117,7 +119,9 @@ module Steep
|
|
117
119
|
env.alias_decls.each do |name, entry|
|
118
120
|
rescue_validation_errors do
|
119
121
|
Steep.logger.debug "Validating alias `#{name}`..."
|
120
|
-
|
122
|
+
builder.expand_alias(name).tap do |type|
|
123
|
+
validate_type(type)
|
124
|
+
end
|
121
125
|
end
|
122
126
|
end
|
123
127
|
end
|
@@ -136,6 +140,12 @@ module Steep
|
|
136
140
|
name: factory.type_name(exn.type_name),
|
137
141
|
location: exn.location
|
138
142
|
)
|
143
|
+
rescue RBS::InvalidOverloadMethodError => exn
|
144
|
+
@errors << Errors::InvalidMethodOverloadError.new(
|
145
|
+
class_name: factory.type_name(exn.type_name),
|
146
|
+
method_name: exn.method_name,
|
147
|
+
location: exn.members[0].location
|
148
|
+
)
|
139
149
|
end
|
140
150
|
end
|
141
151
|
end
|
data/lib/steep/source.rb
CHANGED
@@ -79,6 +79,7 @@ module Steep
|
|
79
79
|
end
|
80
80
|
|
81
81
|
mapping = {}
|
82
|
+
|
82
83
|
construct_mapping(node: node, annotations: annotations, mapping: mapping)
|
83
84
|
|
84
85
|
annotations.each do |annot|
|
@@ -185,7 +186,7 @@ module Steep
|
|
185
186
|
construct_mapping(node: node.children[0], annotations: annotations, mapping: mapping, line_range: nil)
|
186
187
|
end
|
187
188
|
|
188
|
-
if node.
|
189
|
+
if node.children.last
|
189
190
|
else_node = node.children.last
|
190
191
|
else_start = node.loc.else.last_line
|
191
192
|
else_end = node.loc.end.line
|
@@ -9,6 +9,84 @@ module Steep
|
|
9
9
|
@cache = {}
|
10
10
|
end
|
11
11
|
|
12
|
+
def instance_super_types(type_name, args:)
|
13
|
+
type_name_1 = factory.type_name_1(type_name)
|
14
|
+
ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
|
15
|
+
|
16
|
+
subst = unless args.empty?
|
17
|
+
args_ = args.map {|type| factory.type_1(type) }
|
18
|
+
RBS::Substitution.build(ancestors.params, args_)
|
19
|
+
end
|
20
|
+
|
21
|
+
ancestors.each_ancestor.map do |ancestor|
|
22
|
+
name = factory.type_name(ancestor.name)
|
23
|
+
|
24
|
+
case ancestor
|
25
|
+
when RBS::Definition::Ancestor::Instance
|
26
|
+
args = ancestor.args.map do |type|
|
27
|
+
type = type.sub(subst) if subst
|
28
|
+
factory.type(type)
|
29
|
+
end
|
30
|
+
|
31
|
+
if ancestor.name.class?
|
32
|
+
AST::Types::Name::Instance.new(
|
33
|
+
name: name,
|
34
|
+
args: args,
|
35
|
+
location: nil
|
36
|
+
)
|
37
|
+
else
|
38
|
+
AST::Types::Name::Interface.new(
|
39
|
+
name: name,
|
40
|
+
args: args,
|
41
|
+
location: nil
|
42
|
+
)
|
43
|
+
end
|
44
|
+
when RBS::Definition::Ancestor::Singleton
|
45
|
+
AST::Types::Name::Class.new(
|
46
|
+
name: name,
|
47
|
+
constructor: nil,
|
48
|
+
location: nil
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def singleton_super_types(type_name)
|
55
|
+
type_name_1 = factory.type_name_1(type_name)
|
56
|
+
ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
|
57
|
+
|
58
|
+
ancestors.each_ancestor.map do |ancestor|
|
59
|
+
name = factory.type_name(ancestor.name)
|
60
|
+
|
61
|
+
case ancestor
|
62
|
+
when RBS::Definition::Ancestor::Instance
|
63
|
+
args = ancestor.args.map do |type|
|
64
|
+
factory.type(type)
|
65
|
+
end
|
66
|
+
|
67
|
+
if ancestor.name.class?
|
68
|
+
AST::Types::Name::Instance.new(
|
69
|
+
name: name,
|
70
|
+
args: args,
|
71
|
+
location: nil
|
72
|
+
)
|
73
|
+
else
|
74
|
+
AST::Types::Name::Interface.new(
|
75
|
+
name: name,
|
76
|
+
args: args,
|
77
|
+
location: nil
|
78
|
+
)
|
79
|
+
end
|
80
|
+
when RBS::Definition::Ancestor::Singleton
|
81
|
+
AST::Types::Name::Class.new(
|
82
|
+
name: name,
|
83
|
+
constructor: nil,
|
84
|
+
location: nil
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
12
90
|
def check(relation, constraints:, self_type:, assumption: Set.new, trace: Trace.new)
|
13
91
|
Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
|
14
92
|
prefix = trace.size
|
@@ -102,15 +180,6 @@ module Steep
|
|
102
180
|
constraints: constraints
|
103
181
|
)
|
104
182
|
|
105
|
-
when relation.sub_type.is_a?(AST::Types::Literal)
|
106
|
-
check(
|
107
|
-
Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
|
108
|
-
self_type: self_type,
|
109
|
-
assumption: assumption,
|
110
|
-
trace: trace,
|
111
|
-
constraints: constraints
|
112
|
-
)
|
113
|
-
|
114
183
|
when relation.sub_type.is_a?(AST::Types::Union)
|
115
184
|
results = relation.sub_type.types.map do |sub_type|
|
116
185
|
check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
|
@@ -175,30 +244,45 @@ module Steep
|
|
175
244
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
176
245
|
trace: trace)
|
177
246
|
|
178
|
-
when relation.
|
179
|
-
|
180
|
-
|
181
|
-
Relation.new(sub_type: sub, super_type: sup).yield_self do |rel|
|
182
|
-
[rel, rel.flip]
|
183
|
-
end
|
184
|
-
end.map do |relation|
|
185
|
-
check(relation,
|
186
|
-
self_type: self_type,
|
187
|
-
assumption: assumption,
|
188
|
-
trace: trace,
|
189
|
-
constraints: constraints)
|
190
|
-
end
|
247
|
+
when relation.super_type.is_a?(AST::Types::Name::Interface)
|
248
|
+
sub_interface = factory.interface(relation.sub_type, private: false)
|
249
|
+
super_interface = factory.interface(relation.super_type, private: false)
|
191
250
|
|
192
|
-
|
193
|
-
|
251
|
+
check_interface(sub_interface,
|
252
|
+
super_interface,
|
253
|
+
self_type: self_type,
|
254
|
+
assumption: assumption,
|
255
|
+
trace: trace,
|
256
|
+
constraints: constraints)
|
257
|
+
|
258
|
+
when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
|
259
|
+
if relation.sub_type.name == relation.super_type.name && relation.sub_type.class == relation.super_type.class
|
260
|
+
if arg_type?(relation.sub_type) && arg_type?(relation.super_type)
|
261
|
+
check_type_arg(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
194
262
|
else
|
195
|
-
|
263
|
+
success(constraints: constraints)
|
196
264
|
end
|
197
265
|
else
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
266
|
+
possible_sub_types = case relation.sub_type
|
267
|
+
when AST::Types::Name::Instance
|
268
|
+
instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
|
269
|
+
when AST::Types::Name::Class
|
270
|
+
singleton_super_types(relation.sub_type.name)
|
271
|
+
else
|
272
|
+
[]
|
273
|
+
end
|
274
|
+
|
275
|
+
unless possible_sub_types.empty?
|
276
|
+
success_any?(possible_sub_types) do |sub_type|
|
277
|
+
check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
|
278
|
+
self_type: self_type,
|
279
|
+
assumption: assumption,
|
280
|
+
trace: trace,
|
281
|
+
constraints: constraints)
|
282
|
+
end
|
283
|
+
else
|
284
|
+
failure(error: Result::Failure::UnknownPairError.new(relation: relation), trace: trace)
|
285
|
+
end
|
202
286
|
end
|
203
287
|
|
204
288
|
when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
|
@@ -234,16 +318,17 @@ module Steep
|
|
234
318
|
trace: trace)
|
235
319
|
end
|
236
320
|
|
237
|
-
when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type
|
238
|
-
|
239
|
-
|
321
|
+
when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
|
322
|
+
tuple_element_type = AST::Types::Union.build(
|
323
|
+
types: relation.sub_type.types,
|
324
|
+
location: relation.sub_type.location
|
325
|
+
)
|
240
326
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
constraints: constraints)
|
327
|
+
check(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]),
|
328
|
+
self_type: self_type,
|
329
|
+
assumption: assumption,
|
330
|
+
trace: trace,
|
331
|
+
constraints: constraints)
|
247
332
|
|
248
333
|
when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
|
249
334
|
if Set.new(relation.sub_type.elements.keys).superset?(Set.new(relation.super_type.elements.keys))
|
@@ -276,6 +361,32 @@ module Steep
|
|
276
361
|
trace: trace,
|
277
362
|
constraints: constraints)
|
278
363
|
|
364
|
+
when relation.super_type.is_a?(AST::Types::Literal)
|
365
|
+
case
|
366
|
+
when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
|
367
|
+
success(constraints: constraints)
|
368
|
+
when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
|
369
|
+
success(constraints: constraints)
|
370
|
+
else
|
371
|
+
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
372
|
+
trace: trace)
|
373
|
+
end
|
374
|
+
|
375
|
+
when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
|
376
|
+
success(constraints: constraints)
|
377
|
+
|
378
|
+
when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
|
379
|
+
success(constraints: constraints)
|
380
|
+
|
381
|
+
when relation.sub_type.is_a?(AST::Types::Literal)
|
382
|
+
check(
|
383
|
+
Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
|
384
|
+
self_type: self_type,
|
385
|
+
assumption: assumption,
|
386
|
+
trace: trace,
|
387
|
+
constraints: constraints
|
388
|
+
)
|
389
|
+
|
279
390
|
else
|
280
391
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
281
392
|
trace: trace)
|
@@ -283,6 +394,80 @@ module Steep
|
|
283
394
|
end
|
284
395
|
end
|
285
396
|
|
397
|
+
def definition_for_type(type)
|
398
|
+
type_name = factory.type_name_1(type.name)
|
399
|
+
|
400
|
+
case type
|
401
|
+
when AST::Types::Name::Instance
|
402
|
+
factory.definition_builder.build_instance(type_name)
|
403
|
+
when AST::Types::Name::Class
|
404
|
+
factory.definition_builder.build_singleton(type_name)
|
405
|
+
when AST::Types::Name::Interface
|
406
|
+
factory.definition_builder.build_interface(type_name)
|
407
|
+
else
|
408
|
+
raise
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
def arg_type?(type)
|
413
|
+
case type
|
414
|
+
when AST::Types::Name::Instance, AST::Types::Name::Interface
|
415
|
+
type.args.size > 0
|
416
|
+
else
|
417
|
+
false
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def check_type_arg(relation, self_type:, assumption:, trace:, constraints:)
|
422
|
+
sub_args = relation.sub_type.args
|
423
|
+
sup_args = relation.super_type.args
|
424
|
+
|
425
|
+
sup_def = definition_for_type(relation.super_type)
|
426
|
+
sup_params = sup_def.type_params_decl
|
427
|
+
|
428
|
+
success_all?(sub_args.zip(sup_args, sup_params.each)) do |sub_arg, sup_arg, sup_param|
|
429
|
+
case sup_param.variance
|
430
|
+
when :covariant
|
431
|
+
check(Relation.new(sub_type: sub_arg, super_type: sup_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
432
|
+
when :contravariant
|
433
|
+
check(Relation.new(sub_type: sup_arg, super_type: sub_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
434
|
+
when :invariant
|
435
|
+
rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
|
436
|
+
success_all?([rel, rel.flip]) do |r|
|
437
|
+
check(r, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def success_all?(collection, &block)
|
444
|
+
results = collection.map do |obj|
|
445
|
+
result = yield(obj)
|
446
|
+
|
447
|
+
if result.failure?
|
448
|
+
return result
|
449
|
+
end
|
450
|
+
|
451
|
+
result
|
452
|
+
end
|
453
|
+
|
454
|
+
results[0]
|
455
|
+
end
|
456
|
+
|
457
|
+
def success_any?(collection, &block)
|
458
|
+
results = collection.map do |obj|
|
459
|
+
result = yield(obj)
|
460
|
+
|
461
|
+
if result.success?
|
462
|
+
return result
|
463
|
+
end
|
464
|
+
|
465
|
+
result
|
466
|
+
end
|
467
|
+
|
468
|
+
results[0]
|
469
|
+
end
|
470
|
+
|
286
471
|
def extract_nominal_pairs(relation)
|
287
472
|
sub_type = relation.sub_type
|
288
473
|
super_type = relation.super_type
|
@@ -316,20 +501,7 @@ module Steep
|
|
316
501
|
return true
|
317
502
|
end
|
318
503
|
|
319
|
-
|
320
|
-
when relation.sub_type == relation.super_type
|
321
|
-
true
|
322
|
-
when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
|
323
|
-
if (pairs = extract_nominal_pairs(relation))
|
324
|
-
pairs.all? do |(s, t)|
|
325
|
-
same_type?(Relation.new(sub_type: s, super_type: t), assumption: assumption)
|
326
|
-
end
|
327
|
-
else
|
328
|
-
false
|
329
|
-
end
|
330
|
-
else
|
331
|
-
false
|
332
|
-
end
|
504
|
+
relation.sub_type == relation.super_type
|
333
505
|
end
|
334
506
|
|
335
507
|
def check_interface(sub_interface, super_interface, self_type:, assumption:, trace:, constraints:)
|