rubocop 1.75.8 → 1.82.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.
Files changed (229) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -16
  3. data/config/default.yml +142 -33
  4. data/config/obsoletion.yml +10 -3
  5. data/exe/rubocop +1 -8
  6. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  7. data/lib/rubocop/cli.rb +20 -4
  8. data/lib/rubocop/comment_config.rb +62 -17
  9. data/lib/rubocop/config_loader.rb +6 -40
  10. data/lib/rubocop/config_loader_resolver.rb +7 -6
  11. data/lib/rubocop/config_store.rb +5 -0
  12. data/lib/rubocop/cop/autocorrect_logic.rb +8 -4
  13. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
  14. data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -7
  15. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  16. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  17. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  18. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +0 -22
  19. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
  20. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  21. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
  22. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -1
  23. data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
  24. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +4 -4
  25. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  26. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +4 -1
  27. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +3 -2
  28. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  29. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  30. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  31. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  32. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -0
  34. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +30 -12
  35. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  36. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
  37. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  38. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  39. data/lib/rubocop/cop/layout/end_alignment.rb +4 -0
  40. data/lib/rubocop/cop/layout/hash_alignment.rb +2 -5
  41. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
  42. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -4
  43. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  44. data/lib/rubocop/cop/layout/indentation_width.rb +12 -1
  45. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  46. data/lib/rubocop/cop/layout/line_length.rb +43 -10
  47. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  48. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +5 -1
  49. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +8 -4
  50. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
  51. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  52. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  53. data/lib/rubocop/cop/layout/space_around_keyword.rb +7 -2
  54. data/lib/rubocop/cop/layout/space_around_operators.rb +8 -0
  55. data/lib/rubocop/cop/layout/space_before_brackets.rb +2 -9
  56. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -2
  57. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  58. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  59. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
  60. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  61. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
  62. data/lib/rubocop/cop/lint/debugger.rb +0 -2
  63. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
  64. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  65. data/lib/rubocop/cop/lint/duplicate_methods.rb +25 -4
  66. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  67. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  68. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  69. data/lib/rubocop/cop/lint/float_comparison.rb +4 -4
  70. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  71. data/lib/rubocop/cop/lint/literal_as_condition.rb +38 -28
  72. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  73. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
  74. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
  75. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +1 -0
  76. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  77. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  78. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
  79. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
  80. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +7 -1
  81. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +4 -4
  82. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  83. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  84. data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
  85. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +4 -4
  86. data/lib/rubocop/cop/lint/self_assignment.rb +39 -5
  87. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  88. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +5 -0
  89. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
  90. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  91. data/lib/rubocop/cop/lint/useless_access_modifier.rb +29 -4
  92. data/lib/rubocop/cop/lint/useless_assignment.rb +44 -16
  93. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  94. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +1 -0
  95. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  96. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +3 -3
  97. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  98. data/lib/rubocop/cop/lint/void.rb +7 -0
  99. data/lib/rubocop/cop/message_annotator.rb +1 -1
  100. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  101. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  102. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  103. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -4
  104. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  105. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  106. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  107. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  108. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +1 -1
  109. data/lib/rubocop/cop/mixin/line_length_help.rb +45 -10
  110. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  111. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  112. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  113. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  114. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  115. data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
  116. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
  117. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  118. data/lib/rubocop/cop/naming/method_name.rb +129 -13
  119. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  120. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +4 -4
  121. data/lib/rubocop/cop/security/eval.rb +2 -1
  122. data/lib/rubocop/cop/security/json_load.rb +33 -11
  123. data/lib/rubocop/cop/security/open.rb +1 -0
  124. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -1
  125. data/lib/rubocop/cop/style/accessor_grouping.rb +13 -1
  126. data/lib/rubocop/cop/style/arguments_forwarding.rb +11 -17
  127. data/lib/rubocop/cop/style/array_intersect.rb +99 -35
  128. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  129. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
  130. data/lib/rubocop/cop/style/bitwise_predicate.rb +8 -1
  131. data/lib/rubocop/cop/style/block_delimiters.rb +1 -1
  132. data/lib/rubocop/cop/style/case_equality.rb +11 -13
  133. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  135. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  136. data/lib/rubocop/cop/style/conditional_assignment.rb +12 -16
  137. data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
  138. data/lib/rubocop/cop/style/dig_chain.rb +1 -1
  139. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  140. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  141. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  142. data/lib/rubocop/cop/style/endless_method.rb +15 -2
  143. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
  144. data/lib/rubocop/cop/style/exponential_notation.rb +3 -2
  145. data/lib/rubocop/cop/style/fetch_env_var.rb +32 -6
  146. data/lib/rubocop/cop/style/float_division.rb +15 -1
  147. data/lib/rubocop/cop/style/guard_clause.rb +0 -11
  148. data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
  149. data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
  150. data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -9
  151. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  152. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  153. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  154. data/lib/rubocop/cop/style/it_block_parameter.rb +36 -15
  155. data/lib/rubocop/cop/style/map_to_hash.rb +1 -3
  156. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  157. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +4 -6
  158. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +33 -4
  160. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  161. data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
  162. data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
  163. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  164. data/lib/rubocop/cop/style/one_line_conditional.rb +17 -9
  165. data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
  166. data/lib/rubocop/cop/style/parallel_assignment.rb +34 -22
  167. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  168. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  169. data/lib/rubocop/cop/style/redundant_begin.rb +34 -0
  170. data/lib/rubocop/cop/style/redundant_condition.rb +1 -1
  171. data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
  172. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  173. data/lib/rubocop/cop/style/redundant_format.rb +26 -5
  174. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  175. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  176. data/lib/rubocop/cop/style/redundant_line_continuation.rb +1 -1
  177. data/lib/rubocop/cop/style/redundant_parentheses.rb +55 -16
  178. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  179. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
  180. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
  181. data/lib/rubocop/cop/style/redundant_self.rb +8 -5
  182. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  183. data/lib/rubocop/cop/style/safe_navigation.rb +44 -12
  184. data/lib/rubocop/cop/style/semicolon.rb +23 -7
  185. data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
  186. data/lib/rubocop/cop/style/sole_nested_conditional.rb +40 -3
  187. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  188. data/lib/rubocop/cop/style/string_concatenation.rb +17 -13
  189. data/lib/rubocop/cop/style/super_arguments.rb +2 -2
  190. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  191. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  192. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
  193. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  194. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
  195. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  196. data/lib/rubocop/cop/util.rb +2 -3
  197. data/lib/rubocop/cop/utils/format_string.rb +10 -0
  198. data/lib/rubocop/cop/variable_force/variable.rb +1 -1
  199. data/lib/rubocop/cop/variable_force.rb +25 -8
  200. data/lib/rubocop/cops_documentation_generator.rb +5 -4
  201. data/lib/rubocop/directive_comment.rb +46 -3
  202. data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -5
  203. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  204. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  205. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  206. data/lib/rubocop/formatter/pacman_formatter.rb +1 -0
  207. data/lib/rubocop/lsp/diagnostic.rb +14 -18
  208. data/lib/rubocop/lsp/routes.rb +35 -6
  209. data/lib/rubocop/lsp/stdin_runner.rb +0 -16
  210. data/lib/rubocop/magic_comment.rb +20 -0
  211. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  212. data/lib/rubocop/rake_task.rb +1 -1
  213. data/lib/rubocop/remote_config.rb +7 -8
  214. data/lib/rubocop/result_cache.rb +51 -38
  215. data/lib/rubocop/rspec/expect_offense.rb +9 -3
  216. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  217. data/lib/rubocop/rspec/support.rb +1 -1
  218. data/lib/rubocop/runner.rb +10 -4
  219. data/lib/rubocop/server/cache.rb +4 -2
  220. data/lib/rubocop/server/client_command/base.rb +10 -0
  221. data/lib/rubocop/server/client_command/exec.rb +2 -1
  222. data/lib/rubocop/server/client_command/start.rb +11 -1
  223. data/lib/rubocop/target_finder.rb +9 -9
  224. data/lib/rubocop/target_ruby.rb +11 -2
  225. data/lib/rubocop/version.rb +1 -1
  226. data/lib/rubocop.rb +13 -1
  227. data/lib/ruby_lsp/rubocop/addon.rb +25 -10
  228. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
  229. metadata +20 -8
@@ -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 ignore_cop_directives? && directive_on_source_line?(line_index)
263
+ if allow_cop_directives? && directive_on_source_line?(line_index)
259
264
  return check_directive_line(line, line_index)
260
265
  end
261
- return check_uri_line(line, line_index) if allow_uri?
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) ||
@@ -305,6 +311,7 @@ module RuboCop
305
311
  def max
306
312
  cop_config['Max']
307
313
  end
314
+ alias max_line_length max
308
315
 
309
316
  def allow_heredoc?
310
317
  allowed_heredoc
@@ -321,7 +328,7 @@ module RuboCop
321
328
  def extract_heredocs(ast)
322
329
  return [] unless ast
323
330
 
324
- ast.each_node(:str, :dstr, :xstr).select(&:heredoc?).map do |node|
331
+ ast.each_node(:any_str).select(&:heredoc?).map do |node|
325
332
  body = node.location.heredoc_body
326
333
  delimiter = node.location.heredoc_end.source.strip
327
334
  [body.first_line...body.last_line, delimiter]
@@ -341,6 +348,13 @@ module RuboCop
341
348
  heredocs.any? { |range, _delimiter| range.cover?(line_number) }
342
349
  end
343
350
 
351
+ def receiver_contains_heredoc?(node)
352
+ return false unless (receiver = node.receiver)
353
+ return true if receiver.any_str_type? && receiver.heredoc?
354
+
355
+ receiver.each_descendant(:any_str).any?(&:heredoc?)
356
+ end
357
+
344
358
  def check_directive_line(line, line_index)
345
359
  length_without_directive = line_length_without_directive(line)
346
360
  return if length_without_directive <= max
@@ -358,11 +372,32 @@ module RuboCop
358
372
  )
359
373
  end
360
374
 
361
- def check_uri_line(line, line_index)
362
- uri_range = find_excessive_uri_range(line)
363
- return if uri_range && allowed_uri_position?(line, uri_range)
375
+ def check_line_for_exemptions(line, line_index)
376
+ uri_range = range_if_applicable(line, :uri)
377
+ qualified_name_range = range_if_applicable(line, :qualified_name)
364
378
 
365
- register_offense(excess_range(uri_range, line, line_index), line, line_index)
379
+ return if allowed_combination?(line, uri_range, qualified_name_range)
380
+
381
+ range = uri_range || qualified_name_range
382
+ register_offense(excess_range(range, line, line_index), line, line_index)
383
+ end
384
+
385
+ def range_if_applicable(line, type)
386
+ return unless type == :uri ? allow_uri? : allow_qualified_name?
387
+
388
+ find_excessive_range(line, type)
389
+ end
390
+
391
+ def allowed_combination?(line, uri_range, qualified_name_range)
392
+ if uri_range && qualified_name_range
393
+ allowed_position?(line, uri_range) && allowed_position?(line, qualified_name_range)
394
+ elsif uri_range
395
+ allowed_position?(line, uri_range)
396
+ elsif qualified_name_range
397
+ allowed_position?(line, qualified_name_range)
398
+ else
399
+ false
400
+ end
366
401
  end
367
402
 
368
403
  def breakable_dstr?(node)
@@ -372,9 +407,7 @@ module RuboCop
372
407
 
373
408
  def string_delimiter(node)
374
409
  delimiter = node.loc.begin
375
- if node.parent&.dstr_type? && node.parent.loc.respond_to?(:begin)
376
- delimiter ||= node.parent.loc.begin
377
- end
410
+ delimiter ||= node.parent.loc.begin if node.parent&.dstr_type? && node.parent.loc?(:begin)
378
411
  delimiter = delimiter&.source
379
412
 
380
413
  delimiter if %w[' "].include?(delimiter)
@@ -78,6 +78,8 @@ module RuboCop
78
78
  end
79
79
 
80
80
  def line_break_necessary_in_args?(node)
81
+ return false unless max_line_length
82
+
81
83
  needed_length_for_args(node) > max_line_length
82
84
  end
83
85
 
@@ -84,19 +84,23 @@ module RuboCop
84
84
  end
85
85
  end
86
86
 
87
+ # rubocop:disable Metrics/AbcSize
87
88
  def offending_range(node, lhs, rhs, given_style)
88
89
  return false unless begins_its_line?(rhs)
89
90
  return false if not_for_this_cop?(node)
90
91
 
91
92
  @base = alignment_base(node, rhs, given_style)
92
93
  correct_column = if @base
93
- @base.column + extra_indentation(given_style, node.parent)
94
+ parent = node.parent
95
+ parent = parent.parent if parent&.any_block_type?
96
+ @base.column + extra_indentation(given_style, parent)
94
97
  else
95
98
  indentation(lhs) + correct_indentation(node)
96
99
  end
97
100
  @column_delta = correct_column - rhs.column
98
101
  rhs if @column_delta.nonzero?
99
102
  end
103
+ # rubocop:enable Metrics/AbcSize
100
104
 
101
105
  def extra_indentation(given_style, parent)
102
106
  if given_style == :indented_relative_to_receiver
@@ -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
- (kw_node_with_special_indentation(node) ||
105
- assignment_node ||
106
- argument_in_method_call(node, :with_or_without_parentheses))
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
@@ -23,16 +23,8 @@ module RuboCop
23
23
  cfg['EnforcedStyle'] || 'space'
24
24
  end
25
25
 
26
- def kind(token)
27
- 'comma' if token.comma? && !before_semicolon?(token)
28
- end
29
-
30
- private
31
-
32
- def before_semicolon?(token)
33
- tokens = processed_source.tokens
34
-
35
- tokens[tokens.index(token) + 1].semicolon?
26
+ def kind(token, next_token)
27
+ 'comma' if token.comma? && !next_token.semicolon?
36
28
  end
37
29
  end
38
30
  end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  cfg['EnforcedStyle'] || 'space'
21
21
  end
22
22
 
23
- def kind(token)
23
+ def kind(token, _next_token)
24
24
  'semicolon' if token.semicolon?
25
25
  end
26
26
 
@@ -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 return super yield].freeze
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
@@ -162,7 +167,7 @@ module RuboCop
162
167
 
163
168
  def check(node, locations, begin_keyword = DO)
164
169
  locations.each do |loc|
165
- next unless node.loc.respond_to?(loc)
170
+ next unless node.loc?(loc)
166
171
 
167
172
  range = node.loc.public_send(loc)
168
173
  next unless range
@@ -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(&:left_array_bracket?)
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].left_array_bracket?
200
+ processed_source.tokens_within(node)[i].left_bracket?
196
201
  end
197
202
  end
198
203
 
@@ -113,7 +113,7 @@ module RuboCop
113
113
  return [] unless ast
114
114
 
115
115
  heredocs = []
116
- ast.each_node(:str, :dstr, :xstr) do |node|
116
+ ast.each_node(:any_str) do |node|
117
117
  next unless node.heredoc?
118
118
 
119
119
  body = node.location.heredoc_body
@@ -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
 
@@ -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
- return unless arg_value.lvar_type?
55
- return unless arg_value.to_a == [arg_name]
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(arg_value, message: format(MSG, arg_name: arg_name))
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 nil? $_) nil?)
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
- add_offense(node.loc.assoc, message: format(MSG, constant: constant)) do |corrector|
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
- # # ^ missing comma
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
- # # good
31
- # # rubocop:disable Layout/LineLength, Style/Encoding
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 -- This is a good comment.
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 `todo`.'
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 `--`.'
@@ -102,8 +102,6 @@ module RuboCop
102
102
  end
103
103
 
104
104
  def debugger_method?(send_node)
105
- return false if send_node.parent&.send_type? && send_node.parent.receiver == send_node
106
-
107
105
  debugger_methods.include?(chained_method_name(send_node))
108
106
  end
109
107
 
@@ -118,8 +118,11 @@ module RuboCop
118
118
 
119
119
  def replacement_args(node)
120
120
  algorithm_constant, = algorithm_const(node)
121
- algorithm_name = algorithm_name(algorithm_constant)
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
@@ -25,17 +25,17 @@ module RuboCop
25
25
  #
26
26
  # # bad - repeated alternate patterns with the same conditions don't depend on the order
27
27
  # case x
28
- # in foo | bar
28
+ # in 0 | 1
29
29
  # first_method
30
- # in bar | foo
30
+ # in 1 | 0
31
31
  # second_method
32
32
  # end
33
33
  #
34
34
  # # good
35
35
  # case x
36
- # in foo | bar
36
+ # in 0 | 1
37
37
  # first_method
38
- # in bar | baz
38
+ # in 2 | 3
39
39
  # second_method
40
40
  # end
41
41
  #
@@ -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
- return unless (name = method_alias?(node))
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
- if (name = alias_method?(node))
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)