rubocop 1.79.2 → 1.82.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 +35 -7
- data/config/obsoletion.yml +4 -0
- data/exe/rubocop +1 -8
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli.rb +8 -3
- data/lib/rubocop/comment_config.rb +62 -17
- data/lib/rubocop/config_loader.rb +5 -2
- data/lib/rubocop/config_loader_resolver.rb +7 -6
- data/lib/rubocop/config_store.rb +5 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -4
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -7
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +30 -12
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -5
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +0 -4
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +16 -5
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_interpolation.rb +11 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +15 -6
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +7 -0
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +0 -4
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
- data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
- data/lib/rubocop/cop/mixin/trailing_comma.rb +5 -6
- data/lib/rubocop/cop/naming/method_name.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_method.rb +19 -6
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/style/array_intersect.rb +46 -12
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/case_equality.rb +11 -13
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -14
- data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/endless_method.rb +15 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/float_division.rb +15 -1
- data/lib/rubocop/cop/style/guard_clause.rb +0 -11
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
- data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +0 -4
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/one_line_conditional.rb +17 -9
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +34 -0
- data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +26 -5
- data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -11
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/safe_navigation.rb +18 -1
- data/lib/rubocop/cop/style/semicolon.rb +23 -7
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +8 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
- data/lib/rubocop/cop/style/super_arguments.rb +2 -2
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/cop/variable_force/variable.rb +1 -1
- data/lib/rubocop/cop/variable_force.rb +9 -7
- data/lib/rubocop/cops_documentation_generator.rb +4 -4
- data/lib/rubocop/directive_comment.rb +46 -3
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -5
- data/lib/rubocop/lsp/diagnostic.rb +10 -14
- data/lib/rubocop/lsp/routes.rb +31 -2
- data/lib/rubocop/lsp/stdin_runner.rb +0 -16
- data/lib/rubocop/magic_comment.rb +20 -0
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +7 -8
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/shared_contexts.rb +2 -2
- data/lib/rubocop/rspec/support.rb +1 -1
- data/lib/rubocop/runner.rb +6 -4
- data/lib/rubocop/target_finder.rb +9 -9
- data/lib/rubocop/target_ruby.rb +11 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +2 -0
- data/lib/ruby_lsp/rubocop/addon.rb +23 -8
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +8 -6
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend
|
|
79
|
-
new_identifier = node.first_argument
|
|
79
|
+
return unless (new_identifier = node.first_argument)
|
|
80
80
|
return unless new_identifier.basic_literal?
|
|
81
81
|
|
|
82
82
|
new_identifier = new_identifier.value
|
|
@@ -145,8 +145,10 @@ module RuboCop
|
|
|
145
145
|
next_sibling.if_type? && contains_guard_clause?(next_sibling)
|
|
146
146
|
end
|
|
147
147
|
|
|
148
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
148
149
|
def last_heredoc_argument(node)
|
|
149
150
|
n = last_heredoc_argument_node(node)
|
|
151
|
+
n = n.children.first while n.respond_to?(:begin_type?) && n.begin_type?
|
|
150
152
|
|
|
151
153
|
return n if heredoc?(n)
|
|
152
154
|
return unless n.respond_to?(:arguments)
|
|
@@ -158,6 +160,7 @@ module RuboCop
|
|
|
158
160
|
|
|
159
161
|
last_heredoc_argument(n.receiver) if n.respond_to?(:receiver)
|
|
160
162
|
end
|
|
163
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
161
164
|
|
|
162
165
|
def last_heredoc_argument_node(node)
|
|
163
166
|
return node unless node.respond_to?(:if_branch)
|
|
@@ -76,28 +76,40 @@ module RuboCop
|
|
|
76
76
|
# # good
|
|
77
77
|
# class ErrorA < BaseError; end
|
|
78
78
|
# class ErrorB < BaseError; end
|
|
79
|
-
# class ErrorC < BaseError; end
|
|
80
79
|
#
|
|
81
80
|
# # good
|
|
82
81
|
# class ErrorA < BaseError; end
|
|
83
82
|
#
|
|
84
83
|
# class ErrorB < BaseError; end
|
|
85
84
|
#
|
|
86
|
-
#
|
|
85
|
+
# # good - DefLikeMacros: [memoize]
|
|
86
|
+
# memoize :attribute_a
|
|
87
|
+
# memoize :attribute_b
|
|
88
|
+
#
|
|
89
|
+
# # good
|
|
90
|
+
# memoize :attribute_a
|
|
91
|
+
#
|
|
92
|
+
# memoize :attribute_b
|
|
87
93
|
#
|
|
88
94
|
# @example AllowAdjacentOneLineDefs: false
|
|
89
95
|
#
|
|
90
96
|
# # bad
|
|
91
97
|
# class ErrorA < BaseError; end
|
|
92
98
|
# class ErrorB < BaseError; end
|
|
93
|
-
# class ErrorC < BaseError; end
|
|
94
99
|
#
|
|
95
100
|
# # good
|
|
96
101
|
# class ErrorA < BaseError; end
|
|
97
102
|
#
|
|
98
103
|
# class ErrorB < BaseError; end
|
|
99
104
|
#
|
|
100
|
-
#
|
|
105
|
+
# # bad - DefLikeMacros: [memoize]
|
|
106
|
+
# memoize :attribute_a
|
|
107
|
+
# memoize :attribute_b
|
|
108
|
+
#
|
|
109
|
+
# # good
|
|
110
|
+
# memoize :attribute_a
|
|
111
|
+
#
|
|
112
|
+
# memoize :attribute_b
|
|
101
113
|
#
|
|
102
114
|
class EmptyLineBetweenDefs < Base
|
|
103
115
|
include RangeHelp
|
|
@@ -158,6 +170,8 @@ module RuboCop
|
|
|
158
170
|
def def_location(correction_node)
|
|
159
171
|
if correction_node.any_block_type?
|
|
160
172
|
correction_node.source_range.join(correction_node.children.first.source_range)
|
|
173
|
+
elsif correction_node.send_type?
|
|
174
|
+
correction_node.source_range
|
|
161
175
|
else
|
|
162
176
|
correction_node.loc.keyword.join(correction_node.loc.name)
|
|
163
177
|
end
|
|
@@ -175,8 +189,14 @@ module RuboCop
|
|
|
175
189
|
end
|
|
176
190
|
|
|
177
191
|
def macro_candidate?(node)
|
|
178
|
-
|
|
179
|
-
|
|
192
|
+
macro_candidate = if node.any_block_type?
|
|
193
|
+
node.send_node
|
|
194
|
+
elsif node.send_type?
|
|
195
|
+
node
|
|
196
|
+
end
|
|
197
|
+
return false unless macro_candidate
|
|
198
|
+
|
|
199
|
+
macro_candidate.macro? && empty_line_between_macros.include?(macro_candidate.method_name)
|
|
180
200
|
end
|
|
181
201
|
|
|
182
202
|
def method_candidate?(node)
|
|
@@ -240,7 +260,9 @@ module RuboCop
|
|
|
240
260
|
end
|
|
241
261
|
|
|
242
262
|
def def_start(node)
|
|
243
|
-
|
|
263
|
+
node = node.send_node if node.any_block_type?
|
|
264
|
+
|
|
265
|
+
if node.send_type?
|
|
244
266
|
node.source_range.line
|
|
245
267
|
else
|
|
246
268
|
node.loc.keyword.line
|
|
@@ -252,11 +274,7 @@ module RuboCop
|
|
|
252
274
|
end
|
|
253
275
|
|
|
254
276
|
def end_loc(node)
|
|
255
|
-
|
|
256
|
-
node.source_range.end
|
|
257
|
-
else
|
|
258
|
-
node.loc.end
|
|
259
|
-
end
|
|
277
|
+
node.source_range.end
|
|
260
278
|
end
|
|
261
279
|
|
|
262
280
|
def autocorrect_remove_lines(corrector, newline_pos, count)
|
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
|
38
38
|
RESTRICT_ON_SEND = MODULE_INCLUSION_METHODS
|
|
39
39
|
|
|
40
40
|
def on_send(node)
|
|
41
|
-
return if node.receiver
|
|
41
|
+
return if node.receiver || node.arguments.empty?
|
|
42
42
|
return if node.parent&.type?(:send, :any_block)
|
|
43
43
|
|
|
44
44
|
return if next_line_empty_or_enable_directive_comment?(node.last_line)
|
|
@@ -128,6 +128,10 @@ module RuboCop
|
|
|
128
128
|
# assignment, we let rhs be the receiver of those method calls before
|
|
129
129
|
# we check if it's an if/unless/while/until.
|
|
130
130
|
return unless (rhs = first_part_of_call_chain(rhs))
|
|
131
|
+
|
|
132
|
+
# If `rhs` is a `begin` node, find the first non-`begin` child.
|
|
133
|
+
rhs = rhs.child_nodes.first while rhs.begin_type?
|
|
134
|
+
|
|
131
135
|
return unless rhs.conditional?
|
|
132
136
|
return if rhs.if_type? && rhs.ternary?
|
|
133
137
|
|
|
@@ -193,7 +193,6 @@ module RuboCop
|
|
|
193
193
|
SEPARATOR_ALIGNMENT_STYLES = %w[EnforcedColonStyle EnforcedHashRocketStyle].freeze
|
|
194
194
|
|
|
195
195
|
def on_send(node)
|
|
196
|
-
return if double_splat?(node)
|
|
197
196
|
return unless node.arguments?
|
|
198
197
|
|
|
199
198
|
last_argument = node.last_argument
|
|
@@ -233,6 +232,8 @@ module RuboCop
|
|
|
233
232
|
end
|
|
234
233
|
|
|
235
234
|
def argument_before_hash(hash_node)
|
|
235
|
+
return hash_node.children.first.children.first if hash_node.children.first.kwsplat_type?
|
|
236
|
+
|
|
236
237
|
hash_node.left_sibling.respond_to?(:loc) ? hash_node.left_sibling : nil
|
|
237
238
|
end
|
|
238
239
|
|
|
@@ -241,10 +242,6 @@ module RuboCop
|
|
|
241
242
|
self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
|
|
242
243
|
end
|
|
243
244
|
|
|
244
|
-
def double_splat?(node)
|
|
245
|
-
node.children.last.is_a?(Symbol)
|
|
246
|
-
end
|
|
247
|
-
|
|
248
245
|
def check_pairs(node)
|
|
249
246
|
first_pair = node.pairs.first
|
|
250
247
|
reset!
|
|
@@ -168,7 +168,7 @@ module RuboCop
|
|
|
168
168
|
|
|
169
169
|
def subsequent_closing_parentheses_in_same_line?(outermost_send)
|
|
170
170
|
last_arg_of_outer_send = outermost_send.last_argument
|
|
171
|
-
return false unless last_arg_of_outer_send&.loc
|
|
171
|
+
return false unless last_arg_of_outer_send&.loc?(:end) &&
|
|
172
172
|
(end_of_last_arg_of_outer_send = last_arg_of_outer_send.loc.end)
|
|
173
173
|
|
|
174
174
|
end_of_outer_send = outermost_send.loc.end
|
|
@@ -230,7 +230,7 @@ module RuboCop
|
|
|
230
230
|
|
|
231
231
|
def find_most_bottom_of_heredoc_end(arguments)
|
|
232
232
|
arguments.filter_map do |argument|
|
|
233
|
-
argument.loc.heredoc_end.end_pos if argument.loc
|
|
233
|
+
argument.loc.heredoc_end.end_pos if argument.loc?(:heredoc_end)
|
|
234
234
|
end.max
|
|
235
235
|
end
|
|
236
236
|
|
|
@@ -108,10 +108,6 @@ module RuboCop
|
|
|
108
108
|
config.for_cop('Layout/LineLength')['AllowHeredoc']
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
def max_line_length
|
|
112
|
-
config.for_cop('Layout/LineLength')['Max']
|
|
113
|
-
end
|
|
114
|
-
|
|
115
111
|
def adjust_squiggly(corrector, node)
|
|
116
112
|
corrector.replace(node.loc.heredoc_body, indented_body(node))
|
|
117
113
|
corrector.replace(node.loc.heredoc_end, indented_end(node))
|
|
@@ -101,7 +101,7 @@ module RuboCop
|
|
|
101
101
|
ranges << loc.expression
|
|
102
102
|
elsif literal.heredoc?
|
|
103
103
|
ranges << loc.heredoc_body
|
|
104
|
-
elsif
|
|
104
|
+
elsif literal.loc?(:begin) || ignored_parent?(literal)
|
|
105
105
|
ranges << loc.expression
|
|
106
106
|
end
|
|
107
107
|
end
|
|
@@ -134,6 +134,7 @@ module RuboCop
|
|
|
134
134
|
|
|
135
135
|
def check_for_breakable_block(block_node)
|
|
136
136
|
return unless block_node.single_line?
|
|
137
|
+
return if receiver_contains_heredoc?(block_node)
|
|
137
138
|
|
|
138
139
|
line_index = block_node.loc.line - 1
|
|
139
140
|
range = breakable_block_range(block_node)
|
|
@@ -251,17 +252,22 @@ module RuboCop
|
|
|
251
252
|
[max - indentation_difference(line), 0].max
|
|
252
253
|
end
|
|
253
254
|
|
|
255
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
254
256
|
def check_line(line, line_index)
|
|
255
257
|
return if line_length(line) <= max
|
|
256
258
|
return if allowed_line?(line, line_index)
|
|
259
|
+
if allow_rbs_inline_annotation? && rbs_inline_annotation_on_source_line?(line_index)
|
|
260
|
+
return
|
|
261
|
+
end
|
|
257
262
|
|
|
258
|
-
if
|
|
263
|
+
if allow_cop_directives? && directive_on_source_line?(line_index)
|
|
259
264
|
return check_directive_line(line, line_index)
|
|
260
265
|
end
|
|
261
266
|
return check_line_for_exemptions(line, line_index) if allow_uri? || allow_qualified_name?
|
|
262
267
|
|
|
263
268
|
register_offense(excess_range(nil, line, line_index), line, line_index)
|
|
264
269
|
end
|
|
270
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
265
271
|
|
|
266
272
|
def allowed_line?(line, line_index)
|
|
267
273
|
matches_allowed_pattern?(line) ||
|
|
@@ -321,7 +327,7 @@ module RuboCop
|
|
|
321
327
|
def extract_heredocs(ast)
|
|
322
328
|
return [] unless ast
|
|
323
329
|
|
|
324
|
-
ast.each_node(:
|
|
330
|
+
ast.each_node(:any_str).select(&:heredoc?).map do |node|
|
|
325
331
|
body = node.location.heredoc_body
|
|
326
332
|
delimiter = node.location.heredoc_end.source.strip
|
|
327
333
|
[body.first_line...body.last_line, delimiter]
|
|
@@ -341,6 +347,13 @@ module RuboCop
|
|
|
341
347
|
heredocs.any? { |range, _delimiter| range.cover?(line_number) }
|
|
342
348
|
end
|
|
343
349
|
|
|
350
|
+
def receiver_contains_heredoc?(node)
|
|
351
|
+
return false unless (receiver = node.receiver)
|
|
352
|
+
return true if receiver.any_str_type? && receiver.heredoc?
|
|
353
|
+
|
|
354
|
+
receiver.each_descendant(:any_str).any?(&:heredoc?)
|
|
355
|
+
end
|
|
356
|
+
|
|
344
357
|
def check_directive_line(line, line_index)
|
|
345
358
|
length_without_directive = line_length_without_directive(line)
|
|
346
359
|
return if length_without_directive <= max
|
|
@@ -393,9 +406,7 @@ module RuboCop
|
|
|
393
406
|
|
|
394
407
|
def string_delimiter(node)
|
|
395
408
|
delimiter = node.loc.begin
|
|
396
|
-
if node.parent&.dstr_type? && node.parent.loc
|
|
397
|
-
delimiter ||= node.parent.loc.begin
|
|
398
|
-
end
|
|
409
|
+
delimiter ||= node.parent.loc.begin if node.parent&.dstr_type? && node.parent.loc?(:begin)
|
|
399
410
|
delimiter = delimiter&.source
|
|
400
411
|
|
|
401
412
|
delimiter if %w[' "].include?(delimiter)
|
|
@@ -10,6 +10,8 @@ module RuboCop
|
|
|
10
10
|
# condition, an explicit `return` statement, etc. In other contexts, the second operand should
|
|
11
11
|
# be indented regardless of enforced style.
|
|
12
12
|
#
|
|
13
|
+
# In both styles, operators should be aligned when an assignment begins on the next line.
|
|
14
|
+
#
|
|
13
15
|
# @example EnforcedStyle: aligned (default)
|
|
14
16
|
# # bad
|
|
15
17
|
# if a +
|
|
@@ -100,10 +102,12 @@ module RuboCop
|
|
|
100
102
|
return true if begins_its_line?(assignment_rhs.source_range)
|
|
101
103
|
end
|
|
102
104
|
|
|
103
|
-
given_style == :aligned
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
return false unless given_style == :aligned
|
|
106
|
+
return true if kw_node_with_special_indentation(node) || assignment_node
|
|
107
|
+
|
|
108
|
+
node = argument_in_method_call(node, :with_or_without_parentheses)
|
|
109
|
+
|
|
110
|
+
node.respond_to?(:def_modifier?) && !node.def_modifier?
|
|
107
111
|
end
|
|
108
112
|
|
|
109
113
|
def message(node, lhs, rhs)
|
|
@@ -29,7 +29,7 @@ module RuboCop
|
|
|
29
29
|
MSG = '`%<kw_loc>s` at %<kw_loc_line>d, %<kw_loc_column>d is not ' \
|
|
30
30
|
'aligned with `%<beginning>s` at ' \
|
|
31
31
|
'%<begin_loc_line>d, %<begin_loc_column>d.'
|
|
32
|
-
ANCESTOR_TYPES = %i[kwbegin any_def class module any_block].freeze
|
|
32
|
+
ANCESTOR_TYPES = %i[kwbegin any_def class module sclass any_block].freeze
|
|
33
33
|
ALTERNATIVE_ACCESS_MODIFIERS = %i[public_class_method private_class_method].freeze
|
|
34
34
|
|
|
35
35
|
def on_resbody(node)
|
|
@@ -91,7 +91,7 @@ module RuboCop
|
|
|
91
91
|
)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
# rubocop:disable Metrics/AbcSize
|
|
94
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
95
95
|
def alignment_source(node, starting_loc)
|
|
96
96
|
ending_loc =
|
|
97
97
|
case node.type
|
|
@@ -100,6 +100,8 @@ module RuboCop
|
|
|
100
100
|
when :def, :defs, :class, :module,
|
|
101
101
|
:lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
|
|
102
102
|
node.loc.name
|
|
103
|
+
when :sclass
|
|
104
|
+
node.identifier.source_range
|
|
103
105
|
when :masgn
|
|
104
106
|
node.lhs.source_range
|
|
105
107
|
else
|
|
@@ -109,7 +111,7 @@ module RuboCop
|
|
|
109
111
|
|
|
110
112
|
range_between(starting_loc.begin_pos, ending_loc.end_pos).source
|
|
111
113
|
end
|
|
112
|
-
# rubocop:enable Metrics/AbcSize
|
|
114
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
113
115
|
|
|
114
116
|
# We will use ancestor or wrapper with access modifier.
|
|
115
117
|
|
|
@@ -194,6 +196,14 @@ module RuboCop
|
|
|
194
196
|
def alignment_location(alignment_node)
|
|
195
197
|
if begin_end_alignment_style == 'start_of_line'
|
|
196
198
|
start_line_range(alignment_node)
|
|
199
|
+
elsif alignment_node.any_block_type?
|
|
200
|
+
# If the alignment node is a block, the `rescue`/`ensure` keyword should
|
|
201
|
+
# be aligned to the start of the block. It is possible that the block's
|
|
202
|
+
# `send_node` spans multiple lines, in which case it should align to the
|
|
203
|
+
# start of the last line.
|
|
204
|
+
send_node = alignment_node.send_node
|
|
205
|
+
range = processed_source.buffer.line_range(send_node.last_line)
|
|
206
|
+
range.adjust(begin_pos: range.source =~ /\S/)
|
|
197
207
|
else
|
|
198
208
|
alignment_node.source_range
|
|
199
209
|
end
|
|
@@ -35,6 +35,26 @@ module RuboCop
|
|
|
35
35
|
# def cook(dry_ingredients = self.dry_ingredients)
|
|
36
36
|
# dry_ingredients.combine
|
|
37
37
|
# end
|
|
38
|
+
#
|
|
39
|
+
# # bad
|
|
40
|
+
# def foo(pie = pie = pie)
|
|
41
|
+
# pie.heat_up
|
|
42
|
+
# end
|
|
43
|
+
#
|
|
44
|
+
# # good
|
|
45
|
+
# def foo(pie)
|
|
46
|
+
# pie.heat_up
|
|
47
|
+
# end
|
|
48
|
+
#
|
|
49
|
+
# # bad
|
|
50
|
+
# def foo(pie = cake = pie)
|
|
51
|
+
# [pie, cake].each(&:heat_up)
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# # good
|
|
55
|
+
# def foo(cake = pie)
|
|
56
|
+
# [pie, cake].each(&:heat_up)
|
|
57
|
+
# end
|
|
38
58
|
class CircularArgumentReference < Base
|
|
39
59
|
extend TargetRubyVersion
|
|
40
60
|
|
|
@@ -51,11 +71,35 @@ module RuboCop
|
|
|
51
71
|
private
|
|
52
72
|
|
|
53
73
|
def check_for_circular_argument_references(arg_name, arg_value)
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
if arg_value.lvar_type? && arg_value.to_a == [arg_name]
|
|
75
|
+
add_offense(arg_value, message: format(MSG, arg_name: arg_name))
|
|
76
|
+
|
|
77
|
+
return
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
check_assignment_chain(arg_name, arg_value)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# rubocop:disable Metrics/AbcSize
|
|
84
|
+
def check_assignment_chain(arg_name, node)
|
|
85
|
+
return unless node.lvasgn_type?
|
|
86
|
+
|
|
87
|
+
seen_variables = Set[]
|
|
88
|
+
current_node = node
|
|
89
|
+
|
|
90
|
+
while current_node.lvasgn_type?
|
|
91
|
+
seen_variables << current_node.children.first if current_node.lvasgn_type?
|
|
92
|
+
current_node = current_node.children.last
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return unless current_node.lvar_type?
|
|
96
|
+
|
|
97
|
+
variable_node = current_node.children.first
|
|
98
|
+
return unless seen_variables.include?(variable_node) || variable_node == arg_name
|
|
56
99
|
|
|
57
|
-
add_offense(
|
|
100
|
+
add_offense(current_node, message: format(MSG, arg_name: arg_name))
|
|
58
101
|
end
|
|
102
|
+
# rubocop:enable Metrics/AbcSize
|
|
59
103
|
end
|
|
60
104
|
end
|
|
61
105
|
end
|
|
@@ -31,7 +31,7 @@ module RuboCop
|
|
|
31
31
|
|
|
32
32
|
# @!method overwritten_constant(node)
|
|
33
33
|
def_node_matcher :overwritten_constant, <<~PATTERN
|
|
34
|
-
(resbody nil? (casgn
|
|
34
|
+
(resbody nil? $(casgn _ _) nil?)
|
|
35
35
|
PATTERN
|
|
36
36
|
|
|
37
37
|
def self.autocorrect_incompatible_with
|
|
@@ -41,7 +41,8 @@ module RuboCop
|
|
|
41
41
|
def on_resbody(node)
|
|
42
42
|
return unless (constant = overwritten_constant(node))
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
message = format(MSG, constant: constant.source)
|
|
45
|
+
add_offense(node.loc.assoc, message: message) do |corrector|
|
|
45
46
|
corrector.remove(range_between(node.loc.keyword.end_pos, node.loc.assoc.end_pos))
|
|
46
47
|
end
|
|
47
48
|
end
|
|
@@ -13,34 +13,40 @@ module RuboCop
|
|
|
13
13
|
# @example
|
|
14
14
|
# # bad
|
|
15
15
|
# # rubocop:disable Layout/LineLength Style/Encoding
|
|
16
|
-
#
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# # rubocop:disable Layout/LineLength, Style/Encoding
|
|
17
19
|
#
|
|
18
20
|
# # bad
|
|
19
21
|
# # rubocop:disable
|
|
20
22
|
#
|
|
23
|
+
# # good
|
|
24
|
+
# # rubocop:disable all
|
|
25
|
+
#
|
|
21
26
|
# # bad
|
|
22
27
|
# # rubocop:disable Layout/LineLength # rubocop:disable Style/Encoding
|
|
23
28
|
#
|
|
29
|
+
# # good
|
|
30
|
+
# # rubocop:disable Layout/LineLength
|
|
31
|
+
# # rubocop:disable Style/Encoding
|
|
32
|
+
#
|
|
24
33
|
# # bad
|
|
25
34
|
# # rubocop:wrongmode Layout/LineLength
|
|
26
35
|
#
|
|
27
36
|
# # good
|
|
28
37
|
# # rubocop:disable Layout/LineLength
|
|
29
38
|
#
|
|
30
|
-
# #
|
|
31
|
-
# # rubocop:disable Layout/LineLength
|
|
32
|
-
#
|
|
33
|
-
# # good
|
|
34
|
-
# # rubocop:disable all
|
|
39
|
+
# # bad
|
|
40
|
+
# # rubocop:disable Layout/LineLength comment
|
|
35
41
|
#
|
|
36
42
|
# # good
|
|
37
|
-
# # rubocop:disable Layout/LineLength --
|
|
43
|
+
# # rubocop:disable Layout/LineLength -- comment
|
|
38
44
|
#
|
|
39
45
|
class CopDirectiveSyntax < Base
|
|
40
46
|
COMMON_MSG = 'Malformed directive comment detected.'
|
|
41
47
|
|
|
42
48
|
MISSING_MODE_NAME_MSG = 'The mode name is missing.'
|
|
43
|
-
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, or `
|
|
49
|
+
INVALID_MODE_NAME_MSG = 'The mode name must be one of `enable`, `disable`, `todo`, `push`, or `pop`.' # rubocop:disable Layout/LineLength
|
|
44
50
|
MISSING_COP_NAME_MSG = 'The cop name is missing.'
|
|
45
51
|
MALFORMED_COP_NAMES_MSG = 'Cop names must be separated by commas. ' \
|
|
46
52
|
'Comment in the directive must start with `--`.'
|
|
@@ -118,8 +118,11 @@ module RuboCop
|
|
|
118
118
|
|
|
119
119
|
def replacement_args(node)
|
|
120
120
|
algorithm_constant, = algorithm_const(node)
|
|
121
|
-
|
|
121
|
+
if algorithm_constant.source == 'OpenSSL::Cipher::Cipher'
|
|
122
|
+
return node.first_argument.source
|
|
123
|
+
end
|
|
122
124
|
|
|
125
|
+
algorithm_name = algorithm_name(algorithm_constant)
|
|
123
126
|
if openssl_class(algorithm_constant) == 'OpenSSL::Cipher'
|
|
124
127
|
build_cipher_arguments(node, algorithm_name, node.arguments.empty?)
|
|
125
128
|
else
|
|
@@ -24,8 +24,6 @@ module RuboCop
|
|
|
24
24
|
|
|
25
25
|
MSG_REPEATED_ELEMENT = 'Duplicate element inside regexp character class'
|
|
26
26
|
|
|
27
|
-
OCTAL_DIGITS_AFTER_ESCAPE = 2
|
|
28
|
-
|
|
29
27
|
def on_regexp(node)
|
|
30
28
|
each_repeated_character_class_element_loc(node) do |loc|
|
|
31
29
|
add_offense(loc, message: MSG_REPEATED_ELEMENT) do |corrector|
|
|
@@ -40,9 +38,9 @@ module RuboCop
|
|
|
40
38
|
|
|
41
39
|
seen = Set.new
|
|
42
40
|
group_expressions(node, expr.expressions) do |group|
|
|
43
|
-
group_source = group.
|
|
41
|
+
group_source = group.to_s
|
|
44
42
|
|
|
45
|
-
yield
|
|
43
|
+
yield group.expression if seen.include?(group_source)
|
|
46
44
|
|
|
47
45
|
seen << group_source
|
|
48
46
|
end
|
|
@@ -52,40 +50,13 @@ module RuboCop
|
|
|
52
50
|
private
|
|
53
51
|
|
|
54
52
|
def group_expressions(node, expressions)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
until expressions.empty?
|
|
59
|
-
# With we may need to compose a group of multiple expressions.
|
|
60
|
-
group = [expressions.shift]
|
|
61
|
-
next if within_interpolation?(node, group.first)
|
|
62
|
-
|
|
63
|
-
# With regexp_parser < 2.7 escaped octal sequences may be up to 3
|
|
64
|
-
# separate expressions ("\\0", "0", "1").
|
|
65
|
-
pop_octal_digits(group, expressions) if escaped_octal?(group.first.to_s)
|
|
66
|
-
|
|
67
|
-
yield(group)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def pop_octal_digits(current_child, expressions)
|
|
72
|
-
OCTAL_DIGITS_AFTER_ESCAPE.times do
|
|
73
|
-
next_child = expressions.first
|
|
74
|
-
break unless octal?(next_child.to_s)
|
|
53
|
+
expressions.each do |expression|
|
|
54
|
+
next if within_interpolation?(node, expression)
|
|
75
55
|
|
|
76
|
-
|
|
56
|
+
yield(expression)
|
|
77
57
|
end
|
|
78
58
|
end
|
|
79
59
|
|
|
80
|
-
def source_range(children)
|
|
81
|
-
return children.first.expression if children.size == 1
|
|
82
|
-
|
|
83
|
-
range_between(
|
|
84
|
-
children.first.expression.begin_pos,
|
|
85
|
-
children.last.expression.begin_pos + children.last.to_s.length
|
|
86
|
-
)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
60
|
def skip_expression?(expr)
|
|
90
61
|
expr.type != :set || expr.token == :intersection
|
|
91
62
|
end
|
|
@@ -99,14 +70,6 @@ module RuboCop
|
|
|
99
70
|
interpolation_locs(node).any? { |il| il.overlaps?(parse_tree_child_loc) }
|
|
100
71
|
end
|
|
101
72
|
|
|
102
|
-
def escaped_octal?(string)
|
|
103
|
-
string.length == 2 && string[0] == '\\' && octal?(string[1])
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def octal?(char)
|
|
107
|
-
('0'..'7').cover?(char)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
73
|
def interpolation_locs(node)
|
|
111
74
|
@interpolation_locs ||= {}
|
|
112
75
|
|