steep 1.9.4 → 1.10.0.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -3
- data/Steepfile +5 -2
- data/lib/steep/annotations_helper.rb +43 -0
- data/lib/steep/ast/ignore.rb +3 -4
- data/lib/steep/cli.rb +102 -23
- data/lib/steep/diagnostic/lsp_formatter.rb +17 -3
- data/lib/steep/diagnostic/ruby.rb +75 -0
- data/lib/steep/diagnostic/signature.rb +20 -0
- data/lib/steep/drivers/check.rb +3 -1
- data/lib/steep/drivers/diagnostic_printer/base_formatter.rb +19 -0
- data/lib/steep/drivers/diagnostic_printer/code_formatter.rb +95 -0
- data/lib/steep/drivers/diagnostic_printer/github_actions_formatter.rb +44 -0
- data/lib/steep/drivers/diagnostic_printer.rb +9 -86
- data/lib/steep/drivers/langserver.rb +4 -1
- data/lib/steep/drivers/worker.rb +2 -0
- data/lib/steep/interface/builder.rb +2 -2
- data/lib/steep/server/custom_methods.rb +12 -0
- data/lib/steep/server/interaction_worker.rb +33 -6
- data/lib/steep/server/master.rb +103 -7
- data/lib/steep/server/type_check_worker.rb +48 -2
- data/lib/steep/server/worker_process.rb +31 -20
- data/lib/steep/services/completion_provider.rb +12 -2
- data/lib/steep/services/signature_service.rb +2 -2
- data/lib/steep/services/type_check_service.rb +22 -7
- data/lib/steep/signature/validator.rb +56 -4
- data/lib/steep/source.rb +3 -1
- data/lib/steep/subtyping/check.rb +22 -16
- data/lib/steep/type_construction.rb +153 -34
- data/lib/steep/type_inference/case_when.rb +2 -0
- data/lib/steep/type_inference/logic_type_interpreter.rb +77 -15
- data/lib/steep/type_inference/method_call.rb +5 -3
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +10 -0
- data/manual/ruby-diagnostics.md +114 -1
- data/sample/Steepfile +0 -2
- data/sample/lib/conference.rb +14 -0
- data/sample/lib/deprecated.rb +7 -0
- data/sample/sig/deprecated.rbs +16 -0
- data/steep.gemspec +4 -3
- metadata +28 -8
@@ -155,7 +155,6 @@ module Steep
|
|
155
155
|
definition.methods[method_name]&.yield_self do |method|
|
156
156
|
method.method_types
|
157
157
|
.map {|method_type| checker.factory.method_type(method_type) }
|
158
|
-
.select {|method_type| method_type.is_a?(Interface::MethodType) }
|
159
158
|
.inject {|t1, t2| t1 + t2}
|
160
159
|
end
|
161
160
|
end
|
@@ -163,6 +162,18 @@ module Steep
|
|
163
162
|
|
164
163
|
method_type = annotation_method_type || definition_method_type
|
165
164
|
|
165
|
+
unless method_type
|
166
|
+
if definition
|
167
|
+
typing.add_error(
|
168
|
+
Diagnostic::Ruby::UndeclaredMethodDefinition.new(method_name: method_name, type_name: definition.type_name, node: node)
|
169
|
+
)
|
170
|
+
else
|
171
|
+
typing.add_error(
|
172
|
+
Diagnostic::Ruby::MethodDefinitionInUndeclaredModule.new(method_name: method_name, node: node)
|
173
|
+
)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
166
177
|
if (annotation_return_type = annots&.return_type) && (method_type_return_type = method_type&.type&.return_type)
|
167
178
|
check_relation(sub_type: annotation_return_type, super_type: method_type_return_type).else do |result|
|
168
179
|
typing.add_error(
|
@@ -1483,6 +1494,10 @@ module Steep
|
|
1483
1494
|
Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
|
1484
1495
|
)
|
1485
1496
|
end
|
1497
|
+
|
1498
|
+
if class_name
|
1499
|
+
check_deprecation_constant(class_name, name_node, name_node.location.expression)
|
1500
|
+
end
|
1486
1501
|
else
|
1487
1502
|
_, constr = synthesize(name_node)
|
1488
1503
|
end
|
@@ -1538,6 +1553,10 @@ module Steep
|
|
1538
1553
|
_, constr, module_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
|
1539
1554
|
typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
|
1540
1555
|
end
|
1556
|
+
|
1557
|
+
if module_name
|
1558
|
+
check_deprecation_constant(module_name, name_node, name_node.location.expression)
|
1559
|
+
end
|
1541
1560
|
else
|
1542
1561
|
_, constr = synthesize(name_node)
|
1543
1562
|
end
|
@@ -1608,6 +1627,7 @@ module Steep
|
|
1608
1627
|
|
1609
1628
|
if name
|
1610
1629
|
typing.source_index.add_reference(constant: name, ref: node)
|
1630
|
+
constr.check_deprecation_constant(name, node, node.location.expression)
|
1611
1631
|
end
|
1612
1632
|
|
1613
1633
|
Pair.new(type: type, constr: constr)
|
@@ -1626,6 +1646,8 @@ module Steep
|
|
1626
1646
|
|
1627
1647
|
if constant_name
|
1628
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)
|
1629
1651
|
end
|
1630
1652
|
|
1631
1653
|
value_type, constr = constr.synthesize(node.children.last, hint: constant_type)
|
@@ -2015,8 +2037,8 @@ module Steep
|
|
2015
2037
|
branch_result =
|
2016
2038
|
if body
|
2017
2039
|
when_clause_constr
|
2018
|
-
.for_branch(body)
|
2019
2040
|
.update_type_env {|env| env.join(*body_envs) }
|
2041
|
+
.for_branch(body)
|
2020
2042
|
.tap {|constr| typing.cursor_context.set_node_context(body, constr.context) }
|
2021
2043
|
.synthesize(body, hint: hint)
|
2022
2044
|
else
|
@@ -2040,14 +2062,16 @@ module Steep
|
|
2040
2062
|
|
2041
2063
|
if els
|
2042
2064
|
branch_results << condition_constr.synthesize(els, hint: hint)
|
2065
|
+
else
|
2066
|
+
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: condition_constr)
|
2067
|
+
end
|
2068
|
+
|
2069
|
+
branch_results.reject! do |result|
|
2070
|
+
result.type.is_a?(AST::Types::Bot)
|
2043
2071
|
end
|
2044
2072
|
|
2045
2073
|
types = branch_results.map(&:type)
|
2046
2074
|
envs = branch_results.map {|result| result.constr.context.type_env }
|
2047
|
-
|
2048
|
-
unless els
|
2049
|
-
types << AST::Builtin.nil_type
|
2050
|
-
end
|
2051
2075
|
end
|
2052
2076
|
|
2053
2077
|
constr = constr.update_type_env do |env|
|
@@ -2387,6 +2411,9 @@ module Steep
|
|
2387
2411
|
lhs_type = context.type_env[name]
|
2388
2412
|
rhs_type, constr = synthesize(rhs, hint: lhs_type).to_ary
|
2389
2413
|
|
2414
|
+
location = node.location #: Parser::Source::Map & Parser::AST::_Variable
|
2415
|
+
constr.check_deprecation_global(name, node, location.name)
|
2416
|
+
|
2390
2417
|
type, constr = constr.gvasgn(node, rhs_type)
|
2391
2418
|
|
2392
2419
|
constr.add_typing(node, type: type)
|
@@ -2395,6 +2422,9 @@ module Steep
|
|
2395
2422
|
when :gvar
|
2396
2423
|
yield_self do
|
2397
2424
|
name = node.children.first
|
2425
|
+
|
2426
|
+
check_deprecation_global(name, node, node.location.expression)
|
2427
|
+
|
2398
2428
|
if type = context.type_env[name]
|
2399
2429
|
add_typing(node, type: type)
|
2400
2430
|
else
|
@@ -2943,7 +2973,7 @@ module Steep
|
|
2943
2973
|
nil
|
2944
2974
|
]
|
2945
2975
|
else
|
2946
|
-
# No
|
2976
|
+
# No nesting
|
2947
2977
|
synthesize_constant(node, nil, constant_name, &block)
|
2948
2978
|
end
|
2949
2979
|
end
|
@@ -3207,6 +3237,18 @@ module Steep
|
|
3207
3237
|
end
|
3208
3238
|
end
|
3209
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
|
+
|
3210
3252
|
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:, hint:)
|
3211
3253
|
method = interface.methods[method_name]
|
3212
3254
|
|
@@ -3260,6 +3302,20 @@ module Steep
|
|
3260
3302
|
end
|
3261
3303
|
end
|
3262
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
|
3263
3319
|
end
|
3264
3320
|
|
3265
3321
|
if node.type == :csend || ((node.type == :block || node.type == :numblock) && node.children[0].type == :csend)
|
@@ -3808,26 +3864,40 @@ module Steep
|
|
3808
3864
|
if forwarded_args
|
3809
3865
|
method_name or raise "method_name cannot be nil if `forwarded_args` is given, because proc/block doesn't support `...` arg"
|
3810
3866
|
|
3811
|
-
|
3867
|
+
method_context = context.method_context or raise
|
3868
|
+
forward_arg_type = method_context.forward_arg_type
|
3812
3869
|
|
3813
|
-
|
3814
|
-
|
3815
|
-
|
3816
|
-
|
3817
|
-
|
3818
|
-
|
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
|
+
)
|
3819
3889
|
)
|
3820
|
-
)
|
3821
3890
|
|
3822
|
-
|
3823
|
-
|
3824
|
-
|
3825
|
-
|
3826
|
-
|
3827
|
-
|
3828
|
-
|
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
|
+
)
|
3829
3899
|
)
|
3830
|
-
|
3900
|
+
end
|
3831
3901
|
end
|
3832
3902
|
end
|
3833
3903
|
end
|
@@ -4181,18 +4251,29 @@ module Steep
|
|
4181
4251
|
|
4182
4252
|
case
|
4183
4253
|
when forwarded_args_node = args.forwarded_args_node
|
4184
|
-
|
4254
|
+
case forward_arg_type = method_context!.forward_arg_type
|
4255
|
+
when nil
|
4256
|
+
if method_context!.method_type
|
4257
|
+
raise "Method context must have `forwarded_arg_type` if `...` node appears in it"
|
4258
|
+
else
|
4259
|
+
# Skips type checking forwarded argument because the method type is not given
|
4260
|
+
end
|
4261
|
+
when true
|
4262
|
+
# Skip type checking because it's untyped function
|
4263
|
+
else
|
4264
|
+
_, block = forward_arg_type
|
4185
4265
|
|
4186
|
-
|
4187
|
-
|
4266
|
+
method_block_type = method_type.block&.to_proc_type || AST::Builtin.nil_type
|
4267
|
+
forwarded_block_type = block&.to_proc_type || AST::Builtin.nil_type
|
4188
4268
|
|
4189
|
-
|
4190
|
-
|
4191
|
-
|
4192
|
-
|
4193
|
-
|
4194
|
-
|
4195
|
-
|
4269
|
+
if result = constr.no_subtyping?(sub_type: forwarded_block_type, super_type: method_block_type)
|
4270
|
+
errors << Diagnostic::Ruby::IncompatibleArgumentForwarding.new(
|
4271
|
+
method_name: method_name,
|
4272
|
+
node: forwarded_args_node,
|
4273
|
+
block_pair: [block, method_type.block],
|
4274
|
+
result: result
|
4275
|
+
)
|
4276
|
+
end
|
4196
4277
|
end
|
4197
4278
|
|
4198
4279
|
when arg.compatible?
|
@@ -4440,7 +4521,7 @@ module Steep
|
|
4440
4521
|
|
4441
4522
|
param_types = param_types_hash.each.with_object({}) do |pair, hash| #$ Hash[Symbol, [AST::Types::t, AST::Types::t?]]
|
4442
4523
|
name, type = pair
|
4443
|
-
# skip
|
4524
|
+
# skip unnamed arguments `*`, `**` and `&`
|
4444
4525
|
next if name.nil?
|
4445
4526
|
hash[name] = [type, nil]
|
4446
4527
|
end
|
@@ -5166,5 +5247,43 @@ module Steep
|
|
5166
5247
|
end
|
5167
5248
|
end
|
5168
5249
|
end
|
5250
|
+
|
5251
|
+
def check_deprecation_global(name, node, location)
|
5252
|
+
if global_entry = checker.factory.env.global_decls[name]
|
5253
|
+
if (_, message = AnnotationsHelper.deprecated_annotation?(global_entry.decl.annotations))
|
5254
|
+
typing.add_error(
|
5255
|
+
Diagnostic::Ruby::DeprecatedReference.new(
|
5256
|
+
node: node,
|
5257
|
+
location: location,
|
5258
|
+
message: message
|
5259
|
+
)
|
5260
|
+
)
|
5261
|
+
end
|
5262
|
+
end
|
5263
|
+
end
|
5264
|
+
|
5265
|
+
def check_deprecation_constant(name, node, location)
|
5266
|
+
entry = checker.builder.factory.env.constant_entry(name)
|
5267
|
+
|
5268
|
+
annotations =
|
5269
|
+
case entry
|
5270
|
+
when RBS::Environment::ModuleEntry, RBS::Environment::ClassEntry
|
5271
|
+
entry.decls.flat_map { _1.decl.annotations }
|
5272
|
+
when RBS::Environment::ConstantEntry, RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
|
5273
|
+
entry.decl.annotations
|
5274
|
+
end
|
5275
|
+
|
5276
|
+
if annotations
|
5277
|
+
if (_, message = AnnotationsHelper.deprecated_annotation?(annotations))
|
5278
|
+
typing.add_error(
|
5279
|
+
Diagnostic::Ruby::DeprecatedReference.new(
|
5280
|
+
node: node,
|
5281
|
+
location: location,
|
5282
|
+
message: message
|
5283
|
+
)
|
5284
|
+
)
|
5285
|
+
end
|
5286
|
+
end
|
5287
|
+
end
|
5169
5288
|
end
|
5170
5289
|
end
|
@@ -169,25 +169,45 @@ module Steep
|
|
169
169
|
return [truthy_result, falsy_result]
|
170
170
|
end
|
171
171
|
else
|
172
|
-
|
173
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
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
|
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
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 = []
|
data/manual/ruby-diagnostics.md
CHANGED
@@ -40,7 +40,7 @@ A type annotation has a syntax error.
|
|
40
40
|
### Ruby code
|
41
41
|
|
42
42
|
```ruby
|
43
|
-
# @type var foo: () ->
|
43
|
+
# @type var foo: () ->
|
44
44
|
```
|
45
45
|
|
46
46
|
### Diagnostic
|
@@ -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
|
|
@@ -703,6 +749,36 @@ test.rb:2:6: [error] Cannot allow method body have type `::Integer` because decl
|
|
703
749
|
| - | - | - | - | - |
|
704
750
|
| error | error | error | warning | - |
|
705
751
|
|
752
|
+
<a name='Ruby::MethodDefinitionInUndeclaredModule'></a>
|
753
|
+
## Ruby::MethodDefinitionInUndeclaredModule
|
754
|
+
|
755
|
+
A `def` syntax doesn't have method type because the module/class is undefined in RBS.
|
756
|
+
|
757
|
+
### Ruby code
|
758
|
+
|
759
|
+
```ruby
|
760
|
+
class UndeclaredClass
|
761
|
+
def to_s = 123
|
762
|
+
end
|
763
|
+
```
|
764
|
+
|
765
|
+
### Diagnostic
|
766
|
+
|
767
|
+
```
|
768
|
+
test.rb:2:6: [error] Method `to_s` is defined in undeclared module
|
769
|
+
│ Diagnostic ID: Ruby::MethodDefinitionInUndeclaredModule
|
770
|
+
│
|
771
|
+
└ def to_s = 123
|
772
|
+
~~~~
|
773
|
+
```
|
774
|
+
|
775
|
+
|
776
|
+
### Severity
|
777
|
+
|
778
|
+
| all_error | strict | default | lenient | silent |
|
779
|
+
| - | - | - | - | - |
|
780
|
+
| error | warning | information | hint | - |
|
781
|
+
|
706
782
|
<a name='Ruby::MethodDefinitionMissing'></a>
|
707
783
|
## Ruby::MethodDefinitionMissing
|
708
784
|
|
@@ -1235,6 +1311,43 @@ test.rb:2:4: [error] Empty hash doesn't have type annotation
|
|
1235
1311
|
| - | - | - | - | - |
|
1236
1312
|
| error | error | warning | hint | - |
|
1237
1313
|
|
1314
|
+
<a name='Ruby::UndeclaredMethodDefinition'></a>
|
1315
|
+
## Ruby::UndeclaredMethodDefinition
|
1316
|
+
|
1317
|
+
A `def` syntax doesn't have corresponding RBS method definition.
|
1318
|
+
|
1319
|
+
### RBS
|
1320
|
+
|
1321
|
+
```rbs
|
1322
|
+
class Foo
|
1323
|
+
end
|
1324
|
+
```
|
1325
|
+
|
1326
|
+
### Ruby code
|
1327
|
+
|
1328
|
+
```ruby
|
1329
|
+
class Foo
|
1330
|
+
def undeclared = nil
|
1331
|
+
end
|
1332
|
+
```
|
1333
|
+
|
1334
|
+
### Diagnostic
|
1335
|
+
|
1336
|
+
```
|
1337
|
+
test.rb:2:6: [error] Method `::Foo#undeclared` is not declared in RBS
|
1338
|
+
│ Diagnostic ID: Ruby::UndeclaredMethodDefinition
|
1339
|
+
│
|
1340
|
+
└ def undeclared = nil
|
1341
|
+
~~~~~~~~~~
|
1342
|
+
```
|
1343
|
+
|
1344
|
+
|
1345
|
+
### Severity
|
1346
|
+
|
1347
|
+
| all_error | strict | default | lenient | silent |
|
1348
|
+
| - | - | - | - | - |
|
1349
|
+
| error | warning | warning | information | - |
|
1350
|
+
|
1238
1351
|
<a name='Ruby::UnexpectedBlockGiven'></a>
|
1239
1352
|
## Ruby::UnexpectedBlockGiven
|
1240
1353
|
|
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
|
data/sample/lib/conference.rb
CHANGED
@@ -7,19 +7,33 @@ class Conference
|
|
7
7
|
@title = title
|
8
8
|
@year = year
|
9
9
|
end
|
10
|
+
|
11
|
+
def hello_world
|
12
|
+
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
Conference.new()
|
13
17
|
|
14
18
|
Konference.new()
|
15
19
|
|
20
|
+
class Hogehogehoge
|
21
|
+
def to_s = 123
|
16
22
|
|
23
|
+
def foo = 23
|
24
|
+
end
|
17
25
|
|
18
26
|
# @type var foo: Konference
|
19
27
|
|
20
28
|
foo = Conference.new
|
21
29
|
|
30
|
+
class Conference
|
31
|
+
def hello = 123
|
32
|
+
end
|
33
|
+
|
22
34
|
class Conference12
|
35
|
+
def hello = 123
|
36
|
+
|
23
37
|
class Integer
|
24
38
|
end
|
25
39
|
end
|