steep 1.7.0 → 1.8.0.dev.1
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 +6 -0
- data/doc/shape.md +18 -0
- data/lib/steep/interface/builder.rb +11 -4
- data/lib/steep/signature/validator.rb +184 -132
- data/lib/steep/source.rb +28 -2
- data/lib/steep/subtyping/check.rb +25 -21
- data/lib/steep/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 635cc7b37608055562fc399845485f40c065e7300072a2ca194ea15137a0ac11
|
4
|
+
data.tar.gz: c16be740c2d1a8a11ece00fc3abbca6b33a715ddbbfb0a210bc8e09287e2c7d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 164e5369654bc6ef2bd0ef355b796f3b9ee2c43a1887501cfc0282c8cccedc84a2d3a61a4ca257c51ea2500f342f5ad7c9496e03b29d1433aee81c020bae18db
|
7
|
+
data.tar.gz: 03ba49762f19dda444ff5a73a08eca0417ef02d89bed4039ccbc01c07cb1d59e05714583cfaa654dff5597e55ebc55844a038483ec1a46068cd8613f9d575c78
|
data/CHANGELOG.md
CHANGED
data/doc/shape.md
CHANGED
@@ -24,7 +24,9 @@ Shape (_Foo) {
|
|
24
24
|
Note that the `self` type in the example is resolved to `_Foo` during shape calculation.
|
25
25
|
|
26
26
|
The shape calculation of an object is straightforward. Calculate a `RBS::Definition` of a class singleton/instance, or an interface, and translate the data structure to a `Shape` object. But there are a few things to consider.
|
27
|
+
|
27
28
|
## Tuple, record, and proc types
|
29
|
+
|
28
30
|
The shape of tuple, record, or proc types are based on their base types -- Array, Hash, or Proc classes --, but with specialized method types.
|
29
31
|
|
30
32
|
```
|
@@ -37,16 +39,22 @@ Shape ([Integer, String]) {
|
|
37
39
|
```
|
38
40
|
|
39
41
|
The specialization is implemented as a part of shape calculation.
|
42
|
+
|
40
43
|
## Special methods
|
44
|
+
|
41
45
|
Steep recognizes some special methods for type narrowing, including `#is_a?`, `#===`, `#nil?`, ... These methods are defined with normal RBS syntax, but the method types in shapes are transformed to types using logic types.
|
42
46
|
|
43
47
|
The shape calculation inserts the specialized methods with these special methods.
|
48
|
+
|
44
49
|
## `self` types
|
50
|
+
|
45
51
|
There are two cases of `self` types to consider during shape calculation.
|
46
52
|
|
47
53
|
1. `self` types included in the shape of a type
|
48
54
|
2. `self` types included in given types
|
55
|
+
|
49
56
|
### 1. `self` types included in the shape of a type
|
57
|
+
|
50
58
|
`self` types may be included in a class or interface definition.
|
51
59
|
|
52
60
|
```rbs
|
@@ -62,7 +70,9 @@ Shape (_Foo) {
|
|
62
70
|
itself: () -> _Foo
|
63
71
|
}
|
64
72
|
```
|
73
|
+
|
65
74
|
### 2. `self` types included in given types
|
75
|
+
|
66
76
|
Unlike `self` types included in definitions, `self` types in given types should be preserved.
|
67
77
|
|
68
78
|
```rbs
|
@@ -100,7 +110,9 @@ end
|
|
100
110
|
```
|
101
111
|
|
102
112
|
We want the type of `foo.get` to be `self`, not `Foo`, to avoid a type error being detected.
|
113
|
+
|
103
114
|
## Shape of `self` types
|
115
|
+
|
104
116
|
We also want `self` type if `self` is the type of the shape.
|
105
117
|
|
106
118
|
```rb
|
@@ -154,7 +166,9 @@ Shape (Foo | Bar) {
|
|
154
166
|
So, the resulting type of `self.foo` where the type of `self` is `Foo | Bar`, would be `Integer | Foo | Bar`. But, actually, it won't be `Foo` because the `self` comes from `Bar`.
|
155
167
|
|
156
168
|
This is an incorrect result, but Steep is doing this right now.
|
169
|
+
|
157
170
|
## `class` and `instance` types
|
171
|
+
|
158
172
|
The shape calculation provides limited support for `class` and `instance` types.
|
159
173
|
|
160
174
|
1. `class`/`instance` types from the definition are resolved
|
@@ -162,13 +176,17 @@ The shape calculation provides limited support for `class` and `instance` types.
|
|
162
176
|
3. Shape of `class`/`instance` types are resolved to configuration's `class_type` and `instance_type`, and the translated types are used to calculate the shape
|
163
177
|
|
164
178
|
It's different from `self` types except case #2. The relationship between `self`/`class`/`instance` is not trivial in Ruby. All of them might be resolved to any type, which means calculating one from another of them is simply impossible.
|
179
|
+
|
165
180
|
## Public methods, private methods
|
181
|
+
|
166
182
|
`Shape` objects have a flag of if the shape is for *public* method calls or *private* method calls. Private method call is a form of `foo()` or `self.foo()` -- when the receiver is omitted or `self`. Public method calls are anything else.
|
167
183
|
|
168
184
|
The shape calculation starts with *private methods*, and the `Shape#public_shape` method returns another shape that only has *public* methods.
|
169
185
|
|
170
186
|
> Note that the private shape calculation is required even on public method calls. This means a possible chance of future optimizations.
|
187
|
+
|
171
188
|
## Lazy method type calculation
|
189
|
+
|
172
190
|
We rarely need all of the methods available for an object. If we want to type check a method call, we only need the method type of that method. All other methods can be just ignored.
|
173
191
|
|
174
192
|
*Lazy method type calculation* is introduced for that case. Instead of calculating the types of all of the methods, it registers a block that computes the method type.
|
@@ -9,8 +9,6 @@ module Steep
|
|
9
9
|
@class_type = class_type
|
10
10
|
@instance_type = instance_type
|
11
11
|
@variable_bounds = variable_bounds
|
12
|
-
|
13
|
-
validate
|
14
12
|
end
|
15
13
|
|
16
14
|
def self.empty
|
@@ -23,11 +21,16 @@ module Steep
|
|
23
21
|
end
|
24
22
|
end
|
25
23
|
|
26
|
-
def
|
24
|
+
def validate_self_type
|
27
25
|
validate_fvs(:self_type, self_type)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_instance_type
|
28
29
|
validate_fvs(:instance_type, instance_type)
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_class_type
|
29
33
|
validate_fvs(:class_type, class_type)
|
30
|
-
self
|
31
34
|
end
|
32
35
|
|
33
36
|
def validate_fvs(name, type)
|
@@ -37,6 +40,7 @@ module Steep
|
|
37
40
|
raise "#{name} cannot include 'self' type: #{type}"
|
38
41
|
end
|
39
42
|
if fvs.include?(AST::Types::Instance.instance)
|
43
|
+
Steep.logger.fatal { "#{name} cannot include 'instance' type: #{type}" }
|
40
44
|
raise "#{name} cannot include 'instance' type: #{type}"
|
41
45
|
end
|
42
46
|
if fvs.include?(AST::Types::Class.instance)
|
@@ -87,12 +91,15 @@ module Steep
|
|
87
91
|
def raw_shape(type, config)
|
88
92
|
case type
|
89
93
|
when AST::Types::Self
|
94
|
+
config.validate_self_type
|
90
95
|
self_type = config.self_type or raise
|
91
96
|
self_shape(self_type, config)
|
92
97
|
when AST::Types::Instance
|
98
|
+
config.validate_instance_type
|
93
99
|
instance_type = config.instance_type or raise
|
94
100
|
raw_shape(instance_type, config)
|
95
101
|
when AST::Types::Class
|
102
|
+
config.validate_class_type
|
96
103
|
klass_type = config.class_type or raise
|
97
104
|
raw_shape(klass_type, config)
|
98
105
|
when AST::Types::Name::Singleton
|
@@ -5,10 +5,23 @@ module Steep
|
|
5
5
|
Declarations = RBS::AST::Declarations
|
6
6
|
|
7
7
|
attr_reader :checker
|
8
|
+
attr_reader :context
|
8
9
|
|
9
10
|
def initialize(checker:)
|
10
11
|
@checker = checker
|
11
12
|
@errors = []
|
13
|
+
@context = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def push_context(self_type: latest_context[0], class_type: latest_context[1], instance_type: latest_context[2])
|
17
|
+
@context.push([self_type, class_type, instance_type])
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
@context.pop
|
21
|
+
end
|
22
|
+
|
23
|
+
def latest_context
|
24
|
+
context.last || [nil, nil, nil]
|
12
25
|
end
|
13
26
|
|
14
27
|
def has_error?
|
@@ -72,11 +85,13 @@ module Steep
|
|
72
85
|
|
73
86
|
constraints = Subtyping::Constraints.empty
|
74
87
|
|
88
|
+
self_type, class_type, instance_type = latest_context
|
89
|
+
|
75
90
|
checker.check(
|
76
91
|
Subtyping::Relation.new(sub_type: arg_type, super_type: upper_bound_type),
|
77
|
-
self_type:
|
78
|
-
class_type:
|
79
|
-
instance_type:
|
92
|
+
self_type: self_type,
|
93
|
+
class_type: class_type,
|
94
|
+
instance_type: instance_type,
|
80
95
|
constraints: constraints
|
81
96
|
).else do |result|
|
82
97
|
@errors << Diagnostic::Signature::UnsatisfiableTypeApplication.new(
|
@@ -236,25 +251,113 @@ module Steep
|
|
236
251
|
end
|
237
252
|
end
|
238
253
|
|
239
|
-
def validate_one_class_decl(name)
|
254
|
+
def validate_one_class_decl(name, entry)
|
240
255
|
rescue_validation_errors(name) do
|
241
256
|
Steep.logger.debug { "Validating class definition `#{name}`..." }
|
242
257
|
|
258
|
+
class_type = AST::Types::Name::Singleton.new(name: name, location: nil)
|
259
|
+
instance_type = AST::Types::Name::Instance.new(
|
260
|
+
name: name,
|
261
|
+
args: entry.type_params.map { AST::Types::Any.new(location: nil) },
|
262
|
+
location: nil
|
263
|
+
)
|
264
|
+
|
243
265
|
Steep.logger.tagged "#{name}" do
|
244
266
|
builder.build_instance(name).tap do |definition|
|
245
267
|
upper_bounds = definition.type_params_decl.each.with_object({}) do |param, bounds|
|
246
268
|
bounds[param.name] = factory.type_opt(param.upper_bound)
|
247
269
|
end
|
248
270
|
|
249
|
-
|
271
|
+
self_type = AST::Types::Name::Instance.new(
|
272
|
+
name: name,
|
273
|
+
args: entry.type_params.map { AST::Types::Var.new(name: _1.name) },
|
274
|
+
location: nil
|
275
|
+
)
|
276
|
+
|
277
|
+
push_context(self_type: self_type, class_type: class_type, instance_type: instance_type) do
|
278
|
+
checker.push_variable_bounds(upper_bounds) do
|
279
|
+
definition.instance_variables.each do |name, var|
|
280
|
+
if parent = var.parent_variable
|
281
|
+
var_type = checker.factory.type(var.type)
|
282
|
+
parent_type = checker.factory.type(parent.type)
|
283
|
+
|
284
|
+
relation = Subtyping::Relation.new(sub_type: var_type, super_type: parent_type)
|
285
|
+
result1 = checker.check(relation, self_type: nil, instance_type: nil, class_type: nil, constraints: Subtyping::Constraints.empty)
|
286
|
+
result2 = checker.check(relation.flip, self_type: nil, instance_type: nil, class_type: nil, constraints: Subtyping::Constraints.empty)
|
287
|
+
|
288
|
+
unless result1.success? and result2.success?
|
289
|
+
@errors << Diagnostic::Signature::InstanceVariableTypeError.new(
|
290
|
+
name: name,
|
291
|
+
location: var.type.location,
|
292
|
+
var_type: var_type,
|
293
|
+
parent_type: parent_type
|
294
|
+
)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
ancestors = builder.ancestor_builder.one_instance_ancestors(name)
|
300
|
+
mixin_constraints(definition, ancestors.included_modules || raise, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
301
|
+
checker.check(
|
302
|
+
relation,
|
303
|
+
self_type: AST::Types::Self.instance,
|
304
|
+
instance_type: AST::Types::Instance.instance,
|
305
|
+
class_type: AST::Types::Class.instance,
|
306
|
+
constraints: Subtyping::Constraints.empty
|
307
|
+
).else do
|
308
|
+
raise if ancestor.source.is_a?(Symbol)
|
309
|
+
|
310
|
+
@errors << Diagnostic::Signature::ModuleSelfTypeError.new(
|
311
|
+
name: name,
|
312
|
+
location: ancestor.source&.location || raise,
|
313
|
+
ancestor: ancestor,
|
314
|
+
relation: relation
|
315
|
+
)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
ancestors.each_ancestor do |ancestor|
|
320
|
+
case ancestor
|
321
|
+
when RBS::Definition::Ancestor::Instance
|
322
|
+
validate_ancestor_application(name, ancestor)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
validate_definition_type(definition)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
builder.build_singleton(name).tap do |definition|
|
332
|
+
entry =
|
333
|
+
case definition.entry
|
334
|
+
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
335
|
+
definition.entry
|
336
|
+
else
|
337
|
+
raise
|
338
|
+
end
|
339
|
+
|
340
|
+
push_context(self_type: class_type, class_type: class_type, instance_type: instance_type) do
|
250
341
|
definition.instance_variables.each do |name, var|
|
251
342
|
if parent = var.parent_variable
|
252
343
|
var_type = checker.factory.type(var.type)
|
253
344
|
parent_type = checker.factory.type(parent.type)
|
254
345
|
|
255
346
|
relation = Subtyping::Relation.new(sub_type: var_type, super_type: parent_type)
|
256
|
-
result1 = checker.check(
|
257
|
-
|
347
|
+
result1 = checker.check(
|
348
|
+
relation,
|
349
|
+
self_type: AST::Types::Self.instance,
|
350
|
+
instance_type: AST::Types::Instance.instance,
|
351
|
+
class_type: AST::Types::Class.instance,
|
352
|
+
constraints: Subtyping::Constraints.empty
|
353
|
+
)
|
354
|
+
result2 = checker.check(
|
355
|
+
relation.flip,
|
356
|
+
self_type: AST::Types::Self.instance,
|
357
|
+
instance_type: AST::Types::Instance.instance,
|
358
|
+
class_type: AST::Types::Class.instance,
|
359
|
+
constraints: Subtyping::Constraints.empty
|
360
|
+
)
|
258
361
|
|
259
362
|
unless result1.success? and result2.success?
|
260
363
|
@errors << Diagnostic::Signature::InstanceVariableTypeError.new(
|
@@ -267,11 +370,32 @@ module Steep
|
|
267
370
|
end
|
268
371
|
end
|
269
372
|
|
270
|
-
|
271
|
-
|
373
|
+
definition.class_variables.each do |name, var|
|
374
|
+
if var.declared_in == definition.type_name
|
375
|
+
if (parent = var.parent_variable) && var.declared_in != parent.declared_in
|
376
|
+
class_var = entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
|
377
|
+
member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
|
378
|
+
end
|
379
|
+
|
380
|
+
if class_var
|
381
|
+
loc = class_var.location #: RBS::Location[untyped, untyped]?
|
382
|
+
@errors << Diagnostic::Signature::ClassVariableDuplicationError.new(
|
383
|
+
class_name: definition.type_name,
|
384
|
+
other_class_name: parent.declared_in,
|
385
|
+
variable_name: name,
|
386
|
+
location: loc&.[](:name) || raise
|
387
|
+
)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
|
394
|
+
ancestors.extended_modules or raise
|
395
|
+
mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
272
396
|
checker.check(
|
273
397
|
relation,
|
274
|
-
self_type: AST::Types::Self.instance,
|
398
|
+
self_type: AST::Types::Self.instance ,
|
275
399
|
instance_type: AST::Types::Instance.instance,
|
276
400
|
class_type: AST::Types::Class.instance,
|
277
401
|
constraints: Subtyping::Constraints.empty
|
@@ -286,7 +410,6 @@ module Steep
|
|
286
410
|
)
|
287
411
|
end
|
288
412
|
end
|
289
|
-
|
290
413
|
ancestors.each_ancestor do |ancestor|
|
291
414
|
case ancestor
|
292
415
|
when RBS::Definition::Ancestor::Instance
|
@@ -297,97 +420,6 @@ module Steep
|
|
297
420
|
validate_definition_type(definition)
|
298
421
|
end
|
299
422
|
end
|
300
|
-
|
301
|
-
builder.build_singleton(name).tap do |definition|
|
302
|
-
entry =
|
303
|
-
case definition.entry
|
304
|
-
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
305
|
-
definition.entry
|
306
|
-
else
|
307
|
-
raise
|
308
|
-
end
|
309
|
-
|
310
|
-
definition.instance_variables.each do |name, var|
|
311
|
-
if parent = var.parent_variable
|
312
|
-
var_type = checker.factory.type(var.type)
|
313
|
-
parent_type = checker.factory.type(parent.type)
|
314
|
-
|
315
|
-
relation = Subtyping::Relation.new(sub_type: var_type, super_type: parent_type)
|
316
|
-
result1 = checker.check(
|
317
|
-
relation,
|
318
|
-
self_type: AST::Types::Self.instance,
|
319
|
-
instance_type: AST::Types::Instance.instance,
|
320
|
-
class_type: AST::Types::Class.instance,
|
321
|
-
constraints: Subtyping::Constraints.empty
|
322
|
-
)
|
323
|
-
result2 = checker.check(
|
324
|
-
relation.flip,
|
325
|
-
self_type: AST::Types::Self.instance,
|
326
|
-
instance_type: AST::Types::Instance.instance,
|
327
|
-
class_type: AST::Types::Class.instance,
|
328
|
-
constraints: Subtyping::Constraints.empty
|
329
|
-
)
|
330
|
-
|
331
|
-
unless result1.success? and result2.success?
|
332
|
-
@errors << Diagnostic::Signature::InstanceVariableTypeError.new(
|
333
|
-
name: name,
|
334
|
-
location: var.type.location,
|
335
|
-
var_type: var_type,
|
336
|
-
parent_type: parent_type
|
337
|
-
)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
definition.class_variables.each do |name, var|
|
343
|
-
if var.declared_in == definition.type_name
|
344
|
-
if (parent = var.parent_variable) && var.declared_in != parent.declared_in
|
345
|
-
class_var = entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
|
346
|
-
member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
|
347
|
-
end
|
348
|
-
|
349
|
-
if class_var
|
350
|
-
loc = class_var.location #: RBS::Location[untyped, untyped]?
|
351
|
-
@errors << Diagnostic::Signature::ClassVariableDuplicationError.new(
|
352
|
-
class_name: definition.type_name,
|
353
|
-
other_class_name: parent.declared_in,
|
354
|
-
variable_name: name,
|
355
|
-
location: loc&.[](:name) || raise
|
356
|
-
)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
|
363
|
-
ancestors.extended_modules or raise
|
364
|
-
mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
|
365
|
-
checker.check(
|
366
|
-
relation,
|
367
|
-
self_type: AST::Types::Self.instance ,
|
368
|
-
instance_type: AST::Types::Instance.instance,
|
369
|
-
class_type: AST::Types::Class.instance,
|
370
|
-
constraints: Subtyping::Constraints.empty
|
371
|
-
).else do
|
372
|
-
raise if ancestor.source.is_a?(Symbol)
|
373
|
-
|
374
|
-
@errors << Diagnostic::Signature::ModuleSelfTypeError.new(
|
375
|
-
name: name,
|
376
|
-
location: ancestor.source&.location || raise,
|
377
|
-
ancestor: ancestor,
|
378
|
-
relation: relation
|
379
|
-
)
|
380
|
-
end
|
381
|
-
end
|
382
|
-
ancestors.each_ancestor do |ancestor|
|
383
|
-
case ancestor
|
384
|
-
when RBS::Definition::Ancestor::Instance
|
385
|
-
validate_ancestor_application(name, ancestor)
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
|
-
validate_definition_type(definition)
|
390
|
-
end
|
391
423
|
end
|
392
424
|
end
|
393
425
|
end
|
@@ -397,7 +429,7 @@ module Steep
|
|
397
429
|
|
398
430
|
case entry
|
399
431
|
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
400
|
-
validate_one_class_decl(name)
|
432
|
+
validate_one_class_decl(name, entry)
|
401
433
|
when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
|
402
434
|
validate_one_class_alias(name, entry)
|
403
435
|
end
|
@@ -453,23 +485,31 @@ module Steep
|
|
453
485
|
bounds[param.name] = factory.type_opt(param.upper_bound)
|
454
486
|
end
|
455
487
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
ancestor
|
471
|
-
|
472
|
-
|
488
|
+
self_type = AST::Types::Name::Interface.new(
|
489
|
+
name: name,
|
490
|
+
args: definition.type_params.map { AST::Types::Var.new(name: _1) },
|
491
|
+
location: nil
|
492
|
+
)
|
493
|
+
|
494
|
+
push_context(self_type: self_type, class_type: nil, instance_type: nil) do
|
495
|
+
checker.push_variable_bounds(upper_bounds) do
|
496
|
+
validate_definition_type(definition)
|
497
|
+
|
498
|
+
ancestors = builder.ancestor_builder.one_interface_ancestors(name)
|
499
|
+
ancestors.each_ancestor do |ancestor|
|
500
|
+
case ancestor
|
501
|
+
when RBS::Definition::Ancestor::Instance
|
502
|
+
# Interface ancestor cannot be other than Interface
|
503
|
+
ancestor.source.is_a?(Symbol) and raise
|
504
|
+
|
505
|
+
defn = builder.build_interface(ancestor.name)
|
506
|
+
validate_type_application_constraints(
|
507
|
+
ancestor.name,
|
508
|
+
defn.type_params_decl,
|
509
|
+
ancestor.args,
|
510
|
+
location: ancestor.source&.location || raise
|
511
|
+
)
|
512
|
+
end
|
473
513
|
end
|
474
514
|
end
|
475
515
|
end
|
@@ -519,21 +559,33 @@ module Steep
|
|
519
559
|
end
|
520
560
|
|
521
561
|
def validate_one_alias(name, entry = env.type_alias_decls[name])
|
522
|
-
|
523
|
-
|
562
|
+
*, inner_most_outer_module = entry.outer
|
563
|
+
if inner_most_outer_module
|
564
|
+
class_type = AST::Types::Name::Singleton.new(name: inner_most_outer_module.name, location: nil)
|
565
|
+
instance_type = AST::Types::Name::Instance.new(
|
566
|
+
name: inner_most_outer_module.name,
|
567
|
+
args: inner_most_outer_module.type_params.map { AST::Types::Any.new(location: nil) },
|
568
|
+
location: nil
|
569
|
+
)
|
570
|
+
end
|
524
571
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
end
|
572
|
+
push_context(class_type: class_type, instance_type: instance_type, self_type: nil) do
|
573
|
+
rescue_validation_errors(name) do
|
574
|
+
Steep.logger.debug "Validating alias `#{name}`..."
|
529
575
|
|
530
|
-
|
531
|
-
|
532
|
-
|
576
|
+
unless name.namespace.empty?
|
577
|
+
outer = name.namespace.to_type_name
|
578
|
+
builder.validate_type_name(outer, entry.decl.location&.aref(:name))
|
579
|
+
end
|
580
|
+
|
581
|
+
upper_bounds = entry.decl.type_params.each.with_object({}) do |param, bounds|
|
582
|
+
bounds[param.name] = factory.type_opt(param.upper_bound)
|
583
|
+
end
|
533
584
|
|
534
|
-
|
535
|
-
|
536
|
-
|
585
|
+
validator.validate_type_alias(entry: entry) do |type|
|
586
|
+
checker.push_variable_bounds(upper_bounds) do
|
587
|
+
validate_type(entry.decl.type)
|
588
|
+
end
|
537
589
|
end
|
538
590
|
end
|
539
591
|
end
|
data/lib/steep/source.rb
CHANGED
@@ -459,12 +459,14 @@ module Steep
|
|
459
459
|
case node.type
|
460
460
|
when :lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn
|
461
461
|
# Skip
|
462
|
+
when :return, :break, :next
|
463
|
+
# Skip
|
464
|
+
when :def, :defs
|
465
|
+
# Skip
|
462
466
|
when :masgn
|
463
467
|
lhs, rhs = node.children
|
464
468
|
node = node.updated(nil, [lhs, insert_type_node(rhs, comments)])
|
465
469
|
return adjust_location(node)
|
466
|
-
when :return, :break, :next
|
467
|
-
# Skip
|
468
470
|
when :begin
|
469
471
|
location = node.loc #: Parser::Source::Map & Parser::AST::_Collection
|
470
472
|
if location.begin
|
@@ -475,6 +477,15 @@ module Steep
|
|
475
477
|
return assertion_node(node, last_comment)
|
476
478
|
end
|
477
479
|
else
|
480
|
+
if (receiver, name, * = deconstruct_send_node(node))
|
481
|
+
if receiver.nil?
|
482
|
+
if name == :attr_reader || name == :attr_writer || name == :attr_accessor
|
483
|
+
child_assertions = comments.except(last_line)
|
484
|
+
node = map_child_node(node) {|child| insert_type_node(child, child_assertions) }
|
485
|
+
return adjust_location(node)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
478
489
|
child_assertions = comments.except(last_line)
|
479
490
|
node = map_child_node(node) {|child| insert_type_node(child, child_assertions) }
|
480
491
|
node = adjust_location(node)
|
@@ -540,6 +551,21 @@ module Steep
|
|
540
551
|
]
|
541
552
|
)
|
542
553
|
)
|
554
|
+
when :def
|
555
|
+
name, args, body = node.children
|
556
|
+
assertion_location = args&.location&.expression || (_ = node.location).name
|
557
|
+
no_assertion_comments = comments.except(assertion_location.last_line)
|
558
|
+
args = insert_type_node(args, no_assertion_comments)
|
559
|
+
body = insert_type_node(body, comments) if body
|
560
|
+
return adjust_location(node.updated(nil, [name, args, body]))
|
561
|
+
when :defs
|
562
|
+
object, name, args, body = node.children
|
563
|
+
assertion_location = args&.location&.expression || (_ = node.location).name
|
564
|
+
no_assertion_comments = comments.except(assertion_location.last_line)
|
565
|
+
object = insert_type_node(object, no_assertion_comments)
|
566
|
+
args = insert_type_node(args, no_assertion_comments)
|
567
|
+
body = insert_type_node(body, comments) if body
|
568
|
+
return adjust_location(node.updated(nil, [object, name, args, body]))
|
543
569
|
else
|
544
570
|
adjust_location(
|
545
571
|
map_child_node(node, nil) {|child| insert_type_node(child, comments) }
|
@@ -798,33 +798,37 @@ module Steep
|
|
798
798
|
end
|
799
799
|
|
800
800
|
def check_method_type(name, relation)
|
801
|
-
relation.
|
801
|
+
Steep.logger.tagged "#{name} : #{relation.sub_type} <: #{relation.super_type}" do
|
802
|
+
relation.method!
|
802
803
|
|
803
|
-
|
804
|
+
sub_type, super_type = relation
|
804
805
|
|
805
|
-
|
806
|
-
|
806
|
+
sub_type.type_params.empty? or raise "Expected monomorphic method type: #{sub_type}"
|
807
|
+
super_type.type_params.empty? or raise "Expected monomorphic method type: #{super_type}"
|
807
808
|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
809
|
+
All(relation) do |result|
|
810
|
+
type_relation = Relation.new(sub_type: sub_type.type, super_type: super_type.type)
|
811
|
+
|
812
|
+
ret = expand_block_given(name, Relation.new(sub_type: sub_type.block, super_type: super_type.block))
|
813
|
+
|
814
|
+
case ret
|
815
|
+
when true
|
816
|
+
result.add(type_relation) { check_function(name, type_relation) }
|
817
|
+
when Relation
|
818
|
+
result.add(type_relation) { check_function(name, type_relation) }
|
819
|
+
result.add(ret) do
|
820
|
+
All(ret) do |result|
|
821
|
+
result.add_result(check_self_type_binding(ret, ret.super_type.self_type, ret.sub_type.self_type))
|
822
|
+
result.add(Relation(ret.super_type.type, ret.sub_type.type)) do |block_relation|
|
823
|
+
check_function(name, block_relation)
|
824
|
+
end
|
823
825
|
end
|
824
826
|
end
|
827
|
+
when Result::Failure
|
828
|
+
result.add(ret.relation) { ret }
|
829
|
+
end.tap do |ret|
|
830
|
+
Steep.logger.debug "result=#{ret.class}"
|
825
831
|
end
|
826
|
-
when Result::Failure
|
827
|
-
result.add(ret.relation) { ret }
|
828
832
|
end
|
829
833
|
end
|
830
834
|
end
|
data/lib/steep/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0.dev.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|