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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -13
  3. data/config/default.yml +79 -23
  4. data/config/obsoletion.yml +6 -3
  5. data/lib/rubocop/config_validator.rb +6 -6
  6. data/lib/rubocop/cop/autocorrect_logic.rb +18 -10
  7. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  8. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
  9. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  10. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
  11. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +1 -0
  12. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +6 -1
  13. data/lib/rubocop/cop/layout/class_structure.rb +35 -0
  14. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  15. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +6 -2
  16. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -1
  17. data/lib/rubocop/cop/layout/hash_alignment.rb +2 -2
  18. data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
  19. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
  20. data/lib/rubocop/cop/layout/space_after_semicolon.rb +10 -0
  21. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -32
  22. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +5 -1
  23. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  24. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  25. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  26. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -5
  27. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  28. data/lib/rubocop/cop/lint/duplicate_methods.rb +84 -2
  29. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  30. data/lib/rubocop/cop/lint/float_comparison.rb +27 -0
  31. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  32. data/lib/rubocop/cop/lint/literal_as_condition.rb +31 -25
  33. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  34. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
  35. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -0
  36. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
  37. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  38. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  39. data/lib/rubocop/cop/lint/void.rb +2 -2
  40. data/lib/rubocop/cop/message_annotator.rb +7 -3
  41. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  42. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  43. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
  44. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  45. data/lib/rubocop/cop/mixin/trailing_comma.rb +9 -5
  46. data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
  47. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +2 -2
  48. data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -10
  49. data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -5
  50. data/lib/rubocop/cop/style/class_and_module_children.rb +19 -3
  51. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  52. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  53. data/lib/rubocop/cop/style/comparable_between.rb +5 -2
  54. data/lib/rubocop/cop/style/conditional_assignment.rb +15 -6
  55. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  56. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  57. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  58. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  59. data/lib/rubocop/cop/style/hash_fetch_chain.rb +0 -1
  60. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  61. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  62. data/lib/rubocop/cop/style/identical_conditional_branches.rb +3 -3
  63. data/lib/rubocop/cop/style/if_unless_modifier.rb +22 -4
  64. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  65. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
  66. data/lib/rubocop/cop/style/it_block_parameter.rb +33 -14
  67. data/lib/rubocop/cop/style/lambda_call.rb +7 -2
  68. data/lib/rubocop/cop/style/map_into_array.rb +3 -1
  69. data/lib/rubocop/cop/style/map_to_hash.rb +11 -0
  70. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -1
  71. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  72. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  73. data/lib/rubocop/cop/style/redundant_array_flatten.rb +48 -0
  74. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +1 -1
  75. data/lib/rubocop/cop/style/redundant_format.rb +6 -1
  76. data/lib/rubocop/cop/style/redundant_line_continuation.rb +0 -3
  77. data/lib/rubocop/cop/style/redundant_parentheses.rb +31 -3
  78. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  79. data/lib/rubocop/cop/style/safe_navigation.rb +28 -10
  80. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -2
  81. data/lib/rubocop/cop/style/string_concatenation.rb +1 -2
  82. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  83. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +7 -1
  84. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
  85. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
  86. data/lib/rubocop/cop/team.rb +1 -1
  87. data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
  88. data/lib/rubocop/cops_documentation_generator.rb +6 -2
  89. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  90. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  91. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  92. data/lib/rubocop/rspec/cop_helper.rb +2 -2
  93. data/lib/rubocop/rspec/shared_contexts.rb +1 -2
  94. data/lib/rubocop/target_finder.rb +5 -1
  95. data/lib/rubocop/version.rb +1 -1
  96. data/lib/rubocop.rb +6 -1
  97. 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.type?(:match_pattern, :match_pattern_p)
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.children
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{./+}.freeze
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
- formatted_string = format(string, *argument_values(arguments))
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, :def, :any_block)
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.arithmetic_operation? && node.first_argument.begin_type?
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
- begin_node = begin_node.parent if node.range_type?
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') ['PreferredDelimiters']['%r'].chars
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 != rhs_receiver || rhs_receiver.nil?
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 == checked_variable
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
- send_node.assignment? ||
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
- (node.call_type? && node.arguments.any? && !node.parenthesized?)
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) : contents_range(part).source
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
@@ -279,7 +279,7 @@ module RuboCop
279
279
  @errors << message
280
280
  warn message
281
281
  if debug?
282
- puts error.message, error.backtrace
282
+ puts error.full_message
283
283
  else
284
284
  warn 'To see the complete backtrace run rubocop -d.'
285
285
  end
@@ -110,8 +110,13 @@ module RuboCop
110
110
  end
111
111
 
112
112
  def multiple_assignment_node
113
- return nil unless node.parent&.mlhs_type?
114
- return nil unless (grandparent_node = node.parent&.parent)
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
- AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
331
- VersionChanged
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require 'cgi/escape'
4
4
  require 'erb'
5
5
 
6
6
  module RuboCop
@@ -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((@total_files - (cols * @repetitions)))
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.4.
15
- ruby_version >= 3.5 ? :parser_prism : ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym
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
 
@@ -267,6 +267,5 @@ RSpec.shared_context 'ruby 3.4' do
267
267
  end
268
268
 
269
269
  RSpec.shared_context 'ruby 3.5' do
270
- # Parser supports parsing Ruby <= 3.4.
271
- let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.5 : 3.4 }
270
+ let(:ruby_version) { 3.5 }
272
271
  end
@@ -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 = all_files.select { |file| to_inspect?(file, hidden_files, base_dir_config) }
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
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.75.2'
6
+ STRING = '1.76.0'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
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/predicate_name'
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'