steep 1.7.0.dev.2 → 1.7.0.dev.4
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/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
@@ -878,6 +878,7 @@ module Steep
|
|
878
878
|
if self_type && method_context!.method
|
879
879
|
if super_def = method_context!.super_method
|
880
880
|
super_method = Interface::Shape::Entry.new(
|
881
|
+
private_method: true,
|
881
882
|
method_types: super_def.defs.map {|type_def|
|
882
883
|
decl = TypeInference::MethodCall::MethodDecl.new(
|
883
884
|
method_name: InstanceMethodName.new(
|
@@ -1634,28 +1635,32 @@ module Steep
|
|
1634
1635
|
when :yield
|
1635
1636
|
if method_context && method_context.method_type
|
1636
1637
|
if block_type = method_context.block_type
|
1637
|
-
|
1638
|
-
type
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1638
|
+
if block_type.type.params
|
1639
|
+
type = AST::Types::Proc.new(
|
1640
|
+
type: block_type.type,
|
1641
|
+
block: nil,
|
1642
|
+
self_type: block_type.self_type
|
1643
|
+
)
|
1644
|
+
args = TypeInference::SendArgs.new(
|
1645
|
+
node: node,
|
1646
|
+
arguments: node.children,
|
1647
|
+
type: type
|
1648
|
+
)
|
1647
1649
|
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1650
|
+
# @type var errors: Array[Diagnostic::Ruby::Base]
|
1651
|
+
errors = []
|
1652
|
+
constr = type_check_args(
|
1653
|
+
nil,
|
1654
|
+
args,
|
1655
|
+
Subtyping::Constraints.new(unknowns: []),
|
1656
|
+
errors
|
1657
|
+
)
|
1656
1658
|
|
1657
|
-
|
1658
|
-
|
1659
|
+
errors.each do |error|
|
1660
|
+
typing.add_error(error)
|
1661
|
+
end
|
1662
|
+
else
|
1663
|
+
constr = type_check_untyped_args(node.children)
|
1659
1664
|
end
|
1660
1665
|
|
1661
1666
|
add_typing(node, type: block_type.type.return_type)
|
@@ -1812,7 +1817,7 @@ module Steep
|
|
1812
1817
|
.for_branch(right_node)
|
1813
1818
|
.synthesize(right_node, hint: left_truthy.type, condition: true).to_ary
|
1814
1819
|
|
1815
|
-
right_truthy, right_falsy = interpreter.eval(env:
|
1820
|
+
right_truthy, right_falsy = interpreter.eval(env: right_context.type_env, node: right_node)
|
1816
1821
|
|
1817
1822
|
case
|
1818
1823
|
when left_falsy.unreachable
|
@@ -2171,10 +2176,21 @@ module Steep
|
|
2171
2176
|
var_type = AST::Builtin.any_type
|
2172
2177
|
else
|
2173
2178
|
if each = calculate_interface(collection_type, :each, private: true)
|
2174
|
-
|
2179
|
+
method_type = (each.method_types || []).find do |type|
|
2180
|
+
if type.block
|
2181
|
+
if type.block.type.params
|
2182
|
+
type.block.type.params.first_param
|
2183
|
+
else
|
2184
|
+
true
|
2185
|
+
end
|
2186
|
+
end
|
2187
|
+
end
|
2188
|
+
if method_type
|
2175
2189
|
if block = method_type.block
|
2176
|
-
if first_param = block.type
|
2190
|
+
if first_param = block.type&.params&.first_param
|
2177
2191
|
var_type = first_param.type #: AST::Types::t
|
2192
|
+
else
|
2193
|
+
var_type - AST::Builtin.any_type
|
2178
2194
|
end
|
2179
2195
|
end
|
2180
2196
|
end
|
@@ -2385,31 +2401,33 @@ module Steep
|
|
2385
2401
|
|
2386
2402
|
if hint.is_a?(AST::Types::Proc) && value_node.type == :sym
|
2387
2403
|
if hint.one_arg?
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
method_type.type.
|
2404
|
+
if hint.type.params
|
2405
|
+
# Assumes Symbol#to_proc implementation
|
2406
|
+
param_type = hint.type.params.required[0]
|
2407
|
+
case param_type
|
2408
|
+
when AST::Types::Any
|
2409
|
+
type = AST::Types::Any.new
|
2410
|
+
else
|
2411
|
+
if method = calculate_interface(param_type, private: true)&.methods&.[](value_node.children[0])
|
2412
|
+
return_types = method.method_types.filter_map do |method_type|
|
2413
|
+
if method_type.type.params.nil? || method_type.type.params.optional?
|
2414
|
+
method_type.type.return_type
|
2415
|
+
end
|
2398
2416
|
end
|
2399
|
-
end
|
2400
2417
|
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2418
|
+
unless return_types.empty?
|
2419
|
+
type = AST::Types::Proc.new(
|
2420
|
+
type: Interface::Function.new(
|
2421
|
+
params: Interface::Function::Params.empty.with_first_param(
|
2422
|
+
Interface::Function::Params::PositionalParams::Required.new(param_type)
|
2423
|
+
),
|
2424
|
+
return_type: return_types[0],
|
2425
|
+
location: nil
|
2406
2426
|
),
|
2407
|
-
|
2408
|
-
|
2409
|
-
)
|
2410
|
-
|
2411
|
-
self_type: nil
|
2412
|
-
)
|
2427
|
+
block: nil,
|
2428
|
+
self_type: nil
|
2429
|
+
)
|
2430
|
+
end
|
2413
2431
|
end
|
2414
2432
|
end
|
2415
2433
|
end
|
@@ -2611,6 +2629,7 @@ module Steep
|
|
2611
2629
|
end
|
2612
2630
|
end
|
2613
2631
|
rescue RBS::BaseError => exn
|
2632
|
+
Steep.logger.warn("hello")
|
2614
2633
|
Steep.logger.warn { "Unexpected RBS error: #{exn.message}" }
|
2615
2634
|
exn.backtrace&.each {|loc| Steep.logger.warn " #{loc}" }
|
2616
2635
|
typing.add_error(Diagnostic::Ruby::UnexpectedError.new(node: node, error: exn))
|
@@ -3184,7 +3203,7 @@ module Steep
|
|
3184
3203
|
end
|
3185
3204
|
|
3186
3205
|
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:, hint:)
|
3187
|
-
method = interface
|
3206
|
+
method = interface.methods[method_name]
|
3188
3207
|
|
3189
3208
|
if method
|
3190
3209
|
call, constr = type_method_call(
|
@@ -3431,16 +3450,16 @@ module Steep
|
|
3431
3450
|
self_type: self_type,
|
3432
3451
|
class_type: module_context.module_type,
|
3433
3452
|
instance_type: module_context.instance_type,
|
3434
|
-
variable_bounds: variable_context.upper_bounds
|
3453
|
+
variable_bounds: context.variable_context.upper_bounds
|
3435
3454
|
)
|
3436
3455
|
end
|
3437
3456
|
|
3438
3457
|
def calculate_interface(type, method_name = nil, private:)
|
3439
|
-
shape = checker.builder.shape(
|
3440
|
-
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
3458
|
+
shape = checker.builder.shape(type, builder_config)
|
3459
|
+
|
3460
|
+
unless private
|
3461
|
+
shape = shape&.public_shape
|
3462
|
+
end
|
3444
3463
|
|
3445
3464
|
if method_name
|
3446
3465
|
if shape
|
@@ -3913,13 +3932,17 @@ module Steep
|
|
3913
3932
|
# @type var errors: Array[Diagnostic::Ruby::Base]
|
3914
3933
|
errors = []
|
3915
3934
|
|
3916
|
-
|
3917
|
-
|
3918
|
-
|
3919
|
-
|
3920
|
-
|
3921
|
-
|
3922
|
-
|
3935
|
+
if method_type.type.params
|
3936
|
+
args = TypeInference::SendArgs.new(node: node, arguments: arguments, type: method_type)
|
3937
|
+
constr = constr.type_check_args(
|
3938
|
+
method_name,
|
3939
|
+
args,
|
3940
|
+
constraints,
|
3941
|
+
errors
|
3942
|
+
)
|
3943
|
+
else
|
3944
|
+
constr = constr.type_check_untyped_args(arguments)
|
3945
|
+
end
|
3923
3946
|
|
3924
3947
|
if block_params
|
3925
3948
|
# block is given
|
@@ -4008,11 +4031,12 @@ module Steep
|
|
4008
4031
|
end
|
4009
4032
|
|
4010
4033
|
method_type, solved, s = apply_solution(errors, node: node, method_type: method_type) {
|
4011
|
-
|
4012
|
-
|
4013
|
-
|
4014
|
-
|
4015
|
-
|
4034
|
+
fvs_ = Set[] #: Set[AST::Types::variable]
|
4035
|
+
|
4036
|
+
fvs_.merge(method_type.type.params.free_variables) if method_type.type.params
|
4037
|
+
fvs_.merge(method_type.block.type.params.free_variables) if method_type.block.type.params
|
4038
|
+
|
4039
|
+
constraints.solution(checker, variables: fvs_, context: ccontext)
|
4016
4040
|
}
|
4017
4041
|
|
4018
4042
|
method_type.block or raise
|
@@ -4100,129 +4124,143 @@ module Steep
|
|
4100
4124
|
return_type = method_type.type.return_type
|
4101
4125
|
end
|
4102
4126
|
else
|
4103
|
-
|
4104
|
-
|
4105
|
-
|
4106
|
-
|
4107
|
-
|
4127
|
+
if args
|
4128
|
+
# Block is given but method doesn't accept
|
4129
|
+
#
|
4130
|
+
constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
|
4131
|
+
errors << error
|
4132
|
+
end
|
4108
4133
|
|
4109
|
-
|
4110
|
-
|
4111
|
-
|
4112
|
-
|
4113
|
-
|
4114
|
-
|
4134
|
+
case node.children[0].type
|
4135
|
+
when :super, :zsuper
|
4136
|
+
unless method_context!.super_method
|
4137
|
+
errors << Diagnostic::Ruby::UnexpectedSuper.new(
|
4138
|
+
node: node.children[0],
|
4139
|
+
method: method_name
|
4140
|
+
)
|
4141
|
+
end
|
4142
|
+
else
|
4143
|
+
errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
|
4144
|
+
node: node,
|
4145
|
+
method_type: method_type
|
4115
4146
|
)
|
4116
4147
|
end
|
4148
|
+
|
4149
|
+
method_type = eliminate_vars(method_type, type_param_names)
|
4150
|
+
return_type = method_type.type.return_type
|
4117
4151
|
else
|
4118
|
-
|
4119
|
-
|
4120
|
-
|
4121
|
-
|
4152
|
+
if block_body
|
4153
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
4154
|
+
type_block_without_hint(
|
4155
|
+
node: node,
|
4156
|
+
block_annotations: block_annotations,
|
4157
|
+
block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
|
4158
|
+
block_body: block_body
|
4159
|
+
)
|
4160
|
+
end
|
4122
4161
|
end
|
4123
|
-
|
4124
|
-
method_type = eliminate_vars(method_type, type_param_names)
|
4125
|
-
return_type = method_type.type.return_type
|
4126
4162
|
end
|
4127
4163
|
else
|
4128
4164
|
# Block syntax is not given
|
4129
|
-
|
4165
|
+
if args
|
4166
|
+
arg = args.block_pass_arg
|
4130
4167
|
|
4131
|
-
|
4132
|
-
|
4133
|
-
|
4168
|
+
case
|
4169
|
+
when forwarded_args_node = args.forwarded_args_node
|
4170
|
+
(_, block = method_context!.forward_arg_type) or raise
|
4134
4171
|
|
4135
|
-
|
4136
|
-
|
4172
|
+
method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
|
4173
|
+
forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
|
4137
4174
|
|
4138
|
-
|
4139
|
-
|
4140
|
-
|
4141
|
-
|
4142
|
-
|
4143
|
-
|
4144
|
-
|
4145
|
-
|
4175
|
+
if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
|
4176
|
+
errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
4177
|
+
method_name: method_name,
|
4178
|
+
node: forwarded_args_node,
|
4179
|
+
block_pair: [block, method_type.block],
|
4180
|
+
result: result
|
4181
|
+
)
|
4182
|
+
end
|
4146
4183
|
|
4147
|
-
|
4148
|
-
|
4149
|
-
|
4150
|
-
|
4184
|
+
when arg.compatible?
|
4185
|
+
if arg.node
|
4186
|
+
# Block pass (&block) is given
|
4187
|
+
node_type, constr = constr.synthesize(arg.node, hint: arg.node_type)
|
4151
4188
|
|
4152
|
-
|
4153
|
-
|
4154
|
-
|
4189
|
+
nil_given =
|
4190
|
+
constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success? &&
|
4191
|
+
!node_type.is_a?(AST::Types::Any)
|
4155
4192
|
|
4156
|
-
|
4157
|
-
|
4158
|
-
|
4159
|
-
|
4160
|
-
|
4161
|
-
|
4193
|
+
if nil_given
|
4194
|
+
# nil is given ==> no block arg node is given
|
4195
|
+
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4196
|
+
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4197
|
+
}
|
4198
|
+
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4162
4199
|
|
4163
|
-
|
4164
|
-
|
4165
|
-
|
4166
|
-
|
4167
|
-
)
|
4168
|
-
else
|
4169
|
-
# non-nil value is given
|
4170
|
-
constr.check_relation(sub_type: node_type, super_type: arg.node_type, constraints: constraints).else do |result|
|
4171
|
-
errors << Diagnostic::Ruby::BlockTypeMismatch.new(
|
4172
|
-
node: arg.node,
|
4173
|
-
expected: arg.node_type,
|
4174
|
-
actual: node_type,
|
4175
|
-
result: result
|
4200
|
+
# Passing no block
|
4201
|
+
errors << Diagnostic::Ruby::RequiredBlockMissing.new(
|
4202
|
+
node: node,
|
4203
|
+
method_type: method_type
|
4176
4204
|
)
|
4177
|
-
|
4205
|
+
else
|
4206
|
+
# non-nil value is given
|
4207
|
+
constr.check_relation(sub_type: node_type, super_type: arg.node_type, constraints: constraints).else do |result|
|
4208
|
+
errors << Diagnostic::Ruby::BlockTypeMismatch.new(
|
4209
|
+
node: arg.node,
|
4210
|
+
expected: arg.node_type,
|
4211
|
+
actual: node_type,
|
4212
|
+
result: result
|
4213
|
+
)
|
4214
|
+
end
|
4178
4215
|
|
4216
|
+
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4217
|
+
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4218
|
+
}
|
4219
|
+
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4220
|
+
end
|
4221
|
+
else
|
4222
|
+
# Block is not given
|
4179
4223
|
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4180
4224
|
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4181
4225
|
}
|
4182
4226
|
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4183
4227
|
end
|
4184
|
-
|
4185
|
-
|
4228
|
+
|
4229
|
+
return_type = method_type.type.return_type
|
4230
|
+
|
4231
|
+
when arg.block_missing?
|
4232
|
+
# Block is required but not given
|
4186
4233
|
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4187
4234
|
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4188
4235
|
}
|
4189
|
-
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4190
|
-
end
|
4191
4236
|
|
4192
|
-
|
4193
|
-
|
4194
|
-
when arg.block_missing?
|
4195
|
-
# Block is required but not given
|
4196
|
-
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4197
|
-
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4198
|
-
}
|
4199
|
-
|
4200
|
-
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4201
|
-
return_type = method_type.type.return_type
|
4237
|
+
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4238
|
+
return_type = method_type.type.return_type
|
4202
4239
|
|
4203
|
-
|
4204
|
-
|
4205
|
-
|
4206
|
-
|
4240
|
+
errors << Diagnostic::Ruby::RequiredBlockMissing.new(
|
4241
|
+
node: node,
|
4242
|
+
method_type: method_type
|
4243
|
+
)
|
4207
4244
|
|
4208
|
-
|
4209
|
-
|
4245
|
+
when arg.unexpected_block?
|
4246
|
+
# Unexpected block pass node is given
|
4210
4247
|
|
4211
|
-
|
4248
|
+
arg.node or raise
|
4212
4249
|
|
4213
|
-
|
4214
|
-
|
4215
|
-
|
4216
|
-
|
4217
|
-
|
4250
|
+
method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
|
4251
|
+
constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
|
4252
|
+
}
|
4253
|
+
method_type = eliminate_vars(method_type, type_param_names) unless solved
|
4254
|
+
return_type = method_type.type.return_type
|
4218
4255
|
|
4219
|
-
|
4256
|
+
node_type, constr = constr.synthesize(arg.node)
|
4220
4257
|
|
4221
|
-
|
4222
|
-
|
4223
|
-
|
4224
|
-
|
4225
|
-
|
4258
|
+
unless constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success?
|
4259
|
+
errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
|
4260
|
+
node: node,
|
4261
|
+
method_type: method_type
|
4262
|
+
)
|
4263
|
+
end
|
4226
4264
|
end
|
4227
4265
|
end
|
4228
4266
|
end
|
@@ -4349,7 +4387,7 @@ module Steep
|
|
4349
4387
|
def for_block(body_node, block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:, block_self_hint:)
|
4350
4388
|
block_param_pairs = block_param_hint && block_params.zip(block_param_hint, block_block_hint, factory: checker.factory)
|
4351
4389
|
|
4352
|
-
# @type var param_types_hash: Hash[Symbol
|
4390
|
+
# @type var param_types_hash: Hash[Symbol?, AST::Types::t]
|
4353
4391
|
param_types_hash = {}
|
4354
4392
|
if block_param_pairs
|
4355
4393
|
block_param_pairs.each do |param, type|
|
@@ -4384,10 +4422,12 @@ module Steep
|
|
4384
4422
|
end
|
4385
4423
|
end
|
4386
4424
|
|
4387
|
-
param_types_hash.delete_if {|name, _| SPECIAL_LVAR_NAMES.include?(name) }
|
4425
|
+
param_types_hash.delete_if {|name, _| name && SPECIAL_LVAR_NAMES.include?(name) }
|
4388
4426
|
|
4389
4427
|
param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
4390
4428
|
name, type = pair
|
4429
|
+
# skip unamed arguments `*`, `**` and `&`
|
4430
|
+
next if name.nil?
|
4391
4431
|
hash[name] = [type, nil]
|
4392
4432
|
end
|
4393
4433
|
|
@@ -4792,7 +4832,7 @@ module Steep
|
|
4792
4832
|
if shape = calculate_interface(type, private: false)
|
4793
4833
|
if entry = shape.methods[method]
|
4794
4834
|
method_type = entry.method_types.find do |method_type|
|
4795
|
-
method_type.type.params.optional?
|
4835
|
+
method_type.type.params.nil? || method_type.type.params.optional?
|
4796
4836
|
end
|
4797
4837
|
|
4798
4838
|
method_type.type.return_type if method_type
|
@@ -57,8 +57,9 @@ module Steep
|
|
57
57
|
|
58
58
|
def variable_types
|
59
59
|
each_param.with_object({}) do |param, hash|
|
60
|
+
var_name = param.var || next
|
60
61
|
# @type var hash: Hash[Symbol, AST::Types::t?]
|
61
|
-
hash[
|
62
|
+
hash[var_name] = param.type
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
@@ -133,10 +134,17 @@ module Steep
|
|
133
134
|
else
|
134
135
|
var = arg.children[0]
|
135
136
|
type = annotations.var_type(lvar: var)
|
136
|
-
|
137
137
|
case arg.type
|
138
|
-
when :arg
|
138
|
+
when :arg
|
139
139
|
default_params << Param.new(var: var, type: type, value: nil, node: arg)
|
140
|
+
when :procarg0
|
141
|
+
var = arg.children[0]
|
142
|
+
if var.is_a?(Symbol)
|
143
|
+
default_params << Param.new(var: var, type: type, value: nil, node: arg)
|
144
|
+
else
|
145
|
+
var = var.children[0]
|
146
|
+
default_params << Param.new(var: var, type: type, value: nil, node: arg)
|
147
|
+
end
|
140
148
|
when :optarg
|
141
149
|
default_params = trailing_params
|
142
150
|
optional_params << Param.new(var: var, type: type, value: arg.children.last, node: arg)
|
@@ -240,7 +248,7 @@ module Steep
|
|
240
248
|
# @type var zip: Array[[Param | MultipleParam, AST::Types::t]]
|
241
249
|
zip = []
|
242
250
|
|
243
|
-
if untyped_args?(params_type)
|
251
|
+
if params_type.nil? || untyped_args?(params_type)
|
244
252
|
params.each do |param|
|
245
253
|
if param == rest_param
|
246
254
|
zip << [param, AST::Builtin::Array.instance_type(fill_untyped: true)]
|
@@ -125,7 +125,7 @@ module Steep
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def upper_bounds
|
128
|
-
table.each_value.with_object({}) do |type_param, bounds|
|
128
|
+
@upper_bounds ||= table.each_value.with_object({}) do |type_param, bounds|
|
129
129
|
if type_param.upper_bound
|
130
130
|
bounds[type_param.name] = type_param.upper_bound
|
131
131
|
end
|
@@ -593,10 +593,11 @@ module Steep
|
|
593
593
|
end
|
594
594
|
|
595
595
|
def try_convert(type, method)
|
596
|
-
if shape = subtyping.builder.shape(type,
|
596
|
+
if shape = subtyping.builder.shape(type, config)
|
597
597
|
if entry = shape.methods[method]
|
598
598
|
method_type = entry.method_types.find do |method_type|
|
599
|
-
method_type.type.params.
|
599
|
+
method_type.type.params.nil? ||
|
600
|
+
method_type.type.params.optional?
|
600
601
|
end
|
601
602
|
|
602
603
|
method_type.type.return_type if method_type
|
@@ -241,6 +241,22 @@ module Steep
|
|
241
241
|
|
242
242
|
instance = new(args: original, method_type: method_type, forward_arg_type: nil)
|
243
243
|
|
244
|
+
unless method_type.type.params
|
245
|
+
args.each do |arg|
|
246
|
+
case arg.type
|
247
|
+
when :arg
|
248
|
+
name = arg.children[0]
|
249
|
+
instance.params[name] = PositionalParameter.new(name: name, type: AST::Builtin.any_type, node: arg)
|
250
|
+
when :optarg
|
251
|
+
name = arg.children[0]
|
252
|
+
instance.params[name] = PositionalParameter.new(name: name, type: AST::Builtin.any_type, node: arg)
|
253
|
+
when :forward_arg
|
254
|
+
return instance.update(forward_arg_type: true)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
return instance
|
258
|
+
end
|
259
|
+
|
244
260
|
positional_params = method_type.type.params.positional_params
|
245
261
|
|
246
262
|
loop do
|
@@ -500,6 +500,7 @@ module Steep
|
|
500
500
|
attr_reader :type
|
501
501
|
|
502
502
|
def initialize(node:, arguments:, type:)
|
503
|
+
raise "Untyped function is not supported" unless type.type.params
|
503
504
|
@node = node
|
504
505
|
@arguments = arguments
|
505
506
|
@type = type
|
@@ -508,9 +509,9 @@ module Steep
|
|
508
509
|
def params
|
509
510
|
case type
|
510
511
|
when Interface::MethodType
|
511
|
-
type.type.params
|
512
|
+
type.type.params or raise
|
512
513
|
when AST::Types::Proc
|
513
|
-
type.type.params
|
514
|
+
type.type.params or raise
|
514
515
|
else
|
515
516
|
raise
|
516
517
|
end
|
@@ -526,10 +527,12 @@ module Steep
|
|
526
527
|
end
|
527
528
|
|
528
529
|
def positional_params
|
530
|
+
params or raise
|
529
531
|
params.positional_params
|
530
532
|
end
|
531
533
|
|
532
534
|
def keyword_params
|
535
|
+
params or raise
|
533
536
|
params.keyword_params
|
534
537
|
end
|
535
538
|
|
data/lib/steep/version.rb
CHANGED
data/lib/steep.rb
CHANGED
@@ -186,15 +186,19 @@ module Steep
|
|
186
186
|
@ui_logger = nil
|
187
187
|
self.log_output = STDERR
|
188
188
|
|
189
|
-
def self.measure(message, level: :warn)
|
189
|
+
def self.measure(message, level: :warn, threshold: 0.0)
|
190
190
|
start = Time.now
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
level
|
191
|
+
begin
|
192
|
+
yield
|
193
|
+
ensure
|
194
|
+
time = Time.now - start
|
195
|
+
if level.is_a?(Symbol)
|
196
|
+
level = Logger.const_get(level.to_s.upcase)
|
197
|
+
end
|
198
|
+
if time > threshold
|
199
|
+
self.logger.log(level) { "#{message} took #{time} seconds" }
|
200
|
+
end
|
196
201
|
end
|
197
|
-
self.logger.log(level) { "#{message} took #{time} seconds" }
|
198
202
|
end
|
199
203
|
|
200
204
|
def self.log_error(exn, message: "Unexpected error: #{exn.inspect}")
|
@@ -28,9 +28,9 @@ module Steep
|
|
28
28
|
|
29
29
|
def type_1_opt: (t?) -> RBS::Types::t?
|
30
30
|
|
31
|
-
def function_1: (Interface::Function func) -> RBS::Types::
|
31
|
+
def function_1: (Interface::Function func) -> RBS::Types::function
|
32
32
|
|
33
|
-
def params: (RBS::Types::
|
33
|
+
def params: (RBS::Types::function `type`) -> Interface::Function::Params?
|
34
34
|
|
35
35
|
def type_param: (RBS::AST::TypeParam type_param) -> Interface::TypeParam
|
36
36
|
|