rubocop 1.35.0 → 1.36.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 +11 -0
- data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +0 -0
- data/lib/rubocop/config.rb +1 -1
- data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/layout/block_alignment.rb +14 -12
- data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +3 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +31 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +14 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +10 -5
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +13 -5
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +9 -5
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +77 -1
- data/lib/rubocop/cop/style/case_equality.rb +40 -10
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +40 -5
- data/lib/rubocop/cop/style/guard_clause.rb +27 -16
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +1 -5
- data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +4 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +0 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/style/word_array.rb +1 -1
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/feature_loader.rb +3 -1
- data/lib/rubocop/formatter/html_formatter.rb +2 -2
- data/lib/rubocop/runner.rb +4 -0
- data/lib/rubocop/server/cache.rb +9 -8
- data/lib/rubocop/version.rb +3 -2
- data/lib/rubocop.rb +1 -1
- metadata +5 -5
@@ -68,6 +68,8 @@ module RuboCop
|
|
68
68
|
# `transform_values` if value transformation uses key.
|
69
69
|
return if captures.transformation_uses_both_args?
|
70
70
|
|
71
|
+
return unless captures.use_transformed_argname?
|
72
|
+
|
71
73
|
message = "Prefer `#{new_method_name}` over `#{match_desc}`."
|
72
74
|
add_offense(node, message: message) do |corrector|
|
73
75
|
correction = prepare_correction(node)
|
@@ -113,11 +115,7 @@ module RuboCop
|
|
113
115
|
end
|
114
116
|
|
115
117
|
# Internal helper class to hold match data
|
116
|
-
Captures = Struct.new(
|
117
|
-
:transformed_argname,
|
118
|
-
:transforming_body_expr,
|
119
|
-
:unchanged_body_expr
|
120
|
-
) do
|
118
|
+
Captures = Struct.new(:transformed_argname, :transforming_body_expr, :unchanged_body_expr) do
|
121
119
|
def noop_transformation?
|
122
120
|
transforming_body_expr.lvar_type? &&
|
123
121
|
transforming_body_expr.children == [transformed_argname]
|
@@ -126,6 +124,12 @@ module RuboCop
|
|
126
124
|
def transformation_uses_both_args?
|
127
125
|
transforming_body_expr.descendants.include?(unchanged_body_expr)
|
128
126
|
end
|
127
|
+
|
128
|
+
def use_transformed_argname?
|
129
|
+
transforming_body_expr.each_descendant(:lvar).any? do |node|
|
130
|
+
node.source == transformed_argname.to_s
|
131
|
+
end
|
132
|
+
end
|
129
133
|
end
|
130
134
|
|
131
135
|
# Internal helper class to hold autocorrect data
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
end
|
58
58
|
|
59
59
|
if left_parenthesis && style == :special_inside_parentheses
|
60
|
-
return [left_parenthesis.column + 1, :
|
60
|
+
return [left_parenthesis.column + 1, :first_column_after_left_parenthesis]
|
61
61
|
end
|
62
62
|
|
63
63
|
[left_brace.source_line =~ /\S/, :start_of_line]
|
@@ -72,10 +72,10 @@ module RuboCop
|
|
72
72
|
PATTERN
|
73
73
|
|
74
74
|
def allowed_conditional_expression_on_rhs?(node)
|
75
|
-
node&.if_type? &&
|
75
|
+
node&.if_type? && contains_constant?(node)
|
76
76
|
end
|
77
77
|
|
78
|
-
def
|
78
|
+
def contains_constant?(node)
|
79
79
|
node.branches.any?(&:const_type?)
|
80
80
|
end
|
81
81
|
end
|
@@ -9,6 +9,11 @@ module RuboCop
|
|
9
9
|
# Applications of visibility methods to symbols can be controlled
|
10
10
|
# using AllowModifiersOnSymbols config.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# Autocorrection is not safe, because the visibility of dynamically
|
14
|
+
# defined methods can vary depending on the state determined by
|
15
|
+
# the group access modifier.
|
16
|
+
#
|
12
17
|
# @example EnforcedStyle: group (default)
|
13
18
|
# # bad
|
14
19
|
# class Foo
|
@@ -63,7 +68,10 @@ module RuboCop
|
|
63
68
|
#
|
64
69
|
# end
|
65
70
|
class AccessModifierDeclarations < Base
|
71
|
+
extend AutoCorrector
|
72
|
+
|
66
73
|
include ConfigurableEnforcedStyle
|
74
|
+
include RangeHelp
|
67
75
|
|
68
76
|
GROUP_STYLE_MESSAGE = [
|
69
77
|
'`%<access_modifier>s` should not be',
|
@@ -88,7 +96,10 @@ module RuboCop
|
|
88
96
|
return if allow_modifiers_on_symbols?(node)
|
89
97
|
|
90
98
|
if offense?(node)
|
91
|
-
add_offense(node.loc.selector)
|
99
|
+
add_offense(node.loc.selector) do |corrector|
|
100
|
+
autocorrect(corrector, node)
|
101
|
+
end
|
102
|
+
opposite_style_detected
|
92
103
|
else
|
93
104
|
correct_style_detected
|
94
105
|
end
|
@@ -96,6 +107,23 @@ module RuboCop
|
|
96
107
|
|
97
108
|
private
|
98
109
|
|
110
|
+
def autocorrect(corrector, node)
|
111
|
+
case style
|
112
|
+
when :group
|
113
|
+
def_node = find_corresponding_def_node(node)
|
114
|
+
return unless def_node
|
115
|
+
|
116
|
+
remove_node(corrector, def_node)
|
117
|
+
remove_node(corrector, node)
|
118
|
+
insert_def(corrector, node, def_node.source)
|
119
|
+
when :inline
|
120
|
+
remove_node(corrector, node)
|
121
|
+
select_grouped_def_nodes(node).each do |grouped_def_node|
|
122
|
+
insert_inline_modifier(corrector, grouped_def_node, node.method_name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
99
127
|
def allow_modifiers_on_symbols?(node)
|
100
128
|
cop_config['AllowModifiersOnSymbols'] && access_modifier_with_symbol?(node)
|
101
129
|
end
|
@@ -130,6 +158,54 @@ module RuboCop
|
|
130
158
|
format(INLINE_STYLE_MESSAGE, access_modifier: access_modifier)
|
131
159
|
end
|
132
160
|
end
|
161
|
+
|
162
|
+
def find_corresponding_def_node(node)
|
163
|
+
if access_modifier_with_symbol?(node)
|
164
|
+
method_name = node.arguments.first.value
|
165
|
+
node.parent.each_child_node(:def).find do |child|
|
166
|
+
child.method?(method_name)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
node.arguments.first
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def find_argument_less_modifier_node(node)
|
174
|
+
node.parent.each_child_node(:send).find do |child|
|
175
|
+
child.method?(node.method_name) && child.arguments.empty?
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def select_grouped_def_nodes(node)
|
180
|
+
node.right_siblings.take_while do |sibling|
|
181
|
+
!(sibling.send_type? && sibling.bare_access_modifier_declaration?)
|
182
|
+
end.select(&:def_type?)
|
183
|
+
end
|
184
|
+
|
185
|
+
def insert_def(corrector, node, source)
|
186
|
+
argument_less_modifier_node = find_argument_less_modifier_node(node)
|
187
|
+
if argument_less_modifier_node
|
188
|
+
corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
|
189
|
+
else
|
190
|
+
corrector.insert_before(
|
191
|
+
node.each_ancestor(:block, :class, :module).first.location.end,
|
192
|
+
"#{node.method_name}\n\n#{source}\n"
|
193
|
+
)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def insert_inline_modifier(corrector, node, modifier_name)
|
198
|
+
corrector.insert_before(node, "#{modifier_name} ")
|
199
|
+
end
|
200
|
+
|
201
|
+
def remove_node(corrector, node)
|
202
|
+
corrector.remove(
|
203
|
+
range_by_whole_lines(
|
204
|
+
node.location.expression,
|
205
|
+
include_final_newline: true
|
206
|
+
)
|
207
|
+
)
|
208
|
+
end
|
133
209
|
end
|
134
210
|
end
|
135
211
|
end
|
@@ -7,6 +7,9 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
|
9
9
|
# the case equality operator is a constant.
|
10
|
+
|
11
|
+
# If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of
|
12
|
+
# the case equality operator is `self.class`. Note intermediate variables are not accepted.
|
10
13
|
#
|
11
14
|
# @example
|
12
15
|
# # bad
|
@@ -26,6 +29,14 @@ module RuboCop
|
|
26
29
|
# # good
|
27
30
|
# Array === something
|
28
31
|
#
|
32
|
+
# @example AllowOnSelfClass: false (default)
|
33
|
+
# # bad
|
34
|
+
# self.class === something
|
35
|
+
#
|
36
|
+
# @example AllowOnSelfClass: true
|
37
|
+
# # good
|
38
|
+
# self.class === something
|
39
|
+
#
|
29
40
|
class CaseEquality < Base
|
30
41
|
extend AutoCorrector
|
31
42
|
|
@@ -33,7 +44,10 @@ module RuboCop
|
|
33
44
|
RESTRICT_ON_SEND = %i[===].freeze
|
34
45
|
|
35
46
|
# @!method case_equality?(node)
|
36
|
-
def_node_matcher :case_equality?, '(send $#
|
47
|
+
def_node_matcher :case_equality?, '(send $#offending_receiver? :=== $_)'
|
48
|
+
|
49
|
+
# @!method self_class?(node)
|
50
|
+
def_node_matcher :self_class?, '(send (self) :class)'
|
37
51
|
|
38
52
|
def on_send(node)
|
39
53
|
case_equality?(node) do |lhs, rhs|
|
@@ -48,12 +62,11 @@ module RuboCop
|
|
48
62
|
|
49
63
|
private
|
50
64
|
|
51
|
-
def
|
52
|
-
if cop_config.fetch('AllowOnConstant', false)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
65
|
+
def offending_receiver?(node)
|
66
|
+
return false if node&.const_type? && cop_config.fetch('AllowOnConstant', false)
|
67
|
+
return false if self_class?(node) && cop_config.fetch('AllowOnSelfClass', false)
|
68
|
+
|
69
|
+
true
|
57
70
|
end
|
58
71
|
|
59
72
|
def replacement(lhs, rhs)
|
@@ -66,12 +79,29 @@ module RuboCop
|
|
66
79
|
#
|
67
80
|
# So here is noop.
|
68
81
|
when :begin
|
69
|
-
|
70
|
-
"#{lhs.source}.include?(#{rhs.source})" if child&.range_type?
|
82
|
+
begin_replacement(lhs, rhs)
|
71
83
|
when :const
|
72
|
-
|
84
|
+
const_replacement(lhs, rhs)
|
85
|
+
when :send
|
86
|
+
send_replacement(lhs, rhs)
|
73
87
|
end
|
74
88
|
end
|
89
|
+
|
90
|
+
def begin_replacement(lhs, rhs)
|
91
|
+
return unless lhs.children.first&.range_type?
|
92
|
+
|
93
|
+
"#{lhs.source}.include?(#{rhs.source})"
|
94
|
+
end
|
95
|
+
|
96
|
+
def const_replacement(lhs, rhs)
|
97
|
+
"#{rhs.source}.is_a?(#{lhs.source})"
|
98
|
+
end
|
99
|
+
|
100
|
+
def send_replacement(lhs, rhs)
|
101
|
+
return unless self_class?(lhs)
|
102
|
+
|
103
|
+
"#{rhs.source}.is_a?(#{lhs.source})"
|
104
|
+
end
|
75
105
|
end
|
76
106
|
end
|
77
107
|
end
|
@@ -28,14 +28,14 @@ module RuboCop
|
|
28
28
|
MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.'
|
29
29
|
|
30
30
|
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
|
31
|
-
return unless
|
31
|
+
return unless offending?(node)
|
32
32
|
|
33
33
|
send_node = node.send_node
|
34
34
|
|
35
35
|
range = send_node.receiver.source_range.join(send_node.loc.selector)
|
36
36
|
|
37
37
|
add_offense(range) do |corrector|
|
38
|
-
range_type, min, max =
|
38
|
+
range_type, min, max = each_range(node)
|
39
39
|
|
40
40
|
max += 1 if range_type == :irange
|
41
41
|
|
@@ -45,9 +45,44 @@ module RuboCop
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
def offending?(node)
|
49
|
+
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!method each_range(node)
|
53
|
+
def_node_matcher :each_range, <<~PATTERN
|
54
|
+
(block
|
55
|
+
(send
|
56
|
+
(begin
|
57
|
+
(${irange erange}
|
58
|
+
(int $_) (int $_)))
|
59
|
+
:each)
|
60
|
+
(args ...)
|
61
|
+
...)
|
62
|
+
PATTERN
|
63
|
+
|
64
|
+
# @!method each_range_with_zero_origin?(node)
|
65
|
+
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
66
|
+
(block
|
67
|
+
(send
|
68
|
+
(begin
|
69
|
+
({irange erange}
|
70
|
+
(int 0) (int _)))
|
71
|
+
:each)
|
72
|
+
(args ...)
|
73
|
+
...)
|
74
|
+
PATTERN
|
75
|
+
|
76
|
+
# @!method each_range_without_block_argument?(node)
|
77
|
+
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
78
|
+
(block
|
79
|
+
(send
|
80
|
+
(begin
|
81
|
+
({irange erange}
|
82
|
+
(int _) (int _)))
|
83
|
+
:each)
|
84
|
+
(args)
|
85
|
+
...)
|
51
86
|
PATTERN
|
52
87
|
end
|
53
88
|
end
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# Use a guard clause instead of wrapping the code inside a conditional
|
7
7
|
# expression
|
8
8
|
#
|
9
|
+
# A condition with an `elsif` or `else` branch is allowed unless
|
10
|
+
# one of `return`, `break`, `next`, `raise`, or `fail` is used
|
11
|
+
# in the body of the conditional expression.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
# # bad
|
11
15
|
# def test
|
@@ -50,34 +54,41 @@ module RuboCop
|
|
50
54
|
#
|
51
55
|
# @example AllowConsecutiveConditionals: false (default)
|
52
56
|
# # bad
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
57
|
+
# def test
|
58
|
+
# if foo?
|
59
|
+
# work
|
60
|
+
# end
|
56
61
|
#
|
57
|
-
#
|
58
|
-
#
|
62
|
+
# if bar? # <- reports an offense
|
63
|
+
# work
|
64
|
+
# end
|
59
65
|
# end
|
60
66
|
#
|
61
67
|
# @example AllowConsecutiveConditionals: true
|
62
68
|
# # good
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
69
|
+
# def test
|
70
|
+
# if foo?
|
71
|
+
# work
|
72
|
+
# end
|
66
73
|
#
|
67
|
-
#
|
68
|
-
#
|
74
|
+
# if bar?
|
75
|
+
# work
|
76
|
+
# end
|
69
77
|
# end
|
70
78
|
#
|
71
79
|
# # bad
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
80
|
+
# def test
|
81
|
+
# if foo?
|
82
|
+
# work
|
83
|
+
# end
|
75
84
|
#
|
76
|
-
#
|
85
|
+
# do_something
|
77
86
|
#
|
78
|
-
#
|
79
|
-
#
|
87
|
+
# if bar? # <- reports an offense
|
88
|
+
# work
|
89
|
+
# end
|
80
90
|
# end
|
91
|
+
#
|
81
92
|
class GuardClause < Base
|
82
93
|
include MinBodyLength
|
83
94
|
include StatementModifier
|
@@ -130,7 +130,7 @@ module RuboCop
|
|
130
130
|
call_as_argument_or_chain?(node) ||
|
131
131
|
hash_literal_in_arguments?(node) ||
|
132
132
|
node.descendants.any? do |n|
|
133
|
-
n.forwarded_args_type? ||
|
133
|
+
n.forwarded_args_type? || ambiguous_literal?(n) || logical_operator?(n) ||
|
134
134
|
call_with_braced_block?(n)
|
135
135
|
end
|
136
136
|
end
|
@@ -166,7 +166,7 @@ module RuboCop
|
|
166
166
|
previous.parenthesized? || allowed_chained_call_with_parentheses?(previous)
|
167
167
|
end
|
168
168
|
|
169
|
-
def
|
169
|
+
def ambiguous_literal?(node)
|
170
170
|
splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) || unary_literal?(node)
|
171
171
|
end
|
172
172
|
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
|
50
50
|
# Requires `then` for write `in` and its body on the same line.
|
51
51
|
def require_then?(in_pattern_node)
|
52
|
-
return true
|
52
|
+
return true unless in_pattern_node.pattern.single_line?
|
53
53
|
return false unless in_pattern_node.body
|
54
54
|
|
55
55
|
same_line?(in_pattern_node, in_pattern_node.body)
|
@@ -225,11 +225,7 @@ module RuboCop
|
|
225
225
|
adjustment = delta + @reindented_lines[lineno]
|
226
226
|
@reindented_lines[lineno] = adjustment
|
227
227
|
|
228
|
-
if adjustment.positive?
|
229
|
-
corrector.remove_leading(buffer.line_range(lineno), adjustment)
|
230
|
-
elsif adjustment.negative?
|
231
|
-
corrector.insert_before(buffer.line_range(lineno), ' ' * -adjustment)
|
232
|
-
end
|
228
|
+
corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
|
233
229
|
end
|
234
230
|
end
|
235
231
|
end
|
@@ -83,10 +83,31 @@ module RuboCop
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
# @private
|
87
|
+
# @param [RuboCop::AST::Node] node
|
88
|
+
# @return [String, nil]
|
89
|
+
def preferred_expression_to_node_with_constant_prefix(node)
|
90
|
+
expression = preferred_expression_to(node)
|
91
|
+
return unless expression
|
92
|
+
|
93
|
+
"#{constant_prefix(node)}#{expression}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# @private
|
97
|
+
# @param [RuboCop::AST::Node] node
|
98
|
+
# @return [String]
|
99
|
+
def constant_prefix(node)
|
100
|
+
if node.each_ancestor(:class, :module).any?
|
101
|
+
'::'
|
102
|
+
else
|
103
|
+
''
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
86
107
|
# @private
|
87
108
|
# @param [RuboCop::AST::Node] node
|
88
109
|
def on_back_ref_or_gvar_or_nth_ref(node)
|
89
|
-
preferred_expression =
|
110
|
+
preferred_expression = preferred_expression_to_node_with_constant_prefix(node)
|
90
111
|
return unless preferred_expression
|
91
112
|
|
92
113
|
add_offense(
|
@@ -29,6 +29,9 @@ module RuboCop
|
|
29
29
|
# @!method rescue?(node)
|
30
30
|
def_node_matcher :rescue?, '{^resbody ^^resbody}'
|
31
31
|
|
32
|
+
# @!method allowed_pin_operator?(node)
|
33
|
+
def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
|
34
|
+
|
32
35
|
# @!method arg_in_call_with_block?(node)
|
33
36
|
def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)'
|
34
37
|
|
@@ -44,6 +47,7 @@ module RuboCop
|
|
44
47
|
empty_parentheses?(node) ||
|
45
48
|
first_arg_begins_with_hash_literal?(node) ||
|
46
49
|
rescue?(node) ||
|
50
|
+
allowed_pin_operator?(node) ||
|
47
51
|
allowed_expression?(node)
|
48
52
|
end
|
49
53
|
|
@@ -141,7 +141,7 @@ module RuboCop
|
|
141
141
|
|
142
142
|
corrector.remove(begin_range(node, body))
|
143
143
|
corrector.remove(end_range(node, body))
|
144
|
-
corrector.insert_before(method_call.loc.dot, '&')
|
144
|
+
corrector.insert_before(method_call.loc.dot, '&') unless method_call.safe_navigation?
|
145
145
|
handle_comments(corrector, node, method_call)
|
146
146
|
|
147
147
|
add_safe_nav_to_all_methods_in_chain(corrector, method_call, body)
|
@@ -250,7 +250,9 @@ module RuboCop
|
|
250
250
|
end
|
251
251
|
|
252
252
|
def unsafe_method?(send_node)
|
253
|
-
negated?(send_node) ||
|
253
|
+
negated?(send_node) ||
|
254
|
+
send_node.assignment? ||
|
255
|
+
(!send_node.dot? && !send_node.safe_navigation?)
|
254
256
|
end
|
255
257
|
|
256
258
|
def negated?(send_node)
|
@@ -173,8 +173,6 @@ module RuboCop
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def correct_for_comment(corrector, node, if_branch)
|
176
|
-
return if config.for_cop('Style/IfUnlessModifier')['Enabled']
|
177
|
-
|
178
176
|
comments = processed_source.ast_with_comments[if_branch]
|
179
177
|
comment_text = comments.map(&:text).join("\n") << "\n"
|
180
178
|
|
@@ -69,7 +69,7 @@ module RuboCop
|
|
69
69
|
if c.dsym_type?
|
70
70
|
string_literal = to_string_literal(c.source)
|
71
71
|
|
72
|
-
":#{
|
72
|
+
":#{trim_string_interpolation_escape_character(string_literal)}"
|
73
73
|
else
|
74
74
|
to_symbol_literal(c.value.to_s)
|
75
75
|
end
|
@@ -11,10 +11,11 @@ module RuboCop
|
|
11
11
|
# These are customizable with `AllowedMethods` option.
|
12
12
|
#
|
13
13
|
# @safety
|
14
|
-
# This cop is unsafe because
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# an `ArgumentError
|
14
|
+
# This cop is unsafe because there is a difference that a `Proc`
|
15
|
+
# generated from `Symbol#to_proc` behaves as a lambda, while
|
16
|
+
# a `Proc` generated from a block does not.
|
17
|
+
# For example, a lambda will raise an `ArgumentError` if the
|
18
|
+
# number of arguments is wrong, but a non-lambda `Proc` will not.
|
18
19
|
#
|
19
20
|
# For example:
|
20
21
|
#
|
@@ -87,7 +87,7 @@ module RuboCop
|
|
87
87
|
if word.dstr_type?
|
88
88
|
string_literal = to_string_literal(word.source)
|
89
89
|
|
90
|
-
|
90
|
+
trim_string_interpolation_escape_character(string_literal)
|
91
91
|
else
|
92
92
|
to_string_literal(word.children[0])
|
93
93
|
end
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -41,7 +41,9 @@ module RuboCop
|
|
41
41
|
# https://github.com/rubocop/rubocop/issues/10893
|
42
42
|
require(namespaced_target)
|
43
43
|
rescue ::LoadError => error_for_namespaced_target
|
44
|
-
|
44
|
+
# NOTE: This wrap is necessary due to JRuby 9.3.4.0 incompatibility:
|
45
|
+
# https://github.com/jruby/jruby/issues/7316
|
46
|
+
raise LoadError, e if error_for_namespaced_target.path == namespaced_target
|
45
47
|
|
46
48
|
raise error_for_namespaced_target
|
47
49
|
end
|
@@ -93,12 +93,12 @@ module RuboCop
|
|
93
93
|
|
94
94
|
def highlighted_source_line(offense)
|
95
95
|
source_before_highlight(offense) +
|
96
|
-
|
96
|
+
highlight_source_tag(offense) +
|
97
97
|
source_after_highlight(offense) +
|
98
98
|
possible_ellipses(offense.location)
|
99
99
|
end
|
100
100
|
|
101
|
-
def
|
101
|
+
def highlight_source_tag(offense)
|
102
102
|
"<span class=\"highlight #{offense.severity}\">" \
|
103
103
|
"#{escape(offense.highlighted_area.source)}" \
|
104
104
|
'</span>'
|
data/lib/rubocop/runner.rb
CHANGED
@@ -64,6 +64,10 @@ module RuboCop
|
|
64
64
|
# instances that each inspects its allotted group of files.
|
65
65
|
def warm_cache(target_files)
|
66
66
|
saved_options = @options.dup
|
67
|
+
if target_files.length <= 1
|
68
|
+
puts 'Skipping parallel inspection: only a single file needs inspection' if @options[:debug]
|
69
|
+
return
|
70
|
+
end
|
67
71
|
puts 'Running parallel inspection' if @options[:debug]
|
68
72
|
%i[autocorrect safe_autocorrect].each { |opt| @options[opt] = false }
|
69
73
|
Parallel.each(target_files) { |target_file| file_offenses(target_file) }
|
data/lib/rubocop/server/cache.rb
CHANGED
@@ -62,17 +62,18 @@ module RuboCop
|
|
62
62
|
# `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
|
63
63
|
# so that only the necessary `CacheRootDirectory` can be obtained.
|
64
64
|
require 'yaml'
|
65
|
-
|
66
65
|
config_path = ConfigFinder.find_config_path(Dir.pwd)
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
require 'erb'
|
68
|
+
file_contents = File.read(config_path)
|
69
|
+
yaml_code = ERB.new(file_contents).result
|
70
|
+
|
71
|
+
config_yaml = YAML.safe_load(yaml_code, permitted_classes: [Regexp, Symbol])
|
73
72
|
|
74
|
-
|
75
|
-
|
73
|
+
# For compatibility with Ruby 3.0 or lower.
|
74
|
+
if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
|
75
|
+
config_yaml == false ? nil : config_yaml
|
76
|
+
end
|
76
77
|
|
77
78
|
config_yaml&.dig('AllCops', 'CacheRootDirectory')
|
78
79
|
end
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,11 +3,11 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '1.
|
6
|
+
STRING = '1.36.0'
|
7
7
|
|
8
8
|
MSG = '%<version>s (using Parser %<parser_version>s, ' \
|
9
9
|
'rubocop-ast %<rubocop_ast_version>s, ' \
|
10
|
-
'running on %<ruby_engine>s %<ruby_version>s %<ruby_platform>s
|
10
|
+
'running on %<ruby_engine>s %<ruby_version>s)%<server>s [%<ruby_platform>s]'
|
11
11
|
|
12
12
|
CANONICAL_FEATURE_NAMES = { 'Rspec' => 'RSpec', 'Graphql' => 'GraphQL', 'Md' => 'Markdown',
|
13
13
|
'Thread_safety' => 'ThreadSafety' }.freeze
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
verbose_version = format(MSG, version: STRING, parser_version: Parser::VERSION,
|
20
20
|
rubocop_ast_version: RuboCop::AST::Version::STRING,
|
21
21
|
ruby_engine: RUBY_ENGINE, ruby_version: RUBY_VERSION,
|
22
|
+
server: Server.running? ? ' +server' : '',
|
22
23
|
ruby_platform: RUBY_PLATFORM)
|
23
24
|
return verbose_version unless env
|
24
25
|
|
data/lib/rubocop.rb
CHANGED
@@ -703,7 +703,7 @@ require_relative 'rubocop/cli'
|
|
703
703
|
require_relative 'rubocop/cli/command'
|
704
704
|
require_relative 'rubocop/cli/environment'
|
705
705
|
require_relative 'rubocop/cli/command/base'
|
706
|
-
require_relative 'rubocop/cli/command/
|
706
|
+
require_relative 'rubocop/cli/command/auto_generate_config'
|
707
707
|
require_relative 'rubocop/cli/command/execute_runner'
|
708
708
|
require_relative 'rubocop/cli/command/init_dotfile'
|
709
709
|
require_relative 'rubocop/cli/command/show_cops'
|