rubocop 1.67.0 → 1.69.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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +81 -6
- data/lib/rubocop/cached_data.rb +12 -4
- data/lib/rubocop/cli/command/execute_runner.rb +1 -1
- data/lib/rubocop/cli/command/version.rb +2 -2
- data/lib/rubocop/cop/autocorrect_logic.rb +22 -2
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +2 -4
- data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +46 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +1 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +3 -4
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +3 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
- data/lib/rubocop/cop/layout/leading_comment_space.rb +44 -1
- data/lib/rubocop/cop/layout/line_length.rb +118 -4
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
- data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
- data/lib/rubocop/cop/layout/redundant_line_break.rb +3 -35
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +16 -17
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -12
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
- data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
- data/lib/rubocop/cop/lint/empty_file.rb +0 -2
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +14 -6
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -3
- data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -5
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +8 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +106 -0
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
- data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
- data/lib/rubocop/cop/lint/void.rb +3 -2
- data/lib/rubocop/cop/metrics/class_length.rb +7 -7
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -2
- data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
- data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
- data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
- data/lib/rubocop/cop/mixin/range_help.rb +0 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +6 -7
- data/lib/rubocop/cop/naming/file_name.rb +0 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -11
- data/lib/rubocop/cop/naming/variable_name.rb +3 -4
- data/lib/rubocop/cop/naming/variable_number.rb +2 -3
- data/lib/rubocop/cop/offense.rb +2 -3
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +53 -24
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
- data/lib/rubocop/cop/style/array_intersect.rb +5 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +18 -3
- data/lib/rubocop/cop/style/case_like_if.rb +8 -11
- data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +19 -21
- data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
- data/lib/rubocop/cop/style/dig_chain.rb +90 -0
- data/lib/rubocop/cop/style/endless_method.rb +1 -14
- data/lib/rubocop/cop/style/file_null.rb +73 -0
- data/lib/rubocop/cop/style/file_touch.rb +75 -0
- data/lib/rubocop/cop/style/for.rb +0 -1
- data/lib/rubocop/cop/style/global_vars.rb +1 -3
- data/lib/rubocop/cop/style/guard_clause.rb +15 -2
- data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
- data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +14 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +0 -1
- data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
- data/lib/rubocop/cop/style/lambda_call.rb +0 -1
- data/lib/rubocop/cop/style/map_into_array.rb +6 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +7 -11
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
- data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
- data/lib/rubocop/cop/style/multiple_comparison.rb +28 -39
- data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -4
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
- data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
- data/lib/rubocop/cop/style/or_assignment.rb +3 -6
- data/lib/rubocop/cop/style/parallel_assignment.rb +8 -13
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +36 -21
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +21 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +9 -11
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +1 -0
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/redundant_self.rb +7 -14
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +7 -5
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -1
- data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
- data/lib/rubocop/cop/style/self_assignment.rb +11 -17
- data/lib/rubocop/cop/style/signal_exception.rb +2 -3
- data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +13 -3
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -3
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +0 -1
- data/lib/rubocop/cop/style/swap_values.rb +4 -15
- data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
- data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
- data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
- data/lib/rubocop/cop/variable_force/branch.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +5 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/cop/variable_force.rb +4 -10
- data/lib/rubocop/cops_documentation_generator.rb +20 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/runner.rb +16 -8
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +27 -8
- data/lib/rubocop.rb +16 -0
- metadata +28 -12
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Looks for places where
|
6
|
+
# Looks for places where a subset of an Enumerable (array,
|
7
7
|
# range, set, etc.; see note below) is calculated based on a `Regexp`
|
8
8
|
# match, and suggests `grep` or `grep_v` instead.
|
9
9
|
#
|
@@ -37,33 +37,29 @@ module RuboCop
|
|
37
37
|
private
|
38
38
|
|
39
39
|
def check(node, var_type)
|
40
|
-
|
41
|
-
return unless rhs
|
40
|
+
return unless (rhs = node.expression)
|
42
41
|
|
43
|
-
if rhs.send_type?
|
44
|
-
check_send_node(node, rhs,
|
42
|
+
if rhs.send_type? && rhs.arguments.one?
|
43
|
+
check_send_node(node, rhs, node.name, var_type)
|
45
44
|
elsif rhs.operator_keyword?
|
46
|
-
check_boolean_node(node, rhs,
|
45
|
+
check_boolean_node(node, rhs, node.name, var_type)
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
50
49
|
def check_send_node(node, rhs, var_name, var_type)
|
51
|
-
|
52
|
-
return unless OPS.include?(method_name)
|
50
|
+
return unless OPS.include?(rhs.method_name)
|
53
51
|
|
54
52
|
target_node = s(var_type, var_name)
|
55
|
-
return unless receiver == target_node
|
53
|
+
return unless rhs.receiver == target_node
|
56
54
|
|
57
|
-
add_offense(node, message: format(MSG, method: method_name)) do |corrector|
|
55
|
+
add_offense(node, message: format(MSG, method: rhs.method_name)) do |corrector|
|
58
56
|
autocorrect(corrector, node)
|
59
57
|
end
|
60
58
|
end
|
61
59
|
|
62
60
|
def check_boolean_node(node, rhs, var_name, var_type)
|
63
|
-
first_operand, _second_operand = *rhs
|
64
|
-
|
65
61
|
target_node = s(var_type, var_name)
|
66
|
-
return unless
|
62
|
+
return unless rhs.lhs == target_node
|
67
63
|
|
68
64
|
operator = rhs.loc.operator.source
|
69
65
|
add_offense(node, message: format(MSG, method: operator)) do |corrector|
|
@@ -72,7 +68,7 @@ module RuboCop
|
|
72
68
|
end
|
73
69
|
|
74
70
|
def autocorrect(corrector, node)
|
75
|
-
|
71
|
+
rhs = node.expression
|
76
72
|
|
77
73
|
if rhs.send_type?
|
78
74
|
autocorrect_send_node(corrector, node, rhs)
|
@@ -82,13 +78,11 @@ module RuboCop
|
|
82
78
|
end
|
83
79
|
|
84
80
|
def autocorrect_send_node(corrector, node, rhs)
|
85
|
-
|
86
|
-
apply_autocorrect(corrector, node, rhs, method_name.to_s, args)
|
81
|
+
apply_autocorrect(corrector, node, rhs, rhs.method_name, rhs.first_argument)
|
87
82
|
end
|
88
83
|
|
89
84
|
def autocorrect_boolean_node(corrector, node, rhs)
|
90
|
-
|
91
|
-
apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, second_operand)
|
85
|
+
apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, rhs.rhs)
|
92
86
|
end
|
93
87
|
|
94
88
|
def apply_autocorrect(corrector, node, rhs, operator, new_rhs)
|
@@ -122,10 +122,9 @@ module RuboCop
|
|
122
122
|
def on_rescue(node)
|
123
123
|
return unless style == :semantic
|
124
124
|
|
125
|
-
|
126
|
-
check_scope(:raise, begin_node)
|
125
|
+
check_scope(:raise, node.body)
|
127
126
|
|
128
|
-
|
127
|
+
node.resbody_branches.each do |rescue_node|
|
129
128
|
check_scope(:fail, rescue_node)
|
130
129
|
allow(:raise, rescue_node)
|
131
130
|
end
|
@@ -33,22 +33,19 @@ module RuboCop
|
|
33
33
|
#
|
34
34
|
class SingleArgumentDig < Base
|
35
35
|
extend AutoCorrector
|
36
|
+
include DigHelp
|
36
37
|
|
37
38
|
MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
|
38
39
|
RESTRICT_ON_SEND = %i[dig].freeze
|
39
40
|
IGNORED_ARGUMENT_TYPES = %i[block_pass forwarded_restarg forwarded_args hash].freeze
|
40
41
|
|
41
|
-
# @!method single_argument_dig?(node)
|
42
|
-
def_node_matcher :single_argument_dig?, <<~PATTERN
|
43
|
-
(send _ :dig $!splat)
|
44
|
-
PATTERN
|
45
|
-
|
46
42
|
def on_send(node)
|
47
43
|
return unless node.receiver
|
48
44
|
|
49
45
|
expression = single_argument_dig?(node)
|
50
46
|
return unless expression
|
51
47
|
return if IGNORED_ARGUMENT_TYPES.include?(expression.type)
|
48
|
+
return if ignore_dig_chain?(node)
|
52
49
|
|
53
50
|
receiver = node.receiver.source
|
54
51
|
argument = expression.source
|
@@ -63,6 +60,13 @@ module RuboCop
|
|
63
60
|
|
64
61
|
ignore_node(node)
|
65
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def ignore_dig_chain?(node)
|
67
|
+
dig_chain_enabled? &&
|
68
|
+
(dig?(node.receiver) || dig?(node.parent))
|
69
|
+
end
|
66
70
|
end
|
67
71
|
end
|
68
72
|
end
|
@@ -6,8 +6,13 @@ module RuboCop
|
|
6
6
|
# Checks for single-line `do`...`end` block.
|
7
7
|
#
|
8
8
|
# In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic`
|
9
|
-
#
|
10
|
-
# preserve semantics and does not change it to `{`...`}` block.
|
9
|
+
# is configured for `Style/BlockDelimiters`. The autocorrection maintains the
|
10
|
+
# `do` ... `end` syntax to preserve semantics and does not change it to `{`...`}` block.
|
11
|
+
#
|
12
|
+
# NOTE: If `InspectBlocks` is set to `true` for `Layout/RedundantLineBreak`, blocks will
|
13
|
+
# be autocorrected to be on a single line if possible. This cop respects that configuration
|
14
|
+
# by not registering an offense if it would subsequently cause a
|
15
|
+
# `Layout/RedundantLineBreak` offense.
|
11
16
|
#
|
12
17
|
# @example
|
13
18
|
#
|
@@ -27,12 +32,14 @@ module RuboCop
|
|
27
32
|
#
|
28
33
|
class SingleLineDoEndBlock < Base
|
29
34
|
extend AutoCorrector
|
35
|
+
include CheckSingleLineSuitability
|
30
36
|
|
31
37
|
MSG = 'Prefer multiline `do`...`end` block.'
|
32
38
|
|
33
39
|
# rubocop:disable Metrics/AbcSize
|
34
40
|
def on_block(node)
|
35
41
|
return if !node.single_line? || node.braces?
|
42
|
+
return if single_line_blocks_preferred? && suitable_as_single_line?(node)
|
36
43
|
|
37
44
|
add_offense(node) do |corrector|
|
38
45
|
corrector.insert_after(do_line(node), "\n")
|
@@ -60,7 +67,10 @@ module RuboCop
|
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
63
|
-
def
|
70
|
+
def single_line_blocks_preferred?
|
71
|
+
redundant_line_break_config = @config.for_cop('Layout/RedundantLineBreak')
|
72
|
+
redundant_line_break_config['Enabled'] && redundant_line_break_config['InspectBlocks']
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|
66
76
|
end
|
@@ -214,7 +214,7 @@ module RuboCop
|
|
214
214
|
end
|
215
215
|
|
216
216
|
def insert_bang_for_and(corrector, node)
|
217
|
-
lhs, rhs = *node
|
217
|
+
lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
|
218
218
|
|
219
219
|
if lhs.and_type?
|
220
220
|
insert_bang_for_and(corrector, lhs)
|
@@ -237,8 +237,7 @@ module RuboCop
|
|
237
237
|
end
|
238
238
|
|
239
239
|
def wrap_condition?(node)
|
240
|
-
node.
|
241
|
-
(node.call_type? && node.arguments.any? && !node.parenthesized?)
|
240
|
+
node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
|
242
241
|
end
|
243
242
|
|
244
243
|
def replace_condition(condition)
|
@@ -79,26 +79,15 @@ module RuboCop
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def lhs(node)
|
82
|
-
|
83
|
-
|
84
|
-
namespace, name, = *node
|
85
|
-
if namespace
|
86
|
-
"#{namespace.const_name}::#{name}"
|
87
|
-
else
|
88
|
-
name.to_s
|
89
|
-
end
|
82
|
+
if node.casgn_type?
|
83
|
+
"#{'::' if node.absolute?}#{node.const_name}"
|
90
84
|
else
|
91
|
-
node.
|
85
|
+
node.name.to_s
|
92
86
|
end
|
93
87
|
end
|
94
88
|
|
95
89
|
def rhs(node)
|
96
|
-
|
97
|
-
when :casgn
|
98
|
-
node.children[2].source
|
99
|
-
else
|
100
|
-
node.children[1].source
|
101
|
-
end
|
90
|
+
node.expression.source
|
102
91
|
end
|
103
92
|
|
104
93
|
def correction_range(tmp_assign, y_assign)
|
@@ -171,9 +171,7 @@ module RuboCop
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def unsafe_autocorrect?(condition)
|
174
|
-
condition.children.any?
|
175
|
-
unparenthesized_method_call?(child) || below_ternary_precedence?(child)
|
176
|
-
end
|
174
|
+
condition.children.any? { |child| below_ternary_precedence?(child) }
|
177
175
|
end
|
178
176
|
|
179
177
|
def unparenthesized_method_call?(child)
|
@@ -192,7 +190,7 @@ module RuboCop
|
|
192
190
|
# @!method method_name(node)
|
193
191
|
def_node_matcher :method_name, <<~PATTERN
|
194
192
|
{($:defined? _ ...)
|
195
|
-
(
|
193
|
+
(call {_ nil?} $_ _ ...)}
|
196
194
|
PATTERN
|
197
195
|
|
198
196
|
def correct_parenthesized(corrector, condition)
|
@@ -203,16 +201,39 @@ module RuboCop
|
|
203
201
|
# If we remove the parentheses, we need to add a space or we'll
|
204
202
|
# generate invalid code.
|
205
203
|
corrector.insert_after(condition.loc.end, ' ') unless whitespace_after?(condition)
|
204
|
+
|
205
|
+
if (send_node = condition.child_nodes.last) && node_args_need_parens?(send_node)
|
206
|
+
parenthesize_condition_arguments(corrector, send_node)
|
207
|
+
end
|
206
208
|
end
|
207
209
|
|
208
210
|
def correct_unparenthesized(corrector, condition)
|
209
211
|
corrector.wrap(condition, '(', ')')
|
210
212
|
end
|
211
213
|
|
214
|
+
def parenthesize_condition_arguments(corrector, send_node)
|
215
|
+
range_start = send_node.defined_type? ? send_node.loc.keyword : send_node.loc.selector
|
216
|
+
opening_range = range_start.end.join(send_node.first_argument.source_range.begin)
|
217
|
+
|
218
|
+
corrector.replace(opening_range, '(')
|
219
|
+
corrector.insert_after(send_node.last_argument, ')')
|
220
|
+
end
|
221
|
+
|
212
222
|
def whitespace_after?(node)
|
213
223
|
last_token = processed_source.last_token_of(node)
|
214
224
|
last_token.space_after?
|
215
225
|
end
|
226
|
+
|
227
|
+
def node_args_need_parens?(send_node)
|
228
|
+
return false unless node_with_args?(send_node)
|
229
|
+
return false if send_node.arguments.none? || send_node.parenthesized?
|
230
|
+
|
231
|
+
send_node.dot? || send_node.safe_navigation? || unparenthesized_method_call?(send_node)
|
232
|
+
end
|
233
|
+
|
234
|
+
def node_with_args?(node)
|
235
|
+
node.call_type? || node.defined_type?
|
236
|
+
end
|
216
237
|
end
|
217
238
|
end
|
218
239
|
end
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def unneeded_ranges(node)
|
97
|
-
node.masgn_type? ?
|
97
|
+
mlhs_node = node.masgn_type? ? node.lhs : node
|
98
98
|
variables = *mlhs_node
|
99
99
|
|
100
100
|
main_offense = main_node_offense(node)
|
@@ -106,15 +106,15 @@ module RuboCop
|
|
106
106
|
end
|
107
107
|
|
108
108
|
def main_node_offense(node)
|
109
|
-
node.masgn_type? ?
|
110
|
-
|
109
|
+
mlhs_node = node.masgn_type? ? node.lhs : node
|
111
110
|
variables = *mlhs_node
|
111
|
+
|
112
112
|
first_offense = find_first_offense(variables)
|
113
113
|
|
114
114
|
return unless first_offense
|
115
115
|
|
116
116
|
if unused_variables_only?(first_offense, variables)
|
117
|
-
return unused_range(node.type, mlhs_node,
|
117
|
+
return unused_range(node.type, mlhs_node, node.rhs)
|
118
118
|
end
|
119
119
|
|
120
120
|
return range_for_parentheses(first_offense, mlhs_node) if Util.parentheses?(mlhs_node)
|
@@ -19,8 +19,7 @@ module RuboCop
|
|
19
19
|
include Interpolation
|
20
20
|
extend AutoCorrector
|
21
21
|
|
22
|
-
MSG = 'Replace interpolated variable `%<variable>s` '
|
23
|
-
'with expression `#{%<variable>s}`.' # rubocop:disable Lint/InterpolationCheck
|
22
|
+
MSG = 'Replace interpolated variable `%<variable>s` with expression `#{%<variable>s}`.'
|
24
23
|
|
25
24
|
def on_node_with_interpolations(node)
|
26
25
|
var_nodes(node.children).each do |var_node|
|
@@ -9,9 +9,10 @@ module RuboCop
|
|
9
9
|
|
10
10
|
MULTIPLE_LEFT_HAND_SIDE_TYPE = :mlhs
|
11
11
|
|
12
|
-
attr_reader :node, :variable, :referenced, :references
|
12
|
+
attr_reader :node, :variable, :referenced, :references, :reassigned
|
13
13
|
|
14
14
|
alias referenced? referenced
|
15
|
+
alias reassigned? reassigned
|
15
16
|
|
16
17
|
def initialize(node, variable)
|
17
18
|
unless VARIABLE_ASSIGNMENT_TYPES.include?(node.type)
|
@@ -24,6 +25,7 @@ module RuboCop
|
|
24
25
|
@variable = variable
|
25
26
|
@referenced = false
|
26
27
|
@references = []
|
28
|
+
@reassigned = false
|
27
29
|
end
|
28
30
|
|
29
31
|
def name
|
@@ -39,8 +41,14 @@ module RuboCop
|
|
39
41
|
@referenced = true
|
40
42
|
end
|
41
43
|
|
44
|
+
def reassigned!
|
45
|
+
return if referenced?
|
46
|
+
|
47
|
+
@reassigned = true
|
48
|
+
end
|
49
|
+
|
42
50
|
def used?
|
43
|
-
@variable.captured_by_block? || @referenced
|
51
|
+
(!reassigned? && @variable.captured_by_block?) || @referenced
|
44
52
|
end
|
45
53
|
|
46
54
|
def regexp_named_capture?
|
@@ -102,6 +110,7 @@ module RuboCop
|
|
102
110
|
end
|
103
111
|
|
104
112
|
def multiple_assignment_node
|
113
|
+
return nil unless node.parent&.mlhs_type?
|
105
114
|
return nil unless (grandparent_node = node.parent&.parent)
|
106
115
|
if (node = find_multiple_assignment_node(grandparent_node))
|
107
116
|
return node
|
@@ -119,7 +128,13 @@ module RuboCop
|
|
119
128
|
end
|
120
129
|
|
121
130
|
def for_assignment_node
|
122
|
-
node.
|
131
|
+
return unless (parent_node = node.parent)
|
132
|
+
return parent_node if parent_node.for_type?
|
133
|
+
|
134
|
+
grandparent_node = parent_node.parent
|
135
|
+
return grandparent_node if parent_node.mlhs_type? && grandparent_node&.for_type?
|
136
|
+
|
137
|
+
nil
|
123
138
|
end
|
124
139
|
|
125
140
|
def find_multiple_assignment_node(grandparent_node)
|
@@ -29,7 +29,11 @@ module RuboCop
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def assign(node)
|
32
|
-
|
32
|
+
assignment = Assignment.new(node, self)
|
33
|
+
|
34
|
+
@assignments.last&.reassigned! unless captured_by_block?
|
35
|
+
|
36
|
+
@assignments << assignment
|
33
37
|
end
|
34
38
|
|
35
39
|
def referenced?
|
@@ -61,8 +61,8 @@ module RuboCop
|
|
61
61
|
"at #{node.source_range}, #{node.inspect}"
|
62
62
|
end
|
63
63
|
|
64
|
-
variable.assign(node)
|
65
64
|
mark_variable_as_captured_by_block_if_so(variable)
|
65
|
+
variable.assign(node)
|
66
66
|
end
|
67
67
|
|
68
68
|
def reference_variable(name, node)
|
@@ -87,8 +87,8 @@ module RuboCop
|
|
87
87
|
# So just skip.
|
88
88
|
return unless variable
|
89
89
|
|
90
|
-
variable.reference!(node)
|
91
90
|
mark_variable_as_captured_by_block_if_so(variable)
|
91
|
+
variable.reference!(node)
|
92
92
|
end
|
93
93
|
|
94
94
|
def find_variable(name)
|
@@ -194,15 +194,10 @@ module RuboCop
|
|
194
194
|
end
|
195
195
|
|
196
196
|
def process_variable_operator_assignment(node)
|
197
|
-
|
198
|
-
asgn_node, rhs_node = *node
|
199
|
-
else
|
200
|
-
asgn_node, _operator, rhs_node = *node
|
201
|
-
end
|
202
|
-
|
197
|
+
asgn_node = node.lhs
|
203
198
|
return unless asgn_node.lvasgn_type?
|
204
199
|
|
205
|
-
name = asgn_node.
|
200
|
+
name = asgn_node.name
|
206
201
|
|
207
202
|
variable_table.declare_variable(name, asgn_node) unless variable_table.variable_exist?(name)
|
208
203
|
|
@@ -222,7 +217,7 @@ module RuboCop
|
|
222
217
|
# before processing rhs nodes.
|
223
218
|
|
224
219
|
variable_table.reference_variable(name, node)
|
225
|
-
process_node(
|
220
|
+
process_node(node.rhs)
|
226
221
|
variable_table.assign_to_variable(name, asgn_node)
|
227
222
|
|
228
223
|
skip_children!
|
@@ -355,8 +350,7 @@ module RuboCop
|
|
355
350
|
when :lvasgn
|
356
351
|
AssignmentReference.new(node)
|
357
352
|
when *OPERATOR_ASSIGNMENT_TYPES
|
358
|
-
|
359
|
-
VariableReference.new(asgn_node.children.first) if asgn_node.lvasgn_type?
|
353
|
+
VariableReference.new(node.lhs.name) if node.lhs.lvasgn_type?
|
360
354
|
end
|
361
355
|
end
|
362
356
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'yard'
|
4
5
|
|
5
6
|
# Class for generating documentation of all cops departments
|
6
7
|
# @api private
|
@@ -35,13 +36,14 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
35
36
|
# This will insert the string returned from the lambda _after_ the section from RuboCop itself.
|
36
37
|
# See `CopsDocumentationGenerator::STRUCTURE` for available sections.
|
37
38
|
#
|
38
|
-
def initialize(departments: [], extra_info: {})
|
39
|
+
def initialize(departments: [], extra_info: {}, base_dir: Dir.pwd)
|
39
40
|
@departments = departments.map(&:to_sym).sort!
|
40
41
|
@extra_info = extra_info
|
41
42
|
@cops = RuboCop::Cop::Registry.global
|
42
43
|
@config = RuboCop::ConfigLoader.default_configuration
|
43
|
-
@
|
44
|
-
|
44
|
+
@base_dir = base_dir
|
45
|
+
@docs_path = "#{base_dir}/docs/modules/ROOT"
|
46
|
+
FileUtils.mkdir_p("#{@docs_path}/pages")
|
45
47
|
end
|
46
48
|
|
47
49
|
def call
|
@@ -112,7 +114,15 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
112
114
|
def required_ruby_version(cop)
|
113
115
|
return '' unless cop.respond_to?(:required_minimum_ruby_version)
|
114
116
|
|
115
|
-
|
117
|
+
if cop.required_minimum_ruby_version
|
118
|
+
requirement = cop.required_minimum_ruby_version
|
119
|
+
elsif cop.required_maximum_ruby_version
|
120
|
+
requirement = "<= #{cop.required_maximum_ruby_version}"
|
121
|
+
else
|
122
|
+
return ''
|
123
|
+
end
|
124
|
+
|
125
|
+
"NOTE: Requires Ruby version #{requirement}\n\n"
|
116
126
|
end
|
117
127
|
|
118
128
|
# rubocop:disable Metrics/MethodLength
|
@@ -157,8 +167,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
157
167
|
end
|
158
168
|
|
159
169
|
def example_header(title, cop)
|
160
|
-
content = "[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
161
|
-
content <<
|
170
|
+
content = +"[##{to_anchor(title)}-#{to_anchor(cop.cop_name)}]\n"
|
171
|
+
content << "==== #{title}\n"
|
162
172
|
content << "\n"
|
163
173
|
content
|
164
174
|
end
|
@@ -246,7 +256,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
246
256
|
else
|
247
257
|
wrap_backtick(val.nil? ? '<none>' : val)
|
248
258
|
end
|
249
|
-
value.gsub("#{
|
259
|
+
value.gsub("#{@base_dir}/", '').rstrip
|
250
260
|
end
|
251
261
|
|
252
262
|
def wrap_backtick(value)
|
@@ -275,7 +285,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
275
285
|
return '' unless department == :Layout
|
276
286
|
|
277
287
|
filename = "#{department_to_basename(department)}_footer.adoc"
|
278
|
-
file = "#{
|
288
|
+
file = "#{docs_path}/partials/#{filename}"
|
279
289
|
return '' unless File.exist?(file)
|
280
290
|
|
281
291
|
"\ninclude::../partials/#{filename}[]\n"
|
@@ -295,7 +305,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
295
305
|
HEADER
|
296
306
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
297
307
|
content << footer_for_department(department)
|
298
|
-
file_name = "#{docs_path}/#{department_to_basename(department)}.adoc"
|
308
|
+
file_name = "#{docs_path}/pages/#{department_to_basename(department)}.adoc"
|
299
309
|
File.open(file_name, 'w') do |file|
|
300
310
|
puts "* generated #{file_name}"
|
301
311
|
file.write("#{content.strip}\n")
|
@@ -344,7 +354,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
344
354
|
end
|
345
355
|
|
346
356
|
def print_table_of_contents
|
347
|
-
path = "#{docs_path}/cops.adoc"
|
357
|
+
path = "#{docs_path}/pages/cops.adoc"
|
348
358
|
|
349
359
|
File.write(path, table_contents) and return unless File.exist?(path)
|
350
360
|
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
HEADING = <<~COMMENTS
|
11
11
|
# This configuration was generated by
|
12
12
|
# `%<command>s`
|
13
|
-
# %<timestamp>susing RuboCop version #{Version
|
13
|
+
# %<timestamp>susing RuboCop version #{Version::STRING}.
|
14
14
|
# The point is for the user to remove these configuration records
|
15
15
|
# one by one as the offenses are removed from the code base.
|
16
16
|
# Note that changes in the inspected code, or installation of new
|
data/lib/rubocop/runner.rb
CHANGED
@@ -139,7 +139,7 @@ module RuboCop
|
|
139
139
|
offenses = process_file(file)
|
140
140
|
yield file
|
141
141
|
|
142
|
-
if offenses.any? { |o| considered_failure?(o) }
|
142
|
+
if offenses.any? { |o| considered_failure?(o) && offense_displayed?(o) }
|
143
143
|
break false if @options[:fail_fast]
|
144
144
|
|
145
145
|
next false
|
@@ -363,8 +363,12 @@ module RuboCop
|
|
363
363
|
result = ruby_extractor.call(processed_source)
|
364
364
|
break result if result
|
365
365
|
rescue StandardError
|
366
|
-
|
367
|
-
|
366
|
+
location = if ruby_extractor.is_a?(Proc)
|
367
|
+
ruby_extractor.source_location
|
368
|
+
else
|
369
|
+
ruby_extractor.method(:call).source_location
|
370
|
+
end
|
371
|
+
raise Error, "Ruby extractor #{location[0]} failed to process #{processed_source.path}."
|
368
372
|
end
|
369
373
|
end
|
370
374
|
|
@@ -436,18 +440,22 @@ module RuboCop
|
|
436
440
|
!offense.corrected? && offense.severity >= minimum_severity_to_fail
|
437
441
|
end
|
438
442
|
|
439
|
-
def
|
443
|
+
def offense_displayed?(offense)
|
440
444
|
if @options[:display_only_fail_level_offenses]
|
441
|
-
|
445
|
+
considered_failure?(offense)
|
442
446
|
elsif @options[:display_only_safe_correctable]
|
443
|
-
|
447
|
+
supports_safe_autocorrect?(offense)
|
444
448
|
elsif @options[:display_only_correctable]
|
445
|
-
|
449
|
+
offense.correctable?
|
446
450
|
else
|
447
|
-
|
451
|
+
true
|
448
452
|
end
|
449
453
|
end
|
450
454
|
|
455
|
+
def offenses_to_report(offenses)
|
456
|
+
offenses.select { |o| offense_displayed?(o) }
|
457
|
+
end
|
458
|
+
|
451
459
|
def supports_safe_autocorrect?(offense)
|
452
460
|
cop_class = Cop::Registry.global.find_by_cop_name(offense.cop_name)
|
453
461
|
default_cfg = default_config(offense.cop_name)
|