steep 0.19.0 → 0.24.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 +26 -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/project/target.rb +12 -1
- 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/subtyping/check.rb +214 -43
- data/lib/steep/type_construction.rb +152 -65
- data/lib/steep/typing.rb +6 -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: 3fc0de639f659b9b59f83ca0f8968550e7230ee1dbb6ae8e0d005325267ab46e
|
4
|
+
data.tar.gz: a1f73b521a222fa1313c2f58b1e0d3fb2a07149aba42c17e91c8df495e3319de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcedd630c3b51bc4d3a24549c6bcde88156af410be2b64ec51d813c238f3cb5d5f9f85b980302cae3cacd007e478ae51f99019ed10f3b6a31df84723bd43f35b
|
7
|
+
data.tar.gz: da09a3c3e7f762ec48b378533b6c624c1b9590a0cfd58ffc7aed87212fde2c67897bc1aa745eaa8f4baeaa19b1e6c7b0a4826e7fb6e582a6ef6798ee3b4a47a4
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.24.0 (2020-08-11)
|
6
|
+
|
7
|
+
* Update RBS to 0.10 ([#180](https://github.com/soutaro/steep/pull/180))
|
8
|
+
|
9
|
+
## 0.23.0 (2020-08-06)
|
10
|
+
|
11
|
+
* Fix literal typing with hint ([#179](https://github.com/soutaro/steep/pull/179))
|
12
|
+
* Fix literal type subtyping ([#178](https://github.com/soutaro/steep/pull/178))
|
13
|
+
|
14
|
+
## 0.22.0 (2020-08-03)
|
15
|
+
|
16
|
+
* Improve signature validation ([#175](https://github.com/soutaro/steep/pull/175), [#177](https://github.com/soutaro/steep/pull/177))
|
17
|
+
* Fix boolean literal typing ([#172](https://github.com/soutaro/steep/pull/172))
|
18
|
+
* Make exit code success when Steep has unreported type errors ([#171](https://github.com/soutaro/steep/pull/171))
|
19
|
+
* Allow `./` prefix for signature pattern ([#170](https://github.com/soutaro/steep/pull/170))
|
20
|
+
|
21
|
+
## 0.21.0 (2020-07-20)
|
22
|
+
|
23
|
+
* Fix LSP hover ([#168](https://github.com/soutaro/steep/pull/168))
|
24
|
+
* Nominal subtyping ([#167](https://github.com/soutaro/steep/pull/167))
|
25
|
+
|
26
|
+
## 0.20.0 (2020-07-17)
|
27
|
+
|
28
|
+
* Support singleton class definitions ([#166](https://github.com/soutaro/steep/pull/166))
|
29
|
+
|
5
30
|
## 0.19.0 (2020-07-12)
|
6
31
|
|
7
32
|
* Update RBS. ([#157](https://github.com/soutaro/steep/pull/157))
|
@@ -35,7 +60,7 @@
|
|
35
60
|
|
36
61
|
* Fix constant resolution ([#143](https://github.com/soutaro/steep/pull/143))
|
37
62
|
* Fix RBS diagnostics line number in LSP ([#142](https://github.com/soutaro/steep/pull/142))
|
38
|
-
* Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
|
63
|
+
* Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
|
39
64
|
|
40
65
|
## 0.16.0 (2020-05-19)
|
41
66
|
|
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/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,6 +161,16 @@ 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
|
164
175
|
@status = SignatureOtherErrorStatus.new(error: exn, timestamp: Time.now)
|
165
176
|
end
|
@@ -205,7 +216,7 @@ module Steep
|
|
205
216
|
def errors
|
206
217
|
case status
|
207
218
|
when TypeCheckStatus
|
208
|
-
source_files.each_value.flat_map(&:errors)
|
219
|
+
source_files.each_value.flat_map(&:errors).select { |error | options.error_to_report?(error) }
|
209
220
|
else
|
210
221
|
[]
|
211
222
|
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
|
@@ -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)
|
@@ -276,6 +360,32 @@ module Steep
|
|
276
360
|
trace: trace,
|
277
361
|
constraints: constraints)
|
278
362
|
|
363
|
+
when relation.super_type.is_a?(AST::Types::Literal)
|
364
|
+
case
|
365
|
+
when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
|
366
|
+
success(constraints: constraints)
|
367
|
+
when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
|
368
|
+
success(constraints: constraints)
|
369
|
+
else
|
370
|
+
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
371
|
+
trace: trace)
|
372
|
+
end
|
373
|
+
|
374
|
+
when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
|
375
|
+
success(constraints: constraints)
|
376
|
+
|
377
|
+
when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
|
378
|
+
success(constraints: constraints)
|
379
|
+
|
380
|
+
when relation.sub_type.is_a?(AST::Types::Literal)
|
381
|
+
check(
|
382
|
+
Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
|
383
|
+
self_type: self_type,
|
384
|
+
assumption: assumption,
|
385
|
+
trace: trace,
|
386
|
+
constraints: constraints
|
387
|
+
)
|
388
|
+
|
279
389
|
else
|
280
390
|
failure(error: Result::Failure::UnknownPairError.new(relation: relation),
|
281
391
|
trace: trace)
|
@@ -283,6 +393,80 @@ module Steep
|
|
283
393
|
end
|
284
394
|
end
|
285
395
|
|
396
|
+
def definition_for_type(type)
|
397
|
+
type_name = factory.type_name_1(type.name)
|
398
|
+
|
399
|
+
case type
|
400
|
+
when AST::Types::Name::Instance
|
401
|
+
factory.definition_builder.build_instance(type_name)
|
402
|
+
when AST::Types::Name::Class
|
403
|
+
factory.definition_builder.build_singleton(type_name)
|
404
|
+
when AST::Types::Name::Interface
|
405
|
+
factory.definition_builder.build_interface(type_name)
|
406
|
+
else
|
407
|
+
raise
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def arg_type?(type)
|
412
|
+
case type
|
413
|
+
when AST::Types::Name::Instance, AST::Types::Name::Interface
|
414
|
+
type.args.size > 0
|
415
|
+
else
|
416
|
+
false
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
def check_type_arg(relation, self_type:, assumption:, trace:, constraints:)
|
421
|
+
sub_args = relation.sub_type.args
|
422
|
+
sup_args = relation.super_type.args
|
423
|
+
|
424
|
+
sup_def = definition_for_type(relation.super_type)
|
425
|
+
sup_params = sup_def.type_params_decl
|
426
|
+
|
427
|
+
success_all?(sub_args.zip(sup_args, sup_params.each)) do |sub_arg, sup_arg, sup_param|
|
428
|
+
case sup_param.variance
|
429
|
+
when :covariant
|
430
|
+
check(Relation.new(sub_type: sub_arg, super_type: sup_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
431
|
+
when :contravariant
|
432
|
+
check(Relation.new(sub_type: sup_arg, super_type: sub_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
433
|
+
when :invariant
|
434
|
+
rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
|
435
|
+
success_all?([rel, rel.flip]) do |r|
|
436
|
+
check(r, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
def success_all?(collection, &block)
|
443
|
+
results = collection.map do |obj|
|
444
|
+
result = yield(obj)
|
445
|
+
|
446
|
+
if result.failure?
|
447
|
+
return result
|
448
|
+
end
|
449
|
+
|
450
|
+
result
|
451
|
+
end
|
452
|
+
|
453
|
+
results[0]
|
454
|
+
end
|
455
|
+
|
456
|
+
def success_any?(collection, &block)
|
457
|
+
results = collection.map do |obj|
|
458
|
+
result = yield(obj)
|
459
|
+
|
460
|
+
if result.success?
|
461
|
+
return result
|
462
|
+
end
|
463
|
+
|
464
|
+
result
|
465
|
+
end
|
466
|
+
|
467
|
+
results[0]
|
468
|
+
end
|
469
|
+
|
286
470
|
def extract_nominal_pairs(relation)
|
287
471
|
sub_type = relation.sub_type
|
288
472
|
super_type = relation.super_type
|
@@ -316,20 +500,7 @@ module Steep
|
|
316
500
|
return true
|
317
501
|
end
|
318
502
|
|
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
|
503
|
+
relation.sub_type == relation.super_type
|
333
504
|
end
|
334
505
|
|
335
506
|
def check_interface(sub_interface, super_interface, self_type:, assumption:, trace:, constraints:)
|
@@ -230,6 +230,39 @@ module Steep
|
|
230
230
|
)
|
231
231
|
end
|
232
232
|
|
233
|
+
def implement_module(module_name:, super_name: nil, annotations:)
|
234
|
+
if (annotation = annotations.implement_module_annotation)
|
235
|
+
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
236
|
+
if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
237
|
+
AST::Annotation::Implements::Module.new(
|
238
|
+
name: absolute_name,
|
239
|
+
args: annotation.name.args
|
240
|
+
)
|
241
|
+
else
|
242
|
+
Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
|
243
|
+
nil
|
244
|
+
end
|
245
|
+
end
|
246
|
+
else
|
247
|
+
name = nil
|
248
|
+
name ||= absolute_name(module_name).yield_self do |absolute_name|
|
249
|
+
absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
250
|
+
end
|
251
|
+
name ||= super_name && absolute_name(super_name).yield_self do |absolute_name|
|
252
|
+
absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
|
253
|
+
end
|
254
|
+
|
255
|
+
if name
|
256
|
+
absolute_name_ = checker.factory.type_name_1(name)
|
257
|
+
entry = checker.factory.env.class_decls[absolute_name_]
|
258
|
+
AST::Annotation::Implements::Module.new(
|
259
|
+
name: name,
|
260
|
+
args: entry.type_params.each.map(&:name)
|
261
|
+
)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
233
266
|
def for_module(node)
|
234
267
|
new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
|
235
268
|
new_namespace = nested_namespace_for_module(new_module_name)
|
@@ -240,28 +273,7 @@ module Steep
|
|
240
273
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
241
274
|
module_type = AST::Builtin::Module.instance_type
|
242
275
|
|
243
|
-
implement_module_name =
|
244
|
-
if (annotation = annots.implement_module_annotation)
|
245
|
-
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
246
|
-
if checker.factory.module_name?(absolute_name)
|
247
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
248
|
-
args: annotation.name.args)
|
249
|
-
else
|
250
|
-
Steep.logger.error "Unknown module name given to @implements: #{annotation.name.name}"
|
251
|
-
nil
|
252
|
-
end
|
253
|
-
end
|
254
|
-
else
|
255
|
-
absolute_name(new_module_name).yield_self do |absolute_name|
|
256
|
-
if checker.factory.module_name?(absolute_name)
|
257
|
-
absolute_name_ = checker.factory.type_name_1(absolute_name)
|
258
|
-
entry = checker.factory.env.class_decls[absolute_name_]
|
259
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
260
|
-
args: entry.type_params.each.map(&:name))
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
276
|
+
implement_module_name = implement_module(module_name: new_module_name, annotations: annots)
|
265
277
|
|
266
278
|
if implement_module_name
|
267
279
|
module_name = implement_module_name.name
|
@@ -352,36 +364,7 @@ module Steep
|
|
352
364
|
|
353
365
|
annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
|
354
366
|
|
355
|
-
implement_module_name =
|
356
|
-
if (annotation = annots.implement_module_annotation)
|
357
|
-
absolute_name(annotation.name.name).yield_self do |absolute_name|
|
358
|
-
if checker.factory.class_name?(absolute_name)
|
359
|
-
AST::Annotation::Implements::Module.new(name: absolute_name,
|
360
|
-
args: annotation.name.args)
|
361
|
-
else
|
362
|
-
Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
|
363
|
-
nil
|
364
|
-
end
|
365
|
-
end
|
366
|
-
else
|
367
|
-
name = nil
|
368
|
-
name ||= absolute_name(new_class_name).yield_self do |absolute_name|
|
369
|
-
absolute_name if checker.factory.class_name?(absolute_name)
|
370
|
-
end
|
371
|
-
name ||= super_class_name && absolute_name(super_class_name).yield_self do |absolute_name|
|
372
|
-
absolute_name if checker.factory.class_name?(absolute_name)
|
373
|
-
end
|
374
|
-
|
375
|
-
if name
|
376
|
-
absolute_name_ = checker.factory.type_name_1(name)
|
377
|
-
entry = checker.factory.env.class_decls[absolute_name_]
|
378
|
-
AST::Annotation::Implements::Module.new(
|
379
|
-
name: name,
|
380
|
-
args: entry.type_params.each.map(&:name)
|
381
|
-
)
|
382
|
-
end
|
383
|
-
end
|
384
|
-
end
|
367
|
+
implement_module_name = implement_module(module_name: new_class_name, super_name: super_class_name, annotations: annots)
|
385
368
|
|
386
369
|
if annots.implement_module_annotation
|
387
370
|
new_class_name = implement_module_name.name
|
@@ -450,6 +433,83 @@ module Steep
|
|
450
433
|
)
|
451
434
|
end
|
452
435
|
|
436
|
+
def for_sclass(node, type)
|
437
|
+
annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
438
|
+
|
439
|
+
instance_type = if type.is_a?(AST::Types::Self)
|
440
|
+
context.self_type
|
441
|
+
else
|
442
|
+
type
|
443
|
+
end
|
444
|
+
|
445
|
+
module_type = case instance_type
|
446
|
+
when AST::Types::Name::Class
|
447
|
+
AST::Builtin::Class.instance_type
|
448
|
+
when AST::Types::Name::Module
|
449
|
+
AST::Builtin::Module.instance_type
|
450
|
+
when AST::Types::Name::Instance
|
451
|
+
instance_type.to_class(constructor: nil)
|
452
|
+
else
|
453
|
+
raise "Unexpected type for sclass node: #{type}"
|
454
|
+
end
|
455
|
+
|
456
|
+
instance_definition = case instance_type
|
457
|
+
when AST::Types::Name::Class, AST::Types::Name::Module
|
458
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
459
|
+
checker.factory.definition_builder.build_singleton(type_name)
|
460
|
+
when AST::Types::Name::Instance
|
461
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
462
|
+
checker.factory.definition_builder.build_instance(type_name)
|
463
|
+
end
|
464
|
+
|
465
|
+
module_definition = case module_type
|
466
|
+
when AST::Types::Name::Class, AST::Types::Name::Module
|
467
|
+
type_name = checker.factory.type_name_1(instance_type.name)
|
468
|
+
checker.factory.definition_builder.build_singleton(type_name)
|
469
|
+
else
|
470
|
+
nil
|
471
|
+
end
|
472
|
+
|
473
|
+
module_context = TypeInference::Context::ModuleContext.new(
|
474
|
+
instance_type: annots.instance_type || instance_type,
|
475
|
+
module_type: annots.self_type || annots.module_type || module_type,
|
476
|
+
implement_name: nil,
|
477
|
+
current_namespace: current_namespace,
|
478
|
+
const_env: self.module_context.const_env,
|
479
|
+
class_name: self.module_context.class_name,
|
480
|
+
module_definition: module_definition,
|
481
|
+
instance_definition: instance_definition
|
482
|
+
)
|
483
|
+
|
484
|
+
type_env = TypeInference::TypeEnv.build(annotations: annots,
|
485
|
+
subtyping: checker,
|
486
|
+
const_env: self.module_context.const_env,
|
487
|
+
signatures: checker.factory.env)
|
488
|
+
|
489
|
+
lvar_env = TypeInference::LocalVariableTypeEnv.empty(
|
490
|
+
subtyping: checker,
|
491
|
+
self_type: module_context.module_type
|
492
|
+
).annotate(annots)
|
493
|
+
|
494
|
+
body_context = TypeInference::Context.new(
|
495
|
+
method_context: nil,
|
496
|
+
block_context: nil,
|
497
|
+
module_context: module_context,
|
498
|
+
break_context: nil,
|
499
|
+
self_type: module_context.module_type,
|
500
|
+
type_env: type_env,
|
501
|
+
lvar_env: lvar_env
|
502
|
+
)
|
503
|
+
|
504
|
+
self.class.new(
|
505
|
+
checker: checker,
|
506
|
+
source: source,
|
507
|
+
annotations: annots,
|
508
|
+
typing: typing,
|
509
|
+
context: body_context
|
510
|
+
)
|
511
|
+
end
|
512
|
+
|
453
513
|
def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
|
454
514
|
annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
|
455
515
|
|
@@ -578,7 +638,8 @@ module Steep
|
|
578
638
|
when :__skip__
|
579
639
|
add_typing(node, type: AST::Builtin.any_type)
|
580
640
|
else
|
581
|
-
|
641
|
+
hint ||= context.lvar_env.declared_types[name]&.type
|
642
|
+
rhs_result = synthesize(rhs, hint: hint)
|
582
643
|
|
583
644
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
584
645
|
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
@@ -1002,7 +1063,7 @@ module Steep
|
|
1002
1063
|
|
1003
1064
|
when :int
|
1004
1065
|
yield_self do
|
1005
|
-
literal_type =
|
1066
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1006
1067
|
|
1007
1068
|
if literal_type
|
1008
1069
|
add_typing(node, type: literal_type)
|
@@ -1013,7 +1074,7 @@ module Steep
|
|
1013
1074
|
|
1014
1075
|
when :sym
|
1015
1076
|
yield_self do
|
1016
|
-
literal_type =
|
1077
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1017
1078
|
|
1018
1079
|
if literal_type
|
1019
1080
|
add_typing(node, type: literal_type)
|
@@ -1024,7 +1085,7 @@ module Steep
|
|
1024
1085
|
|
1025
1086
|
when :str
|
1026
1087
|
yield_self do
|
1027
|
-
literal_type =
|
1088
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1028
1089
|
|
1029
1090
|
if literal_type
|
1030
1091
|
add_typing(node, type: literal_type)
|
@@ -1034,7 +1095,13 @@ module Steep
|
|
1034
1095
|
end
|
1035
1096
|
|
1036
1097
|
when :true, :false
|
1037
|
-
|
1098
|
+
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1099
|
+
|
1100
|
+
if hint && check_relation(sub_type: ty, super_type: hint).success?
|
1101
|
+
add_typing(node, type: hint)
|
1102
|
+
else
|
1103
|
+
add_typing(node, type: AST::Types::Boolean.new)
|
1104
|
+
end
|
1038
1105
|
|
1039
1106
|
when :hash
|
1040
1107
|
yield_self do
|
@@ -1130,6 +1197,25 @@ module Steep
|
|
1130
1197
|
add_typing(node, type: AST::Builtin.nil_type)
|
1131
1198
|
end
|
1132
1199
|
|
1200
|
+
when :sclass
|
1201
|
+
yield_self do
|
1202
|
+
type, constr = synthesize(node.children[0])
|
1203
|
+
constructor = constr.for_sclass(node, type)
|
1204
|
+
|
1205
|
+
constructor.typing.add_context_for_node(node, context: constructor.context)
|
1206
|
+
constructor.typing.add_context_for_body(node, context: constructor.context)
|
1207
|
+
|
1208
|
+
constructor.synthesize(node.children[1]) if node.children[1]
|
1209
|
+
|
1210
|
+
if constructor.module_context.instance_definition && module_context.module_definition
|
1211
|
+
if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
|
1212
|
+
module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
|
1213
|
+
end
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
add_typing(node, type: AST::Builtin.nil_type)
|
1217
|
+
end
|
1218
|
+
|
1133
1219
|
when :self
|
1134
1220
|
add_typing node, type: AST::Types::Self.new
|
1135
1221
|
|
@@ -2937,14 +3023,15 @@ module Steep
|
|
2937
3023
|
end
|
2938
3024
|
|
2939
3025
|
def test_literal_type(literal, hint)
|
2940
|
-
|
2941
|
-
|
2942
|
-
|
2943
|
-
|
2944
|
-
|
2945
|
-
|
2946
|
-
|
2947
|
-
|
3026
|
+
if hint
|
3027
|
+
case hint
|
3028
|
+
when AST::Types::Any
|
3029
|
+
nil
|
3030
|
+
else
|
3031
|
+
literal_type = AST::Types::Literal.new(value: literal, location: nil)
|
3032
|
+
if check_relation(sub_type: literal_type, super_type: hint).success?
|
3033
|
+
hint
|
3034
|
+
end
|
2948
3035
|
end
|
2949
3036
|
end
|
2950
3037
|
end
|
data/lib/steep/typing.rb
CHANGED
@@ -95,6 +95,12 @@ module Steep
|
|
95
95
|
end_pos = node.loc.end.begin_pos
|
96
96
|
add_context(begin_pos..end_pos, context: context)
|
97
97
|
|
98
|
+
when :sclass
|
99
|
+
name_node = node.children[0]
|
100
|
+
begin_pos = name_node.loc.expression.end_pos
|
101
|
+
end_pos = node.loc.end.begin_pos
|
102
|
+
add_context(begin_pos..end_pos, context: context)
|
103
|
+
|
98
104
|
when :def, :defs
|
99
105
|
args_node = case node.type
|
100
106
|
when :def
|
data/lib/steep/version.rb
CHANGED
data/smoke/class/a.rbs
CHANGED
data/smoke/class/f.rb
CHANGED
data/steep.gemspec
CHANGED
@@ -28,18 +28,11 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
spec.required_ruby_version = '>= 2.6.0'
|
30
30
|
|
31
|
-
spec.add_development_dependency "bundler", ">= 1.13"
|
32
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
33
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
34
|
-
spec.add_development_dependency "racc", "~> 1.4"
|
35
|
-
spec.add_development_dependency "minitest-reporters", "~> 1.4.2"
|
36
|
-
spec.add_development_dependency "minitest-hooks", "~> 1.5.0"
|
37
|
-
|
38
31
|
spec.add_runtime_dependency "parser", "~> 2.7.0"
|
39
32
|
spec.add_runtime_dependency "ast_utils", "~> 0.3.0"
|
40
33
|
spec.add_runtime_dependency "activesupport", ">= 5.1"
|
41
34
|
spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
|
42
35
|
spec.add_runtime_dependency "listen", "~> 3.1"
|
43
36
|
spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.2"
|
44
|
-
spec.add_runtime_dependency "rbs", "
|
37
|
+
spec.add_runtime_dependency "rbs", "~> 0.10.0"
|
45
38
|
end
|
metadata
CHANGED
@@ -1,99 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.13'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.13'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '13.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '13.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: minitest
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '5.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '5.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: racc
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.4'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.4'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest-reporters
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 1.4.2
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 1.4.2
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: minitest-hooks
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 1.5.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 1.5.0
|
97
13
|
- !ruby/object:Gem::Dependency
|
98
14
|
name: parser
|
99
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,22 +104,16 @@ dependencies:
|
|
188
104
|
name: rbs
|
189
105
|
requirement: !ruby/object:Gem::Requirement
|
190
106
|
requirements:
|
191
|
-
- - "
|
192
|
-
- !ruby/object:Gem::Version
|
193
|
-
version: 0.6.0
|
194
|
-
- - "<"
|
107
|
+
- - "~>"
|
195
108
|
- !ruby/object:Gem::Version
|
196
|
-
version: 0.
|
109
|
+
version: 0.10.0
|
197
110
|
type: :runtime
|
198
111
|
prerelease: false
|
199
112
|
version_requirements: !ruby/object:Gem::Requirement
|
200
113
|
requirements:
|
201
|
-
- - "
|
202
|
-
- !ruby/object:Gem::Version
|
203
|
-
version: 0.6.0
|
204
|
-
- - "<"
|
114
|
+
- - "~>"
|
205
115
|
- !ruby/object:Gem::Version
|
206
|
-
version: 0.
|
116
|
+
version: 0.10.0
|
207
117
|
description: Gradual Typing for Ruby
|
208
118
|
email:
|
209
119
|
- matsumoto@soutaro.com
|
@@ -224,6 +134,7 @@ files:
|
|
224
134
|
- bin/console
|
225
135
|
- bin/setup
|
226
136
|
- bin/smoke_runner.rb
|
137
|
+
- bin/steep-prof
|
227
138
|
- exe/steep
|
228
139
|
- lib/steep.rb
|
229
140
|
- lib/steep/annotation_parser.rb
|