rubocop 1.85.1 → 1.86.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/config/default.yml +9 -12
- data/lib/rubocop/cache_config.rb +1 -1
- data/lib/rubocop/cli/command/auto_generate_config.rb +1 -1
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +1 -1
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader_resolver.rb +2 -1
- data/lib/rubocop/config_store.rb +1 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +9 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +6 -3
- data/lib/rubocop/cop/layout/line_length.rb +5 -3
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +28 -3
- data/lib/rubocop/cop/layout/space_around_keyword.rb +3 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
- data/lib/rubocop/cop/lint/constant_reassignment.rb +59 -9
- data/lib/rubocop/cop/lint/duplicate_methods.rb +55 -8
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +16 -0
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +22 -7
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/registry.rb +20 -13
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +14 -2
- data/lib/rubocop/cop/style/and_or.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +23 -31
- data/lib/rubocop/cop/style/collection_compact.rb +36 -16
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +0 -4
- data/lib/rubocop/cop/style/empty_class_definition.rb +24 -2
- data/lib/rubocop/cop/style/file_open.rb +1 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -1
- data/lib/rubocop/cop/style/guard_clause.rb +9 -6
- data/lib/rubocop/cop/style/hash_lookup_method.rb +7 -0
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -5
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +2 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -3
- data/lib/rubocop/cop/style/module_member_existence_check.rb +1 -11
- data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/one_class_per_file.rb +24 -4
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +22 -20
- data/lib/rubocop/cop/style/redundant_percent_q.rb +4 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +10 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +4 -3
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +10 -3
- data/lib/rubocop/mcp/server.rb +27 -1
- data/lib/rubocop/path_util.rb +14 -2
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/result_cache.rb +10 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/shared_contexts.rb +11 -2
- data/lib/rubocop/runner.rb +8 -3
- data/lib/rubocop/server/core.rb +2 -0
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +2 -2
- metadata +5 -19
|
@@ -197,6 +197,13 @@ module RuboCop
|
|
|
197
197
|
# @!method sym_name(node)
|
|
198
198
|
def_node_matcher :sym_name, '(sym $_name)'
|
|
199
199
|
|
|
200
|
+
# @!method class_or_module_new_block?(node)
|
|
201
|
+
def_node_matcher :class_or_module_new_block?, <<~PATTERN
|
|
202
|
+
(block
|
|
203
|
+
(send (const _ {:Class :Module}) :new ...)
|
|
204
|
+
...)
|
|
205
|
+
PATTERN
|
|
206
|
+
|
|
200
207
|
def on_send(node) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
201
208
|
name, original_name = alias_method?(node)
|
|
202
209
|
|
|
@@ -233,9 +240,12 @@ module RuboCop
|
|
|
233
240
|
|
|
234
241
|
def check_self_receiver(node, name)
|
|
235
242
|
enclosing = node.parent_module_name
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
if enclosing
|
|
244
|
+
found_method(node, "#{enclosing}.#{name}")
|
|
245
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
246
|
+
scope = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
247
|
+
found_method(node, "#{scope}.#{name}", scope_id: anon_block_scope_id(anon_block))
|
|
248
|
+
end
|
|
239
249
|
end
|
|
240
250
|
|
|
241
251
|
def inside_condition?(node)
|
|
@@ -274,16 +284,50 @@ module RuboCop
|
|
|
274
284
|
end
|
|
275
285
|
|
|
276
286
|
def found_instance_method(node, name)
|
|
277
|
-
|
|
287
|
+
if (scope = node.parent_module_name)
|
|
288
|
+
found_method(node, "#{humanize_scope(scope)}#{name}")
|
|
289
|
+
elsif (anon_block = anonymous_class_block(node))
|
|
290
|
+
base = qualified_name(anon_block.parent_module_name, nil, 'Object')
|
|
291
|
+
scope = node.each_ancestor(:sclass).any? ? "#<Class:#{base}>" : base
|
|
292
|
+
found_method(
|
|
293
|
+
node, "#{humanize_scope(scope)}#{name}", scope_id: anon_block_scope_id(anon_block)
|
|
294
|
+
)
|
|
295
|
+
else
|
|
296
|
+
found_sclass_method(node, name)
|
|
297
|
+
end
|
|
298
|
+
end
|
|
278
299
|
|
|
279
|
-
|
|
300
|
+
def humanize_scope(scope)
|
|
280
301
|
scope = scope.sub(
|
|
281
302
|
/(?:(?<name>.*)::)#<Class:\k<name>>|#<Class:(?<name>.*)>(?:::)?/,
|
|
282
303
|
'\k<name>.'
|
|
283
304
|
)
|
|
284
|
-
scope
|
|
305
|
+
scope.end_with?('.') ? scope : "#{scope}#"
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def anonymous_class_block(node)
|
|
309
|
+
first_block = node.each_ancestor(:block).first
|
|
310
|
+
return unless class_or_module_new_block?(first_block)
|
|
311
|
+
return if first_block.parent&.type?(:lvasgn)
|
|
312
|
+
return if node.each_ancestor(:sclass).any? { |s| !s.children.first.self_type? }
|
|
313
|
+
|
|
314
|
+
first_block
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def anon_block_scope_id(anon_block)
|
|
318
|
+
parent = anon_block.parent
|
|
319
|
+
return unless parent&.type?(:any_block, :begin, :call, :casgn, :any_def)
|
|
320
|
+
|
|
321
|
+
if (receiver = named_receiver(parent))
|
|
322
|
+
"#{receiver.source}.#{parent.method_name}"
|
|
323
|
+
elsif !parent.begin_type? || parent.parent&.any_block_type?
|
|
324
|
+
source_location(anon_block)
|
|
325
|
+
end
|
|
326
|
+
end
|
|
285
327
|
|
|
286
|
-
|
|
328
|
+
def named_receiver(node)
|
|
329
|
+
receiver = node.receiver
|
|
330
|
+
receiver unless class_or_module_new_block?(receiver)
|
|
287
331
|
end
|
|
288
332
|
|
|
289
333
|
def found_sclass_method(node, name)
|
|
@@ -296,8 +340,10 @@ module RuboCop
|
|
|
296
340
|
found_method(node, "#{singleton_receiver_node.method_name}.#{name}")
|
|
297
341
|
end
|
|
298
342
|
|
|
299
|
-
|
|
343
|
+
# rubocop:disable Metrics/AbcSize
|
|
344
|
+
def found_method(node, method_name, scope_id: nil)
|
|
300
345
|
key = method_key(node, method_name)
|
|
346
|
+
key = "#{key}@#{scope_id}" if scope_id
|
|
301
347
|
scope = node.each_ancestor(:rescue, :ensure).first&.type
|
|
302
348
|
|
|
303
349
|
if @definitions.key?(key)
|
|
@@ -314,6 +360,7 @@ module RuboCop
|
|
|
314
360
|
@definitions[key] = node
|
|
315
361
|
end
|
|
316
362
|
end
|
|
363
|
+
# rubocop:enable Metrics/AbcSize
|
|
317
364
|
|
|
318
365
|
def method_key(node, method_name)
|
|
319
366
|
if (ancestor_def = node.each_ancestor(:any_def).first)
|
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
|
70
70
|
|
|
71
71
|
def on_if(node)
|
|
72
72
|
return if node.body || same_line?(node.loc.begin, node.loc.end)
|
|
73
|
-
return if
|
|
73
|
+
return if allow_comments?(node)
|
|
74
74
|
|
|
75
75
|
range = offense_range(node)
|
|
76
76
|
|
|
@@ -83,6 +83,11 @@ module RuboCop
|
|
|
83
83
|
|
|
84
84
|
private
|
|
85
85
|
|
|
86
|
+
def allow_comments?(node)
|
|
87
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
88
|
+
!comments_contain_disables?(node, name)
|
|
89
|
+
end
|
|
90
|
+
|
|
86
91
|
def offense_range(node)
|
|
87
92
|
if node.loc.else
|
|
88
93
|
node.source_range.begin.join(node.loc.else.begin)
|
|
@@ -53,11 +53,18 @@ module RuboCop
|
|
|
53
53
|
def on_case_match(node)
|
|
54
54
|
node.in_pattern_branches.each do |branch|
|
|
55
55
|
next if branch.body
|
|
56
|
-
next if
|
|
56
|
+
next if allow_comments?(branch)
|
|
57
57
|
|
|
58
58
|
add_offense(branch)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def allow_comments?(node)
|
|
65
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
66
|
+
!comments_contain_disables?(node, name)
|
|
67
|
+
end
|
|
61
68
|
end
|
|
62
69
|
end
|
|
63
70
|
end
|
|
@@ -50,11 +50,18 @@ module RuboCop
|
|
|
50
50
|
def on_case(node)
|
|
51
51
|
node.when_branches.each do |when_node|
|
|
52
52
|
next if when_node.body
|
|
53
|
-
next if
|
|
53
|
+
next if allow_comments?(when_node)
|
|
54
54
|
|
|
55
55
|
add_offense(when_node)
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def allow_comments?(node)
|
|
62
|
+
cop_config['AllowComments'] && contains_comments?(node) &&
|
|
63
|
+
!comments_contain_disables?(node, name)
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
66
|
end
|
|
60
67
|
end
|
|
@@ -162,7 +162,7 @@ module RuboCop
|
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
def allow_receiver?(receiver)
|
|
165
|
-
if receiver.numeric_type? || (receiver.
|
|
165
|
+
if receiver.numeric_type? || (receiver.call_type? &&
|
|
166
166
|
(conversion_method?(receiver.method_name) ||
|
|
167
167
|
allowed_method_name?(receiver.method_name)))
|
|
168
168
|
true
|
|
@@ -62,6 +62,22 @@ module RuboCop
|
|
|
62
62
|
# do_something if attrs.respond_to?(:[])
|
|
63
63
|
#
|
|
64
64
|
# # bad
|
|
65
|
+
# foo&.bar ? foo&.bar.baz : qux
|
|
66
|
+
#
|
|
67
|
+
# # good
|
|
68
|
+
# foo&.bar ? foo.bar.baz : qux
|
|
69
|
+
#
|
|
70
|
+
# # bad
|
|
71
|
+
# if foo&.bar
|
|
72
|
+
# foo&.bar.baz
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
# # good
|
|
76
|
+
# if foo&.bar
|
|
77
|
+
# foo.bar.baz
|
|
78
|
+
# end
|
|
79
|
+
#
|
|
80
|
+
# # bad
|
|
65
81
|
# while node&.is_a?(BeginNode)
|
|
66
82
|
# node = node.parent
|
|
67
83
|
# end
|
|
@@ -37,20 +37,25 @@ module RuboCop
|
|
|
37
37
|
}
|
|
38
38
|
PATTERN
|
|
39
39
|
|
|
40
|
+
# rubocop:disable Metrics/AbcSize
|
|
40
41
|
def on_send(node)
|
|
41
42
|
return unless require_safe_navigation?(node)
|
|
42
43
|
|
|
43
44
|
bad_method?(node) do |safe_nav, method|
|
|
44
45
|
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
|
46
|
+
return if ternary_safe_navigation?(node, safe_nav)
|
|
45
47
|
|
|
46
48
|
begin_range = node.loc.dot || safe_nav.source_range.end
|
|
47
49
|
location = begin_range.join(node.source_range.end)
|
|
48
50
|
|
|
49
51
|
add_offense(location) do |corrector|
|
|
52
|
+
next if ternary_else_branch?(node, safe_nav)
|
|
53
|
+
|
|
50
54
|
autocorrect(corrector, offense_range: location, send_node: node)
|
|
51
55
|
end
|
|
52
56
|
end
|
|
53
57
|
end
|
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
|
54
59
|
|
|
55
60
|
private
|
|
56
61
|
|
|
@@ -61,6 +66,18 @@ module RuboCop
|
|
|
61
66
|
parent.rhs != node || parent.lhs.receiver != parent.rhs.receiver
|
|
62
67
|
end
|
|
63
68
|
|
|
69
|
+
def ternary_safe_navigation?(node, safe_nav)
|
|
70
|
+
return false unless (parent = node.parent)
|
|
71
|
+
|
|
72
|
+
parent.if_type? && node.equal?(parent.if_branch) && parent.condition == safe_nav
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def ternary_else_branch?(node, safe_nav)
|
|
76
|
+
return false unless (parent = node.parent)
|
|
77
|
+
|
|
78
|
+
parent.if_type? && node.equal?(parent.else_branch) && parent.condition == safe_nav
|
|
79
|
+
end
|
|
80
|
+
|
|
64
81
|
# @param [Parser::Source::Range] offense_range
|
|
65
82
|
# @param [RuboCop::AST::SendNode] send_node
|
|
66
83
|
# @return [String]
|
|
@@ -26,7 +26,31 @@ module RuboCop
|
|
|
26
26
|
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
|
27
27
|
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
location = diagnostic_location(diagnostic.location)
|
|
30
|
+
add_offense(location, message: message, severity: diagnostic.level)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Expand zero-length diagnostic ranges so that editors and formatters
|
|
34
|
+
# can display them. This typically occurs when the parser reports
|
|
35
|
+
# `unexpected token $end` at EOF.
|
|
36
|
+
def diagnostic_location(location)
|
|
37
|
+
return location if location.size.positive?
|
|
38
|
+
|
|
39
|
+
source_buffer = location.source_buffer
|
|
40
|
+
if location.end_pos < source_buffer.source.size
|
|
41
|
+
location.resize(1)
|
|
42
|
+
elsif location.begin_pos.positive?
|
|
43
|
+
location.adjust(begin_pos: -1)
|
|
44
|
+
else
|
|
45
|
+
location
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Override to skip multiline_ranges check which requires AST.
|
|
50
|
+
# Syntax errors mean the AST is nil, so we go directly to
|
|
51
|
+
# the EOL comment insertion path.
|
|
52
|
+
def disable_offense(offense_range)
|
|
53
|
+
disable_offense_with_eol_or_surround_comment(offense_range)
|
|
30
54
|
end
|
|
31
55
|
|
|
32
56
|
def add_offense_from_error(error)
|
|
@@ -32,6 +32,7 @@ module RuboCop
|
|
|
32
32
|
include RangeHelp
|
|
33
33
|
|
|
34
34
|
MSG = 'Avoid leaving a trailing comma in attribute declarations.'
|
|
35
|
+
RESTRICT_ON_SEND = %i[attr_reader attr_writer attr_accessor attr].freeze
|
|
35
36
|
|
|
36
37
|
def on_send(node)
|
|
37
38
|
return unless node.attribute_accessor? && node.last_argument.def_type?
|
|
@@ -95,10 +95,20 @@ module RuboCop
|
|
|
95
95
|
return unless variable.method_argument?
|
|
96
96
|
return if variable.keyword_argument? && cop_config['AllowUnusedKeywordArguments']
|
|
97
97
|
return if ignored_method?(variable.scope.node.body)
|
|
98
|
+
return if block_argument_with_yield?(variable)
|
|
98
99
|
|
|
99
100
|
super
|
|
100
101
|
end
|
|
101
102
|
|
|
103
|
+
def block_argument_with_yield?(variable)
|
|
104
|
+
return false unless variable.declaration_node.blockarg_type?
|
|
105
|
+
|
|
106
|
+
method_body = variable.scope.node.body
|
|
107
|
+
return false unless method_body
|
|
108
|
+
|
|
109
|
+
method_body.yield_type? || method_body.each_descendant(:yield).any?
|
|
110
|
+
end
|
|
111
|
+
|
|
102
112
|
def ignored_method?(body)
|
|
103
113
|
(cop_config['IgnoreEmptyMethods'] && body.nil?) ||
|
|
104
114
|
(cop_config['IgnoreNotImplementedMethods'] && not_implemented?(body))
|
|
@@ -48,12 +48,12 @@ module RuboCop
|
|
|
48
48
|
|
|
49
49
|
def after_private_modifier?(left_siblings)
|
|
50
50
|
access_modifier_candidates = left_siblings.compact.select do |left_sibling|
|
|
51
|
-
left_sibling.respond_to?(:
|
|
51
|
+
left_sibling.respond_to?(:bare_access_modifier?) && left_sibling.bare_access_modifier?
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
access_modifier_candidates.
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
return false if access_modifier_candidates.empty?
|
|
55
|
+
|
|
56
|
+
access_modifier_candidates.last.command?(:private)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def private_constantize?(right_siblings, const_value)
|
|
@@ -82,28 +82,35 @@ module RuboCop
|
|
|
82
82
|
!NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
85
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
86
86
|
def sole_condition_of_parent_if?(node)
|
|
87
|
+
child = node
|
|
87
88
|
parent = node.parent
|
|
88
89
|
|
|
89
90
|
while parent
|
|
90
91
|
if parent.if_type?
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
end
|
|
92
|
+
condition = parent.condition
|
|
93
|
+
return true if !child.equal?(condition) && non_nil_condition?(condition, node)
|
|
94
|
+
|
|
95
|
+
parent = find_top_if(parent) if parent.elsif?
|
|
96
96
|
elsif else_branch?(parent)
|
|
97
97
|
# Find the top `if` for `else`.
|
|
98
98
|
parent = parent.parent
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
child = parent
|
|
101
102
|
parent = parent&.parent
|
|
102
103
|
end
|
|
103
104
|
|
|
104
105
|
false
|
|
105
106
|
end
|
|
106
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
107
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
108
|
+
|
|
109
|
+
def non_nil_condition?(condition, node)
|
|
110
|
+
return true if condition == node
|
|
111
|
+
|
|
112
|
+
condition.csend_type? && csend_root_receiver(condition) == node
|
|
113
|
+
end
|
|
107
114
|
|
|
108
115
|
def else_branch?(node)
|
|
109
116
|
node.parent&.if_type? && node.parent.else_branch == node
|
|
@@ -114,6 +121,14 @@ module RuboCop
|
|
|
114
121
|
|
|
115
122
|
node
|
|
116
123
|
end
|
|
124
|
+
|
|
125
|
+
def csend_root_receiver(node)
|
|
126
|
+
return unless (receiver = node.receiver)
|
|
127
|
+
|
|
128
|
+
receiver = receiver.receiver while receiver.call_type? && receiver.receiver
|
|
129
|
+
|
|
130
|
+
receiver
|
|
131
|
+
end
|
|
117
132
|
end
|
|
118
133
|
end
|
|
119
134
|
end
|
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def safe_to_split?(node)
|
|
41
|
-
node.each_descendant(:if, :case, :kwbegin, :any_def).none? &&
|
|
41
|
+
node.each_descendant(:if, :case, :kwbegin, :any_def, :rescue, :ensure).none? &&
|
|
42
42
|
node.each_descendant(:dstr, :str).none? { |n| n.heredoc? || n.value.include?("\n") } &&
|
|
43
43
|
node.each_descendant(:begin, :sym).none?(&:multiline?)
|
|
44
44
|
end
|
data/lib/rubocop/cop/registry.rb
CHANGED
|
@@ -16,7 +16,7 @@ module RuboCop
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# Registry that tracks all cops by their badge and department.
|
|
19
|
-
class Registry
|
|
19
|
+
class Registry # rubocop:disable Metrics/ClassLength
|
|
20
20
|
include Enumerable
|
|
21
21
|
|
|
22
22
|
def self.all
|
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
|
46
46
|
global.qualify_badge(badge).first == badge
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
attr_reader :options
|
|
49
|
+
attr_reader :options, :warnings
|
|
50
50
|
|
|
51
51
|
def initialize(cops = [], options = {})
|
|
52
52
|
@registry = {}
|
|
@@ -58,6 +58,7 @@ module RuboCop
|
|
|
58
58
|
|
|
59
59
|
@enabled_cache = {}.compare_by_identity
|
|
60
60
|
@disabled_cache = {}.compare_by_identity
|
|
61
|
+
@warnings = {}
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
def enlist(cop)
|
|
@@ -132,7 +133,7 @@ module RuboCop
|
|
|
132
133
|
# @return [String] Qualified cop name
|
|
133
134
|
def qualified_cop_name(name, path, warn: true)
|
|
134
135
|
badge = Badge.parse(name)
|
|
135
|
-
|
|
136
|
+
print_department_missing_warning(name, path) if warn && department_missing?(badge, name)
|
|
136
137
|
return name if registered?(badge)
|
|
137
138
|
|
|
138
139
|
potential_badges = qualify_badge(badge)
|
|
@@ -148,12 +149,12 @@ module RuboCop
|
|
|
148
149
|
!badge.qualified? && unqualified_cop_names.include?(name)
|
|
149
150
|
end
|
|
150
151
|
|
|
151
|
-
def
|
|
152
|
-
message = "
|
|
152
|
+
def print_department_missing_warning(name, path)
|
|
153
|
+
message = "no department given for #{name}."
|
|
153
154
|
if path.end_with?('.rb')
|
|
154
155
|
message += ' Run `rubocop -a --only Migration/DepartmentName` to fix.'
|
|
155
156
|
end
|
|
156
|
-
|
|
157
|
+
emit_warning(path, message)
|
|
157
158
|
end
|
|
158
159
|
|
|
159
160
|
def unqualified_cop_names
|
|
@@ -274,6 +275,10 @@ module RuboCop
|
|
|
274
275
|
attr_reader :global
|
|
275
276
|
end
|
|
276
277
|
|
|
278
|
+
def warnings?(path)
|
|
279
|
+
@warnings[path]
|
|
280
|
+
end
|
|
281
|
+
|
|
277
282
|
private
|
|
278
283
|
|
|
279
284
|
def initialize_copy(reg)
|
|
@@ -297,18 +302,20 @@ module RuboCop
|
|
|
297
302
|
end
|
|
298
303
|
|
|
299
304
|
def resolve_badge(given_badge, real_badge, source_path, warn: true)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
warn("#{path}: #{given_badge} has the wrong namespace - " \
|
|
305
|
-
"replace it with #{given_badge.with_department(real_badge.department)}")
|
|
306
|
-
end
|
|
305
|
+
if warn && !given_badge.match?(real_badge)
|
|
306
|
+
emit_warning(source_path,
|
|
307
|
+
"#{given_badge} has the wrong namespace - " \
|
|
308
|
+
"replace it with #{given_badge.with_department(real_badge.department)}")
|
|
307
309
|
end
|
|
308
310
|
|
|
309
311
|
real_badge.to_s
|
|
310
312
|
end
|
|
311
313
|
|
|
314
|
+
def emit_warning(path, message)
|
|
315
|
+
Registry.global.warnings[path] = true
|
|
316
|
+
warn "#{PathUtil.smart_path(path)}: Warning: #{message}"
|
|
317
|
+
end
|
|
318
|
+
|
|
312
319
|
def registered?(badge)
|
|
313
320
|
clear_enrollment_queue
|
|
314
321
|
@registry.key?(badge)
|
|
@@ -348,8 +348,20 @@ module RuboCop
|
|
|
348
348
|
|
|
349
349
|
def remove_modifier_node_within_begin(corrector, modifier_node, begin_node)
|
|
350
350
|
def_node = begin_node.children[begin_node.children.index(modifier_node) + 1]
|
|
351
|
-
range
|
|
352
|
-
|
|
351
|
+
# Stop the removal range at the first comment that precedes the def, if
|
|
352
|
+
# any exist. Without this, comments between the modifier and the def are
|
|
353
|
+
# dropped because they fall inside the removed range.
|
|
354
|
+
end_pos = first_comment_or_node_start(def_node)
|
|
355
|
+
corrector.remove(modifier_node.source_range.begin.join(end_pos))
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def first_comment_or_node_start(node)
|
|
359
|
+
preceding = processed_source.ast_with_comments[node].select do |comment|
|
|
360
|
+
comment.loc.line < node.loc.line
|
|
361
|
+
end
|
|
362
|
+
return node.source_range.begin if preceding.empty?
|
|
363
|
+
|
|
364
|
+
preceding.first.source_range.begin
|
|
353
365
|
end
|
|
354
366
|
|
|
355
367
|
def def_source(node, def_nodes)
|
|
@@ -424,21 +424,39 @@ module RuboCop
|
|
|
424
424
|
end
|
|
425
425
|
|
|
426
426
|
def forwarded_rest_arg
|
|
427
|
-
return
|
|
427
|
+
return @forwarded_rest_arg if defined?(@forwarded_rest_arg)
|
|
428
428
|
|
|
429
|
-
|
|
429
|
+
@forwarded_rest_arg = if referenced_rest_arg?
|
|
430
|
+
nil
|
|
431
|
+
else
|
|
432
|
+
arguments.find do |arg|
|
|
433
|
+
forwarded_rest_arg?(arg, @rest_arg_name)
|
|
434
|
+
end
|
|
435
|
+
end
|
|
430
436
|
end
|
|
431
437
|
|
|
432
438
|
def forwarded_kwrest_arg
|
|
433
|
-
return
|
|
439
|
+
return @forwarded_kwrest_arg if defined?(@forwarded_kwrest_arg)
|
|
434
440
|
|
|
435
|
-
|
|
441
|
+
@forwarded_kwrest_arg = if referenced_kwrest_arg?
|
|
442
|
+
nil
|
|
443
|
+
else
|
|
444
|
+
arguments.filter_map do |arg|
|
|
445
|
+
extract_forwarded_kwrest_arg(arg, @kwrest_arg_name)
|
|
446
|
+
end.first
|
|
447
|
+
end
|
|
436
448
|
end
|
|
437
449
|
|
|
438
450
|
def forwarded_block_arg
|
|
439
|
-
return
|
|
440
|
-
|
|
441
|
-
|
|
451
|
+
return @forwarded_block_arg if defined?(@forwarded_block_arg)
|
|
452
|
+
|
|
453
|
+
@forwarded_block_arg = if referenced_block_arg?
|
|
454
|
+
nil
|
|
455
|
+
else
|
|
456
|
+
arguments.find do |arg|
|
|
457
|
+
forwarded_block_arg?(arg, @block_arg_name)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
442
460
|
end
|
|
443
461
|
|
|
444
462
|
def classification
|