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
@@ -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
|
|