rubocop 1.75.8 → 1.81.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +20 -16
- data/config/default.yml +117 -26
- data/config/obsoletion.yml +6 -3
- data/exe/rubocop +1 -8
- data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
- data/lib/rubocop/cli.rb +18 -3
- data/lib/rubocop/config_loader.rb +4 -39
- data/lib/rubocop/config_store.rb +5 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +4 -4
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +7 -4
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +0 -22
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +4 -1
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +1 -1
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +30 -12
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +35 -6
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +8 -0
- data/lib/rubocop/cop/layout/space_around_keyword.rb +6 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +2 -9
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -2
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +25 -4
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +4 -4
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +34 -28
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +4 -4
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
- data/lib/rubocop/cop/lint/self_assignment.rb +30 -4
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
- data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +29 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +7 -0
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +24 -8
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/method_name.rb +127 -13
- data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
- data/lib/rubocop/cop/style/array_intersect.rb +98 -34
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -2
- data/lib/rubocop/cop/style/dig_chain.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -2
- data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +13 -6
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
- data/lib/rubocop/cop/style/it_assignment.rb +69 -12
- data/lib/rubocop/cop/style/it_block_parameter.rb +36 -15
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -3
- data/lib/rubocop/cop/style/map_to_set.rb +1 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -6
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +16 -0
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
- data/lib/rubocop/cop/style/parallel_assignment.rb +32 -20
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -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_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +18 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +55 -16
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_self.rb +8 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +44 -12
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +32 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
- data/lib/rubocop/cop/style/symbol_array.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- 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 +25 -8
- data/lib/rubocop/cops_documentation_generator.rb +1 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +18 -5
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
- data/lib/rubocop/lsp/diagnostic.rb +25 -24
- data/lib/rubocop/lsp/routes.rb +65 -9
- data/lib/rubocop/lsp/runtime.rb +2 -2
- data/lib/rubocop/lsp/server.rb +2 -2
- data/lib/rubocop/lsp/stdin_runner.rb +0 -16
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/result_cache.rb +14 -12
- data/lib/rubocop/rspec/expect_offense.rb +9 -3
- data/lib/rubocop/runner.rb +6 -4
- data/lib/rubocop/server/cache.rb +4 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/target_finder.rb +9 -9
- data/lib/rubocop/target_ruby.rb +10 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +12 -1
- data/lib/ruby_lsp/rubocop/addon.rb +25 -10
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +22 -8
@@ -138,7 +138,7 @@ module RuboCop
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def previous_line_ignoring_comments(processed_source, send_line)
|
141
|
-
processed_source[0..send_line - 2].reverse.find { |line| !comment_line?(line) }
|
141
|
+
processed_source[0..(send_line - 2)].reverse.find { |line| !comment_line?(line) }
|
142
142
|
end
|
143
143
|
|
144
144
|
def previous_line_empty?(send_line)
|
@@ -62,40 +62,19 @@ module RuboCop
|
|
62
62
|
node.receiver && node.receiver.loc.last_line != node.loc.selector&.line
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
lines.map { |_, line| line }
|
69
|
-
end
|
70
|
-
|
71
|
-
def extra_lines(node)
|
72
|
-
empty_lines(node).each do |line|
|
73
|
-
range = source_range(processed_source.buffer, line, 0)
|
74
|
-
yield(range)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def processed_lines(node)
|
79
|
-
line_numbers(node).each_with_object([]) do |num, array|
|
80
|
-
array << [processed_source.lines[num - 1], num]
|
65
|
+
def extra_lines(node, &block)
|
66
|
+
node.arguments.each do |arg|
|
67
|
+
empty_range_for_starting_point(arg.source_range.begin, &block)
|
81
68
|
end
|
82
|
-
end
|
83
69
|
|
84
|
-
|
85
|
-
inner_lines = []
|
86
|
-
line_nums = node.arguments.each_with_object([]) do |arg_node, lines|
|
87
|
-
lines << outer_lines(arg_node)
|
88
|
-
inner_lines << inner_lines(arg_node) if arg_node.multiline?
|
89
|
-
end
|
90
|
-
line_nums.flatten.uniq - inner_lines.flatten - outer_lines(node)
|
70
|
+
empty_range_for_starting_point(node.loc.end.begin, &block) if node.loc.end
|
91
71
|
end
|
92
72
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
73
|
+
def empty_range_for_starting_point(start)
|
74
|
+
range = range_with_surrounding_space(start, whitespace: true, side: :left)
|
75
|
+
return unless range.last_line - range.first_line > 1
|
96
76
|
|
97
|
-
|
98
|
-
[node.first_line - 1, node.last_line + 1]
|
77
|
+
yield range.source_buffer.line_range(range.last_line - 1).adjust(end_pos: 1)
|
99
78
|
end
|
100
79
|
end
|
101
80
|
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)
|
@@ -258,7 +259,7 @@ module RuboCop
|
|
258
259
|
if ignore_cop_directives? && directive_on_source_line?(line_index)
|
259
260
|
return check_directive_line(line, line_index)
|
260
261
|
end
|
261
|
-
return
|
262
|
+
return check_line_for_exemptions(line, line_index) if allow_uri? || allow_qualified_name?
|
262
263
|
|
263
264
|
register_offense(excess_range(nil, line, line_index), line, line_index)
|
264
265
|
end
|
@@ -321,7 +322,7 @@ module RuboCop
|
|
321
322
|
def extract_heredocs(ast)
|
322
323
|
return [] unless ast
|
323
324
|
|
324
|
-
ast.each_node(:
|
325
|
+
ast.each_node(:any_str).select(&:heredoc?).map do |node|
|
325
326
|
body = node.location.heredoc_body
|
326
327
|
delimiter = node.location.heredoc_end.source.strip
|
327
328
|
[body.first_line...body.last_line, delimiter]
|
@@ -341,6 +342,13 @@ module RuboCop
|
|
341
342
|
heredocs.any? { |range, _delimiter| range.cover?(line_number) }
|
342
343
|
end
|
343
344
|
|
345
|
+
def receiver_contains_heredoc?(node)
|
346
|
+
return false unless (receiver = node.receiver)
|
347
|
+
return true if receiver.any_str_type? && receiver.heredoc?
|
348
|
+
|
349
|
+
receiver.each_descendant(:any_str).any?(&:heredoc?)
|
350
|
+
end
|
351
|
+
|
344
352
|
def check_directive_line(line, line_index)
|
345
353
|
length_without_directive = line_length_without_directive(line)
|
346
354
|
return if length_without_directive <= max
|
@@ -358,11 +366,32 @@ module RuboCop
|
|
358
366
|
)
|
359
367
|
end
|
360
368
|
|
361
|
-
def
|
362
|
-
uri_range
|
363
|
-
|
369
|
+
def check_line_for_exemptions(line, line_index)
|
370
|
+
uri_range = range_if_applicable(line, :uri)
|
371
|
+
qualified_name_range = range_if_applicable(line, :qualified_name)
|
372
|
+
|
373
|
+
return if allowed_combination?(line, uri_range, qualified_name_range)
|
374
|
+
|
375
|
+
range = uri_range || qualified_name_range
|
376
|
+
register_offense(excess_range(range, line, line_index), line, line_index)
|
377
|
+
end
|
364
378
|
|
365
|
-
|
379
|
+
def range_if_applicable(line, type)
|
380
|
+
return unless type == :uri ? allow_uri? : allow_qualified_name?
|
381
|
+
|
382
|
+
find_excessive_range(line, type)
|
383
|
+
end
|
384
|
+
|
385
|
+
def allowed_combination?(line, uri_range, qualified_name_range)
|
386
|
+
if uri_range && qualified_name_range
|
387
|
+
allowed_position?(line, uri_range) && allowed_position?(line, qualified_name_range)
|
388
|
+
elsif uri_range
|
389
|
+
allowed_position?(line, uri_range)
|
390
|
+
elsif qualified_name_range
|
391
|
+
allowed_position?(line, qualified_name_range)
|
392
|
+
else
|
393
|
+
false
|
394
|
+
end
|
366
395
|
end
|
367
396
|
|
368
397
|
def breakable_dstr?(node)
|
@@ -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)
|
@@ -194,6 +194,14 @@ module RuboCop
|
|
194
194
|
def alignment_location(alignment_node)
|
195
195
|
if begin_end_alignment_style == 'start_of_line'
|
196
196
|
start_line_range(alignment_node)
|
197
|
+
elsif alignment_node.any_block_type?
|
198
|
+
# If the alignment node is a block, the `rescue`/`ensure` keyword should
|
199
|
+
# be aligned to the start of the block. It is possible that the block's
|
200
|
+
# `send_node` spans multiple lines, in which case it should align to the
|
201
|
+
# start of the last line.
|
202
|
+
send_node = alignment_node.send_node
|
203
|
+
range = processed_source.buffer.line_range(send_node.last_line)
|
204
|
+
range.adjust(begin_pos: range.source =~ /\S/)
|
197
205
|
else
|
198
206
|
alignment_node.source_range
|
199
207
|
end
|
@@ -16,6 +16,8 @@ module RuboCop
|
|
16
16
|
#
|
17
17
|
# something = 123if test
|
18
18
|
#
|
19
|
+
# return(foo + bar)
|
20
|
+
#
|
19
21
|
# # good
|
20
22
|
# something 'test' do |x|
|
21
23
|
# end
|
@@ -24,6 +26,9 @@ module RuboCop
|
|
24
26
|
# end
|
25
27
|
#
|
26
28
|
# something = 123 if test
|
29
|
+
#
|
30
|
+
# return (foo + bar)
|
31
|
+
#
|
27
32
|
class SpaceAroundKeyword < Base
|
28
33
|
extend AutoCorrector
|
29
34
|
|
@@ -33,7 +38,7 @@ module RuboCop
|
|
33
38
|
DO = 'do'
|
34
39
|
SAFE_NAVIGATION = '&.'
|
35
40
|
NAMESPACE_OPERATOR = '::'
|
36
|
-
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue
|
41
|
+
ACCEPT_LEFT_PAREN = %w[break defined? next not rescue super yield].freeze
|
37
42
|
ACCEPT_LEFT_SQUARE_BRACKET = %w[super yield].freeze
|
38
43
|
ACCEPT_NAMESPACE_OPERATOR = 'super'
|
39
44
|
RESTRICT_ON_SEND = %i[!].freeze
|
@@ -151,6 +151,14 @@ module RuboCop
|
|
151
151
|
check_operator(:match_pattern, node.loc.operator, node)
|
152
152
|
end
|
153
153
|
|
154
|
+
def on_match_alt(node)
|
155
|
+
check_operator(:match_alt, node.loc.operator, node)
|
156
|
+
end
|
157
|
+
|
158
|
+
def on_match_as(node)
|
159
|
+
check_operator(:match_as, node.loc.operator, node)
|
160
|
+
end
|
161
|
+
|
154
162
|
alias on_or on_binary
|
155
163
|
alias on_and on_binary
|
156
164
|
alias on_lvasgn on_assignment
|
@@ -22,10 +22,11 @@ module RuboCop
|
|
22
22
|
RESTRICT_ON_SEND = %i[[] []=].freeze
|
23
23
|
|
24
24
|
def on_send(node)
|
25
|
+
return if node.loc.dot
|
26
|
+
|
25
27
|
receiver_end_pos = node.receiver.source_range.end_pos
|
26
28
|
selector_begin_pos = node.loc.selector.begin_pos
|
27
29
|
return if receiver_end_pos >= selector_begin_pos
|
28
|
-
return if dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
29
30
|
|
30
31
|
range = range_between(receiver_end_pos, selector_begin_pos)
|
31
32
|
|
@@ -33,14 +34,6 @@ module RuboCop
|
|
33
34
|
corrector.remove(range)
|
34
35
|
end
|
35
36
|
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def dot_before_brackets?(node, receiver_end_pos, selector_begin_pos)
|
40
|
-
return false unless node.loc.respond_to?(:dot) && (dot = node.loc.dot)
|
41
|
-
|
42
|
-
dot.begin_pos == receiver_end_pos && dot.end_pos == selector_begin_pos
|
43
|
-
end
|
44
37
|
end
|
45
38
|
end
|
46
39
|
end
|
@@ -86,6 +86,7 @@ module RuboCop
|
|
86
86
|
def on_array(node)
|
87
87
|
return if node.array_type? && !node.square_brackets?
|
88
88
|
|
89
|
+
node = find_node_with_brackets(node)
|
89
90
|
tokens, left, right = array_brackets(node)
|
90
91
|
return unless left && right
|
91
92
|
|
@@ -102,6 +103,10 @@ module RuboCop
|
|
102
103
|
|
103
104
|
private
|
104
105
|
|
106
|
+
def find_node_with_brackets(node)
|
107
|
+
node.ancestors.find(&:const_pattern_type?) || node
|
108
|
+
end
|
109
|
+
|
105
110
|
def autocorrect(corrector, node)
|
106
111
|
tokens, left, right = array_brackets(node)
|
107
112
|
|
@@ -119,7 +124,7 @@ module RuboCop
|
|
119
124
|
def array_brackets(node)
|
120
125
|
tokens = processed_source.tokens_within(node)
|
121
126
|
|
122
|
-
left = tokens.find(&:
|
127
|
+
left = tokens.find(&:left_bracket?)
|
123
128
|
right = tokens.reverse_each.find(&:right_bracket?)
|
124
129
|
|
125
130
|
[tokens, left, right]
|
@@ -192,7 +197,7 @@ module RuboCop
|
|
192
197
|
if side == :right
|
193
198
|
processed_source.tokens_within(node)[i].right_bracket?
|
194
199
|
else
|
195
|
-
processed_source.tokens_within(node)[i].
|
200
|
+
processed_source.tokens_within(node)[i].left_bracket?
|
196
201
|
end
|
197
202
|
end
|
198
203
|
|
@@ -27,7 +27,9 @@ module RuboCop
|
|
27
27
|
# @example
|
28
28
|
# # bad
|
29
29
|
# x || 1..2
|
30
|
+
# x - 1..2
|
30
31
|
# (x || 1..2)
|
32
|
+
# x || 1..y || 2
|
31
33
|
# 1..2.to_a
|
32
34
|
#
|
33
35
|
# # good, unambiguous
|
@@ -41,6 +43,7 @@ module RuboCop
|
|
41
43
|
#
|
42
44
|
# # good, ambiguity removed
|
43
45
|
# x || (1..2)
|
46
|
+
# (x - 1)..2
|
44
47
|
# (x || 1)..2
|
45
48
|
# (x || 1)..(y || 2)
|
46
49
|
# (1..2).to_a
|
@@ -96,6 +99,8 @@ module RuboCop
|
|
96
99
|
# to avoid the ambiguity of `1..2.to_a`.
|
97
100
|
return false if node.receiver&.basic_literal?
|
98
101
|
|
102
|
+
return false if node.operator_method? && !node.method?(:[])
|
103
|
+
|
99
104
|
require_parentheses_for_method_chain? || node.receiver.nil?
|
100
105
|
end
|
101
106
|
|
@@ -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
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# Checks for duplicated instance (or singleton) method
|
7
7
|
# definitions.
|
8
8
|
#
|
9
|
+
# NOTE: Aliasing a method to itself is allowed, as it indicates that
|
10
|
+
# the developer intends to suppress Ruby's method redefinition warnings.
|
11
|
+
# See https://bugs.ruby-lang.org/issues/13574.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
#
|
11
15
|
# # bad
|
@@ -40,6 +44,18 @@ module RuboCop
|
|
40
44
|
#
|
41
45
|
# alias bar foo
|
42
46
|
#
|
47
|
+
# # good
|
48
|
+
# alias foo foo
|
49
|
+
# def foo
|
50
|
+
# 1
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # good
|
54
|
+
# alias_method :foo, :foo
|
55
|
+
# def foo
|
56
|
+
# 1
|
57
|
+
# end
|
58
|
+
#
|
43
59
|
# @example AllCops:ActiveSupportExtensionsEnabled: false (default)
|
44
60
|
#
|
45
61
|
# # good
|
@@ -113,11 +129,13 @@ module RuboCop
|
|
113
129
|
|
114
130
|
# @!method method_alias?(node)
|
115
131
|
def_node_matcher :method_alias?, <<~PATTERN
|
116
|
-
(alias (sym $_name) sym)
|
132
|
+
(alias (sym $_name) (sym $_original_name))
|
117
133
|
PATTERN
|
118
134
|
|
119
135
|
def on_alias(node)
|
120
|
-
|
136
|
+
name, original_name = method_alias?(node)
|
137
|
+
return unless name && original_name
|
138
|
+
return if name == original_name
|
121
139
|
return if node.ancestors.any?(&:if_type?)
|
122
140
|
|
123
141
|
found_instance_method(node, name)
|
@@ -125,7 +143,7 @@ module RuboCop
|
|
125
143
|
|
126
144
|
# @!method alias_method?(node)
|
127
145
|
def_node_matcher :alias_method?, <<~PATTERN
|
128
|
-
(send nil? :alias_method (sym $_name)
|
146
|
+
(send nil? :alias_method (sym $_name) (sym $_original_name))
|
129
147
|
PATTERN
|
130
148
|
|
131
149
|
# @!method delegate_method?(node)
|
@@ -140,7 +158,10 @@ module RuboCop
|
|
140
158
|
def_node_matcher :sym_name, '(sym $_name)'
|
141
159
|
|
142
160
|
def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
143
|
-
|
161
|
+
name, original_name = alias_method?(node)
|
162
|
+
|
163
|
+
if name && original_name
|
164
|
+
return if name == original_name
|
144
165
|
return if node.ancestors.any?(&:if_type?)
|
145
166
|
|
146
167
|
found_instance_method(node, name)
|
@@ -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
|
|
@@ -19,7 +19,9 @@ module RuboCop
|
|
19
19
|
MSG = 'Empty interpolation detected.'
|
20
20
|
|
21
21
|
def on_interpolation(begin_node)
|
22
|
-
|
22
|
+
node_children = begin_node.children.dup
|
23
|
+
node_children.delete_if { |e| e.nil_type? || (e.basic_literal? && e.str_content&.empty?) }
|
24
|
+
return unless node_children.empty?
|
23
25
|
|
24
26
|
add_offense(begin_node) { |corrector| corrector.remove(begin_node) }
|
25
27
|
end
|
@@ -94,7 +94,7 @@ module RuboCop
|
|
94
94
|
when :float
|
95
95
|
true
|
96
96
|
when :send
|
97
|
-
|
97
|
+
float_send?(node)
|
98
98
|
when :begin
|
99
99
|
float?(node.children.first)
|
100
100
|
else
|
@@ -108,18 +108,18 @@ module RuboCop
|
|
108
108
|
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
109
109
|
end
|
110
110
|
|
111
|
-
def
|
111
|
+
def float_send?(node)
|
112
112
|
if node.arithmetic_operation?
|
113
113
|
float?(node.receiver) || float?(node.first_argument)
|
114
114
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
115
115
|
true
|
116
116
|
elsif node.receiver&.float_type?
|
117
117
|
FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
|
118
|
-
|
118
|
+
numeric_returning_method?(node)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
def
|
122
|
+
def numeric_returning_method?(node)
|
123
123
|
return false unless node.receiver
|
124
124
|
|
125
125
|
case node.method_name
|
@@ -11,39 +11,43 @@ module RuboCop
|
|
11
11
|
# @example
|
12
12
|
# # bad
|
13
13
|
# foo.object_id == bar.object_id
|
14
|
+
# foo.object_id != baz.object_id
|
14
15
|
#
|
15
16
|
# # good
|
16
17
|
# foo.equal?(bar)
|
18
|
+
# !foo.equal?(baz)
|
17
19
|
#
|
18
20
|
class IdentityComparison < Base
|
19
21
|
extend AutoCorrector
|
20
22
|
|
21
|
-
MSG = 'Use
|
22
|
-
RESTRICT_ON_SEND = %i[==].freeze
|
23
|
+
MSG = 'Use `%<bang>sequal?` instead of `%<comparison_method>s` when comparing `object_id`.'
|
24
|
+
RESTRICT_ON_SEND = %i[== !=].freeze
|
25
|
+
|
26
|
+
# @!method object_id_comparison(node)
|
27
|
+
def_node_matcher :object_id_comparison, <<~PATTERN
|
28
|
+
(send
|
29
|
+
(send
|
30
|
+
_lhs_receiver :object_id) ${:== :!=}
|
31
|
+
(send
|
32
|
+
_rhs_receiver :object_id))
|
33
|
+
PATTERN
|
23
34
|
|
24
35
|
def on_send(node)
|
25
|
-
return unless
|
36
|
+
return unless (comparison_method = object_id_comparison(node))
|
26
37
|
|
27
|
-
|
38
|
+
bang = comparison_method == :== ? '' : '!'
|
39
|
+
add_offense(node,
|
40
|
+
message: format(MSG, comparison_method: comparison_method,
|
41
|
+
bang: bang)) do |corrector|
|
28
42
|
receiver = node.receiver.receiver
|
29
43
|
argument = node.first_argument.receiver
|
30
44
|
return unless receiver && argument
|
31
45
|
|
32
|
-
replacement = "#{receiver.source}.equal?(#{argument.source})"
|
46
|
+
replacement = "#{bang}#{receiver.source}.equal?(#{argument.source})"
|
33
47
|
|
34
48
|
corrector.replace(node, replacement)
|
35
49
|
end
|
36
50
|
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def compare_between_object_id_by_double_equal?(node)
|
41
|
-
object_id_method?(node.receiver) && object_id_method?(node.first_argument)
|
42
|
-
end
|
43
|
-
|
44
|
-
def object_id_method?(node)
|
45
|
-
node.send_type? && node.method?(:object_id)
|
46
|
-
end
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|