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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +17 -19
  3. data/doc/narrowing.md +1 -1
  4. data/doc/shape.md +176 -0
  5. data/gemfile_steep/Gemfile.lock +10 -12
  6. data/lib/steep/ast/types/factory.rb +27 -18
  7. data/lib/steep/ast/types/helper.rb +4 -0
  8. data/lib/steep/ast/types/intersection.rb +7 -0
  9. data/lib/steep/ast/types/proc.rb +14 -9
  10. data/lib/steep/ast/types/record.rb +7 -0
  11. data/lib/steep/ast/types/tuple.rb +7 -0
  12. data/lib/steep/ast/types/union.rb +7 -0
  13. data/lib/steep/drivers/stats.rb +2 -2
  14. data/lib/steep/drivers/validate.rb +4 -2
  15. data/lib/steep/expectations.rb +2 -2
  16. data/lib/steep/interface/block.rb +1 -1
  17. data/lib/steep/interface/builder.rb +337 -360
  18. data/lib/steep/interface/function.rb +82 -11
  19. data/lib/steep/interface/method_type.rb +18 -10
  20. data/lib/steep/interface/shape.rb +69 -18
  21. data/lib/steep/interface/substitution.rb +4 -0
  22. data/lib/steep/node_helper.rb +18 -1
  23. data/lib/steep/project/pattern.rb +1 -2
  24. data/lib/steep/server/interaction_worker.rb +6 -0
  25. data/lib/steep/server/lsp_formatter.rb +2 -0
  26. data/lib/steep/services/completion_provider.rb +20 -18
  27. data/lib/steep/services/file_loader.rb +15 -20
  28. data/lib/steep/services/signature_help_provider.rb +17 -18
  29. data/lib/steep/signature/validator.rb +1 -1
  30. data/lib/steep/subtyping/check.rb +19 -22
  31. data/lib/steep/subtyping/variable_variance.rb +3 -3
  32. data/lib/steep/test.rb +9 -0
  33. data/lib/steep/type_construction.rb +198 -158
  34. data/lib/steep/type_inference/block_params.rb +12 -4
  35. data/lib/steep/type_inference/context.rb +1 -1
  36. data/lib/steep/type_inference/logic_type_interpreter.rb +3 -2
  37. data/lib/steep/type_inference/method_params.rb +16 -0
  38. data/lib/steep/type_inference/send_args.rb +5 -2
  39. data/lib/steep/version.rb +1 -1
  40. data/lib/steep.rb +11 -7
  41. data/sig/steep/ast/types/factory.rbs +2 -2
  42. data/sig/steep/ast/types/helper.rbs +2 -0
  43. data/sig/steep/ast/types/intersection.rbs +2 -0
  44. data/sig/steep/ast/types/name.rbs +4 -0
  45. data/sig/steep/ast/types/record.rbs +2 -0
  46. data/sig/steep/ast/types/tuple.rbs +2 -0
  47. data/sig/steep/ast/types/union.rbs +2 -0
  48. data/sig/steep/expectations.rbs +1 -1
  49. data/sig/steep/interface/block.rbs +2 -2
  50. data/sig/steep/interface/builder.rbs +54 -109
  51. data/sig/steep/interface/function.rbs +38 -32
  52. data/sig/steep/interface/shape.rbs +23 -4
  53. data/sig/steep/interface/substitution.rbs +2 -0
  54. data/sig/steep/node_helper.rbs +11 -0
  55. data/sig/steep/services/signature_help_provider.rbs +3 -1
  56. data/sig/steep/subtyping/constraints.rbs +2 -2
  57. data/sig/steep/subtyping/variable_variance.rbs +1 -1
  58. data/sig/steep/type_construction.rbs +1 -1
  59. data/sig/steep/type_inference/block_params.rbs +3 -3
  60. data/sig/steep/type_inference/context.rbs +2 -0
  61. data/sig/steep/type_inference/method_params.rbs +3 -3
  62. data/sig/steep.rbs +1 -1
  63. data/steep.gemspec +1 -1
  64. 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
- type = AST::Types::Proc.new(
1638
- type: block_type.type,
1639
- block: nil,
1640
- self_type: block_type.self_type
1641
- )
1642
- args = TypeInference::SendArgs.new(
1643
- node: node,
1644
- arguments: node.children,
1645
- type: type
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
- # @type var errors: Array[Diagnostic::Ruby::Base]
1649
- errors = []
1650
- constr = type_check_args(
1651
- nil,
1652
- args,
1653
- Subtyping::Constraints.new(unknowns: []),
1654
- errors
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
- errors.each do |error|
1658
- typing.add_error(error)
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: left_falsy.env, node: right_node)
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
- if method_type = (each.method_types || []).find {|type| type.block && type.block.type.params.first_param }
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.params.first_param
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
- # Assumes Symbol#to_proc implementation
2389
- param_type = hint.type.params.required[0]
2390
- case param_type
2391
- when AST::Types::Any
2392
- type = AST::Types::Any.new
2393
- else
2394
- if method = calculate_interface(param_type, private: true)&.methods&.[](value_node.children[0])
2395
- return_types = method.method_types.filter_map do |method_type|
2396
- if method_type.type.params.optional?
2397
- method_type.type.return_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
- unless return_types.empty?
2402
- type = AST::Types::Proc.new(
2403
- type: Interface::Function.new(
2404
- params: Interface::Function::Params.empty.with_first_param(
2405
- Interface::Function::Params::PositionalParams::Required.new(param_type)
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
- return_type: return_types[0],
2408
- location: nil
2409
- ),
2410
- block: nil,
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&.methods&.[](method_name)
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
- type,
3441
- public_only: !private,
3442
- config: builder_config
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
- args = TypeInference::SendArgs.new(node: node, arguments: arguments, type: method_type)
3917
- constr = constr.type_check_args(
3918
- method_name,
3919
- args,
3920
- constraints,
3921
- errors
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
- constraints.solution(
4012
- checker,
4013
- variables: method_type.type.params.free_variables + method_type.block.type.params.free_variables,
4014
- context: ccontext
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
- # Block is given but method doesn't accept
4104
- #
4105
- constr.type_block_without_hint(node: node, block_annotations: block_annotations, block_params: block_params_, block_body: block_body) do |error|
4106
- errors << error
4107
- end
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
- case node.children[0].type
4110
- when :super, :zsuper
4111
- unless method_context!.super_method
4112
- errors << Diagnostic::Ruby::UnexpectedSuper.new(
4113
- node: node.children[0],
4114
- method: method_name
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
- errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
4119
- node: node,
4120
- method_type: method_type
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
- arg = args.block_pass_arg
4165
+ if args
4166
+ arg = args.block_pass_arg
4130
4167
 
4131
- case
4132
- when forwarded_args_node = args.forwarded_args_node
4133
- (_, block = method_context!.forward_arg_type) or raise
4168
+ case
4169
+ when forwarded_args_node = args.forwarded_args_node
4170
+ (_, block = method_context!.forward_arg_type) or raise
4134
4171
 
4135
- method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
4136
- forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
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
- if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
4139
- errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
4140
- method_name: method_name,
4141
- node: forwarded_args_node,
4142
- block_pair: [block, method_type.block],
4143
- result: result
4144
- )
4145
- end
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
- when arg.compatible?
4148
- if arg.node
4149
- # Block pass (&block) is given
4150
- node_type, constr = constr.synthesize(arg.node, hint: arg.node_type)
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
- nil_given =
4153
- constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success? &&
4154
- !node_type.is_a?(AST::Types::Any)
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
- if nil_given
4157
- # nil is given ==> no block arg node is given
4158
- method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
4159
- constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
4160
- }
4161
- method_type = eliminate_vars(method_type, type_param_names) unless solved
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
- # Passing no block
4164
- errors << Diagnostic::Ruby::RequiredBlockMissing.new(
4165
- node: node,
4166
- method_type: method_type
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
- end
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
- else
4185
- # Block is not given
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
- return_type = method_type.type.return_type
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
- errors << Diagnostic::Ruby::RequiredBlockMissing.new(
4204
- node: node,
4205
- method_type: method_type
4206
- )
4240
+ errors << Diagnostic::Ruby::RequiredBlockMissing.new(
4241
+ node: node,
4242
+ method_type: method_type
4243
+ )
4207
4244
 
4208
- when arg.unexpected_block?
4209
- # Unexpected block pass node is given
4245
+ when arg.unexpected_block?
4246
+ # Unexpected block pass node is given
4210
4247
 
4211
- arg.node or raise
4248
+ arg.node or raise
4212
4249
 
4213
- method_type, solved, _ = apply_solution(errors, node: node, method_type: method_type) {
4214
- constraints.solution(checker, variables: method_type.free_variables, context: ccontext)
4215
- }
4216
- method_type = eliminate_vars(method_type, type_param_names) unless solved
4217
- return_type = method_type.type.return_type
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
- node_type, constr = constr.synthesize(arg.node)
4256
+ node_type, constr = constr.synthesize(arg.node)
4220
4257
 
4221
- unless constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success?
4222
- errors << Diagnostic::Ruby::UnexpectedBlockGiven.new(
4223
- node: node,
4224
- method_type: method_type
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, AST::Types::t]
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[param.var] = param.type
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, :procarg0
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, public_only: true, config: config)
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.optional?
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
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.7.0.dev.2"
2
+ VERSION = "1.7.0.dev.4"
3
3
  end
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
- yield
192
- ensure
193
- time = Time.now - start
194
- if level.is_a?(Symbol)
195
- level = Logger.const_get(level.to_s.upcase)
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::Function
31
+ def function_1: (Interface::Function func) -> RBS::Types::function
32
32
 
33
- def params: (RBS::Types::Function `type`) -> Interface::Function::Params
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