steep 0.27.0 → 0.28.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|