steep 1.7.0.dev.2 → 1.7.0.dev.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +17 -19
- data/doc/narrowing.md +1 -1
- data/doc/shape.md +176 -0
- data/gemfile_steep/Gemfile.lock +10 -12
- data/lib/steep/ast/types/factory.rb +27 -18
- data/lib/steep/ast/types/helper.rb +4 -0
- data/lib/steep/ast/types/intersection.rb +7 -0
- data/lib/steep/ast/types/proc.rb +14 -9
- data/lib/steep/ast/types/record.rb +7 -0
- data/lib/steep/ast/types/tuple.rb +7 -0
- data/lib/steep/ast/types/union.rb +7 -0
- data/lib/steep/drivers/stats.rb +2 -2
- data/lib/steep/drivers/validate.rb +4 -2
- data/lib/steep/expectations.rb +2 -2
- data/lib/steep/interface/block.rb +1 -1
- data/lib/steep/interface/builder.rb +337 -360
- data/lib/steep/interface/function.rb +82 -11
- data/lib/steep/interface/method_type.rb +18 -10
- data/lib/steep/interface/shape.rb +69 -18
- data/lib/steep/interface/substitution.rb +4 -0
- data/lib/steep/node_helper.rb +18 -1
- data/lib/steep/project/pattern.rb +1 -2
- data/lib/steep/server/interaction_worker.rb +6 -0
- data/lib/steep/server/lsp_formatter.rb +2 -0
- data/lib/steep/services/completion_provider.rb +20 -18
- data/lib/steep/services/file_loader.rb +15 -20
- data/lib/steep/services/signature_help_provider.rb +17 -18
- data/lib/steep/signature/validator.rb +1 -1
- data/lib/steep/subtyping/check.rb +19 -22
- data/lib/steep/subtyping/variable_variance.rb +3 -3
- data/lib/steep/test.rb +9 -0
- data/lib/steep/type_construction.rb +198 -158
- data/lib/steep/type_inference/block_params.rb +12 -4
- data/lib/steep/type_inference/context.rb +1 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -2
- data/lib/steep/type_inference/method_params.rb +16 -0
- data/lib/steep/type_inference/send_args.rb +5 -2
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +11 -7
- data/sig/steep/ast/types/factory.rbs +2 -2
- data/sig/steep/ast/types/helper.rbs +2 -0
- data/sig/steep/ast/types/intersection.rbs +2 -0
- data/sig/steep/ast/types/name.rbs +4 -0
- data/sig/steep/ast/types/record.rbs +2 -0
- data/sig/steep/ast/types/tuple.rbs +2 -0
- data/sig/steep/ast/types/union.rbs +2 -0
- data/sig/steep/expectations.rbs +1 -1
- data/sig/steep/interface/block.rbs +2 -2
- data/sig/steep/interface/builder.rbs +54 -109
- data/sig/steep/interface/function.rbs +38 -32
- data/sig/steep/interface/shape.rbs +23 -4
- data/sig/steep/interface/substitution.rbs +2 -0
- data/sig/steep/node_helper.rbs +11 -0
- data/sig/steep/services/signature_help_provider.rbs +3 -1
- data/sig/steep/subtyping/constraints.rbs +2 -2
- data/sig/steep/subtyping/variable_variance.rbs +1 -1
- data/sig/steep/type_construction.rbs +1 -1
- data/sig/steep/type_inference/block_params.rbs +3 -3
- data/sig/steep/type_inference/context.rbs +2 -0
- data/sig/steep/type_inference/method_params.rbs +3 -3
- data/sig/steep.rbs +1 -1
- data/steep.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17795ed14e183d6e8858e6ea8f57f71dbd3cdced0e4d9cf7e43c646188e486cd
|
4
|
+
data.tar.gz: 7005e9d96f44f23a47f1844597b86fd3d774f000b1de5cf100d235e68c56a0b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e178baa7a185edaafb359032266bfa7f29d082c9da30ca418e5ef4030b5723423f3f36ba4165a640d996e252bb91883dcfe55b1f750f51c3153452b368e5a9ee
|
7
|
+
data.tar.gz: 8919d4c047097e7e7fd63ecba71ae96f412a56588c7b6ff1d381838d2d935d2ba7dc382ca83fe5b679f35ebbe298460e80e87047c88b6ebcc5e3e6ef258e2535
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (1.7.0.dev.
|
4
|
+
steep (1.7.0.dev.4)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
concurrent-ruby (>= 1.1.10)
|
7
7
|
csv (>= 3.0.9)
|
@@ -12,7 +12,7 @@ PATH
|
|
12
12
|
logger (>= 1.3.0)
|
13
13
|
parser (>= 3.1)
|
14
14
|
rainbow (>= 2.2.2, < 4.0)
|
15
|
-
rbs (>= 3.
|
15
|
+
rbs (>= 3.5.0.pre)
|
16
16
|
securerandom (>= 0.1)
|
17
17
|
strscan (>= 1.0.0)
|
18
18
|
terminal-table (>= 2, < 4)
|
@@ -33,53 +33,51 @@ GEM
|
|
33
33
|
tzinfo (~> 2.0)
|
34
34
|
ast (2.4.2)
|
35
35
|
base64 (0.2.0)
|
36
|
-
bigdecimal (3.1.
|
36
|
+
bigdecimal (3.1.8)
|
37
37
|
concurrent-ruby (1.2.3)
|
38
38
|
connection_pool (2.4.1)
|
39
|
-
csv (3.
|
40
|
-
debug (1.9.
|
39
|
+
csv (3.3.0)
|
40
|
+
debug (1.9.2)
|
41
41
|
irb (~> 1.10)
|
42
42
|
reline (>= 0.3.8)
|
43
|
-
drb (2.2.
|
44
|
-
ruby2_keywords
|
43
|
+
drb (2.2.1)
|
45
44
|
ffi (1.16.3)
|
46
45
|
fileutils (1.7.2)
|
47
|
-
i18n (1.14.
|
46
|
+
i18n (1.14.5)
|
48
47
|
concurrent-ruby (~> 1.0)
|
49
48
|
io-console (0.7.2)
|
50
|
-
irb (1.
|
51
|
-
rdoc
|
49
|
+
irb (1.13.1)
|
50
|
+
rdoc (>= 4.0.0)
|
52
51
|
reline (>= 0.4.2)
|
53
|
-
json (2.7.
|
52
|
+
json (2.7.2)
|
54
53
|
language_server-protocol (3.17.0.3)
|
55
|
-
listen (3.
|
54
|
+
listen (3.9.0)
|
56
55
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
57
56
|
rb-inotify (~> 0.9, >= 0.9.10)
|
58
57
|
logger (1.6.0)
|
59
|
-
minitest (5.22.
|
58
|
+
minitest (5.22.3)
|
60
59
|
minitest-hooks (1.5.1)
|
61
60
|
minitest (> 5.3)
|
62
61
|
minitest-slow_test (0.2.0)
|
63
62
|
minitest (>= 5.0)
|
64
63
|
mutex_m (0.2.0)
|
65
|
-
parser (3.3.0
|
64
|
+
parser (3.3.1.0)
|
66
65
|
ast (~> 2.4.1)
|
67
66
|
racc
|
68
67
|
psych (5.1.2)
|
69
68
|
stringio
|
70
69
|
racc (1.7.3)
|
71
70
|
rainbow (3.1.1)
|
72
|
-
rake (13.1
|
71
|
+
rake (13.2.1)
|
73
72
|
rb-fsevent (0.11.2)
|
74
73
|
rb-inotify (0.10.1)
|
75
74
|
ffi (~> 1.0)
|
76
|
-
rbs (3.
|
75
|
+
rbs (3.5.0.pre.2)
|
77
76
|
abbrev
|
78
|
-
rdoc (6.6.
|
77
|
+
rdoc (6.6.3.1)
|
79
78
|
psych (>= 4.0.0)
|
80
|
-
reline (0.
|
79
|
+
reline (0.5.6)
|
81
80
|
io-console (~> 0.5)
|
82
|
-
ruby2_keywords (0.0.5)
|
83
81
|
securerandom (0.3.1)
|
84
82
|
stackprof (0.2.26)
|
85
83
|
stringio (3.1.0)
|
data/doc/narrowing.md
CHANGED
@@ -65,7 +65,7 @@ It immediately type checks the left hand side, but with *conditional mode*. Cond
|
|
65
65
|
x && y
|
66
66
|
```
|
67
67
|
|
68
|
-
Going down again, it gets a typing `x: String?` and `y: String
|
68
|
+
Going down again, it gets a typing `x: String?` and `y: String?`. It runs a type narrowing, to obtain a result both of `x` and `y` are `String` for truthy result, both of `x` and `y` are `String?` for falsy result. The two environments should be propagated to the upper node, because the parent node is also `&&` which is a subject of type narrowing. So, it returns an `ENV` type, `String?` for original type, `{ x: String, y: String }` for truthy result, and `{ x: String?, y: String? }` for falsy result.
|
69
69
|
|
70
70
|
Going up to the outer `&&` expression. The left hand side has `ENV` type, and then the right hand side is type checked based on the truthy environment (because of the semantics of `&&` expression.) Both `x` and `y` are `String` and it type checks. The type of the whole expression union of `String` and the falsy part of the original type -- `nil`.
|
71
71
|
## Union type partition
|
data/doc/shape.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# Shapes
|
2
|
+
|
3
|
+
A *shape* is a data structure, which contains the set of available methods and their types, which is associated with a type. Steep uses shapes to type check method calls -- it calculates the shape of the type of the receiver, checks if the called method is defined on the shape and the arguments are compatible with the method, and calculates the return type.
|
4
|
+
|
5
|
+
Assume an interface `_Foo` is defined as follows:
|
6
|
+
|
7
|
+
```rbs
|
8
|
+
interface _Foo
|
9
|
+
def foo: () -> String
|
10
|
+
|
11
|
+
def bar: () -> self
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
The shape of `_Foo` will be the following:
|
16
|
+
|
17
|
+
```
|
18
|
+
Shape (_Foo) {
|
19
|
+
foo: () -> String,
|
20
|
+
bar: () -> _Foo
|
21
|
+
}
|
22
|
+
```
|
23
|
+
|
24
|
+
Note that the `self` type in the example is resolved to `_Foo` during shape calculation.
|
25
|
+
|
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
|
+
## Tuple, record, and proc types
|
28
|
+
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
|
+
|
30
|
+
```
|
31
|
+
Shape ([Integer, String]) {
|
32
|
+
[]: (0) -> Integer
|
33
|
+
| (1) -> String
|
34
|
+
| (Integer) -> (Integer | String)
|
35
|
+
...
|
36
|
+
}
|
37
|
+
```
|
38
|
+
|
39
|
+
The specialization is implemented as a part of shape calculation.
|
40
|
+
## Special methods
|
41
|
+
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
|
+
|
43
|
+
The shape calculation inserts the specialized methods with these special methods.
|
44
|
+
## `self` types
|
45
|
+
There are two cases of `self` types to consider during shape calculation.
|
46
|
+
|
47
|
+
1. `self` types included in the shape of a type
|
48
|
+
2. `self` types included in given types
|
49
|
+
### 1. `self` types included in the shape of a type
|
50
|
+
`self` types may be included in a class or interface definition.
|
51
|
+
|
52
|
+
```rbs
|
53
|
+
interface _Foo
|
54
|
+
def itself: () -> self
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
The `self` types included in the shape of `_Foo` type should be resolved to `_Foo` type.
|
59
|
+
|
60
|
+
```
|
61
|
+
Shape (_Foo) {
|
62
|
+
itself: () -> _Foo
|
63
|
+
}
|
64
|
+
```
|
65
|
+
### 2. `self` types included in given types
|
66
|
+
Unlike `self` types included in definitions, `self` types in given types should be preserved.
|
67
|
+
|
68
|
+
```rbs
|
69
|
+
interface _Foo[A]
|
70
|
+
def get: () -> A
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
The shape of `_Foo[self]` has `self` type as its type argument, and we want the `self` type preserved after the shape calculation.
|
75
|
+
|
76
|
+
```
|
77
|
+
Shape (_Foo[self]) {
|
78
|
+
get: () -> self
|
79
|
+
}
|
80
|
+
```
|
81
|
+
|
82
|
+
We often use `self` types as the return type of a method.
|
83
|
+
|
84
|
+
```rbs
|
85
|
+
class Foo
|
86
|
+
def foo: () -> self
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
So, the implementation of `foo` might use `self` node to return `self` type.
|
91
|
+
|
92
|
+
```rb
|
93
|
+
class Foo
|
94
|
+
def foo
|
95
|
+
# @type var foo: _Foo[self]
|
96
|
+
foo = ...
|
97
|
+
foo.get
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
We want the type of `foo.get` to be `self`, not `Foo`, to avoid a type error being detected.
|
103
|
+
## Shape of `self` types
|
104
|
+
We also want `self` type if `self` is the type of the shape.
|
105
|
+
|
106
|
+
```rb
|
107
|
+
class Foo
|
108
|
+
def foo
|
109
|
+
self.itself
|
110
|
+
end
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
This is a straightforward case, because the type of `self` is `self` itself. Calculate the shape of it, but keep the `self` types in the shape.
|
115
|
+
|
116
|
+
```
|
117
|
+
Shape (self) {
|
118
|
+
itself: () -> self
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
If `self` is a union type, or something built with a type constructor, the shape calculation gets complicated.
|
123
|
+
|
124
|
+
```rbs
|
125
|
+
class Foo
|
126
|
+
def foo: () -> Integer
|
127
|
+
end
|
128
|
+
|
129
|
+
class Bar
|
130
|
+
def foo: () -> self
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
What is the expected shape of `self` where the type of `self` is `Foo | Bar`?
|
135
|
+
|
136
|
+
The shape of a union type is straightforward. It calculates the shape of each type, and then it calculates a union of the shape.
|
137
|
+
|
138
|
+
We do the same for the case with `self` types, but it results in slightly incorrect shapes.
|
139
|
+
|
140
|
+
```
|
141
|
+
Shape (Foo) {
|
142
|
+
foo: () -> Integer
|
143
|
+
}
|
144
|
+
|
145
|
+
Shape (Bar) {
|
146
|
+
foo: () -> self # self is preserved, because the shape of `self` is being calculated
|
147
|
+
}
|
148
|
+
|
149
|
+
Shape (Foo | Bar) {
|
150
|
+
foo: () -> (Integer | self)
|
151
|
+
}
|
152
|
+
```
|
153
|
+
|
154
|
+
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
|
+
|
156
|
+
This is an incorrect result, but Steep is doing this right now.
|
157
|
+
## `class` and `instance` types
|
158
|
+
The shape calculation provides limited support for `class` and `instance` types.
|
159
|
+
|
160
|
+
1. `class`/`instance` types from the definition are resolved
|
161
|
+
2. `class`/`instance` types in generics type arguments of interfaces/instances are preserved
|
162
|
+
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
|
+
|
164
|
+
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.
|
165
|
+
## Public methods, private methods
|
166
|
+
`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
|
+
|
168
|
+
The shape calculation starts with *private methods*, and the `Shape#public_shape` method returns another shape that only has *public* methods.
|
169
|
+
|
170
|
+
> Note that the private shape calculation is required even on public method calls. This means a possible chance of future optimizations.
|
171
|
+
## Lazy method type calculation
|
172
|
+
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
|
+
|
174
|
+
*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.
|
175
|
+
|
176
|
+
It is implemented in `Steep::Interface::Shape::Entry` and used to make the shape calculation of a union type faster.
|
data/gemfile_steep/Gemfile.lock
CHANGED
@@ -2,7 +2,7 @@ GEM
|
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
4
|
abbrev (0.1.2)
|
5
|
-
activesupport (7.1.3)
|
5
|
+
activesupport (7.1.3.2)
|
6
6
|
base64
|
7
7
|
bigdecimal
|
8
8
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
@@ -14,25 +14,24 @@ GEM
|
|
14
14
|
tzinfo (~> 2.0)
|
15
15
|
ast (2.4.2)
|
16
16
|
base64 (0.2.0)
|
17
|
-
bigdecimal (3.1.
|
17
|
+
bigdecimal (3.1.8)
|
18
18
|
concurrent-ruby (1.2.3)
|
19
19
|
connection_pool (2.4.1)
|
20
|
-
csv (3.
|
21
|
-
drb (2.2.
|
22
|
-
ruby2_keywords
|
20
|
+
csv (3.3.0)
|
21
|
+
drb (2.2.1)
|
23
22
|
ffi (1.16.3)
|
24
23
|
fileutils (1.7.2)
|
25
|
-
i18n (1.14.
|
24
|
+
i18n (1.14.5)
|
26
25
|
concurrent-ruby (~> 1.0)
|
27
|
-
json (2.7.
|
26
|
+
json (2.7.2)
|
28
27
|
language_server-protocol (3.17.0.3)
|
29
|
-
listen (3.
|
28
|
+
listen (3.9.0)
|
30
29
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
31
30
|
rb-inotify (~> 0.9, >= 0.9.10)
|
32
31
|
logger (1.6.0)
|
33
|
-
minitest (5.22.
|
32
|
+
minitest (5.22.3)
|
34
33
|
mutex_m (0.2.0)
|
35
|
-
parser (3.3.0
|
34
|
+
parser (3.3.1.0)
|
36
35
|
ast (~> 2.4.1)
|
37
36
|
racc
|
38
37
|
racc (1.7.3)
|
@@ -42,9 +41,8 @@ GEM
|
|
42
41
|
ffi (~> 1.0)
|
43
42
|
rbs (3.4.4)
|
44
43
|
abbrev
|
45
|
-
ruby2_keywords (0.0.5)
|
46
44
|
securerandom (0.3.1)
|
47
|
-
steep (1.7.0.dev.
|
45
|
+
steep (1.7.0.dev.3)
|
48
46
|
activesupport (>= 5.1)
|
49
47
|
concurrent-ruby (>= 1.1.10)
|
50
48
|
csv (>= 3.0.9)
|
@@ -212,27 +212,36 @@ module Steep
|
|
212
212
|
params = func.params
|
213
213
|
return_type = func.return_type
|
214
214
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
215
|
+
if params
|
216
|
+
RBS::Types::Function.new(
|
217
|
+
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
218
|
+
optional_positionals: params.optional.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
219
|
+
rest_positionals: params.rest&.yield_self {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
220
|
+
trailing_positionals: [],
|
221
|
+
required_keywords: params.required_keywords.transform_values {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
222
|
+
optional_keywords: params.optional_keywords.transform_values {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
223
|
+
rest_keywords: params.rest_keywords&.yield_self {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
|
224
|
+
return_type: type_1(return_type)
|
225
|
+
)
|
226
|
+
else
|
227
|
+
RBS::Types::UntypedFunction.new(return_type: type_1(return_type))
|
228
|
+
end
|
225
229
|
end
|
226
230
|
|
227
231
|
def params(type)
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
232
|
+
case type
|
233
|
+
when RBS::Types::Function
|
234
|
+
Interface::Function::Params.build(
|
235
|
+
required: type.required_positionals.map {|param| type(param.type) },
|
236
|
+
optional: type.optional_positionals.map {|param| type(param.type) },
|
237
|
+
rest: type.rest_positionals&.yield_self {|param| type(param.type) },
|
238
|
+
required_keywords: type.required_keywords.transform_values {|param| type(param.type) },
|
239
|
+
optional_keywords: type.optional_keywords.transform_values {|param| type(param.type) },
|
240
|
+
rest_keywords: type.rest_keywords&.yield_self {|param| type(param.type) }
|
241
|
+
)
|
242
|
+
when RBS::Types::UntypedFunction
|
243
|
+
nil
|
244
|
+
end
|
236
245
|
end
|
237
246
|
|
238
247
|
def type_param(type_param)
|
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -57,9 +57,11 @@ module Steep
|
|
57
57
|
include Helper::ChildrenLevel
|
58
58
|
|
59
59
|
def level
|
60
|
-
children = type.params
|
60
|
+
children = type.params&.each_type.to_a + [type.return_type]
|
61
61
|
if block
|
62
|
-
|
62
|
+
if block.type.params
|
63
|
+
children.push(*block.type.params.each_type.to_a)
|
64
|
+
end
|
63
65
|
children.push(block.type.return_type)
|
64
66
|
end
|
65
67
|
if self_type
|
@@ -83,13 +85,16 @@ module Steep
|
|
83
85
|
|
84
86
|
def one_arg?
|
85
87
|
params = type.params
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
if params
|
89
|
+
params.required.size == 1 &&
|
90
|
+
params.optional.empty? &&
|
91
|
+
!params.rest &&
|
92
|
+
params.required_keywords.empty? &&
|
93
|
+
params.optional_keywords.empty? &&
|
94
|
+
!params.rest_keywords
|
95
|
+
else
|
96
|
+
true
|
97
|
+
end
|
93
98
|
end
|
94
99
|
|
95
100
|
def back_type
|
data/lib/steep/drivers/stats.rb
CHANGED
@@ -83,7 +83,7 @@ module Steep
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
table = Terminal::Table.new(
|
86
|
+
table = Terminal::Table.new( # steep:ignore UnknownConstant
|
87
87
|
headings: ["Target", "File", "Status", "Typed calls", "Untyped calls", "All calls", "Typed %"],
|
88
88
|
rows: rows
|
89
89
|
)
|
@@ -166,7 +166,7 @@ module Steep
|
|
166
166
|
{
|
167
167
|
id: stats_id,
|
168
168
|
method: "workspace/executeCommand",
|
169
|
-
params: { command: "steep/stats", arguments: [] }
|
169
|
+
params: { command: "steep/stats", arguments: _ = [] }
|
170
170
|
})
|
171
171
|
|
172
172
|
stats_response = wait_for_response_id(reader: client_reader, id: stats_id)
|
data/lib/steep/expectations.rb
CHANGED
@@ -23,7 +23,7 @@ module Steep
|
|
23
23
|
:information
|
24
24
|
when "HINT"
|
25
25
|
:hint
|
26
|
-
end #: Diagnostic::LSPFormatter::severity
|
26
|
+
end #: Steep::Diagnostic::LSPFormatter::severity
|
27
27
|
|
28
28
|
Diagnostic.new(
|
29
29
|
start_position: start_position,
|
@@ -56,7 +56,7 @@ module Steep
|
|
56
56
|
:hint
|
57
57
|
else
|
58
58
|
:error
|
59
|
-
end #: Diagnostic::LSPFormatter::severity
|
59
|
+
end #: Steep::Diagnostic::LSPFormatter::severity
|
60
60
|
|
61
61
|
Diagnostic.new(
|
62
62
|
start_position: start_position,
|
@@ -82,7 +82,7 @@ module Steep
|
|
82
82
|
def +(other)
|
83
83
|
optional = self.optional? || other.optional?
|
84
84
|
type = Function.new(
|
85
|
-
params: self.type.params + other.type.params,
|
85
|
+
params: self.type.params && other.type.params ? self.type.params + other.type.params : nil,
|
86
86
|
return_type: AST::Types::Union.build(types: [self.type.return_type, other.type.return_type]),
|
87
87
|
location: nil
|
88
88
|
)
|