steep 0.27.0 → 0.28.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 +15 -0
- data/bin/smoke_runner.rb +3 -4
- data/lib/steep.rb +1 -1
- data/lib/steep/ast/builtin.rb +2 -20
- data/lib/steep/ast/types/factory.rb +60 -51
- data/lib/steep/ast/types/intersection.rb +12 -9
- data/lib/steep/ast/types/name.rb +2 -58
- data/lib/steep/ast/types/union.rb +5 -6
- data/lib/steep/errors.rb +14 -0
- data/lib/steep/interface/interface.rb +5 -62
- data/lib/steep/interface/method_type.rb +335 -74
- data/lib/steep/interface/substitution.rb +16 -4
- data/lib/steep/project/completion_provider.rb +1 -1
- data/lib/steep/project/hover_content.rb +1 -1
- data/lib/steep/server/base_worker.rb +1 -0
- data/lib/steep/server/code_worker.rb +2 -0
- data/lib/steep/server/master.rb +10 -3
- data/lib/steep/source.rb +2 -2
- data/lib/steep/subtyping/check.rb +29 -40
- data/lib/steep/type_construction.rb +192 -188
- data/lib/steep/type_inference/block_params.rb +5 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +1 -1
- data/smoke/case/a.rb +1 -1
- data/smoke/if/a.rb +1 -1
- data/smoke/module/a.rb +1 -1
- data/smoke/rescue/a.rb +4 -13
- data/steep.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e15a2388cd89e6b169243007211840853be8c126e035f7aa6434b00258e1087
|
4
|
+
data.tar.gz: e3bb8c7a1d816cb2667e7dc977f5e3155bcb9444e995a210bd58dc716a6a71b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb77f06dcef27e222984269a637966fa581cd78b3157c31a71793e8447f7059467140b7bb3f8f3e7f059a37492c9988f428234011ff7b3f7133a627f60a63cf4
|
7
|
+
data.tar.gz: 9319aebc6f74f89d055098312f460b2ed86ae9cfcd5c17bd21425c69e3ebe8838dffa3f4db9c99bc23bbc4657e4ee9f453bf1a2b3b7e4afe1531c0ba0ccb386c
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,21 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.28.0 (2020-09-17)
|
6
|
+
|
7
|
+
* Fix typing case-when with empty body ([#200](https://github.com/soutaro/steep/pull/200))
|
8
|
+
* Fix lvasgn typing with `void` type hint ([#200](https://github.com/soutaro/steep/pull/200))
|
9
|
+
* Fix subtype checking between type variables and union types ([#200](https://github.com/soutaro/steep/pull/200))
|
10
|
+
* Support endless range ([#200](https://github.com/soutaro/steep/pull/200))
|
11
|
+
* Fix optarg, kwoptarg typing ([#202](https://github.com/soutaro/steep/pull/202))
|
12
|
+
* Better union/intersection types ([#204](https://github.com/soutaro/steep/pull/204))
|
13
|
+
* Fix generic method instantiation ([#205](https://github.com/soutaro/steep/pull/205))
|
14
|
+
* Fix module typing ([#206](https://github.com/soutaro/steep/pull/206))
|
15
|
+
* Fix shutdown problem ([#209](https://github.com/soutaro/steep/pull/209))
|
16
|
+
* Update RBS to 0.12.0 ([#210](https://github.com/soutaro/steep/pull/210))
|
17
|
+
* Improve processing singleton class decls without RBS ([#211](https://github.com/soutaro/steep/pull/211))
|
18
|
+
* Improve processing block parameter with masgn ([#212](https://github.com/soutaro/steep/pull/212))
|
19
|
+
|
5
20
|
## 0.27.0 (2020-08-31)
|
6
21
|
|
7
22
|
* Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
|
data/bin/smoke_runner.rb
CHANGED
@@ -19,8 +19,6 @@ Expectation = Struct.new(:line, :message, :path, :starts) do
|
|
19
19
|
attr_accessor :prefix_test
|
20
20
|
end
|
21
21
|
|
22
|
-
allowed_paths = []
|
23
|
-
|
24
22
|
failed = false
|
25
23
|
|
26
24
|
ARGV.each do |arg|
|
@@ -29,12 +27,13 @@ ARGV.each do |arg|
|
|
29
27
|
|
30
28
|
rb_files = []
|
31
29
|
expectations = []
|
32
|
-
|
30
|
+
allowed_paths = []
|
31
|
+
|
33
32
|
dir.children.each do |file|
|
34
33
|
if file.extname == ".rb"
|
35
34
|
buffer = ::Parser::Source::Buffer.new(file.to_s)
|
36
35
|
buffer.source = file.read
|
37
|
-
parser = ::Parser::
|
36
|
+
parser = ::Parser::Ruby27.new
|
38
37
|
|
39
38
|
_, comments, _ = parser.tokenize(buffer)
|
40
39
|
comments.each do |comment|
|
data/lib/steep.rb
CHANGED
data/lib/steep/ast/builtin.rb
CHANGED
@@ -15,12 +15,8 @@ module Steep
|
|
15
15
|
Types::Name::Instance.new(name: module_name, args: args)
|
16
16
|
end
|
17
17
|
|
18
|
-
def class_type(constructor: nil)
|
19
|
-
Types::Name::Class.new(name: module_name, constructor: constructor)
|
20
|
-
end
|
21
|
-
|
22
18
|
def module_type
|
23
|
-
Types::Name::
|
19
|
+
Types::Name::Singleton.new(name: module_name)
|
24
20
|
end
|
25
21
|
|
26
22
|
def instance_type?(type, args: nil)
|
@@ -36,22 +32,8 @@ module Steep
|
|
36
32
|
end
|
37
33
|
end
|
38
34
|
|
39
|
-
NONE = ::Object.new
|
40
|
-
|
41
|
-
def class_type?(type, constructor: NONE)
|
42
|
-
if type.is_a?(Types::Name::Class)
|
43
|
-
unless constructor.equal?(NONE)
|
44
|
-
type.name == module_name && type.name.constructor == constructor
|
45
|
-
else
|
46
|
-
type.name == module_name
|
47
|
-
end
|
48
|
-
else
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
35
|
def module_type?(type)
|
54
|
-
if type.is_a?(Types::Name::
|
36
|
+
if type.is_a?(Types::Name::Singleton)
|
55
37
|
type.name == module_name
|
56
38
|
else
|
57
39
|
false
|
@@ -44,7 +44,7 @@ module Steep
|
|
44
44
|
Var.new(name: type.name, location: nil)
|
45
45
|
when RBS::Types::ClassSingleton
|
46
46
|
type_name = type_name(type.name)
|
47
|
-
Name::
|
47
|
+
Name::Singleton.new(name: type_name, location: nil)
|
48
48
|
when RBS::Types::ClassInstance
|
49
49
|
type_name = type_name(type.name)
|
50
50
|
args = type.args.map {|arg| type(arg) }
|
@@ -102,7 +102,7 @@ module Steep
|
|
102
102
|
RBS::Types::Bases::Nil.new(location: nil)
|
103
103
|
when Var
|
104
104
|
RBS::Types::Variable.new(name: type.name, location: nil)
|
105
|
-
when Name::
|
105
|
+
when Name::Singleton
|
106
106
|
RBS::Types::ClassSingleton.new(name: type_name_1(type.name), location: nil)
|
107
107
|
when Name::Instance
|
108
108
|
RBS::Types::ClassInstance.new(
|
@@ -219,7 +219,7 @@ module Steep
|
|
219
219
|
end
|
220
220
|
end
|
221
221
|
subst = Interface::Substitution.build(alpha_vars, alpha_types)
|
222
|
-
subst.merge!(subst2) if subst2
|
222
|
+
subst.merge!(subst2, overwrite: true) if subst2
|
223
223
|
|
224
224
|
type = Interface::MethodType.new(
|
225
225
|
type_params: type_params,
|
@@ -313,6 +313,7 @@ module Steep
|
|
313
313
|
end
|
314
314
|
|
315
315
|
def interface(type, private:, self_type: type)
|
316
|
+
Steep.logger.debug { "Factory#interface: #{type}, private=#{private}, self_type=#{self_type}" }
|
316
317
|
type = expand_alias(type)
|
317
318
|
|
318
319
|
case type
|
@@ -340,14 +341,15 @@ module Steep
|
|
340
341
|
)
|
341
342
|
|
342
343
|
definition.methods.each do |name, method|
|
343
|
-
|
344
|
+
Steep.logger.tagged "method = #{name}" do
|
345
|
+
next if method.private? && !private
|
344
346
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
347
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
348
|
+
method_types: method.method_types.map do |type|
|
349
|
+
method_type(type, self_type: self_type, subst2: subst)
|
350
|
+
end
|
351
|
+
)
|
352
|
+
end
|
351
353
|
end
|
352
354
|
end
|
353
355
|
|
@@ -363,16 +365,15 @@ module Steep
|
|
363
365
|
)
|
364
366
|
|
365
367
|
definition.methods.each do |name, method|
|
366
|
-
interface.methods[name] = Interface::Interface::
|
367
|
-
method.method_types.map do |type|
|
368
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
369
|
+
method_types: method.method_types.map do |type|
|
368
370
|
method_type(type, self_type: self_type, subst2: subst)
|
369
|
-
end
|
370
|
-
incompatible: false
|
371
|
+
end
|
371
372
|
)
|
372
373
|
end
|
373
374
|
end
|
374
375
|
|
375
|
-
when Name::
|
376
|
+
when Name::Singleton
|
376
377
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
377
378
|
definition = definition_builder.build_singleton(type_name_1(type.name))
|
378
379
|
|
@@ -389,11 +390,10 @@ module Steep
|
|
389
390
|
definition.methods.each do |name, method|
|
390
391
|
next if !private && method.private?
|
391
392
|
|
392
|
-
interface.methods[name] = Interface::Interface::
|
393
|
-
method.method_types.map do |type|
|
393
|
+
interface.methods[name] = Interface::Interface::Entry.new(
|
394
|
+
method_types: method.method_types.map do |type|
|
394
395
|
method_type(type, self_type: self_type, subst2: subst)
|
395
|
-
end
|
396
|
-
incompatible: false
|
396
|
+
end
|
397
397
|
)
|
398
398
|
end
|
399
399
|
end
|
@@ -416,7 +416,25 @@ module Steep
|
|
416
416
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
417
417
|
common_methods = Set.new(interface1.methods.keys) & Set.new(interface2.methods.keys)
|
418
418
|
common_methods.each do |name|
|
419
|
-
|
419
|
+
types1 = interface1.methods[name].method_types
|
420
|
+
types2 = interface2.methods[name].method_types
|
421
|
+
|
422
|
+
if types1 == types2
|
423
|
+
interface.methods[name] = interface1.methods[name]
|
424
|
+
else
|
425
|
+
method_types = {}
|
426
|
+
|
427
|
+
types1.each do |type1|
|
428
|
+
types2.each do |type2|
|
429
|
+
type = type1 | type2 or next
|
430
|
+
method_types[type] = true
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
unless method_types.empty?
|
435
|
+
interface.methods[name] = Interface::Interface::Entry.new(method_types: method_types.keys)
|
436
|
+
end
|
437
|
+
end
|
420
438
|
end
|
421
439
|
end
|
422
440
|
end
|
@@ -427,11 +445,8 @@ module Steep
|
|
427
445
|
interfaces = type.types.map {|ty| interface(ty, private: private, self_type: self_type) }
|
428
446
|
interfaces.inject do |interface1, interface2|
|
429
447
|
Interface::Interface.new(type: self_type, private: private).tap do |interface|
|
430
|
-
|
431
|
-
|
432
|
-
methods = [interface1.methods[name], interface2.methods[name]].compact
|
433
|
-
interface.methods[name] = Interface::Interface::Combination.intersection(methods)
|
434
|
-
end
|
448
|
+
interface.methods.merge!(interface1.methods)
|
449
|
+
interface.methods.merge!(interface2.methods)
|
435
450
|
end
|
436
451
|
end
|
437
452
|
end
|
@@ -442,8 +457,8 @@ module Steep
|
|
442
457
|
array_type = Builtin::Array.instance_type(element_type)
|
443
458
|
interface(array_type, private: private, self_type: self_type).tap do |array_interface|
|
444
459
|
array_interface.methods[:[]] = array_interface.methods[:[]].yield_self do |aref|
|
445
|
-
Interface::Interface::
|
446
|
-
type.types.map.with_index {|elem_type, index|
|
460
|
+
Interface::Interface::Entry.new(
|
461
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
447
462
|
Interface::MethodType.new(
|
448
463
|
type_params: [],
|
449
464
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
|
@@ -456,14 +471,13 @@ module Steep
|
|
456
471
|
return_type: elem_type,
|
457
472
|
location: nil
|
458
473
|
)
|
459
|
-
} + aref.
|
460
|
-
incompatible: false
|
474
|
+
} + aref.method_types
|
461
475
|
)
|
462
476
|
end
|
463
477
|
|
464
478
|
array_interface.methods[:[]=] = array_interface.methods[:[]=].yield_self do |update|
|
465
|
-
Interface::Interface::
|
466
|
-
type.types.map.with_index {|elem_type, index|
|
479
|
+
Interface::Interface::Entry.new(
|
480
|
+
method_types: type.types.map.with_index {|elem_type, index|
|
467
481
|
Interface::MethodType.new(
|
468
482
|
type_params: [],
|
469
483
|
params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
|
@@ -476,14 +490,13 @@ module Steep
|
|
476
490
|
return_type: elem_type,
|
477
491
|
location: nil
|
478
492
|
)
|
479
|
-
} + update.
|
480
|
-
incompatible: false
|
493
|
+
} + update.method_types
|
481
494
|
)
|
482
495
|
end
|
483
496
|
|
484
497
|
array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
|
485
|
-
Interface::Interface::
|
486
|
-
[
|
498
|
+
Interface::Interface::Entry.new(
|
499
|
+
method_types: [
|
487
500
|
Interface::MethodType.new(
|
488
501
|
type_params: [],
|
489
502
|
params: Interface::Params.empty,
|
@@ -491,14 +504,13 @@ module Steep
|
|
491
504
|
return_type: type.types[0] || AST::Builtin.nil_type,
|
492
505
|
location: nil
|
493
506
|
)
|
494
|
-
]
|
495
|
-
incompatible: false
|
507
|
+
]
|
496
508
|
)
|
497
509
|
end
|
498
510
|
|
499
511
|
array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
|
500
|
-
Interface::Interface::
|
501
|
-
[
|
512
|
+
Interface::Interface::Entry.new(
|
513
|
+
method_types: [
|
502
514
|
Interface::MethodType.new(
|
503
515
|
type_params: [],
|
504
516
|
params: Interface::Params.empty,
|
@@ -506,8 +518,7 @@ module Steep
|
|
506
518
|
return_type: type.types.last || AST::Builtin.nil_type,
|
507
519
|
location: nil
|
508
520
|
)
|
509
|
-
]
|
510
|
-
incompatible: false
|
521
|
+
]
|
511
522
|
)
|
512
523
|
end
|
513
524
|
end
|
@@ -523,8 +534,8 @@ module Steep
|
|
523
534
|
|
524
535
|
interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
|
525
536
|
hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
|
526
|
-
Interface::Interface::
|
527
|
-
type.elements.map {|key_value, value_type|
|
537
|
+
Interface::Interface::Entry.new(
|
538
|
+
method_types: type.elements.map {|key_value, value_type|
|
528
539
|
key_type = Literal.new(value: key_value, location: nil)
|
529
540
|
Interface::MethodType.new(
|
530
541
|
type_params: [],
|
@@ -538,14 +549,13 @@ module Steep
|
|
538
549
|
return_type: value_type,
|
539
550
|
location: nil
|
540
551
|
)
|
541
|
-
} + ref.
|
542
|
-
incompatible: false
|
552
|
+
} + ref.method_types
|
543
553
|
)
|
544
554
|
end
|
545
555
|
|
546
556
|
hash_interface.methods[:[]=] = hash_interface.methods[:[]=].yield_self do |update|
|
547
|
-
Interface::Interface::
|
548
|
-
type.elements.map {|key_value, value_type|
|
557
|
+
Interface::Interface::Entry.new(
|
558
|
+
method_types: type.elements.map {|key_value, value_type|
|
549
559
|
key_type = Literal.new(value: key_value, location: nil)
|
550
560
|
Interface::MethodType.new(
|
551
561
|
type_params: [],
|
@@ -559,8 +569,7 @@ module Steep
|
|
559
569
|
return_type: value_type,
|
560
570
|
location: nil
|
561
571
|
)
|
562
|
-
} + update.
|
563
|
-
incompatible: false
|
572
|
+
} + update.method_types
|
564
573
|
)
|
565
574
|
end
|
566
575
|
end
|
@@ -576,8 +585,8 @@ module Steep
|
|
576
585
|
location: nil
|
577
586
|
)
|
578
587
|
|
579
|
-
interface.methods[:[]] = Interface::Interface::
|
580
|
-
interface.methods[:call] = Interface::Interface::
|
588
|
+
interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
|
589
|
+
interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
|
581
590
|
end
|
582
591
|
|
583
592
|
else
|
@@ -28,33 +28,36 @@ module Steep
|
|
28
28
|
else
|
29
29
|
type
|
30
30
|
end
|
31
|
-
end.compact.
|
32
|
-
|
31
|
+
end.compact.yield_self do |tys|
|
32
|
+
dups = Set.new(tys)
|
33
|
+
|
34
|
+
case dups.size
|
35
|
+
when 0
|
36
|
+
AST::Types::Top.new(location: location)
|
37
|
+
when 1
|
33
38
|
tys.first
|
34
39
|
else
|
35
|
-
new(types:
|
40
|
+
new(types: dups.to_a, location: location)
|
36
41
|
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
40
45
|
def ==(other)
|
41
|
-
other.is_a?(Intersection) &&
|
42
|
-
other.types == types
|
46
|
+
other.is_a?(Intersection) && other.types == types
|
43
47
|
end
|
44
48
|
|
45
49
|
def hash
|
46
|
-
self.class.hash ^ types.hash
|
50
|
+
@hash ||= self.class.hash ^ types.hash
|
47
51
|
end
|
48
52
|
|
49
53
|
alias eql? ==
|
50
54
|
|
51
55
|
def subst(s)
|
52
|
-
self.class.build(location: location,
|
53
|
-
types: types.map {|ty| ty.subst(s) })
|
56
|
+
self.class.build(location: location, types: types.map {|ty| ty.subst(s) })
|
54
57
|
end
|
55
58
|
|
56
59
|
def to_s
|
57
|
-
"(#{types.map(&:to_s).
|
60
|
+
"(#{types.map(&:to_s).join(" & ")})"
|
58
61
|
end
|
59
62
|
|
60
63
|
def free_variables()
|
data/lib/steep/ast/types/name.rb
CHANGED
@@ -79,59 +79,7 @@ module Steep
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
class
|
83
|
-
attr_reader :constructor
|
84
|
-
|
85
|
-
def initialize(name:, constructor:, location: nil)
|
86
|
-
raise "Name should be a module name: #{name.inspect}" unless name.is_a?(Names::Module)
|
87
|
-
super(name: name, location: location)
|
88
|
-
@constructor = constructor
|
89
|
-
end
|
90
|
-
|
91
|
-
def ==(other)
|
92
|
-
other.class == self.class &&
|
93
|
-
other.name == name &&
|
94
|
-
other.constructor == constructor
|
95
|
-
end
|
96
|
-
|
97
|
-
alias eql? ==
|
98
|
-
|
99
|
-
def hash
|
100
|
-
self.class.hash ^ name.hash ^ constructor.hash
|
101
|
-
end
|
102
|
-
|
103
|
-
def to_s
|
104
|
-
k = case constructor
|
105
|
-
when true
|
106
|
-
" constructor"
|
107
|
-
when false
|
108
|
-
" noconstructor"
|
109
|
-
when nil
|
110
|
-
""
|
111
|
-
end
|
112
|
-
"singleton(#{name.to_s})"
|
113
|
-
end
|
114
|
-
|
115
|
-
def with_location(new_location)
|
116
|
-
self.class.new(name: name, constructor: constructor, location: new_location)
|
117
|
-
end
|
118
|
-
|
119
|
-
def to_instance(*args)
|
120
|
-
Instance.new(name: name, args: args)
|
121
|
-
end
|
122
|
-
|
123
|
-
NOTHING = ::Object.new
|
124
|
-
|
125
|
-
def updated(constructor: NOTHING)
|
126
|
-
if NOTHING == constructor
|
127
|
-
constructor = self.constructor
|
128
|
-
end
|
129
|
-
|
130
|
-
self.class.new(name: name, constructor: constructor, location: location)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
class Module < Base
|
82
|
+
class Singleton < Base
|
135
83
|
def ==(other)
|
136
84
|
other.class == self.class &&
|
137
85
|
other.name == name
|
@@ -153,12 +101,8 @@ module Steep
|
|
153
101
|
end
|
154
102
|
|
155
103
|
class Instance < Applying
|
156
|
-
def to_class(constructor:)
|
157
|
-
Class.new(name: name, location: location, constructor: constructor)
|
158
|
-
end
|
159
|
-
|
160
104
|
def to_module
|
161
|
-
|
105
|
+
Singleton.new(name: name, location: location)
|
162
106
|
end
|
163
107
|
end
|
164
108
|
|