steep 1.1.1 → 1.2.0.pre.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 +20 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +12 -11
- data/Gemfile.steep +1 -1
- data/Gemfile.steep.lock +9 -9
- data/README.md +3 -3
- data/Steepfile +23 -0
- data/bin/steep-prof +2 -1
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/class.rb +4 -0
- data/lib/steep/ast/types/factory.rb +86 -602
- data/lib/steep/ast/types/instance.rb +4 -0
- data/lib/steep/ast/types/literal.rb +1 -1
- data/lib/steep/ast/types/proc.rb +22 -8
- data/lib/steep/ast/types/self.rb +4 -0
- data/lib/steep/ast/types/union.rb +1 -1
- data/lib/steep/cli.rb +24 -1
- data/lib/steep/diagnostic/ruby.rb +17 -22
- data/lib/steep/drivers/checkfile.rb +205 -0
- data/lib/steep/drivers/validate.rb +3 -1
- data/lib/steep/equatable.rb +2 -0
- data/lib/steep/interface/block.rb +21 -11
- data/lib/steep/interface/builder.rb +756 -0
- data/lib/steep/interface/function.rb +32 -24
- data/lib/steep/interface/method_type.rb +191 -78
- data/lib/steep/interface/shape.rb +132 -0
- data/lib/steep/interface/substitution.rb +23 -12
- data/lib/steep/interface/type_param.rb +1 -2
- data/lib/steep/path_helper.rb +1 -1
- data/lib/steep/project.rb +5 -7
- data/lib/steep/server/base_worker.rb +2 -2
- data/lib/steep/server/change_buffer.rb +4 -3
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +69 -9
- data/lib/steep/server/type_check_worker.rb +13 -11
- data/lib/steep/server/worker_process.rb +9 -7
- data/lib/steep/services/completion_provider.rb +15 -3
- data/lib/steep/services/hover_provider/singleton_methods.rb +5 -6
- data/lib/steep/services/signature_service.rb +13 -8
- data/lib/steep/services/type_check_service.rb +2 -0
- data/lib/steep/signature/validator.rb +1 -1
- data/lib/steep/subtyping/check.rb +154 -103
- data/lib/steep/subtyping/relation.rb +3 -3
- data/lib/steep/subtyping/result.rb +20 -2
- data/lib/steep/subtyping/variable_variance.rb +9 -0
- data/lib/steep/type_construction.rb +558 -299
- data/lib/steep/type_inference/block_params.rb +169 -86
- data/lib/steep/type_inference/logic_type_interpreter.rb +9 -14
- data/lib/steep/type_inference/method_params.rb +12 -7
- data/lib/steep/type_inference/send_args.rb +41 -35
- data/lib/steep/type_inference/type_env_builder.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +71 -2
- data/rbs_collection.steep.lock.yaml +18 -30
- data/rbs_collection.steep.yaml +1 -0
- data/sig/shims/language-server_protocol.rbs +20 -0
- data/sig/shims/tagged_logging.rbs +6 -0
- data/sig/steep/ast/annotation/collection.rbs +6 -6
- data/sig/steep/ast/types/class.rbs +3 -0
- data/sig/steep/ast/types/factory.rbs +38 -32
- data/sig/steep/ast/types/instance.rbs +3 -0
- data/sig/steep/ast/types/intersection.rbs +1 -1
- data/sig/steep/ast/types/literal.rbs +7 -7
- data/sig/steep/ast/types/name.rbs +14 -13
- data/sig/steep/ast/types/proc.rbs +3 -1
- data/sig/steep/ast/types/self.rbs +3 -0
- data/sig/steep/ast/types/var.rbs +1 -1
- data/sig/steep/diagnostic/ruby.rbs +30 -34
- data/sig/steep/drivers/annotations.rbs +17 -0
- data/sig/steep/drivers/check.rbs +33 -0
- data/sig/steep/drivers/checkfile.rbs +26 -0
- data/sig/steep/drivers/diagnostic_printer.rbs +25 -0
- data/sig/steep/drivers/init.rbs +19 -0
- data/sig/steep/drivers/langserver.rbs +35 -0
- data/sig/steep/drivers/print_project.rbs +15 -0
- data/sig/steep/drivers/stats.rbs +37 -0
- data/sig/steep/drivers/utils/driver_helper.rbs +23 -0
- data/sig/steep/drivers/utils/jobs_count.rbs +11 -0
- data/sig/steep/drivers/validate.rbs +15 -0
- data/sig/steep/drivers/vendor.rbs +19 -0
- data/sig/steep/drivers/watch.rbs +27 -0
- data/sig/steep/drivers/worker.rbs +31 -0
- data/sig/steep/equatable.rbs +11 -0
- data/sig/steep/index/rbs_index.rbs +91 -0
- data/sig/steep/index/signature_symbol_provider.rbs +29 -0
- data/sig/steep/index/source_index.rbs +63 -0
- data/sig/steep/interface/block.rbs +3 -1
- data/sig/steep/interface/builder.rbs +152 -0
- data/sig/steep/interface/function.rbs +67 -55
- data/sig/steep/interface/method_type.rbs +60 -12
- data/sig/steep/interface/shape.rbs +61 -0
- data/sig/steep/interface/substitution.rbs +18 -22
- data/sig/steep/interface/type_param.rbs +9 -1
- data/sig/steep/path_helper.rbs +7 -0
- data/sig/steep/project/pattern.rbs +10 -10
- data/sig/steep/project/target.rbs +2 -2
- data/sig/steep/project.rbs +15 -8
- data/sig/steep/server/base_worker.rbs +49 -0
- data/sig/steep/server/change_buffer.rbs +32 -0
- data/sig/steep/server/interaction_worker.rbs +41 -0
- data/sig/steep/server/lsp_formatter.rbs +29 -0
- data/sig/steep/server/master.rbs +260 -0
- data/sig/steep/server/type_check_worker.rbs +135 -0
- data/sig/steep/server/worker_process.rbs +29 -0
- data/sig/steep/services/completion_provider.rbs +5 -5
- data/sig/steep/services/content_change.rbs +14 -12
- data/sig/steep/services/file_loader.rbs +12 -4
- data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
- data/sig/steep/services/path_assignment.rbs +7 -7
- data/sig/steep/services/signature_service.rbs +67 -40
- data/sig/steep/services/type_check_service.rbs +53 -39
- data/sig/steep/subtyping/check.rbs +80 -44
- data/sig/steep/subtyping/relation.rbs +24 -22
- data/sig/steep/subtyping/result.rbs +48 -30
- data/sig/steep/subtyping/variable_variance.rbs +2 -0
- data/sig/steep/type_construction.rbs +132 -23
- data/sig/steep/type_inference/block_params.rbs +120 -18
- data/sig/steep/type_inference/context.rbs +45 -20
- data/sig/steep/type_inference/context_array.rbs +37 -0
- data/sig/steep/type_inference/logic_type_interpreter.rbs +3 -1
- data/sig/steep/type_inference/method_params.rbs +13 -9
- data/sig/steep/type_inference/send_args.rbs +229 -0
- data/sig/steep/type_inference/type_env_builder.rbs +1 -1
- data/sig/steep/typing.rbs +4 -4
- data/sig/steep.rbs +4 -2
- data/smoke/block/e.rb +12 -0
- data/smoke/block/e.rbs +4 -0
- data/smoke/block/test_expectations.yml +12 -0
- data/smoke/regression/block_param_split.rb +7 -0
- data/smoke/regression/block_param_split.rbs +3 -0
- data/smoke/regression/empty_yield.rb +5 -0
- data/smoke/regression/empty_yield.rbs +3 -0
- data/smoke/regression/test_expectations.yml +12 -0
- data/smoke/yield/test_expectations.yml +4 -4
- data/steep.gemspec +2 -1
- metadata +61 -9
- data/lib/steep/interface/interface.rb +0 -34
- data/sig/steep/interface/interface.rbs +0 -23
- data/sig/version.rbs +0 -3
@@ -23,6 +23,59 @@ module Steep
|
|
23
23
|
def hash
|
24
24
|
self.class.hash ^ var.hash ^ type.hash ^ value.hash ^ node.hash
|
25
25
|
end
|
26
|
+
|
27
|
+
def each_param(&block)
|
28
|
+
if block
|
29
|
+
yield self
|
30
|
+
else
|
31
|
+
enum_for :each_param
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class MultipleParam
|
37
|
+
attr_reader :node
|
38
|
+
|
39
|
+
attr_reader :params
|
40
|
+
|
41
|
+
def initialize(node:, params:)
|
42
|
+
@params = params
|
43
|
+
@node = node
|
44
|
+
end
|
45
|
+
|
46
|
+
def ==(other)
|
47
|
+
other.is_a?(self.class) &&
|
48
|
+
other.node == node &&
|
49
|
+
other.params == params
|
50
|
+
end
|
51
|
+
|
52
|
+
alias eql? ==
|
53
|
+
|
54
|
+
def hash
|
55
|
+
self.class.hash ^ node.hash ^ params.hash
|
56
|
+
end
|
57
|
+
|
58
|
+
def variable_types
|
59
|
+
each_param.with_object({}) do |param, hash|
|
60
|
+
# @type var hash: Hash[Symbol, AST::Types::t?]
|
61
|
+
hash[param.var] = param.type
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def each_param(&block)
|
66
|
+
if block
|
67
|
+
params.each do |param|
|
68
|
+
case param
|
69
|
+
when Param
|
70
|
+
yield param
|
71
|
+
when MultipleParam
|
72
|
+
param.each_param(&block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
else
|
76
|
+
enum_for :each_param
|
77
|
+
end
|
78
|
+
end
|
26
79
|
end
|
27
80
|
|
28
81
|
attr_reader :leading_params
|
@@ -50,35 +103,42 @@ module Steep
|
|
50
103
|
end
|
51
104
|
|
52
105
|
def self.from_node(node, annotations:)
|
106
|
+
# @type var leading_params: Array[Param | MultipleParam]
|
53
107
|
leading_params = []
|
108
|
+
# @type var optional_params: Array[Param]
|
54
109
|
optional_params = []
|
110
|
+
# @type var rest_param: Param?
|
55
111
|
rest_param = nil
|
112
|
+
# @type var trailing_params: Array[Param | MultipleParam]
|
56
113
|
trailing_params = []
|
114
|
+
# @type var block_param: Param?
|
57
115
|
block_param = nil
|
58
116
|
|
59
117
|
default_params = leading_params
|
60
118
|
|
61
119
|
node.children.each do |arg|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
120
|
+
case
|
121
|
+
when arg.type == :mlhs
|
122
|
+
default_params << from_multiple(arg, annotations)
|
123
|
+
when arg.type == :procarg0 && arg.children.size > 1
|
124
|
+
default_params << from_multiple(arg, annotations)
|
125
|
+
else
|
126
|
+
var = arg.children[0]
|
127
|
+
type = annotations.var_type(lvar: var)
|
67
128
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
break
|
129
|
+
case arg.type
|
130
|
+
when :arg, :procarg0
|
131
|
+
default_params << Param.new(var: var, type: type, value: nil, node: arg)
|
132
|
+
when :optarg
|
133
|
+
default_params = trailing_params
|
134
|
+
optional_params << Param.new(var: var, type: type, value: arg.children.last, node: arg)
|
135
|
+
when :restarg
|
136
|
+
default_params = trailing_params
|
137
|
+
rest_param = Param.new(var: var, type: type, value: nil, node: arg)
|
138
|
+
when :blockarg
|
139
|
+
block_param = Param.new(var: var, type: type, value: nil, node: arg)
|
140
|
+
break
|
141
|
+
end
|
82
142
|
end
|
83
143
|
end
|
84
144
|
|
@@ -149,99 +209,100 @@ module Steep
|
|
149
209
|
)
|
150
210
|
end
|
151
211
|
|
152
|
-
def zip(params_type, block)
|
212
|
+
def zip(params_type, block, factory:)
|
153
213
|
if trailing_params.any?
|
154
214
|
Steep.logger.error "Block definition with trailing required parameters are not supported yet"
|
155
215
|
end
|
156
216
|
|
157
|
-
|
158
|
-
|
159
|
-
type = params_type.required[0]
|
160
|
-
|
161
|
-
case
|
162
|
-
when AST::Builtin::Array.instance_type?(type)
|
163
|
-
type_arg = type.args[0]
|
164
|
-
params.each do |param|
|
165
|
-
unless param == rest_param
|
166
|
-
zip << [param, AST::Types::Union.build(types: [type_arg, AST::Builtin.nil_type])]
|
167
|
-
else
|
168
|
-
zip << [param, AST::Builtin::Array.instance_type(type_arg)]
|
169
|
-
end
|
170
|
-
end
|
171
|
-
when type.is_a?(AST::Types::Tuple)
|
172
|
-
types = type.types.dup
|
173
|
-
(leading_params + optional_params).each do |param|
|
174
|
-
ty = types.shift
|
175
|
-
if ty
|
176
|
-
zip << [param, ty]
|
177
|
-
else
|
178
|
-
zip << [param, AST::Types::Nil.new]
|
179
|
-
end
|
180
|
-
end
|
217
|
+
# @type var zip: Array[[Param | MultipleParam, AST::Types::t]]
|
218
|
+
zip = []
|
181
219
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
220
|
+
if expandable? && (type = expandable_params?(params_type, factory))
|
221
|
+
case
|
222
|
+
when AST::Builtin::Array.instance_type?(type)
|
223
|
+
type.is_a?(AST::Types::Name::Instance) or raise
|
224
|
+
|
225
|
+
type_arg = type.args[0]
|
226
|
+
params.each do |param|
|
227
|
+
unless param == rest_param
|
228
|
+
zip << [param, AST::Types::Union.build(types: [type_arg, AST::Builtin.nil_type])]
|
229
|
+
else
|
230
|
+
zip << [param, AST::Builtin::Array.instance_type(type_arg)]
|
189
231
|
end
|
190
232
|
end
|
191
|
-
|
192
|
-
types =
|
193
|
-
|
233
|
+
when type.is_a?(AST::Types::Tuple)
|
234
|
+
types = type.types.dup
|
194
235
|
(leading_params + optional_params).each do |param|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
zip << [param, type]
|
236
|
+
ty = types.shift
|
237
|
+
if ty
|
238
|
+
zip << [param, ty]
|
199
239
|
else
|
200
|
-
zip << [param, AST::
|
240
|
+
zip << [param, AST::Types::Nil.new]
|
201
241
|
end
|
202
242
|
end
|
203
243
|
|
204
244
|
if rest_param
|
205
|
-
if types.
|
206
|
-
|
207
|
-
zip << [rest_param,
|
245
|
+
if types.any?
|
246
|
+
union = AST::Types::Union.build(types: types)
|
247
|
+
zip << [rest_param, AST::Builtin::Array.instance_type(union)]
|
208
248
|
else
|
209
|
-
|
210
|
-
array = AST::Builtin::Array.instance_type(union)
|
211
|
-
zip << [rest_param, array]
|
249
|
+
zip << [rest_param, AST::Types::Nil.new]
|
212
250
|
end
|
213
251
|
end
|
214
252
|
end
|
253
|
+
else
|
254
|
+
types = params_type.flat_unnamed_params
|
215
255
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
zip << [block_param, proc_type]
|
256
|
+
(leading_params + optional_params).each do |param|
|
257
|
+
type = types.shift&.last || params_type.rest
|
258
|
+
|
259
|
+
if type
|
260
|
+
zip << [param, type]
|
261
|
+
else
|
262
|
+
zip << [param, AST::Builtin.nil_type]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
if rest_param
|
267
|
+
if types.empty?
|
268
|
+
array = AST::Builtin::Array.instance_type(params_type.rest || AST::Builtin.any_type)
|
269
|
+
zip << [rest_param, array]
|
231
270
|
else
|
232
|
-
|
271
|
+
union = AST::Types::Union.build(types: types.map(&:last) + [params_type.rest])
|
272
|
+
array = AST::Builtin::Array.instance_type(union)
|
273
|
+
zip << [rest_param, array]
|
233
274
|
end
|
234
275
|
end
|
235
276
|
end
|
277
|
+
|
278
|
+
if block_param
|
279
|
+
if block
|
280
|
+
proc_type = AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
|
281
|
+
if block.optional?
|
282
|
+
proc_type = AST::Types::Union.build(types: [proc_type, AST::Builtin.nil_type])
|
283
|
+
end
|
284
|
+
|
285
|
+
zip << [block_param, proc_type]
|
286
|
+
else
|
287
|
+
zip << [block_param, AST::Builtin.nil_type]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
zip
|
236
292
|
end
|
237
293
|
|
238
|
-
def expandable_params?(params_type)
|
294
|
+
def expandable_params?(params_type, factory)
|
239
295
|
if params_type.flat_unnamed_params.size == 1
|
240
|
-
|
296
|
+
type = params_type.required.first or raise
|
297
|
+
type = factory.deep_expand_alias(type) || type
|
298
|
+
|
299
|
+
case type
|
241
300
|
when AST::Types::Tuple
|
242
|
-
|
301
|
+
type
|
243
302
|
when AST::Types::Name::Base
|
244
|
-
AST::Builtin::Array.instance_type?(type)
|
303
|
+
if AST::Builtin::Array.instance_type?(type)
|
304
|
+
type
|
305
|
+
end
|
245
306
|
end
|
246
307
|
end
|
247
308
|
end
|
@@ -254,16 +315,38 @@ module Steep
|
|
254
315
|
true
|
255
316
|
when params.size == 1 && params[0].node.type == :arg
|
256
317
|
true
|
318
|
+
else
|
319
|
+
false
|
257
320
|
end
|
258
321
|
end
|
259
322
|
|
260
323
|
def each(&block)
|
261
|
-
if
|
324
|
+
if block
|
262
325
|
params.each(&block)
|
263
326
|
else
|
264
327
|
enum_for :each
|
265
328
|
end
|
266
329
|
end
|
330
|
+
|
331
|
+
def self.from_multiple(node, annotations)
|
332
|
+
# @type var params: Array[Param | MultipleParam]
|
333
|
+
params = []
|
334
|
+
|
335
|
+
node.children.each do |child|
|
336
|
+
if child.type == :mlhs
|
337
|
+
params << from_multiple(child, annotations)
|
338
|
+
else
|
339
|
+
var = child.children.first
|
340
|
+
|
341
|
+
raise unless var.is_a?(Symbol)
|
342
|
+
type = annotations.var_type(lvar: var)
|
343
|
+
|
344
|
+
params << Param.new(var: var, node: child, value: nil, type: type)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
MultipleParam.new(node: node, params: params)
|
349
|
+
end
|
267
350
|
end
|
268
351
|
end
|
269
352
|
end
|
@@ -3,10 +3,12 @@ module Steep
|
|
3
3
|
class LogicTypeInterpreter
|
4
4
|
attr_reader :subtyping
|
5
5
|
attr_reader :typing
|
6
|
+
attr_reader :config
|
6
7
|
|
7
|
-
def initialize(subtyping:, typing:)
|
8
|
+
def initialize(subtyping:, typing:, config:)
|
8
9
|
@subtyping = subtyping
|
9
10
|
@typing = typing
|
11
|
+
@config = config
|
10
12
|
end
|
11
13
|
|
12
14
|
def factory
|
@@ -387,22 +389,15 @@ module Steep
|
|
387
389
|
end
|
388
390
|
|
389
391
|
def try_convert(type, method)
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
392
|
+
if shape = subtyping.builder.shape(type, public_only: true, config: config)
|
393
|
+
if entry = shape.methods[method]
|
394
|
+
method_type = entry.method_types.find do |method_type|
|
395
|
+
method_type.type.params.optional?
|
396
|
+
end
|
394
397
|
|
395
|
-
|
396
|
-
if entry = interface.methods[method]
|
397
|
-
method_type = entry.method_types.find do |method_type|
|
398
|
-
method_type.type.params.optional?
|
398
|
+
method_type.type.return_type if method_type
|
399
399
|
end
|
400
|
-
|
401
|
-
method_type.type.return_type if method_type
|
402
400
|
end
|
403
|
-
rescue => exn
|
404
|
-
Steep.log_error(exn, message: "Unexpected error when converting #{type.to_s} with #{method}")
|
405
|
-
nil
|
406
401
|
end
|
407
402
|
end
|
408
403
|
end
|
@@ -95,12 +95,14 @@ module Steep
|
|
95
95
|
attr_reader :name
|
96
96
|
attr_reader :type
|
97
97
|
attr_reader :node
|
98
|
+
attr_reader :self_type
|
98
99
|
|
99
|
-
def initialize(name:, type:, node:, optional:)
|
100
|
+
def initialize(name:, type:, node:, optional:, self_type:)
|
100
101
|
@name = name
|
101
102
|
@type = type
|
102
103
|
@node = node
|
103
104
|
@optional = optional
|
105
|
+
@self_type = self_type
|
104
106
|
end
|
105
107
|
|
106
108
|
def optional?
|
@@ -109,7 +111,7 @@ module Steep
|
|
109
111
|
|
110
112
|
def var_type
|
111
113
|
if type
|
112
|
-
proc_type = AST::Types::Proc.new(type: type, block: nil)
|
114
|
+
proc_type = AST::Types::Proc.new(type: type, block: nil, self_type: self_type)
|
113
115
|
|
114
116
|
if optional?
|
115
117
|
AST::Types::Union.build(types: [proc_type, AST::Builtin.nil_type], location: proc_type.location)
|
@@ -126,13 +128,14 @@ module Steep
|
|
126
128
|
other.name == name &&
|
127
129
|
other.type == type &&
|
128
130
|
other.node == node &&
|
129
|
-
other.optional? == optional?
|
131
|
+
other.optional? == optional? &&
|
132
|
+
other.self_type == self_type
|
130
133
|
end
|
131
134
|
|
132
135
|
alias eql? ==
|
133
136
|
|
134
137
|
def hash
|
135
|
-
self.class.hash ^ name.hash ^ type.hash ^ node.hash ^ optional?.hash
|
138
|
+
self.class.hash ^ name.hash ^ type.hash ^ node.hash ^ optional?.hash ^ self_type.hash
|
136
139
|
end
|
137
140
|
end
|
138
141
|
|
@@ -199,7 +202,7 @@ module Steep
|
|
199
202
|
params.params[name] = KeywordRestParameter.new(name: name, type: nil, node: arg)
|
200
203
|
when :blockarg
|
201
204
|
name = arg.children[0]
|
202
|
-
params.params[name] = BlockParameter.new(name: name, type: nil, optional: nil, node: arg)
|
205
|
+
params.params[name] = BlockParameter.new(name: name, type: nil, optional: nil, node: arg, self_type: nil)
|
203
206
|
end
|
204
207
|
end
|
205
208
|
|
@@ -465,14 +468,16 @@ module Steep
|
|
465
468
|
name: name,
|
466
469
|
type: method_type.block.type,
|
467
470
|
optional: method_type.block.optional?,
|
468
|
-
node: arg
|
471
|
+
node: arg,
|
472
|
+
self_type: method_type.block.self_type
|
469
473
|
)
|
470
474
|
else
|
471
475
|
instance.params[name] = BlockParameter.new(
|
472
476
|
name: name,
|
473
477
|
type: nil,
|
474
478
|
optional: nil,
|
475
|
-
node: arg
|
479
|
+
node: arg,
|
480
|
+
self_type: nil
|
476
481
|
)
|
477
482
|
end
|
478
483
|
end
|
@@ -88,7 +88,7 @@ module Steep
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def following_args
|
91
|
-
args[index..]
|
91
|
+
args[index..] or raise
|
92
92
|
end
|
93
93
|
|
94
94
|
def param
|
@@ -115,12 +115,12 @@ module Steep
|
|
115
115
|
when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Required)
|
116
116
|
[
|
117
117
|
NodeParamPair.new(node: node, param: param),
|
118
|
-
update(index: index+1, positional_params: positional_params
|
118
|
+
update(index: index+1, positional_params: positional_params&.tail)
|
119
119
|
]
|
120
120
|
when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Optional)
|
121
121
|
[
|
122
122
|
NodeParamPair.new(node: node, param: param),
|
123
|
-
update(index: index+1, positional_params: positional_params
|
123
|
+
update(index: index+1, positional_params: positional_params&.tail)
|
124
124
|
]
|
125
125
|
when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Rest)
|
126
126
|
[
|
@@ -148,6 +148,7 @@ module Steep
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def consume(n, node:)
|
151
|
+
# @type var ps: Array[Interface::Function::Params::PositionalParams::param]
|
151
152
|
ps = []
|
152
153
|
params = consume0(n, node: node, params: positional_params, ps: ps)
|
153
154
|
case params
|
@@ -172,7 +173,7 @@ module Steep
|
|
172
173
|
UnexpectedArg.new(node: node)
|
173
174
|
when Interface::Function::Params::PositionalParams::Required, Interface::Function::Params::PositionalParams::Optional
|
174
175
|
ps << head
|
175
|
-
consume0(n-1, node: node, params: params
|
176
|
+
consume0(n-1, node: node, params: params&.tail, ps: ps)
|
176
177
|
when Interface::Function::Params::PositionalParams::Rest
|
177
178
|
ps << head
|
178
179
|
consume0(n-1, node: node, params: params, ps: ps)
|
@@ -302,6 +303,7 @@ module Steep
|
|
302
303
|
end
|
303
304
|
|
304
305
|
def possible_key_type
|
306
|
+
# @type var key_types: Array[AST::Types::t]
|
305
307
|
key_types = all_keys.map {|key| AST::Types::Literal.new(value: key) }
|
306
308
|
key_types << AST::Builtin::Symbol.instance_type if rest_type
|
307
309
|
|
@@ -395,9 +397,12 @@ module Steep
|
|
395
397
|
end
|
396
398
|
|
397
399
|
def consume_keys(keys, node:)
|
400
|
+
# @type var consumed_keys: Array[Symbol]
|
398
401
|
consumed_keys = []
|
402
|
+
# @type var types: Array[AST::Types::t]
|
399
403
|
types = []
|
400
404
|
|
405
|
+
# @type var unexpected_keyword: Symbol?
|
401
406
|
unexpected_keyword = nil
|
402
407
|
|
403
408
|
keys.each do |key|
|
@@ -466,7 +471,9 @@ module Steep
|
|
466
471
|
end
|
467
472
|
|
468
473
|
def node_type
|
469
|
-
|
474
|
+
raise unless block
|
475
|
+
|
476
|
+
type = AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
|
470
477
|
|
471
478
|
if block.optional?
|
472
479
|
type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
|
@@ -478,22 +485,38 @@ module Steep
|
|
478
485
|
|
479
486
|
attr_reader :node
|
480
487
|
attr_reader :arguments
|
481
|
-
attr_reader :
|
482
|
-
attr_reader :method_name
|
488
|
+
attr_reader :type
|
483
489
|
|
484
|
-
def initialize(node:, arguments:,
|
490
|
+
def initialize(node:, arguments:, type:)
|
485
491
|
@node = node
|
486
492
|
@arguments = arguments
|
487
|
-
@
|
488
|
-
|
493
|
+
@type = type
|
494
|
+
end
|
495
|
+
|
496
|
+
def params
|
497
|
+
case type
|
498
|
+
when Interface::MethodType
|
499
|
+
type.type.params
|
500
|
+
when AST::Types::Proc
|
501
|
+
type.type.params
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
def block
|
506
|
+
case type
|
507
|
+
when Interface::MethodType
|
508
|
+
type.block
|
509
|
+
when AST::Types::Proc
|
510
|
+
type.block
|
511
|
+
end
|
489
512
|
end
|
490
513
|
|
491
514
|
def positional_params
|
492
|
-
|
515
|
+
params.positional_params
|
493
516
|
end
|
494
517
|
|
495
518
|
def keyword_params
|
496
|
-
|
519
|
+
params.keyword_params
|
497
520
|
end
|
498
521
|
|
499
522
|
def kwargs_node
|
@@ -520,7 +543,6 @@ module Steep
|
|
520
543
|
|
521
544
|
def block_pass_arg
|
522
545
|
node = arguments.find {|node| node.type == :block_pass }
|
523
|
-
block = method_type.block
|
524
546
|
|
525
547
|
BlockPassArg.new(node: node, block: block)
|
526
548
|
end
|
@@ -589,7 +611,8 @@ module Steep
|
|
589
611
|
when nil
|
590
612
|
raise
|
591
613
|
when AST::Types::Record
|
592
|
-
|
614
|
+
# @type var keys: Array[Symbol]
|
615
|
+
keys = _ = type.elements.keys
|
593
616
|
ts, args = args.consume_keys(keys, node: a.node)
|
594
617
|
|
595
618
|
case ts
|
@@ -625,35 +648,18 @@ module Steep
|
|
625
648
|
errors.each do |error|
|
626
649
|
case error
|
627
650
|
when KeywordArgs::UnexpectedKeyword
|
628
|
-
diagnostics << Diagnostic::Ruby::UnexpectedKeywordArgument.new(
|
629
|
-
node: error.node,
|
630
|
-
method_type: method_type,
|
631
|
-
method_name: method_name
|
632
|
-
)
|
651
|
+
diagnostics << Diagnostic::Ruby::UnexpectedKeywordArgument.new(node: error.node, params: params)
|
633
652
|
when KeywordArgs::MissingKeyword
|
634
653
|
missing_keywords.push(*error.keywords)
|
635
654
|
when PositionalArgs::UnexpectedArg
|
636
|
-
diagnostics << Diagnostic::Ruby::UnexpectedPositionalArgument.new(
|
637
|
-
node: error.node,
|
638
|
-
method_type: method_type,
|
639
|
-
method_name: method_name
|
640
|
-
)
|
655
|
+
diagnostics << Diagnostic::Ruby::UnexpectedPositionalArgument.new(node: error.node, params: params)
|
641
656
|
when PositionalArgs::MissingArg
|
642
|
-
diagnostics << Diagnostic::Ruby::InsufficientPositionalArguments.new(
|
643
|
-
node: node,
|
644
|
-
method_name: method_name,
|
645
|
-
method_type: method_type
|
646
|
-
)
|
657
|
+
diagnostics << Diagnostic::Ruby::InsufficientPositionalArguments.new(node: node, params: params)
|
647
658
|
end
|
648
659
|
end
|
649
660
|
|
650
661
|
unless missing_keywords.empty?
|
651
|
-
diagnostics << Diagnostic::Ruby::InsufficientKeywordArguments.new(
|
652
|
-
node: node,
|
653
|
-
method_name: method_name,
|
654
|
-
method_type: method_type,
|
655
|
-
missing_keywords: missing_keywords
|
656
|
-
)
|
662
|
+
diagnostics << Diagnostic::Ruby::InsufficientKeywordArguments.new(node: node, params: params, missing_keywords: missing_keywords)
|
657
663
|
end
|
658
664
|
|
659
665
|
diagnostics
|
data/lib/steep/version.rb
CHANGED