rubocop 1.92.0 → 1.92.2
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 +1 -0
- data/lib/rubocop/config.rb +0 -4
- data/lib/rubocop/config_obsoletion.rb +9 -0
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +16 -1
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +34 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/class_structure.rb +21 -7
- data/lib/rubocop/cop/layout/dot_position.rb +25 -15
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +11 -7
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +9 -3
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -15
- data/lib/rubocop/cop/layout/extra_spacing.rb +18 -7
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +26 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +15 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +11 -5
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +5 -3
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/line_length.rb +127 -11
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +6 -4
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +16 -5
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +3 -3
- data/lib/rubocop/cop/layout/space_around_operators.rb +31 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +12 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +29 -11
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +20 -17
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +3 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +2 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +22 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +75 -9
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +27 -8
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +11 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +47 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +7 -6
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +3 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +36 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +26 -5
- data/lib/rubocop/cop/mixin/statement_modifier.rb +17 -3
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +30 -2
- data/lib/rubocop/cop/style/and_or.rb +34 -11
- data/lib/rubocop/cop/style/arguments_forwarding.rb +28 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +6 -0
- data/lib/rubocop/cop/style/case_equality.rb +14 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
- data/lib/rubocop/cop/style/class_methods_definitions.rb +7 -0
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/combinable_loops.rb +4 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +13 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +53 -11
- data/lib/rubocop/cop/style/endless_method.rb +38 -6
- data/lib/rubocop/cop/style/float_division.rb +16 -1
- data/lib/rubocop/cop/style/for.rb +14 -1
- data/lib/rubocop/cop/style/guard_clause.rb +22 -21
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +4 -0
- data/lib/rubocop/cop/style/hash_lookup_method.rb +10 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +19 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +63 -2
- data/lib/rubocop/cop/style/lambda.rb +16 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +36 -4
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +9 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- data/lib/rubocop/cop/style/mutable_constant.rb +25 -7
- data/lib/rubocop/cop/style/numeric_predicate.rb +7 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +19 -1
- data/lib/rubocop/cop/style/quoted_symbols.rb +5 -7
- data/lib/rubocop/cop/style/raise_args.rb +80 -11
- data/lib/rubocop/cop/style/reduce_to_hash.rb +32 -34
- data/lib/rubocop/cop/style/redundant_begin.rb +26 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +13 -9
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -2
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +24 -1
- data/lib/rubocop/cop/style/redundant_self.rb +9 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +28 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +38 -4
- data/lib/rubocop/cop/style/require_order.rb +16 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +6 -0
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +26 -0
- data/lib/rubocop/cop/style/string_concatenation.rb +12 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +6 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +23 -23
- data/lib/rubocop/plugin/configuration_integrator.rb +24 -3
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/server/cache.rb +4 -4
- data/lib/rubocop/target_ruby.rb +21 -9
- data/lib/rubocop/version.rb +1 -1
- metadata +2 -2
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
|
|
75
75
|
arguments = [exception_node, message_node].compact.map(&:source).join(', ')
|
|
76
76
|
|
|
77
|
-
if
|
|
77
|
+
if parenthesize?(node)
|
|
78
78
|
"#{node.method_name}(#{arguments})"
|
|
79
79
|
else
|
|
80
80
|
"#{node.method_name} #{arguments}"
|
|
@@ -86,31 +86,60 @@ module RuboCop
|
|
|
86
86
|
return if message_nodes.size > 1
|
|
87
87
|
|
|
88
88
|
argument = message_nodes.first.source
|
|
89
|
-
exception_class = exception_node.
|
|
89
|
+
exception_class = exception_class_node(exception_node).source
|
|
90
90
|
|
|
91
|
-
if
|
|
91
|
+
if parenthesize?(node)
|
|
92
92
|
"#{node.method_name}(#{exception_class}.new(#{argument}))"
|
|
93
93
|
else
|
|
94
94
|
"#{node.method_name} #{exception_class}.new(#{argument})"
|
|
95
95
|
end
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
def exception_class_node(exception_node)
|
|
99
|
+
use_new_method?(exception_node) ? exception_node.receiver : exception_node
|
|
100
|
+
end
|
|
101
|
+
|
|
98
102
|
def check_compact(node)
|
|
99
103
|
if node.arguments.size > 1
|
|
100
104
|
exception = node.first_argument
|
|
101
105
|
return if exception.send_type? && exception.first_argument&.hash_type?
|
|
106
|
+
return if use_new_method?(exception) && exception.arguments?
|
|
102
107
|
|
|
103
108
|
add_offense(node, message: format(COMPACT_MSG, method: node.method_name)) do |corrector|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
corrector.replace(node, replacement)
|
|
107
|
-
opposite_style_detected
|
|
109
|
+
correct_raise(node) { correct_to_compact(corrector, node) }
|
|
108
110
|
end
|
|
109
111
|
else
|
|
110
112
|
correct_style_detected
|
|
111
113
|
end
|
|
112
114
|
end
|
|
113
115
|
|
|
116
|
+
def correct_to_compact(corrector, node)
|
|
117
|
+
if heredoc_message?(node)
|
|
118
|
+
correct_heredoc_exploded_to_compact(corrector, node)
|
|
119
|
+
else
|
|
120
|
+
corrector.replace(node, correction_exploded_to_compact(node))
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def heredoc_message?(node)
|
|
125
|
+
node.parenthesized? && node.arguments.size == 2 && heredoc?(node.last_argument)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def heredoc?(node)
|
|
129
|
+
node.each_node(:any_str).any?(&:heredoc?)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def correct_heredoc_exploded_to_compact(corrector, node)
|
|
133
|
+
exception_node, message_node = *node.arguments
|
|
134
|
+
exception_class = exception_class_node(exception_node)
|
|
135
|
+
corrector.replace(range_between(exception_class, message_node), '.new(')
|
|
136
|
+
corrector.insert_after(message_node, ')')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def range_between(left_node, right_node)
|
|
140
|
+
left_node.source_range.end.join(right_node.source_range.begin)
|
|
141
|
+
end
|
|
142
|
+
|
|
114
143
|
def check_exploded(node)
|
|
115
144
|
return correct_style_detected unless node.arguments.one?
|
|
116
145
|
|
|
@@ -121,13 +150,43 @@ module RuboCop
|
|
|
121
150
|
return if allowed_non_exploded_type?(first_arg)
|
|
122
151
|
|
|
123
152
|
add_offense(node, message: format(EXPLODED_MSG, method: node.method_name)) do |corrector|
|
|
124
|
-
|
|
153
|
+
correct_raise(node) { correct_to_exploded(corrector, node) }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
125
156
|
|
|
126
|
-
|
|
127
|
-
|
|
157
|
+
def correct_to_exploded(corrector, node)
|
|
158
|
+
if heredoc_new_argument?(node)
|
|
159
|
+
correct_heredoc_compact_to_exploded(corrector, node)
|
|
160
|
+
else
|
|
161
|
+
corrector.replace(node, correction_compact_to_exploded(node))
|
|
128
162
|
end
|
|
129
163
|
end
|
|
130
164
|
|
|
165
|
+
def heredoc_new_argument?(node)
|
|
166
|
+
new_call = node.first_argument
|
|
167
|
+
return false unless new_call.arguments.one? && heredoc?(new_call.first_argument)
|
|
168
|
+
|
|
169
|
+
node.parenthesized? || !parenthesize?(node)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def correct_heredoc_compact_to_exploded(corrector, node)
|
|
173
|
+
new_call = node.first_argument
|
|
174
|
+
corrector.replace(range_between(new_call.receiver, new_call.first_argument), ', ')
|
|
175
|
+
corrector.remove(new_call.loc.end) if new_call.loc.end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def correct_raise(node)
|
|
179
|
+
opposite_style_detected
|
|
180
|
+
return if inside_corrected_raise?(node)
|
|
181
|
+
|
|
182
|
+
yield
|
|
183
|
+
ignore_node(node)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def inside_corrected_raise?(node)
|
|
187
|
+
node.each_ancestor(:send).any? { |ancestor| ignored_node?(ancestor) }
|
|
188
|
+
end
|
|
189
|
+
|
|
131
190
|
def use_new_method?(first_arg)
|
|
132
191
|
first_arg.send_type? && first_arg.receiver && first_arg.method?(:new)
|
|
133
192
|
end
|
|
@@ -151,8 +210,18 @@ module RuboCop
|
|
|
151
210
|
Array(cop_config['AllowedCompactTypes']).include?(type)
|
|
152
211
|
end
|
|
153
212
|
|
|
213
|
+
def parenthesize?(node)
|
|
214
|
+
return true if node.parenthesized?
|
|
215
|
+
|
|
216
|
+
node.parent && requires_parens?(node.parent)
|
|
217
|
+
end
|
|
218
|
+
|
|
154
219
|
def requires_parens?(parent)
|
|
155
|
-
|
|
220
|
+
return true if parent.operator_keyword?
|
|
221
|
+
return true if parent.type?(:call, :super, :yield, :array, :pair)
|
|
222
|
+
return true if parent.any_def_type? && parent.endless?
|
|
223
|
+
|
|
224
|
+
parent.if_type? && parent.ternary?
|
|
156
225
|
end
|
|
157
226
|
end
|
|
158
227
|
end
|
|
@@ -100,6 +100,7 @@ module RuboCop
|
|
|
100
100
|
return unless key
|
|
101
101
|
return if accumulator_used_in_expressions?(block_node, key, value)
|
|
102
102
|
return if nested_match?(key) || nested_match?(value)
|
|
103
|
+
return if heredoc_in_inject_numblock?(block_node, key, value)
|
|
103
104
|
|
|
104
105
|
register_offense(node, block_node, key, value)
|
|
105
106
|
end
|
|
@@ -124,6 +125,12 @@ module RuboCop
|
|
|
124
125
|
end
|
|
125
126
|
end
|
|
126
127
|
|
|
128
|
+
def heredoc_in_inject_numblock?(block_node, key, value)
|
|
129
|
+
return false if !block_node.numblock_type? || block_node.method?(:each_with_object)
|
|
130
|
+
|
|
131
|
+
[key, value].any? { |node| node.each_node(:any_str).any?(&:heredoc?) }
|
|
132
|
+
end
|
|
133
|
+
|
|
127
134
|
def accumulator_name(block_node)
|
|
128
135
|
index = block_node.method?(:each_with_object) ? 1 : 0
|
|
129
136
|
block_node.argument_list[index].name
|
|
@@ -136,42 +143,20 @@ module RuboCop
|
|
|
136
143
|
def register_offense(send_node, block_node, key_expr, value_expr)
|
|
137
144
|
message = format(MSG, method: send_node.method_name)
|
|
138
145
|
|
|
146
|
+
# Each part is replaced separately so that heredoc bodies between them are kept.
|
|
139
147
|
add_offense(send_node.loc.selector, message: message) do |corrector|
|
|
140
|
-
corrector.replace(
|
|
141
|
-
replacement_range(send_node, block_node),
|
|
142
|
-
replacement(block_node, key_expr, value_expr)
|
|
143
|
-
)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
148
|
+
corrector.replace(method_call_range(send_node), 'to_h')
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
body = "[#{key_source}, #{value_source}]"
|
|
151
|
-
|
|
152
|
-
if block_node.numblock_type?
|
|
153
|
-
block_node.braces? ? "to_h { #{body} }" : do_end_replacement(block_node, body)
|
|
154
|
-
else
|
|
155
|
-
named_block_replacement(block_node, body)
|
|
156
|
-
end
|
|
157
|
-
end
|
|
150
|
+
unless block_node.numblock_type?
|
|
151
|
+
corrector.replace(block_node.arguments, "|#{element_arg_source(block_node)}|")
|
|
152
|
+
end
|
|
158
153
|
|
|
159
|
-
|
|
160
|
-
arg = element_arg_source(block_node)
|
|
161
|
-
if block_node.braces?
|
|
162
|
-
"to_h { |#{arg}| #{body} }"
|
|
163
|
-
else
|
|
164
|
-
do_end_replacement(block_node, body, arg)
|
|
154
|
+
correct_body(corrector, block_node, key_expr, value_expr)
|
|
165
155
|
end
|
|
166
156
|
end
|
|
167
157
|
|
|
168
|
-
def
|
|
169
|
-
|
|
170
|
-
"to_h do#{args}\n#{indent(block_node)} #{body}\n#{indent(block_node)}end"
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def replacement_range(send_node, block_node)
|
|
174
|
-
range_between(send_node.loc.selector.begin_pos, block_node.source_range.end_pos)
|
|
158
|
+
def method_call_range(send_node)
|
|
159
|
+
range_between(send_node.loc.selector.begin_pos, send_node.source_range.end_pos)
|
|
175
160
|
end
|
|
176
161
|
|
|
177
162
|
def element_arg_source(block_node)
|
|
@@ -182,6 +167,16 @@ module RuboCop
|
|
|
182
167
|
end
|
|
183
168
|
end
|
|
184
169
|
|
|
170
|
+
def correct_body(corrector, block_node, key_expr, value_expr)
|
|
171
|
+
key_source = adjusted_source(key_expr, block_node)
|
|
172
|
+
value_source = adjusted_source(value_expr, block_node)
|
|
173
|
+
body = block_node.body
|
|
174
|
+
assignment = body.begin_type? ? body.children.first : body
|
|
175
|
+
|
|
176
|
+
corrector.replace(assignment, "[#{key_source}, #{value_source}]")
|
|
177
|
+
corrector.remove(accumulator_range(body.children.last)) if body.begin_type?
|
|
178
|
+
end
|
|
179
|
+
|
|
185
180
|
def adjusted_source(expr_node, block_node)
|
|
186
181
|
source = element_source(expr_node)
|
|
187
182
|
return source unless block_node.numblock_type?
|
|
@@ -191,10 +186,6 @@ module RuboCop
|
|
|
191
186
|
source.gsub('_2', '_1')
|
|
192
187
|
end
|
|
193
188
|
|
|
194
|
-
def indent(node)
|
|
195
|
-
' ' * node.source_range.column
|
|
196
|
-
end
|
|
197
|
-
|
|
198
189
|
def element_source(expr_node)
|
|
199
190
|
if command_call?(expr_node) || expr_node.assignment? || expr_node.rescue_type?
|
|
200
191
|
return "(#{expr_node.source})"
|
|
@@ -210,6 +201,13 @@ module RuboCop
|
|
|
210
201
|
|
|
211
202
|
node.arguments? && !node.parenthesized? && !node.operator_method? && !node.setter_method?
|
|
212
203
|
end
|
|
204
|
+
|
|
205
|
+
def accumulator_range(accumulator)
|
|
206
|
+
range = range_with_surrounding_space(accumulator.source_range, side: :left)
|
|
207
|
+
return range unless range.source_buffer.source[range.begin_pos - 1] == ';'
|
|
208
|
+
|
|
209
|
+
range_with_surrounding_space(range.adjust(begin_pos: -1), side: :left, newlines: false)
|
|
210
|
+
end
|
|
213
211
|
end
|
|
214
212
|
end
|
|
215
213
|
end
|
|
@@ -67,6 +67,7 @@ module RuboCop
|
|
|
67
67
|
extend AutoCorrector
|
|
68
68
|
|
|
69
69
|
MSG = 'Redundant `begin` block detected.'
|
|
70
|
+
SPACE_INSIDE_PARENS_STYLES = %w[space compact].freeze
|
|
70
71
|
|
|
71
72
|
def self.autocorrect_incompatible_with
|
|
72
73
|
[Style::BlockDelimiters]
|
|
@@ -132,7 +133,8 @@ module RuboCop
|
|
|
132
133
|
empty_begin?(node) ||
|
|
133
134
|
begin_block_has_multiline_statements?(node) ||
|
|
134
135
|
contain_rescue_or_ensure?(node) ||
|
|
135
|
-
valid_context_using_only_begin?(node)
|
|
136
|
+
valid_context_using_only_begin?(node) ||
|
|
137
|
+
ternary_operand_requiring_begin?(node)
|
|
136
138
|
end
|
|
137
139
|
|
|
138
140
|
def register_offense(node)
|
|
@@ -191,7 +193,8 @@ module RuboCop
|
|
|
191
193
|
def use_modifier_form_after_multiline_begin_block?(node)
|
|
192
194
|
return false unless (parent = node.parent)
|
|
193
195
|
|
|
194
|
-
node.multiline? && parent.if_type? && parent.modifier_form?
|
|
196
|
+
node.multiline? && parent.if_type? && parent.modifier_form? &&
|
|
197
|
+
!parent.condition.equal?(node)
|
|
195
198
|
end
|
|
196
199
|
|
|
197
200
|
def correct_modifier_form_after_multiline_begin_block(corrector, node)
|
|
@@ -228,6 +231,12 @@ module RuboCop
|
|
|
228
231
|
parent&.send_type? || parent&.operator_keyword?
|
|
229
232
|
end
|
|
230
233
|
|
|
234
|
+
def ternary_operand_requiring_begin?(node)
|
|
235
|
+
return false unless node.parent&.if_type? && node.parent.ternary?
|
|
236
|
+
|
|
237
|
+
!node.children.one? || low_precedence_statement?(node.children.first)
|
|
238
|
+
end
|
|
239
|
+
|
|
231
240
|
def valid_begin_assignment?(node)
|
|
232
241
|
node.parent&.assignment? && (!node.children.one? || too_long_when_joined?(node))
|
|
233
242
|
end
|
|
@@ -238,14 +247,28 @@ module RuboCop
|
|
|
238
247
|
return false unless max && statement.single_line?
|
|
239
248
|
|
|
240
249
|
length = statement.source.length
|
|
241
|
-
length +=
|
|
250
|
+
length += parentheses_width if low_precedence_statement?(statement)
|
|
251
|
+
|
|
242
252
|
node.loc.column + length > max
|
|
243
253
|
end
|
|
244
254
|
|
|
255
|
+
def parentheses_width
|
|
256
|
+
space_inside_parens? ? 4 : 2
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def space_inside_parens?
|
|
260
|
+
return false unless config.cop_enabled?('Layout/SpaceInsideParens')
|
|
261
|
+
|
|
262
|
+
style = config.for_cop('Layout/SpaceInsideParens')['EnforcedStyle']
|
|
263
|
+
|
|
264
|
+
SPACE_INSIDE_PARENS_STYLES.include?(style)
|
|
265
|
+
end
|
|
266
|
+
|
|
245
267
|
def inspect_branches(node)
|
|
246
268
|
node.branches.each do |branch|
|
|
247
269
|
next unless branch&.kwbegin_type?
|
|
248
270
|
next if branch.rescue_node || branch.ensure_node
|
|
271
|
+
next if ternary_operand_requiring_begin?(branch)
|
|
249
272
|
|
|
250
273
|
register_offense(branch)
|
|
251
274
|
end
|
|
@@ -37,23 +37,18 @@ module RuboCop
|
|
|
37
37
|
private
|
|
38
38
|
|
|
39
39
|
def fix_exploded(node)
|
|
40
|
-
exploded?(node) do |
|
|
40
|
+
exploded?(node) do |exception, message|
|
|
41
41
|
# `raise RuntimeError, nil` uses the class name as the message, so
|
|
42
42
|
# rewriting it to `raise nil.to_s` (an empty message) would change it.
|
|
43
43
|
next if message.nil_type?
|
|
44
44
|
|
|
45
45
|
add_offense(node, message: MSG_1) do |corrector|
|
|
46
|
-
corrector.
|
|
46
|
+
corrector.remove(exception.source_range.join(message.source_range.begin))
|
|
47
|
+
corrector.replace(message, message_source(message))
|
|
47
48
|
end
|
|
48
49
|
end
|
|
49
50
|
end
|
|
50
51
|
|
|
51
|
-
def replaced_exploded(node, command, message)
|
|
52
|
-
arg = message_source(message)
|
|
53
|
-
arg = node.parenthesized? ? "(#{arg})" : " #{arg}"
|
|
54
|
-
"#{command}#{arg}"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
52
|
def string_message?(message)
|
|
58
53
|
message.any_str_type?
|
|
59
54
|
end
|
|
@@ -63,11 +58,20 @@ module RuboCop
|
|
|
63
58
|
next if message.nil_type?
|
|
64
59
|
|
|
65
60
|
add_offense(node, message: MSG_2) do |corrector|
|
|
61
|
+
# Replacing the call would drop a heredoc body that sits inside its parentheses.
|
|
62
|
+
next if heredoc_body_inside?(new_call, message)
|
|
63
|
+
|
|
66
64
|
corrector.replace(new_call, message_source(message))
|
|
67
65
|
end
|
|
68
66
|
end
|
|
69
67
|
end
|
|
70
68
|
|
|
69
|
+
def heredoc_body_inside?(new_call, message)
|
|
70
|
+
message.each_node(:any_str).any? do |str|
|
|
71
|
+
str.heredoc? && str.loc.heredoc_end.end_pos < new_call.source_range.end_pos
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
71
75
|
def message_source(message)
|
|
72
76
|
if string_message?(message)
|
|
73
77
|
message.source
|
|
@@ -90,7 +94,7 @@ module RuboCop
|
|
|
90
94
|
|
|
91
95
|
# @!method exploded?(node)
|
|
92
96
|
def_node_matcher :exploded?, <<~PATTERN
|
|
93
|
-
(send nil?
|
|
97
|
+
(send nil? {:raise :fail} $(const {nil? cbase} :RuntimeError) $_)
|
|
94
98
|
PATTERN
|
|
95
99
|
|
|
96
100
|
# @!method compact?(node)
|
|
@@ -30,6 +30,10 @@ module RuboCop
|
|
|
30
30
|
|
|
31
31
|
minimum_target_ruby_version 3.0
|
|
32
32
|
|
|
33
|
+
def self.autocorrect_incompatible_with
|
|
34
|
+
[Layout::MultilineMethodCallBraceLayout]
|
|
35
|
+
end
|
|
36
|
+
|
|
33
37
|
# @!method redundant_unfreeze?(node)
|
|
34
38
|
def_node_matcher :redundant_unfreeze?, <<~PATTERN
|
|
35
39
|
{
|
|
@@ -41,9 +45,10 @@ module RuboCop
|
|
|
41
45
|
def on_dstr(node)
|
|
42
46
|
return if uninterpolated_string?(node) || uninterpolated_heredoc?(node)
|
|
43
47
|
return unless redundant_unfreeze?(node.parent)
|
|
48
|
+
return if comment_outside_string?(node)
|
|
44
49
|
|
|
45
50
|
add_offense(offense_range(node.parent)) do |corrector|
|
|
46
|
-
corrector
|
|
51
|
+
remove_unfreeze(corrector, node.parent, node)
|
|
47
52
|
end
|
|
48
53
|
end
|
|
49
54
|
|
|
@@ -56,6 +61,24 @@ module RuboCop
|
|
|
56
61
|
node.loc.selector
|
|
57
62
|
end
|
|
58
63
|
end
|
|
64
|
+
|
|
65
|
+
# Only the parts around the string are removed, so that an unfrozen string
|
|
66
|
+
# interpolated into it can be corrected in the same pass.
|
|
67
|
+
def remove_unfreeze(corrector, node, string)
|
|
68
|
+
corrector.remove(node.source_range.begin.join(string.source_range.begin))
|
|
69
|
+
corrector.remove(string.source_range.end.join(node.source_range.end))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def comment_outside_string?(node)
|
|
73
|
+
call_range = node.parent.source_range
|
|
74
|
+
string_range = node.source_range
|
|
75
|
+
|
|
76
|
+
processed_source.comments.any? do |comment|
|
|
77
|
+
range = comment.source_range
|
|
78
|
+
|
|
79
|
+
call_range.contains?(range) && !string_range.contains?(range)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
59
82
|
end
|
|
60
83
|
end
|
|
61
84
|
end
|
|
@@ -115,7 +115,7 @@ module RuboCop
|
|
|
115
115
|
|
|
116
116
|
def on_send(node)
|
|
117
117
|
return unless node.self_receiver? && regular_method_call?(node)
|
|
118
|
-
return if node
|
|
118
|
+
return if multiple_assignment_target?(node)
|
|
119
119
|
return if allowed_send_node?(node)
|
|
120
120
|
return if it_method_in_block?(node)
|
|
121
121
|
|
|
@@ -154,6 +154,14 @@ module RuboCop
|
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
+
def multiple_assignment_target?(node)
|
|
158
|
+
return false unless (parent = node.parent)
|
|
159
|
+
|
|
160
|
+
parent = parent.parent if parent.splat_type?
|
|
161
|
+
|
|
162
|
+
parent.mlhs_type?
|
|
163
|
+
end
|
|
164
|
+
|
|
157
165
|
def allowed_send_node?(node)
|
|
158
166
|
@allowed_send_nodes.include?(node) ||
|
|
159
167
|
@local_variables_scopes[node].include?(node.method_name) ||
|
|
@@ -23,14 +23,20 @@ module RuboCop
|
|
|
23
23
|
# foo = bar unless condition
|
|
24
24
|
#
|
|
25
25
|
class RedundantSelfAssignmentBranch < Base
|
|
26
|
+
include RescueNode
|
|
26
27
|
extend AutoCorrector
|
|
27
28
|
|
|
28
29
|
MSG = 'Remove the self-assignment branch.'
|
|
29
30
|
|
|
31
|
+
STATEMENT_BODY_TYPES = %i[
|
|
32
|
+
kwbegin def defs block numblock itblock class module sclass rescue ensure
|
|
33
|
+
].freeze
|
|
34
|
+
|
|
30
35
|
def on_lvasgn(node)
|
|
31
36
|
expression = node.expression
|
|
32
37
|
|
|
33
38
|
return unless use_if_and_else_branch?(expression)
|
|
39
|
+
return unless statement?(node)
|
|
34
40
|
|
|
35
41
|
if_branch = expression.if_branch
|
|
36
42
|
else_branch = expression.else_branch
|
|
@@ -51,6 +57,28 @@ module RuboCop
|
|
|
51
57
|
!expression.ternary? || !expression.else?
|
|
52
58
|
end
|
|
53
59
|
|
|
60
|
+
def statement?(node)
|
|
61
|
+
parent = node.parent
|
|
62
|
+
return true if parent.nil? || parent.type?(*STATEMENT_BODY_TYPES)
|
|
63
|
+
return parent.loc.begin.nil? if parent.begin_type?
|
|
64
|
+
return !rescue_modifier?(parent) if parent.resbody_type?
|
|
65
|
+
|
|
66
|
+
statement_branch?(node, parent)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def statement_branch?(node, parent)
|
|
70
|
+
case parent.type
|
|
71
|
+
when :if
|
|
72
|
+
!parent.ternary? && !node.equal?(parent.condition)
|
|
73
|
+
when :when, :in_pattern, :while, :until, :for
|
|
74
|
+
node.equal?(parent.body)
|
|
75
|
+
when :case, :case_match
|
|
76
|
+
node.equal?(parent.else_branch)
|
|
77
|
+
else
|
|
78
|
+
false
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
54
82
|
def inconvertible_to_modifier?(if_branch, else_branch)
|
|
55
83
|
multiple_statements?(if_branch) || multiple_statements?(else_branch) ||
|
|
56
84
|
(else_branch.respond_to?(:elsif?) && else_branch.elsif?)
|
|
@@ -123,12 +123,29 @@ module RuboCop
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
def register_offense(node, sort_node, sorter, accessor)
|
|
126
|
+
return if code_after_accessor_kept_apart?(node)
|
|
127
|
+
|
|
126
128
|
message = message(node, sorter, accessor)
|
|
127
129
|
add_offense(offense_range(sort_node, node), message: message) do |corrector|
|
|
128
130
|
autocorrect(corrector, node, sort_node, sorter, accessor)
|
|
129
131
|
end
|
|
130
132
|
end
|
|
131
133
|
|
|
134
|
+
def code_after_accessor_kept_apart?(node)
|
|
135
|
+
return false if with_logical_operator?(node)
|
|
136
|
+
|
|
137
|
+
source = before_accessor_source(node)
|
|
138
|
+
return false if !source.include?("\n") || source.strip.empty?
|
|
139
|
+
|
|
140
|
+
rest = code_after_accessor(node)
|
|
141
|
+
|
|
142
|
+
!rest.empty? && !rest.match?(/\A(#|&?\.|[)\]},])/)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def code_after_accessor(node)
|
|
146
|
+
processed_source.lines[node.last_line - 1][node.source_range.last_column..].strip
|
|
147
|
+
end
|
|
148
|
+
|
|
132
149
|
def offense_range(sort_node, node)
|
|
133
150
|
range_between(sort_node.loc.selector.begin_pos, node.source_range.end_pos)
|
|
134
151
|
end
|
|
@@ -146,12 +163,29 @@ module RuboCop
|
|
|
146
163
|
end
|
|
147
164
|
|
|
148
165
|
def autocorrect(corrector, node, sort_node, sorter, accessor)
|
|
149
|
-
# Remove accessor, e.g. `first` or `[-1]`.
|
|
150
|
-
corrector.remove(range_between(accessor_start(node), node.source_range.end_pos))
|
|
151
166
|
# Replace "sort" or "sort_by" with the appropriate min/max method.
|
|
152
167
|
corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
|
|
153
|
-
|
|
154
|
-
|
|
168
|
+
remove_accessor(corrector, node)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def remove_accessor(corrector, node)
|
|
172
|
+
if removable_line_break_before_accessor?(node)
|
|
173
|
+
corrector.remove(node.receiver.source_range.end.join(node.source_range.end))
|
|
174
|
+
else
|
|
175
|
+
corrector.remove(range_between(accessor_start(node), node.source_range.end_pos))
|
|
176
|
+
|
|
177
|
+
replace_with_logical_operator(corrector, node) if with_logical_operator?(node)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def removable_line_break_before_accessor?(node)
|
|
182
|
+
source = before_accessor_source(node)
|
|
183
|
+
|
|
184
|
+
source.include?("\n") && source.strip.empty?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def before_accessor_source(node)
|
|
188
|
+
node.receiver.source_range.end.join((node.loc.dot || node.loc.selector).begin).source
|
|
155
189
|
end
|
|
156
190
|
|
|
157
191
|
def replace_with_logical_operator(corrector, node)
|
|
@@ -101,17 +101,19 @@ module RuboCop
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def find_previous_older_sibling(node) # rubocop:disable Metrics
|
|
104
|
-
|
|
104
|
+
oldest = nil
|
|
105
|
+
search_node(node).left_siblings.reverse_each do |sibling|
|
|
105
106
|
next unless sibling.is_a?(AST::Node)
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
break unless
|
|
109
|
-
break unless
|
|
110
|
-
break unless in_same_section?(
|
|
111
|
-
break unless node.first_argument.str_type? &&
|
|
108
|
+
required = sibling_node(sibling)
|
|
109
|
+
break unless required&.send_type? && required.method?(node.method_name)
|
|
110
|
+
break unless required.arguments? && !required.receiver
|
|
111
|
+
break unless in_same_section?(required, node)
|
|
112
|
+
break unless node.first_argument.str_type? && required.first_argument.str_type?
|
|
112
113
|
|
|
113
|
-
node.first_argument.value <
|
|
114
|
+
oldest = sibling if node.first_argument.value < required.first_argument.value
|
|
114
115
|
end
|
|
116
|
+
oldest
|
|
115
117
|
end
|
|
116
118
|
|
|
117
119
|
def own_lines?(node)
|
|
@@ -124,9 +126,15 @@ module RuboCop
|
|
|
124
126
|
def autocorrect(corrector, node, previous_older_sibling)
|
|
125
127
|
range1 = range_with_comments_and_lines(previous_older_sibling)
|
|
126
128
|
range2 = range_with_comments_and_lines(node.parent.if_type? ? node.parent : node)
|
|
129
|
+
source = range2.source
|
|
130
|
+
|
|
131
|
+
unless source.end_with?("\n")
|
|
132
|
+
source += "\n"
|
|
133
|
+
range2 = range2.with(begin_pos: range2.begin_pos - 1)
|
|
134
|
+
end
|
|
127
135
|
|
|
128
136
|
corrector.remove(range2)
|
|
129
|
-
corrector.insert_before(range1,
|
|
137
|
+
corrector.insert_before(range1.begin, source)
|
|
130
138
|
end
|
|
131
139
|
|
|
132
140
|
def search_node(node)
|
|
@@ -56,16 +56,22 @@ module RuboCop
|
|
|
56
56
|
add_offense(rescue_node) do |corrector|
|
|
57
57
|
# The heredoc body would be left behind when the rescue body is moved.
|
|
58
58
|
next if heredoc_end(node)
|
|
59
|
+
next if inside_corrected_rescue_body?(rescue_node)
|
|
59
60
|
|
|
60
61
|
parenthesized = parenthesized?(rescue_node)
|
|
61
62
|
|
|
62
63
|
correct_rescue_block(corrector, rescue_node, parenthesized)
|
|
63
64
|
ParenthesesCorrector.correct(corrector, rescue_node.parent) if parenthesized
|
|
65
|
+
ignore_node(rescue_node)
|
|
64
66
|
end
|
|
65
67
|
end
|
|
66
68
|
|
|
67
69
|
private
|
|
68
70
|
|
|
71
|
+
def inside_corrected_rescue_body?(node)
|
|
72
|
+
node.each_ancestor(:resbody).any? { |resbody| ignored_node?(resbody.parent) }
|
|
73
|
+
end
|
|
74
|
+
|
|
69
75
|
def parenthesized?(node)
|
|
70
76
|
node.parent && parentheses?(node.parent)
|
|
71
77
|
end
|
|
@@ -64,6 +64,10 @@ module RuboCop
|
|
|
64
64
|
undef unless until when while yield
|
|
65
65
|
].freeze
|
|
66
66
|
|
|
67
|
+
def self.autocorrect_incompatible_with
|
|
68
|
+
[Layout::MultilineMethodArgumentLineBreaks]
|
|
69
|
+
end
|
|
70
|
+
|
|
67
71
|
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
68
72
|
def on_send(node)
|
|
69
73
|
return if allow_send? && !node.method?(:public_send)
|