steep-relaxed 1.9.4.3 → 1.10.0.0

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -0
  3. data/Rakefile +23 -0
  4. data/Steepfile +5 -2
  5. data/lib/steep/annotations_helper.rb +43 -0
  6. data/lib/steep/ast/ignore.rb +3 -4
  7. data/lib/steep/cli.rb +102 -23
  8. data/lib/steep/diagnostic/lsp_formatter.rb +17 -3
  9. data/lib/steep/diagnostic/ruby.rb +33 -0
  10. data/lib/steep/diagnostic/signature.rb +48 -0
  11. data/lib/steep/drivers/check.rb +3 -1
  12. data/lib/steep/drivers/diagnostic_printer/base_formatter.rb +19 -0
  13. data/lib/steep/drivers/diagnostic_printer/code_formatter.rb +95 -0
  14. data/lib/steep/drivers/diagnostic_printer/github_actions_formatter.rb +44 -0
  15. data/lib/steep/drivers/diagnostic_printer.rb +9 -86
  16. data/lib/steep/drivers/langserver.rb +4 -1
  17. data/lib/steep/drivers/worker.rb +2 -0
  18. data/lib/steep/interface/builder.rb +2 -2
  19. data/lib/steep/server/custom_methods.rb +12 -0
  20. data/lib/steep/server/interaction_worker.rb +33 -6
  21. data/lib/steep/server/master.rb +103 -7
  22. data/lib/steep/server/type_check_worker.rb +48 -2
  23. data/lib/steep/server/worker_process.rb +31 -20
  24. data/lib/steep/services/completion_provider.rb +12 -2
  25. data/lib/steep/services/signature_service.rb +2 -2
  26. data/lib/steep/signature/validator.rb +56 -4
  27. data/lib/steep/source.rb +2 -2
  28. data/lib/steep/subtyping/check.rb +5 -6
  29. data/lib/steep/type_construction.rb +171 -38
  30. data/lib/steep/type_inference/context.rb +4 -0
  31. data/lib/steep/type_inference/logic_type_interpreter.rb +77 -15
  32. data/lib/steep/type_inference/method_call.rb +5 -3
  33. data/lib/steep/version.rb +1 -1
  34. data/lib/steep.rb +10 -0
  35. data/manual/ruby-diagnostics.md +46 -0
  36. data/sample/Steepfile +0 -2
  37. data/sample/lib/deprecated.rb +7 -0
  38. data/sample/sig/deprecated.rbs +16 -0
  39. data/steep-relaxed.gemspec +5 -3
  40. metadata +15 -12
@@ -1494,6 +1494,10 @@ module Steep
1494
1494
  Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
1495
1495
  )
1496
1496
  end
1497
+
1498
+ if class_name
1499
+ check_deprecation_constant(class_name, name_node, name_node.location.expression)
1500
+ end
1497
1501
  else
1498
1502
  _, constr = synthesize(name_node)
1499
1503
  end
@@ -1549,6 +1553,10 @@ module Steep
1549
1553
  _, constr, module_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
1550
1554
  typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
1551
1555
  end
1556
+
1557
+ if module_name
1558
+ check_deprecation_constant(module_name, name_node, name_node.location.expression)
1559
+ end
1552
1560
  else
1553
1561
  _, constr = synthesize(name_node)
1554
1562
  end
@@ -1619,6 +1627,7 @@ module Steep
1619
1627
 
1620
1628
  if name
1621
1629
  typing.source_index.add_reference(constant: name, ref: node)
1630
+ constr.check_deprecation_constant(name, node, node.location.expression)
1622
1631
  end
1623
1632
 
1624
1633
  Pair.new(type: type, constr: constr)
@@ -1637,6 +1646,8 @@ module Steep
1637
1646
 
1638
1647
  if constant_name
1639
1648
  typing.source_index.add_definition(constant: constant_name, definition: node)
1649
+ location = node.location #: Parser::Source::Map & Parser::AST::_Variable
1650
+ constr.check_deprecation_constant(constant_name, node, location.name)
1640
1651
  end
1641
1652
 
1642
1653
  value_type, constr = constr.synthesize(node.children.last, hint: constant_type)
@@ -2400,6 +2411,9 @@ module Steep
2400
2411
  lhs_type = context.type_env[name]
2401
2412
  rhs_type, constr = synthesize(rhs, hint: lhs_type).to_ary
2402
2413
 
2414
+ location = node.location #: Parser::Source::Map & Parser::AST::_Variable
2415
+ constr.check_deprecation_global(name, node, location.name)
2416
+
2403
2417
  type, constr = constr.gvasgn(node, rhs_type)
2404
2418
 
2405
2419
  constr.add_typing(node, type: type)
@@ -2408,6 +2422,9 @@ module Steep
2408
2422
  when :gvar
2409
2423
  yield_self do
2410
2424
  name = node.children.first
2425
+
2426
+ check_deprecation_global(name, node, node.location.expression)
2427
+
2411
2428
  if type = context.type_env[name]
2412
2429
  add_typing(node, type: type)
2413
2430
  else
@@ -2956,7 +2973,7 @@ module Steep
2956
2973
  nil
2957
2974
  ]
2958
2975
  else
2959
- # No neesting
2976
+ # No nesting
2960
2977
  synthesize_constant(node, nil, constant_name, &block)
2961
2978
  end
2962
2979
  end
@@ -3091,7 +3108,7 @@ module Steep
3091
3108
  body_node,
3092
3109
  block_params: params,
3093
3110
  block_param_hint: params_hint,
3094
- block_type_hint: return_hint,
3111
+ block_next_type: return_hint,
3095
3112
  block_block_hint: block_hint,
3096
3113
  block_annotations: block_annotations,
3097
3114
  block_self_hint: self_hint,
@@ -3220,6 +3237,18 @@ module Steep
3220
3237
  end
3221
3238
  end
3222
3239
 
3240
+ def deprecated_send?(call)
3241
+ return unless call.node.type == :send || call.node.type == :csend
3242
+
3243
+ call.method_decls.each do |decl|
3244
+ if pair = AnnotationsHelper.deprecated_annotation?(decl.method_def.each_annotation.to_a)
3245
+ return pair
3246
+ end
3247
+ end
3248
+
3249
+ nil
3250
+ end
3251
+
3223
3252
  def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:, hint:)
3224
3253
  method = interface.methods[method_name]
3225
3254
 
@@ -3273,6 +3302,20 @@ module Steep
3273
3302
  end
3274
3303
  end
3275
3304
  end
3305
+
3306
+ if (_, message = deprecated_send?(call))
3307
+ send_node, _ = deconstruct_sendish_and_block_nodes(node)
3308
+ send_node or raise
3309
+ _, _, _, loc = deconstruct_send_node!(send_node)
3310
+
3311
+ constr.typing.add_error(
3312
+ Diagnostic::Ruby::DeprecatedReference.new(
3313
+ node: node,
3314
+ location: loc.selector,
3315
+ message: message
3316
+ )
3317
+ )
3318
+ end
3276
3319
  end
3277
3320
 
3278
3321
  if node.type == :csend || ((node.type == :block || node.type == :numblock) && node.children[0].type == :csend)
@@ -3415,7 +3458,7 @@ module Steep
3415
3458
  block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3416
3459
  block_params or raise
3417
3460
 
3418
- constr = constr.synthesize_children(node.children[0])
3461
+ constr = constr.synthesize_children(node.children[0], skips: [receiver])
3419
3462
 
3420
3463
  constr.type_block_without_hint(
3421
3464
  node: node,
@@ -3821,26 +3864,40 @@ module Steep
3821
3864
  if forwarded_args
3822
3865
  method_name or raise "method_name cannot be nil if `forwarded_args` is given, because proc/block doesn't support `...` arg"
3823
3866
 
3824
- (params, block = context.method_context&.forward_arg_type) or raise
3867
+ method_context = context.method_context or raise
3868
+ forward_arg_type = method_context.forward_arg_type
3825
3869
 
3826
- checker.with_context(self_type: self_type, instance_type: context.module_context.instance_type, class_type: context.module_context.module_type, constraints: constraints) do
3827
- result = checker.check_method_params(
3828
- :"... (argument forwarding)",
3829
- Subtyping::Relation.new(
3830
- sub_type: forwarded_args.params,
3831
- super_type: params
3870
+ case forward_arg_type
3871
+ when nil
3872
+ if context.method_context.method_type
3873
+ raise "Method context must have `forwarded_arg_type` if `...` node appears in it"
3874
+ else
3875
+ # Skips type checking forwarded argument because the method type is not given
3876
+ end
3877
+ when true
3878
+ # Skip type checking forwarded argument because the method is untyped function
3879
+ else
3880
+ params, _block = forward_arg_type
3881
+
3882
+ checker.with_context(self_type: self_type, instance_type: context.module_context.instance_type, class_type: context.module_context.module_type, constraints: constraints) do
3883
+ result = checker.check_method_params(
3884
+ :"... (argument forwarding)",
3885
+ Subtyping::Relation.new(
3886
+ sub_type: forwarded_args.params,
3887
+ super_type: params
3888
+ )
3832
3889
  )
3833
- )
3834
3890
 
3835
- if result.failure?
3836
- errors.push(
3837
- Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
3838
- method_name: method_name,
3839
- node: forwarded_args.node,
3840
- params_pair: [params, forwarded_args.params],
3841
- result: result
3891
+ if result.failure?
3892
+ errors.push(
3893
+ Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
3894
+ method_name: method_name,
3895
+ node: forwarded_args.node,
3896
+ params_pair: [params, forwarded_args.params],
3897
+ result: result
3898
+ )
3842
3899
  )
3843
- )
3900
+ end
3844
3901
  end
3845
3902
  end
3846
3903
  end
@@ -4007,7 +4064,7 @@ module Steep
4007
4064
  block_body,
4008
4065
  block_params: block_params_,
4009
4066
  block_param_hint: method_type.block.type.params,
4010
- block_type_hint: method_type.block.type.return_type,
4067
+ block_next_type: method_type.block.type.return_type,
4011
4068
  block_block_hint: nil,
4012
4069
  block_annotations: block_annotations,
4013
4070
  block_self_hint: method_type.block.self_type,
@@ -4062,6 +4119,15 @@ module Steep
4062
4119
 
4063
4120
  fvs_.merge(method_type.type.params.free_variables) if method_type.type.params
4064
4121
  fvs_.merge(method_type.block.type.params.free_variables) if method_type.block.type.params
4122
+ (method_type.type.return_type.free_variables + method_type.block.type.return_type.free_variables).each do |var|
4123
+ if var.is_a?(Symbol)
4124
+ if constraints.unknown?(var)
4125
+ unless constraints.has_constraint?(var)
4126
+ fvs_.delete(var)
4127
+ end
4128
+ end
4129
+ end
4130
+ end
4065
4131
 
4066
4132
  constraints.solution(checker, variables: fvs_, context: ccontext)
4067
4133
  }
@@ -4073,7 +4139,7 @@ module Steep
4073
4139
  block_constr = block_constr.update_type_env {|env| env.subst(s) }
4074
4140
  block_constr = block_constr.update_context {|context|
4075
4141
  context.with(
4076
- self_type: method_type.block.self_type || context.self_type,
4142
+ self_type: context.self_type.subst(s),
4077
4143
  type_env: context.type_env.subst(s),
4078
4144
  block_context: context.block_context&.subst(s),
4079
4145
  break_context: context.break_context&.subst(s)
@@ -4194,18 +4260,29 @@ module Steep
4194
4260
 
4195
4261
  case
4196
4262
  when forwarded_args_node = args.forwarded_args_node
4197
- (_, block = method_context!.forward_arg_type) or raise
4263
+ case forward_arg_type = method_context!.forward_arg_type
4264
+ when nil
4265
+ if method_context!.method_type
4266
+ raise "Method context must have `forwarded_arg_type` if `...` node appears in it"
4267
+ else
4268
+ # Skips type checking forwarded argument because the method type is not given
4269
+ end
4270
+ when true
4271
+ # Skip type checking because it's untyped function
4272
+ else
4273
+ _, block = forward_arg_type
4198
4274
 
4199
- method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
4200
- forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
4275
+ method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
4276
+ forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
4201
4277
 
4202
- if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
4203
- errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
4204
- method_name: method_name,
4205
- node: forwarded_args_node,
4206
- block_pair: [block, method_type.block],
4207
- result: result
4208
- )
4278
+ if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
4279
+ errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
4280
+ method_name: method_name,
4281
+ node: forwarded_args_node,
4282
+ block_pair: [block, method_type.block],
4283
+ result: result
4284
+ )
4285
+ end
4209
4286
  end
4210
4287
 
4211
4288
  when arg.compatible?
@@ -4358,7 +4435,7 @@ module Steep
4358
4435
  block_body,
4359
4436
  block_params: block_params,
4360
4437
  block_param_hint: nil,
4361
- block_type_hint: nil,
4438
+ block_next_type: nil,
4362
4439
  block_block_hint: nil,
4363
4440
  block_annotations: block_annotations,
4364
4441
  block_self_hint: nil,
@@ -4411,7 +4488,7 @@ module Steep
4411
4488
  end
4412
4489
  end
4413
4490
 
4414
- def for_block(body_node, block_params:, block_param_hint:, block_type_hint:, block_block_hint:, block_annotations:, node_type_hint:, block_self_hint:)
4491
+ def for_block(body_node, block_params:, block_param_hint:, block_next_type:, block_block_hint:, block_annotations:, node_type_hint:, block_self_hint:)
4415
4492
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint, block_block_hint, factory: checker.factory)
4416
4493
 
4417
4494
  # @type var param_types_hash: Hash[Symbol?, AST::Types::t]
@@ -4453,7 +4530,7 @@ module Steep
4453
4530
 
4454
4531
  param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
4455
4532
  name, type = pair
4456
- # skip unamed arguments `*`, `**` and `&`
4533
+ # skip unnamed arguments `*`, `**` and `&`
4457
4534
  next if name.nil?
4458
4535
  hash[name] = [type, nil]
4459
4536
  end
@@ -4500,19 +4577,18 @@ module Steep
4500
4577
  end
4501
4578
 
4502
4579
  block_context = TypeInference::Context::BlockContext.new(
4503
- body_type: block_annotations.block_type || block_type_hint
4580
+ body_type: block_annotations.block_type
4504
4581
  )
4505
4582
  break_context = TypeInference::Context::BreakContext.new(
4506
4583
  break_type: break_type || AST::Builtin.any_type,
4507
- next_type: block_context.body_type || AST::Builtin.any_type
4584
+ next_type: block_next_type || AST::Builtin.any_type
4508
4585
  )
4509
4586
 
4510
- self_type = block_annotations.self_type || block_self_hint || self.self_type
4587
+ self_type = block_self_hint || self.self_type
4511
4588
  module_context = self.module_context
4512
4589
 
4513
4590
  if implements = block_annotations.implement_module_annotation
4514
4591
  module_context = default_module_context(implements.name, nesting: nesting)
4515
-
4516
4592
  self_type = module_context.module_type
4517
4593
  end
4518
4594
 
@@ -4520,6 +4596,11 @@ module Steep
4520
4596
  self_type = annotation_self_type
4521
4597
  end
4522
4598
 
4599
+ # self_type here means the top-level `self` type because of the `Interface::Builder` implementation
4600
+ if self_type
4601
+ self_type = expand_self(self_type)
4602
+ end
4603
+
4523
4604
  self.class.new(
4524
4605
  checker: checker,
4525
4606
  source: source,
@@ -4542,6 +4623,20 @@ module Steep
4542
4623
  if block_body
4543
4624
  body_type, _, context = synthesize(block_body, hint: block_context&.body_type || block_type_hint)
4544
4625
 
4626
+ if annotated_body_type = block_context&.body_type
4627
+ if result = no_subtyping?(sub_type: body_type, super_type: annotated_body_type)
4628
+ typing.add_error(
4629
+ Diagnostic::Ruby::BlockBodyTypeMismatch.new(
4630
+ node: node,
4631
+ expected: annotated_body_type,
4632
+ actual: body_type,
4633
+ result: result
4634
+ )
4635
+ )
4636
+ end
4637
+ body_type = annotated_body_type
4638
+ end
4639
+
4545
4640
  range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
4546
4641
  typing.cursor_context.set(range, context)
4547
4642
 
@@ -5179,5 +5274,43 @@ module Steep
5179
5274
  end
5180
5275
  end
5181
5276
  end
5277
+
5278
+ def check_deprecation_global(name, node, location)
5279
+ if global_entry = checker.factory.env.global_decls[name]
5280
+ if (_, message = AnnotationsHelper.deprecated_annotation?(global_entry.decl.annotations))
5281
+ typing.add_error(
5282
+ Diagnostic::Ruby::DeprecatedReference.new(
5283
+ node: node,
5284
+ location: location,
5285
+ message: message
5286
+ )
5287
+ )
5288
+ end
5289
+ end
5290
+ end
5291
+
5292
+ def check_deprecation_constant(name, node, location)
5293
+ entry = checker.builder.factory.env.constant_entry(name)
5294
+
5295
+ annotations =
5296
+ case entry
5297
+ when RBS::Environment::ModuleEntry, RBS::Environment::ClassEntry
5298
+ entry.decls.flat_map { _1.decl.annotations }
5299
+ when RBS::Environment::ConstantEntry, RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
5300
+ entry.decl.annotations
5301
+ end
5302
+
5303
+ if annotations
5304
+ if (_, message = AnnotationsHelper.deprecated_annotation?(annotations))
5305
+ typing.add_error(
5306
+ Diagnostic::Ruby::DeprecatedReference.new(
5307
+ node: node,
5308
+ location: location,
5309
+ message: message
5310
+ )
5311
+ )
5312
+ end
5313
+ end
5314
+ end
5182
5315
  end
5183
5316
  end
@@ -155,6 +155,10 @@ module Steep
155
155
  @type_env = type_env
156
156
  @call_context = call_context
157
157
  @variable_context = variable_context
158
+
159
+ if self_type.free_variables.include?(AST::Types::Self.instance)
160
+ raise "Context#self_type cannot contain `self`"
161
+ end
158
162
  end
159
163
 
160
164
  def with(method_context: self.method_context,
@@ -169,25 +169,45 @@ module Steep
169
169
  return [truthy_result, falsy_result]
170
170
  end
171
171
  else
172
- if env[node]
173
- truthy_type, falsy_type = factory.partition_union(type)
172
+ receiver, *_ = node.children
173
+ receiver_type = typing.type_of(node: receiver) if receiver
174
+
175
+ if env[receiver] && receiver_type.is_a?(AST::Types::Union)
176
+ result = evaluate_union_method_call(node: node, type: type, env: env, receiver: receiver, receiver_type: receiver_type)
177
+ if result
178
+ truthy_result = result[0] unless result[0].unreachable
179
+ falsy_result = result[1] unless result[1].unreachable
180
+ end
181
+ end
174
182
 
175
- truthy_result =
176
- if truthy_type
177
- Result.new(type: truthy_type, env: env.refine_types(pure_call_types: { node => truthy_type }), unreachable: false)
178
- else
179
- Result.new(type: type, env: env, unreachable: true)
180
- end
183
+ truthy_result ||= Result.new(type: type, env: env, unreachable: false)
184
+ falsy_result ||= Result.new(type: type, env: env, unreachable: false)
181
185
 
182
- falsy_result =
183
- if falsy_type
184
- Result.new(type: falsy_type, env: env.refine_types(pure_call_types: { node => falsy_type }), unreachable: false)
185
- else
186
- Result.new(type: type, env: env, unreachable: true)
187
- end
186
+ truthy_type, falsy_type = factory.partition_union(type)
188
187
 
189
- return [truthy_result, falsy_result]
188
+ if truthy_type
189
+ truthy_result = truthy_result.update_type { truthy_type }
190
+ else
191
+ truthy_result = truthy_result.update_type { BOT }.unreachable!
190
192
  end
193
+
194
+ if falsy_type
195
+ falsy_result = falsy_result.update_type { falsy_type }
196
+ else
197
+ falsy_result = falsy_result.update_type { BOT }.unreachable!
198
+ end
199
+
200
+ if truthy_result.env[node] && falsy_result.env[node]
201
+ if truthy_type
202
+ truthy_result = Result.new(type: truthy_type, env: truthy_result.env.refine_types(pure_call_types: { node => truthy_type }), unreachable: false)
203
+ end
204
+
205
+ if falsy_type
206
+ falsy_result = Result.new(type: falsy_type, env: falsy_result.env.refine_types(pure_call_types: { node => falsy_type }), unreachable: false)
207
+ end
208
+ end
209
+
210
+ return [truthy_result, falsy_result]
191
211
  end
192
212
  end
193
213
 
@@ -408,6 +428,48 @@ module Steep
408
428
  end
409
429
  end
410
430
 
431
+ def evaluate_union_method_call(node:, type:, env:, receiver:, receiver_type:)
432
+ call_type = typing.call_of(node: node) rescue nil
433
+ return unless call_type.is_a?(Steep::TypeInference::MethodCall::Typed)
434
+
435
+ truthy_types = [] #: Array[AST::Types::t]
436
+ falsy_types = [] #: Array[AST::Types::t]
437
+
438
+ receiver_type.types.each do |type|
439
+ if shape = subtyping.builder.shape(type, config)
440
+ method = shape.methods[call_type.method_name] or raise
441
+ method_type = method.method_types.find do |method_type|
442
+ call_type.method_decls.any? {|decl| factory.method_type(decl.method_type) == method_type }
443
+ end
444
+ if method_type
445
+ return_type = method_type.type.return_type
446
+ truthy, falsy = factory.partition_union(return_type)
447
+ truthy_types << type if truthy
448
+ falsy_types << type if falsy
449
+ next
450
+ end
451
+ end
452
+
453
+ truthy_types << type
454
+ falsy_types << type
455
+ end
456
+
457
+ truthy_type = truthy_types.empty? ? BOT : AST::Types::Union.build(types: truthy_types)
458
+ falsy_type = falsy_types.empty? ? BOT : AST::Types::Union.build(types: falsy_types)
459
+
460
+ truthy_env, falsy_env = refine_node_type(
461
+ env: env,
462
+ node: receiver,
463
+ truthy_type: truthy_type,
464
+ falsy_type: falsy_type
465
+ )
466
+
467
+ return [
468
+ Result.new(type: type, env: truthy_env, unreachable: truthy_type.nil?),
469
+ Result.new(type: type, env: falsy_env, unreachable: falsy_type.nil?)
470
+ ]
471
+ end
472
+
411
473
  def decompose_value(node)
412
474
  case node.type
413
475
  when :lvar
@@ -124,12 +124,14 @@ module Steep
124
124
 
125
125
  def pure?
126
126
  method_decls.all? do |method_decl|
127
- case member = method_decl.method_def.member
128
- when RBS::AST::Members::MethodDefinition
129
- member.annotations.any? {|annotation| annotation.string == "pure" }
127
+ case method_decl.method_def.member
130
128
  when RBS::AST::Members::Attribute
131
129
  # The attribute writer is not pure
132
130
  !method_decl.method_name.method_name.end_with?("=")
131
+ else
132
+ method_decl.method_def.each_annotation.any? do |annotation|
133
+ annotation.string == "pure"
134
+ end
133
135
  end
134
136
  end
135
137
  end
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.9.4.3"
2
+ VERSION = "1.10.0.0"
3
3
  end
data/lib/steep.rb CHANGED
@@ -17,6 +17,7 @@ require "yaml"
17
17
  require "securerandom"
18
18
  require "base64"
19
19
  require "time"
20
+ require 'socket'
20
21
 
21
22
  require "concurrent/utility/processor_counter"
22
23
  require "terminal-table"
@@ -150,6 +151,11 @@ require "steep/drivers/init"
150
151
  require "steep/drivers/vendor"
151
152
  require "steep/drivers/worker"
152
153
  require "steep/drivers/diagnostic_printer"
154
+ require "steep/drivers/diagnostic_printer/base_formatter"
155
+ require "steep/drivers/diagnostic_printer/code_formatter"
156
+ require "steep/drivers/diagnostic_printer/github_actions_formatter"
157
+
158
+ require "steep/annotations_helper"
153
159
 
154
160
  if ENV["NO_COLOR"]
155
161
  Rainbow.enabled = false
@@ -226,6 +232,10 @@ module Steep
226
232
  end
227
233
  end
228
234
 
235
+ def self.can_fork?
236
+ defined?(fork)
237
+ end
238
+
229
239
  class Sampler
230
240
  def initialize()
231
241
  @samples = []
@@ -237,6 +237,52 @@ test.rb:4:6: [error] ::Kernel is declared as a module in RBS
237
237
  | - | - | - | - | - |
238
238
  | error | error | error | - | - |
239
239
 
240
+ <a name='Ruby::DeprecatedReference'></a>
241
+ ## Ruby::DeprecatedReference
242
+
243
+ Method call or constant reference is deprecated.
244
+
245
+ ### RBS
246
+
247
+ ```rbs
248
+ %a{deprecated} class Foo end
249
+
250
+ class Bar
251
+ %a{deprecated: since v0.9} def self.bar: () -> void
252
+ end
253
+ ```
254
+
255
+ ### Ruby code
256
+
257
+ ```ruby
258
+ Foo
259
+
260
+ Bar.bar()
261
+ ```
262
+
263
+ ### Diagnostic
264
+
265
+ ```
266
+ lib/deprecated.rb:1:0: [warning] The constant is deprecated
267
+ │ Diagnostic ID: Ruby::DeprecatedReference
268
+
269
+ └ Foo
270
+ ~~~
271
+
272
+ lib/deprecated.rb:3:4: [warning] The method is deprecated: since v0.9
273
+ │ Diagnostic ID: Ruby::DeprecatedReference
274
+
275
+ └ Bar.bar()
276
+ ~~~
277
+ ```
278
+
279
+
280
+ ### Severity
281
+
282
+ | all_error | strict | default | lenient | silent |
283
+ | - | - | - | - | - |
284
+ | error | warning | warning | warning | - |
285
+
240
286
  <a name='Ruby::DifferentMethodParameterKind'></a>
241
287
  ## Ruby::DifferentMethodParameterKind
242
288
 
data/sample/Steepfile CHANGED
@@ -5,8 +5,6 @@ target :lib do
5
5
 
6
6
  check "lib" # Directory name
7
7
 
8
- library "rbs"
9
-
10
8
  # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
11
9
  # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
12
10
  # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
@@ -0,0 +1,7 @@
1
+ Foo
2
+
3
+ Bar.bar()
4
+
5
+ Bar.new.hogehoge("")
6
+
7
+ foo = nil #: Foo
@@ -0,0 +1,16 @@
1
+ %a{deprecated: Use Bar instead} class Foo end
2
+
3
+ class Bar
4
+ # Original bar
5
+ def self.bar: %a{deprecated: since v0.9} () -> void
6
+
7
+ # Overloading bar
8
+ def self.bar: (String) -> String | ...
9
+
10
+ def hogehoge: (String) -> void
11
+ | %a{deprecated: Pass an positional argument} (string: String) -> void
12
+ end
13
+
14
+ type t = Foo
15
+
16
+ %a{deprecated} $test: untyped
@@ -41,10 +41,10 @@ Gem::Specification.new do |spec|
41
41
  spec.add_runtime_dependency "activesupport", ">= 4.2"
42
42
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
43
43
  spec.add_runtime_dependency "listen", "~> 3.0"
44
- spec.add_runtime_dependency "language_server-protocol", ">= 3.15", "< 4.0"
45
- spec.add_runtime_dependency "rbs-relaxed", "~> 3.8"
44
+ spec.add_runtime_dependency "language_server-protocol", ">= 3.17.0.4", "< 4.0"
45
+ spec.add_runtime_dependency "rbs-relaxed", "~> 3.9"
46
46
  spec.add_runtime_dependency "concurrent-ruby", ">= 1.1.10"
47
- spec.add_runtime_dependency "terminal-table", ">= 2", "< 4"
47
+ spec.add_runtime_dependency "terminal-table", ">= 2", "< 5"
48
48
 
49
49
  # Stdgem dependencies omitted for compatibility with legacy environments
50
50
  # spec.add_runtime_dependency "securerandom", ">= 0.1"
@@ -53,4 +53,6 @@ Gem::Specification.new do |spec|
53
53
  # spec.add_runtime_dependency "fileutils", ">= 1.1.0"
54
54
  # spec.add_runtime_dependency "strscan", ">= 1.0.0"
55
55
  # spec.add_runtime_dependency "csv", ">= 3.0.9"
56
+ # spec.add_runtime_dependency "uri", ">= 0.12.0"
57
+ # spec.add_runtime_dependency "mutex_m", ">= 0.3.0"
56
58
  end