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