rubocop 1.75.2 → 1.76.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 +19 -13
- data/config/default.yml +79 -23
- data/config/obsoletion.yml +6 -3
- data/lib/rubocop/config_validator.rb +6 -6
- data/lib/rubocop/cop/autocorrect_logic.rb +18 -10
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +6 -1
- data/lib/rubocop/cop/layout/class_structure.rb +35 -0
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -2
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -32
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -1
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +84 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +27 -0
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/literal_as_condition.rb +31 -25
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +2 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/void.rb +2 -2
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +9 -5
- data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -10
- data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -5
- data/lib/rubocop/cop/style/class_and_module_children.rb +19 -3
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
- data/lib/rubocop/cop/style/comparable_between.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +15 -6
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +0 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +22 -4
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/it_block_parameter.rb +33 -14
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +3 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +11 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +48 -0
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +6 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +0 -3
- data/lib/rubocop/cop/style/redundant_parentheses.rb +31 -3
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +28 -10
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +1 -2
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +7 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cops_documentation_generator.rb +6 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +2 -2
- data/lib/rubocop/rspec/shared_contexts.rb +1 -2
- data/lib/rubocop/target_finder.rb +5 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +6 -1
- metadata +12 -7
|
@@ -45,6 +45,11 @@ module RuboCop
|
|
|
45
45
|
}
|
|
46
46
|
PATTERN
|
|
47
47
|
|
|
48
|
+
# @!method destructuring_argument(node)
|
|
49
|
+
def_node_matcher :destructuring_argument, <<~PATTERN
|
|
50
|
+
(args $(mlhs (arg _)+))
|
|
51
|
+
PATTERN
|
|
52
|
+
|
|
48
53
|
def self.autocorrect_incompatible_with
|
|
49
54
|
[Layout::SingleLineBlockChain]
|
|
50
55
|
end
|
|
@@ -73,6 +78,12 @@ module RuboCop
|
|
|
73
78
|
corrector.replace(map_dot, to_h.loc.dot.source)
|
|
74
79
|
end
|
|
75
80
|
corrector.replace(map.loc.selector, 'to_h')
|
|
81
|
+
|
|
82
|
+
return unless map.parent.block_type?
|
|
83
|
+
|
|
84
|
+
if (argument = destructuring_argument(map.parent.arguments))
|
|
85
|
+
corrector.replace(argument, argument.source[1..-2])
|
|
86
|
+
end
|
|
76
87
|
end
|
|
77
88
|
# rubocop:enable Metrics/AbcSize
|
|
78
89
|
end
|
|
@@ -167,7 +167,7 @@ module RuboCop
|
|
|
167
167
|
def call_in_match_pattern?(node)
|
|
168
168
|
return false unless (parent = node.parent)
|
|
169
169
|
|
|
170
|
-
parent.
|
|
170
|
+
parent.any_match_pattern_type?
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
def hash_literal_in_arguments?(node)
|
|
@@ -222,6 +222,9 @@ module RuboCop
|
|
|
222
222
|
end
|
|
223
223
|
|
|
224
224
|
def unary_literal?(node)
|
|
225
|
+
# NOTE: should be removed after releasing https://github.com/rubocop/rubocop-ast/pull/379
|
|
226
|
+
return node.source.match?(/\A[+-]/) if node.complex_type?
|
|
227
|
+
|
|
225
228
|
(node.numeric_type? && node.sign?) ||
|
|
226
229
|
(node.parent&.send_type? && node.parent.unary_operation?)
|
|
227
230
|
end
|
|
@@ -23,11 +23,13 @@ module RuboCop
|
|
|
23
23
|
'clause in a multiline statement.'
|
|
24
24
|
|
|
25
25
|
def on_if(node)
|
|
26
|
+
return if part_of_ignored_node?(node)
|
|
26
27
|
return unless node.modifier_form? && node.body.multiline?
|
|
27
28
|
|
|
28
29
|
add_offense(node, message: format(MSG, keyword: node.keyword)) do |corrector|
|
|
29
30
|
corrector.replace(node, to_normal_if(node))
|
|
30
31
|
end
|
|
32
|
+
ignore_node(node)
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
private
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
|
45
45
|
# Report offense only if changing case doesn't change semantics,
|
|
46
46
|
# i.e., if the string would become dynamic or has special characters.
|
|
47
47
|
ast = parse(corrected(node.source)).ast
|
|
48
|
-
return if node.children != ast
|
|
48
|
+
return if node.children != ast&.children
|
|
49
49
|
|
|
50
50
|
add_offense(node.loc.begin) do |corrector|
|
|
51
51
|
corrector.replace(node, corrected(node.source))
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for redundant calls of `Array#flatten`.
|
|
7
|
+
#
|
|
8
|
+
# `Array#join` joins nested arrays recursively, so flattening an array
|
|
9
|
+
# beforehand is redundant.
|
|
10
|
+
#
|
|
11
|
+
# @safety
|
|
12
|
+
# Cop is unsafe because the receiver of `flatten` method might not
|
|
13
|
+
# be an `Array`, so it's possible it won't respond to `join` method,
|
|
14
|
+
# or the end result would be different.
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# # bad
|
|
18
|
+
# x.flatten.join
|
|
19
|
+
# x.flatten(1).join
|
|
20
|
+
#
|
|
21
|
+
# # good
|
|
22
|
+
# x.join
|
|
23
|
+
#
|
|
24
|
+
class RedundantArrayFlatten < Base
|
|
25
|
+
extend AutoCorrector
|
|
26
|
+
|
|
27
|
+
MSG = 'Remove the redundant `flatten`.'
|
|
28
|
+
|
|
29
|
+
RESTRICT_ON_SEND = %i[flatten].freeze
|
|
30
|
+
|
|
31
|
+
# @!method flatten_join?(node)
|
|
32
|
+
def_node_matcher :flatten_join?, <<~PATTERN
|
|
33
|
+
(call (call !nil? :flatten _?) :join _?)
|
|
34
|
+
PATTERN
|
|
35
|
+
|
|
36
|
+
def on_send(node)
|
|
37
|
+
return unless flatten_join?(node.parent)
|
|
38
|
+
|
|
39
|
+
range = node.loc.dot.begin.join(node.source_range.end)
|
|
40
|
+
add_offense(range) do |corrector|
|
|
41
|
+
corrector.remove(range)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
alias on_csend on_send
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
|
20
20
|
|
|
21
21
|
MSG = 'Remove the redundant current directory path.'
|
|
22
22
|
RESTRICT_ON_SEND = %i[require_relative].freeze
|
|
23
|
-
CURRENT_DIRECTORY_PREFIX = %r{
|
|
23
|
+
CURRENT_DIRECTORY_PREFIX = %r{\./+}.freeze
|
|
24
24
|
REDUNDANT_CURRENT_DIRECTORY_PREFIX = /\A#{CURRENT_DIRECTORY_PREFIX}/.freeze
|
|
25
25
|
|
|
26
26
|
def on_send(node)
|
|
@@ -121,7 +121,12 @@ module RuboCop
|
|
|
121
121
|
def register_all_fields_literal(node, string, arguments)
|
|
122
122
|
return unless all_fields_literal?(string, arguments.dup)
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
format_arguments = argument_values(arguments)
|
|
125
|
+
begin
|
|
126
|
+
formatted_string = format(string, *format_arguments)
|
|
127
|
+
rescue ArgumentError
|
|
128
|
+
return
|
|
129
|
+
end
|
|
125
130
|
replacement = quote(formatted_string, node)
|
|
126
131
|
|
|
127
132
|
add_offense(node, message: message(node, replacement)) do |corrector|
|
|
@@ -181,9 +181,7 @@ module RuboCop
|
|
|
181
181
|
ARGUMENT_TYPES.include?(next_token.type)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
# rubocop:disable Metrics/AbcSize
|
|
185
184
|
def argument_newline?(node)
|
|
186
|
-
node = node.to_a.last if node.assignment?
|
|
187
185
|
return false if node.parenthesized_call?
|
|
188
186
|
|
|
189
187
|
node = node.children.first if node.root? && node.begin_type?
|
|
@@ -196,7 +194,6 @@ module RuboCop
|
|
|
196
194
|
node.loc.selector.line != node.first_argument.loc.line
|
|
197
195
|
end
|
|
198
196
|
end
|
|
199
|
-
# rubocop:enable Metrics/AbcSize
|
|
200
197
|
|
|
201
198
|
def find_node_for_line(last_line)
|
|
202
199
|
processed_source.ast.each_node do |node|
|
|
@@ -49,6 +49,7 @@ module RuboCop
|
|
|
49
49
|
empty_parentheses?(node) ||
|
|
50
50
|
first_arg_begins_with_hash_literal?(node) ||
|
|
51
51
|
rescue?(node) ||
|
|
52
|
+
in_pattern_matching_in_method_argument?(node) ||
|
|
52
53
|
allowed_pin_operator?(node) ||
|
|
53
54
|
allowed_expression?(node)
|
|
54
55
|
end
|
|
@@ -78,7 +79,7 @@ module RuboCop
|
|
|
78
79
|
ancestor = node.ancestors.first
|
|
79
80
|
return false unless ancestor
|
|
80
81
|
|
|
81
|
-
!ancestor.type?(:begin, :
|
|
82
|
+
!ancestor.type?(:begin, :any_def, :any_block)
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
def allowed_ternary?(node)
|
|
@@ -98,7 +99,7 @@ module RuboCop
|
|
|
98
99
|
return false unless node.type?(:send, :super, :yield)
|
|
99
100
|
|
|
100
101
|
node.arguments.one? && !node.parenthesized? &&
|
|
101
|
-
!node.
|
|
102
|
+
!node.operator_method? && node.first_argument.begin_type?
|
|
102
103
|
end
|
|
103
104
|
|
|
104
105
|
def multiline_control_flow_statements?(node)
|
|
@@ -122,6 +123,13 @@ module RuboCop
|
|
|
122
123
|
hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
|
|
123
124
|
end
|
|
124
125
|
|
|
126
|
+
def in_pattern_matching_in_method_argument?(begin_node)
|
|
127
|
+
return false unless begin_node.parent&.call_type?
|
|
128
|
+
return false unless (node = begin_node.children.first)
|
|
129
|
+
|
|
130
|
+
target_ruby_version <= 2.7 ? node.match_pattern_type? : node.match_pattern_p_type?
|
|
131
|
+
end
|
|
132
|
+
|
|
125
133
|
def method_chain_begins_with_hash_literal(node)
|
|
126
134
|
return if node.nil?
|
|
127
135
|
return node if node.hash_type?
|
|
@@ -134,7 +142,9 @@ module RuboCop
|
|
|
134
142
|
node = begin_node.children.first
|
|
135
143
|
|
|
136
144
|
if (message = find_offense_message(begin_node, node))
|
|
137
|
-
|
|
145
|
+
if node.range_type? && !argument_of_parenthesized_method_call?(begin_node, node)
|
|
146
|
+
begin_node = begin_node.parent
|
|
147
|
+
end
|
|
138
148
|
|
|
139
149
|
return offense(begin_node, message)
|
|
140
150
|
end
|
|
@@ -154,7 +164,10 @@ module RuboCop
|
|
|
154
164
|
if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
|
|
155
165
|
return 'an expression'
|
|
156
166
|
end
|
|
167
|
+
|
|
168
|
+
return 'a one-line pattern matching' if node.any_match_pattern_type?
|
|
157
169
|
return 'an interpolated expression' if interpolation?(begin_node)
|
|
170
|
+
return 'a method argument' if argument_of_parenthesized_method_call?(begin_node, node)
|
|
158
171
|
|
|
159
172
|
return if begin_node.chained?
|
|
160
173
|
|
|
@@ -177,6 +190,21 @@ module RuboCop
|
|
|
177
190
|
# @!method interpolation?(node)
|
|
178
191
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
|
179
192
|
|
|
193
|
+
def argument_of_parenthesized_method_call?(begin_node, node)
|
|
194
|
+
if node.basic_conditional? || node.rescue_type? || method_call_parentheses_required?(node)
|
|
195
|
+
return false
|
|
196
|
+
end
|
|
197
|
+
return false unless (parent = begin_node.parent)
|
|
198
|
+
|
|
199
|
+
parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def method_call_parentheses_required?(node)
|
|
203
|
+
return false unless node.call_type?
|
|
204
|
+
|
|
205
|
+
(node.receiver.nil? || node.loc.dot) && node.arguments.any?
|
|
206
|
+
end
|
|
207
|
+
|
|
180
208
|
def allow_in_multiline_conditions?
|
|
181
209
|
!!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
|
|
182
210
|
end
|
|
@@ -155,7 +155,7 @@ module RuboCop
|
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
def preferred_delimiters
|
|
158
|
-
config.for_cop('Style/PercentLiteralDelimiters')
|
|
158
|
+
config.for_cop('Style/PercentLiteralDelimiters')['PreferredDelimiters']['%r'].chars
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def allowed_omit_parentheses_with_percent_r_literal?(node)
|
|
@@ -174,12 +174,17 @@ module RuboCop
|
|
|
174
174
|
range_with_surrounding_space(range: lhs.source_range, side: :right),
|
|
175
175
|
range_with_surrounding_space(range: lhs_operator_range, side: :right),
|
|
176
176
|
offense_range: range_between(lhs.source_range.begin_pos, rhs.source_range.end_pos)
|
|
177
|
-
)
|
|
177
|
+
) do |corrector|
|
|
178
|
+
corrector.replace(rhs_receiver, lhs_receiver.source)
|
|
179
|
+
end
|
|
180
|
+
ignore_node(node)
|
|
178
181
|
end
|
|
179
182
|
end
|
|
180
183
|
|
|
181
184
|
def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
|
|
182
185
|
add_offense(offense_range) do |corrector|
|
|
186
|
+
next if ignored_node?(node)
|
|
187
|
+
|
|
183
188
|
# If the RHS is an `or` we cannot safely autocorrect because in order to remove
|
|
184
189
|
# the non-nil check we need to add safe-navs to all clauses where the receiver is used
|
|
185
190
|
next if and_with_rhs_or?(node)
|
|
@@ -227,10 +232,10 @@ module RuboCop
|
|
|
227
232
|
end
|
|
228
233
|
|
|
229
234
|
def offending_node?(node, lhs_receiver, rhs, rhs_receiver) # rubocop:disable Metrics/CyclomaticComplexity
|
|
230
|
-
return false if lhs_receiver
|
|
235
|
+
return false if !matching_nodes?(lhs_receiver, rhs_receiver) || rhs_receiver.nil?
|
|
231
236
|
return false if use_var_only_in_unless_modifier?(node, lhs_receiver)
|
|
232
237
|
return false if chain_length(rhs, rhs_receiver) > max_chain_length
|
|
233
|
-
return false if unsafe_method_used?(rhs, rhs_receiver.parent)
|
|
238
|
+
return false if unsafe_method_used?(node, rhs, rhs_receiver.parent)
|
|
234
239
|
return false if rhs.send_type? && rhs.method?(:empty?)
|
|
235
240
|
|
|
236
241
|
true
|
|
@@ -306,11 +311,21 @@ module RuboCop
|
|
|
306
311
|
|
|
307
312
|
receiver = method_chain.receiver
|
|
308
313
|
|
|
309
|
-
return receiver if receiver
|
|
314
|
+
return receiver if matching_nodes?(receiver, checked_variable)
|
|
310
315
|
|
|
311
316
|
find_matching_receiver_invocation(receiver, checked_variable)
|
|
312
317
|
end
|
|
313
318
|
|
|
319
|
+
def matching_nodes?(left, right)
|
|
320
|
+
left == right || matching_call_nodes?(left, right)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def matching_call_nodes?(left, right)
|
|
324
|
+
return false unless left && right.respond_to?(:call_type?)
|
|
325
|
+
|
|
326
|
+
left.call_type? && right.call_type? && left.children == right.children
|
|
327
|
+
end
|
|
328
|
+
|
|
314
329
|
def chain_length(method_chain, method)
|
|
315
330
|
method.each_ancestor(:call).inject(0) do |total, ancestor|
|
|
316
331
|
break total + 1 if ancestor == method_chain
|
|
@@ -319,21 +334,24 @@ module RuboCop
|
|
|
319
334
|
end
|
|
320
335
|
end
|
|
321
336
|
|
|
322
|
-
def unsafe_method_used?(method_chain, method)
|
|
323
|
-
return true if unsafe_method?(method)
|
|
337
|
+
def unsafe_method_used?(node, method_chain, method)
|
|
338
|
+
return true if unsafe_method?(node, method)
|
|
324
339
|
|
|
325
340
|
method.each_ancestor(:send).any? do |ancestor|
|
|
326
341
|
break true unless config.cop_enabled?('Lint/SafeNavigationChain')
|
|
327
342
|
|
|
328
|
-
break true if unsafe_method?(ancestor)
|
|
343
|
+
break true if unsafe_method?(node, ancestor)
|
|
329
344
|
break true if nil_methods.include?(ancestor.method_name)
|
|
330
345
|
break false if ancestor == method_chain
|
|
331
346
|
end
|
|
332
347
|
end
|
|
333
348
|
|
|
334
|
-
def unsafe_method?(send_node)
|
|
335
|
-
negated?(send_node)
|
|
336
|
-
|
|
349
|
+
def unsafe_method?(node, send_node)
|
|
350
|
+
return true if negated?(send_node)
|
|
351
|
+
|
|
352
|
+
return false if node.respond_to?(:ternary?) && node.ternary?
|
|
353
|
+
|
|
354
|
+
send_node.assignment? ||
|
|
337
355
|
(!send_node.dot? && !send_node.safe_navigation?)
|
|
338
356
|
end
|
|
339
357
|
|
|
@@ -185,8 +185,10 @@ module RuboCop
|
|
|
185
185
|
end
|
|
186
186
|
|
|
187
187
|
def add_parentheses?(node)
|
|
188
|
-
node.assignment? || (node.operator_keyword? && !node.and_type?)
|
|
189
|
-
|
|
188
|
+
return true if node.assignment? || (node.operator_keyword? && !node.and_type?)
|
|
189
|
+
return false unless node.call_type?
|
|
190
|
+
|
|
191
|
+
(node.arguments.any? && !node.parenthesized?) || node.prefix_not?
|
|
190
192
|
end
|
|
191
193
|
|
|
192
194
|
def parenthesized_method_arguments(node)
|
|
@@ -51,7 +51,6 @@ module RuboCop
|
|
|
51
51
|
# Pathname.new('/') + 'test'
|
|
52
52
|
#
|
|
53
53
|
class StringConcatenation < Base
|
|
54
|
-
include RangeHelp
|
|
55
54
|
extend AutoCorrector
|
|
56
55
|
|
|
57
56
|
MSG = 'Prefer string interpolation to string concatenation.'
|
|
@@ -147,7 +146,7 @@ module RuboCop
|
|
|
147
146
|
when :str
|
|
148
147
|
adjust_str(part)
|
|
149
148
|
when :dstr
|
|
150
|
-
part.children.all?(&:str_type?) ? adjust_str(part) :
|
|
149
|
+
part.children.all?(&:str_type?) ? adjust_str(part) : part.value
|
|
151
150
|
else
|
|
152
151
|
"\#{#{part.source}}"
|
|
153
152
|
end
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks for inheritance from Struct.new.
|
|
6
|
+
# Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
|
|
7
|
+
# adds a superfluous level in inheritance tree.
|
|
7
8
|
#
|
|
8
9
|
# @safety
|
|
9
10
|
# Autocorrection is unsafe because it will change the inheritance
|
|
@@ -17,12 +18,18 @@ module RuboCop
|
|
|
17
18
|
# end
|
|
18
19
|
# end
|
|
19
20
|
#
|
|
21
|
+
# Person.ancestors
|
|
22
|
+
# # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
|
|
23
|
+
#
|
|
20
24
|
# # good
|
|
21
25
|
# Person = Struct.new(:first_name, :last_name) do
|
|
22
26
|
# def age
|
|
23
27
|
# 42
|
|
24
28
|
# end
|
|
25
29
|
# end
|
|
30
|
+
#
|
|
31
|
+
# Person.ancestors
|
|
32
|
+
# # => [Person, Struct, (...)]
|
|
26
33
|
class StructInheritance < Base
|
|
27
34
|
include RangeHelp
|
|
28
35
|
extend AutoCorrector
|
|
@@ -79,10 +79,16 @@ module RuboCop
|
|
|
79
79
|
# # bad
|
|
80
80
|
# method(1, 2,)
|
|
81
81
|
#
|
|
82
|
+
# # bad
|
|
83
|
+
# object[1, 2,]
|
|
84
|
+
#
|
|
82
85
|
# # good
|
|
83
86
|
# method(1, 2)
|
|
84
87
|
#
|
|
85
88
|
# # good
|
|
89
|
+
# object[1, 2]
|
|
90
|
+
#
|
|
91
|
+
# # good
|
|
86
92
|
# method(
|
|
87
93
|
# 1,
|
|
88
94
|
# 2
|
|
@@ -96,7 +102,7 @@ module RuboCop
|
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
def on_send(node)
|
|
99
|
-
return unless node.arguments? && node.parenthesized?
|
|
105
|
+
return unless node.arguments? && (node.parenthesized? || node.method?(:[]))
|
|
100
106
|
|
|
101
107
|
check(node, node.arguments, 'parameter of %<article>s method call',
|
|
102
108
|
node.last_argument.source_range.end_pos,
|
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
|
11
11
|
# * `comma`: Requires a comma after the last item in an array, but only when each item is on
|
|
12
12
|
# its own line.
|
|
13
13
|
# * `diff_comma`: Requires a comma after the last item in an array, but only when that item is
|
|
14
|
-
# followed by an immediate newline.
|
|
14
|
+
# followed by an immediate newline, even if there is an inline comment on the same line.
|
|
15
15
|
# * `no_comma`: Does not require a comma after the last item in an array
|
|
16
16
|
#
|
|
17
17
|
# @example EnforcedStyleForMultiline: consistent_comma
|
|
@@ -11,7 +11,7 @@ module RuboCop
|
|
|
11
11
|
# * `comma`: Requires a comma after the last item in a hash, but only when each item is on its
|
|
12
12
|
# own line.
|
|
13
13
|
# * `diff_comma`: Requires a comma after the last item in a hash, but only when that item is
|
|
14
|
-
# followed by an immediate newline.
|
|
14
|
+
# followed by an immediate newline, even if there is an inline comment on the same line.
|
|
15
15
|
# * `no_comma`: Does not require a comma after the last item in a hash
|
|
16
16
|
#
|
|
17
17
|
# @example EnforcedStyleForMultiline: consistent_comma
|
data/lib/rubocop/cop/team.rb
CHANGED
|
@@ -110,8 +110,13 @@ module RuboCop
|
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
def multiple_assignment_node
|
|
113
|
-
return nil unless node.parent
|
|
114
|
-
|
|
113
|
+
return nil unless (candidate_mlhs_node = node.parent)
|
|
114
|
+
|
|
115
|
+
# In `(foo, bar), *baz`, the splat node must be traversed as well.
|
|
116
|
+
candidate_mlhs_node = candidate_mlhs_node.parent if candidate_mlhs_node.splat_type?
|
|
117
|
+
|
|
118
|
+
return nil unless candidate_mlhs_node.mlhs_type?
|
|
119
|
+
return nil unless (grandparent_node = node.parent.parent)
|
|
115
120
|
if (node = find_multiple_assignment_node(grandparent_node))
|
|
116
121
|
return node
|
|
117
122
|
end
|
|
@@ -139,7 +144,6 @@ module RuboCop
|
|
|
139
144
|
|
|
140
145
|
def find_multiple_assignment_node(grandparent_node)
|
|
141
146
|
return unless grandparent_node.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
|
|
142
|
-
return if grandparent_node.children.any?(&:splat_type?)
|
|
143
147
|
|
|
144
148
|
parent = grandparent_node.parent
|
|
145
149
|
return parent if parent.type == MULTIPLE_ASSIGNMENT_TYPE
|
|
@@ -327,8 +327,12 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
|
327
327
|
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
|
328
328
|
cop_config = config.for_cop(cop)
|
|
329
329
|
non_display_keys = %w[
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
Enabled
|
|
331
|
+
Description
|
|
332
|
+
StyleGuide
|
|
333
|
+
Reference References
|
|
334
|
+
Safe SafeAutoCorrect AutoCorrect
|
|
335
|
+
VersionAdded VersionChanged
|
|
332
336
|
]
|
|
333
337
|
parameters = cop_config.reject { |k| non_display_keys.include? k }
|
|
334
338
|
description = 'No documentation'
|
|
@@ -164,7 +164,7 @@ module RuboCop
|
|
|
164
164
|
|
|
165
165
|
def cop_config_params(default_cfg, cfg)
|
|
166
166
|
default_cfg.keys -
|
|
167
|
-
%w[Description StyleGuide Reference Enabled Exclude Safe
|
|
167
|
+
%w[Description StyleGuide Reference References Enabled Exclude Safe
|
|
168
168
|
SafeAutoCorrect VersionAdded VersionChanged VersionRemoved] -
|
|
169
169
|
cfg.keys
|
|
170
170
|
end
|
|
@@ -178,6 +178,7 @@ module RuboCop
|
|
|
178
178
|
next unless value.is_a?(Array)
|
|
179
179
|
next if value.empty?
|
|
180
180
|
|
|
181
|
+
value.map! { |v| v.nil? ? '~' : v } # Change nil back to ~ as in the YAML file.
|
|
181
182
|
output_buffer.puts "# #{param}: #{value.uniq.join(', ')}"
|
|
182
183
|
end
|
|
183
184
|
end
|
|
@@ -58,7 +58,7 @@ module RuboCop
|
|
|
58
58
|
return pacdots(@total_files) unless @total_files > cols
|
|
59
59
|
return pacdots(cols) unless (@total_files / cols).eql?(@repetitions)
|
|
60
60
|
|
|
61
|
-
pacdots(
|
|
61
|
+
pacdots(@total_files - (cols * @repetitions))
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def pacdots(number)
|
|
@@ -11,8 +11,8 @@ module CopHelper
|
|
|
11
11
|
ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
|
|
12
12
|
end
|
|
13
13
|
let(:parser_engine) do
|
|
14
|
-
# The maximum version Parser can parse is 3.
|
|
15
|
-
ruby_version >= 3.
|
|
14
|
+
# The maximum version Parser can correctly parse is 3.3.
|
|
15
|
+
ruby_version >= 3.4 ? :parser_prism : ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym
|
|
16
16
|
end
|
|
17
17
|
let(:rails_version) { false }
|
|
18
18
|
|
|
@@ -46,7 +46,11 @@ module RuboCop
|
|
|
46
46
|
hidden_files = all_files.select { |file| file.include?(HIDDEN_PATH_SUBSTRING) }.sort
|
|
47
47
|
base_dir_config = @config_store.for(base_dir)
|
|
48
48
|
|
|
49
|
-
target_files =
|
|
49
|
+
target_files = if base_dir.include?(HIDDEN_PATH_SUBSTRING)
|
|
50
|
+
all_files.select { |file| ruby_file?(file) }
|
|
51
|
+
else
|
|
52
|
+
all_files.select { |file| to_inspect?(file, hidden_files, base_dir_config) }
|
|
53
|
+
end
|
|
50
54
|
|
|
51
55
|
target_files.sort_by!(&order)
|
|
52
56
|
end
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
|
@@ -430,10 +430,12 @@ require_relative 'rubocop/cop/lint/uri_regexp'
|
|
|
430
430
|
require_relative 'rubocop/cop/lint/useless_access_modifier'
|
|
431
431
|
require_relative 'rubocop/cop/lint/useless_assignment'
|
|
432
432
|
require_relative 'rubocop/cop/lint/useless_constant_scoping'
|
|
433
|
+
require_relative 'rubocop/cop/lint/useless_default_value_argument'
|
|
433
434
|
require_relative 'rubocop/cop/lint/useless_defined'
|
|
434
435
|
require_relative 'rubocop/cop/lint/useless_else_without_rescue'
|
|
435
436
|
require_relative 'rubocop/cop/lint/useless_method_definition'
|
|
436
437
|
require_relative 'rubocop/cop/lint/useless_numeric_operation'
|
|
438
|
+
require_relative 'rubocop/cop/lint/useless_or'
|
|
437
439
|
require_relative 'rubocop/cop/lint/useless_rescue'
|
|
438
440
|
require_relative 'rubocop/cop/lint/useless_ruby2_keywords'
|
|
439
441
|
require_relative 'rubocop/cop/lint/useless_setter_call'
|
|
@@ -469,7 +471,8 @@ require_relative 'rubocop/cop/naming/memoized_instance_variable_name'
|
|
|
469
471
|
require_relative 'rubocop/cop/naming/method_name'
|
|
470
472
|
require_relative 'rubocop/cop/naming/method_parameter_name'
|
|
471
473
|
require_relative 'rubocop/cop/naming/binary_operator_parameter_name'
|
|
472
|
-
require_relative 'rubocop/cop/naming/
|
|
474
|
+
require_relative 'rubocop/cop/naming/predicate_method'
|
|
475
|
+
require_relative 'rubocop/cop/naming/predicate_prefix'
|
|
473
476
|
require_relative 'rubocop/cop/naming/rescued_exceptions_variable_name'
|
|
474
477
|
require_relative 'rubocop/cop/naming/variable_name'
|
|
475
478
|
require_relative 'rubocop/cop/naming/variable_number'
|
|
@@ -538,6 +541,7 @@ require_relative 'rubocop/cop/style/empty_heredoc'
|
|
|
538
541
|
require_relative 'rubocop/cop/style/empty_lambda_parameter'
|
|
539
542
|
require_relative 'rubocop/cop/style/empty_literal'
|
|
540
543
|
require_relative 'rubocop/cop/style/empty_method'
|
|
544
|
+
require_relative 'rubocop/cop/style/empty_string_inside_interpolation'
|
|
541
545
|
require_relative 'rubocop/cop/style/endless_method'
|
|
542
546
|
require_relative 'rubocop/cop/style/encoding'
|
|
543
547
|
require_relative 'rubocop/cop/style/end_block'
|
|
@@ -604,6 +608,7 @@ require_relative 'rubocop/cop/style/numbered_parameters'
|
|
|
604
608
|
require_relative 'rubocop/cop/style/open_struct_use'
|
|
605
609
|
require_relative 'rubocop/cop/style/operator_method_call'
|
|
606
610
|
require_relative 'rubocop/cop/style/redundant_array_constructor'
|
|
611
|
+
require_relative 'rubocop/cop/style/redundant_array_flatten'
|
|
607
612
|
require_relative 'rubocop/cop/style/redundant_assignment'
|
|
608
613
|
require_relative 'rubocop/cop/style/redundant_constant_base'
|
|
609
614
|
require_relative 'rubocop/cop/style/redundant_current_directory_in_path'
|