rubocop 1.69.2 → 1.73.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 (299) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +90 -13
  5. data/config/internal_affairs.yml +16 -0
  6. data/lib/rubocop/cli/command/execute_runner.rb +3 -3
  7. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  9. data/lib/rubocop/comment_config.rb +2 -2
  10. data/lib/rubocop/config.rb +17 -4
  11. data/lib/rubocop/config_loader.rb +48 -8
  12. data/lib/rubocop/config_loader_resolver.rb +35 -10
  13. data/lib/rubocop/config_validator.rb +19 -9
  14. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  15. data/lib/rubocop/cop/base.rb +6 -0
  16. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  18. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  19. data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
  20. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  21. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  22. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  23. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  24. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  25. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  26. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  27. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  28. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  29. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  30. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  31. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  32. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  33. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  34. data/lib/rubocop/cop/internal_affairs.rb +5 -16
  35. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  36. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
  37. data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
  38. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  39. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  40. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  41. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  42. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  43. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  44. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +27 -1
  45. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  46. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  47. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  48. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  49. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  50. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  51. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  52. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  53. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  54. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  55. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  56. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  57. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  58. data/lib/rubocop/cop/layout/line_length.rb +4 -3
  59. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  60. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  61. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
  62. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  63. data/lib/rubocop/cop/layout/redundant_line_break.rb +7 -6
  64. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  66. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  67. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  68. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  70. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
  71. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
  73. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  74. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  75. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  76. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  77. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  78. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  79. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
  80. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  81. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  82. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  83. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  84. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  85. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
  86. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  87. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  88. data/lib/rubocop/cop/lint/empty_conditional_body.rb +10 -5
  89. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  90. data/lib/rubocop/cop/lint/float_comparison.rb +6 -8
  91. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  92. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  93. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  94. data/lib/rubocop/cop/lint/literal_as_condition.rb +99 -9
  95. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  96. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  97. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
  98. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  99. data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -4
  100. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  101. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -3
  102. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  103. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
  104. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
  105. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  106. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  107. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  108. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  109. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +252 -0
  110. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  111. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
  112. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  113. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  114. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  115. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  116. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  117. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
  118. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  119. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  120. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  121. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  122. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  123. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  124. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  125. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  126. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  127. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  128. data/lib/rubocop/cop/lint/void.rb +11 -9
  129. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  130. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  131. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  132. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  133. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  134. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  135. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  136. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  137. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  138. data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -11
  139. data/lib/rubocop/cop/mixin/comments_help.rb +4 -2
  140. data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
  141. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  142. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  143. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  144. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  145. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  146. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  147. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
  148. data/lib/rubocop/cop/mixin/range_help.rb +3 -3
  149. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  150. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  151. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  152. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  153. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  154. data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
  155. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  156. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
  157. data/lib/rubocop/cop/naming/variable_name.rb +64 -6
  158. data/lib/rubocop/cop/security/compound_hash.rb +1 -0
  159. data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
  160. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  161. data/lib/rubocop/cop/style/and_or.rb +1 -1
  162. data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
  163. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  164. data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
  165. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  166. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  167. data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
  168. data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
  169. data/lib/rubocop/cop/style/commented_keyword.rb +1 -1
  170. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  171. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
  172. data/lib/rubocop/cop/style/documentation.rb +1 -1
  173. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  174. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  175. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  176. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  177. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  178. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  179. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  180. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  181. data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
  182. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  183. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  184. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  185. data/lib/rubocop/cop/style/float_division.rb +8 -4
  186. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  187. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
  188. data/lib/rubocop/cop/style/hash_except.rb +24 -148
  189. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  190. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  191. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  192. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  193. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
  194. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  195. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  196. data/lib/rubocop/cop/style/inverse_methods.rb +6 -6
  197. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  198. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  199. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  200. data/lib/rubocop/cop/style/map_into_array.rb +1 -1
  201. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  202. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  203. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -12
  204. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  205. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
  206. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  207. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  208. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  209. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  210. data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
  211. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  212. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  213. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  214. data/lib/rubocop/cop/style/object_then.rb +13 -15
  215. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  216. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
  217. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  218. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  219. data/lib/rubocop/cop/style/proc.rb +1 -2
  220. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  221. data/lib/rubocop/cop/style/raise_args.rb +6 -4
  222. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  223. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  224. data/lib/rubocop/cop/style/redundant_condition.rb +48 -2
  225. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  226. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  227. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  228. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  229. data/lib/rubocop/cop/style/redundant_format.rb +250 -0
  230. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  231. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  232. data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -13
  233. data/lib/rubocop/cop/style/redundant_parentheses.rb +28 -14
  234. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
  235. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  236. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  237. data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
  238. data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
  239. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  240. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  241. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  242. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  243. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  244. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  245. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
  246. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  247. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  248. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -2
  249. data/lib/rubocop/cop/style/string_concatenation.rb +2 -2
  250. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  251. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  252. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  253. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  254. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  255. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  256. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  257. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  258. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  259. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  260. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  261. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  262. data/lib/rubocop/cop/util.rb +12 -5
  263. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  264. data/lib/rubocop/cop/variable_force/variable.rb +14 -2
  265. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
  266. data/lib/rubocop/cops_documentation_generator.rb +25 -14
  267. data/lib/rubocop/directive_comment.rb +44 -10
  268. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  269. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  270. data/lib/rubocop/lsp/logger.rb +2 -2
  271. data/lib/rubocop/lsp/routes.rb +7 -23
  272. data/lib/rubocop/lsp/runtime.rb +17 -49
  273. data/lib/rubocop/lsp/server.rb +0 -2
  274. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  275. data/lib/rubocop/options.rb +28 -12
  276. data/lib/rubocop/path_util.rb +15 -8
  277. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  278. data/lib/rubocop/plugin/load_error.rb +26 -0
  279. data/lib/rubocop/plugin/loader.rb +100 -0
  280. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  281. data/lib/rubocop/plugin.rb +46 -0
  282. data/lib/rubocop/rake_task.rb +4 -1
  283. data/lib/rubocop/result_cache.rb +13 -13
  284. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  285. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  286. data/lib/rubocop/rspec/shared_contexts.rb +19 -1
  287. data/lib/rubocop/rspec/support.rb +2 -2
  288. data/lib/rubocop/runner.rb +5 -6
  289. data/lib/rubocop/server/cache.rb +35 -2
  290. data/lib/rubocop/server/cli.rb +2 -2
  291. data/lib/rubocop/target_finder.rb +1 -0
  292. data/lib/rubocop/target_ruby.rb +15 -0
  293. data/lib/rubocop/version.rb +17 -2
  294. data/lib/rubocop.rb +11 -1
  295. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  296. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  297. metadata +53 -16
  298. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  299. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -4,7 +4,12 @@ module RuboCop
4
4
  module Cop
5
5
  # Common functionality for checking whether an AST node/token is aligned
6
6
  # with something on a preceding or following line
7
+ # rubocop:disable Metrics/ModuleLength
7
8
  module PrecedingFollowingAlignment
9
+ # Tokens that end with an `=`, as well as `<<`, that can be aligned together:
10
+ # `=`, `==`, `===`, `!=`, `<=`, `>=`, `<<` and operator assignment (`+=`, etc).
11
+ ASSIGNMENT_OR_COMPARISON_TOKENS = %i[tEQL tEQ tEQQ tNEQ tLEQ tGEQ tOP_ASGN tLSHFT].freeze
12
+
8
13
  private
9
14
 
10
15
  def allow_for_alignment?
@@ -19,16 +24,20 @@ module RuboCop
19
24
  aligned_with_adjacent_line?(range, method(:aligned_operator?))
20
25
  end
21
26
 
22
- def aligned_with_preceding_assignment(token)
27
+ # Allows alignment with a preceding operator that ends with an `=`,
28
+ # including assignment and comparison operators.
29
+ def aligned_with_preceding_equals_operator(token)
23
30
  preceding_line_range = token.line.downto(1)
24
31
 
25
- aligned_with_assignment(token, preceding_line_range)
32
+ aligned_with_equals_sign(token, preceding_line_range)
26
33
  end
27
34
 
28
- def aligned_with_subsequent_assignment(token)
35
+ # Allows alignment with a subsequent operator that ends with an `=`,
36
+ # including assignment and comparison operators.
37
+ def aligned_with_subsequent_equals_operator(token)
29
38
  subsequent_line_range = token.line.upto(processed_source.lines.length)
30
39
 
31
- aligned_with_assignment(token, subsequent_line_range)
40
+ aligned_with_equals_sign(token, subsequent_line_range)
32
41
  end
33
42
 
34
43
  def aligned_with_adjacent_line?(range, predicate)
@@ -75,11 +84,11 @@ module RuboCop
75
84
  end
76
85
 
77
86
  def aligned_token?(range, line, lineno)
78
- aligned_words?(range, line) || aligned_assignment?(range, lineno)
87
+ aligned_words?(range, line) || aligned_equals_operator?(range, lineno)
79
88
  end
80
89
 
81
90
  def aligned_operator?(range, line, lineno)
82
- aligned_identical?(range, line) || aligned_assignment?(range, lineno)
91
+ aligned_identical?(range, line) || aligned_equals_operator?(range, lineno)
83
92
  end
84
93
 
85
94
  def aligned_words?(range, line)
@@ -90,22 +99,24 @@ module RuboCop
90
99
  token == line[left_edge, token.length]
91
100
  end
92
101
 
93
- def aligned_assignment?(range, lineno)
94
- # Check that assignment is aligned with a previous assignment operator
95
- # ie. an equals sign, an operator assignment, or an append operator (`<<`)
102
+ def aligned_equals_operator?(range, lineno)
103
+ # Check that the operator is aligned with a previous assignment or comparison operator
104
+ # ie. an equals sign, an operator assignment (eg. `+=`), a comparison (`==`, `<=`, etc.).
105
+ # Since append operators (`<<`) are a type of assignment, they are allowed as well,
106
+ # despite not ending with a literal equals character.
96
107
  line_range = processed_source.buffer.line_range(lineno)
97
108
  return false unless line_range
98
109
 
99
110
  # Find the specific token to avoid matching up to operators inside strings
100
- assignment_token = processed_source.tokens_within(line_range).detect do |token|
101
- token.equal_sign? || token.type == :tLSHFT
111
+ operator_token = processed_source.tokens_within(line_range).detect do |token|
112
+ ASSIGNMENT_OR_COMPARISON_TOKENS.include?(token.type)
102
113
  end
103
114
 
104
- aligned_with_preceding_assignment?(range, assignment_token) ||
105
- aligned_with_append_operator?(range, assignment_token)
115
+ aligned_with_preceding_equals?(range, operator_token) ||
116
+ aligned_with_append_operator?(range, operator_token)
106
117
  end
107
118
 
108
- def aligned_with_preceding_assignment?(range, token)
119
+ def aligned_with_preceding_equals?(range, token)
109
120
  return false unless token
110
121
 
111
122
  range.source[-1] == '=' && range.last_column == token.pos.last_column
@@ -123,7 +134,7 @@ module RuboCop
123
134
  range.source == line[range.column, range.size]
124
135
  end
125
136
 
126
- def aligned_with_assignment(token, line_range)
137
+ def aligned_with_equals_sign(token, line_range)
127
138
  token_line_indent = processed_source.line_indentation(token.line)
128
139
  assignment_lines = relevant_assignment_lines(line_range)
129
140
  relevant_line_number = assignment_lines[1]
@@ -135,7 +146,7 @@ module RuboCop
135
146
  return :none if relevant_indent < token_line_indent
136
147
  return :none unless processed_source.lines[relevant_line_number - 1]
137
148
 
138
- aligned_assignment?(token.pos, relevant_line_number) ? :yes : :no
149
+ aligned_equals_operator?(token.pos, relevant_line_number) ? :yes : :no
139
150
  end
140
151
 
141
152
  def assignment_lines
@@ -146,10 +157,14 @@ module RuboCop
146
157
  @assignment_tokens ||= begin
147
158
  tokens = processed_source.tokens.select(&:equal_sign?)
148
159
 
149
- # we don't want to operate on equals signs which are part of an
150
- # optarg in a method definition
151
- # e.g.: def method(optarg = default_val); end
152
- tokens = remove_optarg_equals(tokens, processed_source)
160
+ # We don't want to operate on equals signs which are part of an `optarg` in a
161
+ # method definition, or the separator of an endless method definition.
162
+ # For example (the equals sign to ignore is highlighted with ^):
163
+ # def method(optarg = default_val); end
164
+ # ^
165
+ # def method = foo
166
+ # ^
167
+ tokens = remove_equals_in_def(tokens, processed_source)
153
168
 
154
169
  # Only attempt to align the first = on each line
155
170
  Set.new(tokens.uniq(&:line))
@@ -185,11 +200,20 @@ module RuboCop
185
200
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
186
201
  # rubocop:enable Metrics/PerceivedComplexity, Metrics/MethodLength
187
202
 
188
- def remove_optarg_equals(asgn_tokens, processed_source)
189
- optargs = processed_source.ast.each_node(:optarg)
190
- optarg_eql = optargs.to_set { |o| o.loc.operator.begin_pos }
191
- asgn_tokens.reject { |t| optarg_eql.include?(t.begin_pos) }
203
+ def remove_equals_in_def(asgn_tokens, processed_source)
204
+ nodes = processed_source.ast.each_node(:optarg, :def)
205
+ eqls_to_ignore = nodes.with_object([]) do |node, arr|
206
+ loc = if node.def_type?
207
+ node.loc.assignment if node.endless?
208
+ else
209
+ node.loc.operator
210
+ end
211
+ arr << loc.begin_pos if loc
212
+ end
213
+
214
+ asgn_tokens.reject { |t| eqls_to_ignore.include?(t.begin_pos) }
192
215
  end
193
216
  end
217
+ # rubocop:enable Metrics/ModuleLength
194
218
  end
195
219
  end
@@ -4,9 +4,10 @@ module RuboCop
4
4
  module Cop
5
5
  # Methods that calculate and return Parser::Source::Ranges
6
6
  module RangeHelp
7
- private
8
-
9
7
  BYTE_ORDER_MARK = 0xfeff # The Unicode codepoint
8
+ NOT_GIVEN = Module.new
9
+
10
+ private
10
11
 
11
12
  def source_range(source_buffer, line_number, column, length = 1)
12
13
  if column.is_a?(Range)
@@ -51,7 +52,6 @@ module RuboCop
51
52
  Parser::Source::Range.new(buffer, begin_pos, end_pos)
52
53
  end
53
54
 
54
- NOT_GIVEN = Module.new
55
55
  def range_with_surrounding_space(range_positional = NOT_GIVEN, # rubocop:disable Metrics/ParameterLists
56
56
  range: NOT_GIVEN, side: :both, newlines: true,
57
57
  whitespace: false, continuations: false,
@@ -36,7 +36,7 @@ module RuboCop
36
36
  end
37
37
 
38
38
  def space_required_after?(token)
39
- (token.left_curly_brace? || token.type == :tLAMBEG) && space_required_after_lcurly?
39
+ token.left_curly_brace? && space_required_after_lcurly?
40
40
  end
41
41
 
42
42
  def space_required_after_lcurly?
@@ -55,14 +55,19 @@ module RuboCop
55
55
  end
56
56
 
57
57
  def if_body_source(if_body)
58
- if if_body.call_type? &&
59
- if_body.last_argument&.hash_type? && if_body.last_argument.pairs.last&.value_omission?
58
+ if if_body.call_type? && !if_body.method?(:[]=) && omitted_value_in_last_hash_arg?(if_body)
60
59
  "#{method_source(if_body)}(#{if_body.arguments.map(&:source).join(', ')})"
61
60
  else
62
61
  if_body.source
63
62
  end
64
63
  end
65
64
 
65
+ def omitted_value_in_last_hash_arg?(if_body)
66
+ return false unless (last_argument = if_body.last_argument)
67
+
68
+ last_argument.hash_type? && last_argument.pairs.last&.value_omission?
69
+ end
70
+
66
71
  def method_source(if_body)
67
72
  end_range = if_body.implicit_call? ? if_body.loc.dot.end : if_body.loc.selector
68
73
 
@@ -96,7 +101,7 @@ module RuboCop
96
101
  end
97
102
 
98
103
  def max_line_length
99
- return unless config.for_cop('Layout/LineLength')['Enabled']
104
+ return unless config.cop_enabled?('Layout/LineLength')
100
105
 
101
106
  config.for_cop('Layout/LineLength')['Max']
102
107
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  def on_str(node)
11
11
  # Constants like __FILE__ are handled as strings,
12
12
  # but don't respond to begin.
13
- return unless node.loc.respond_to?(:begin) && node.loc.begin
13
+ return unless node.loc?(:begin)
14
14
  return if part_of_ignored_node?(node)
15
15
 
16
16
  if offense?(node)
@@ -33,7 +33,7 @@ module RuboCop
33
33
  # A :begin node inside a :dstr, :dsym, or :regexp node is an interpolation.
34
34
  node.ancestors
35
35
  .drop_while { |a| !a.begin_type? }
36
- .any? { |a| a.dstr_type? || a.dsym_type? || a.regexp_type? }
36
+ .any? { |a| a.type?(:dstr, :dsym, :regexp) }
37
37
  end
38
38
  end
39
39
  end
@@ -26,7 +26,7 @@ module RuboCop
26
26
  end
27
27
 
28
28
  def string_literals_config
29
- config.for_cop('Style/StringLiterals')
29
+ config.for_enabled_cop('Style/StringLiterals')
30
30
  end
31
31
  end
32
32
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  module RuboCop
4
4
  module Cop
5
- # Common methods shared by Style/TrailingCommaInArguments and
6
- # Style/TrailingCommaInLiteral
5
+ # Common methods shared by Style/TrailingCommaInArguments,
6
+ # Style/TrailingCommaInArrayLiteral and Style/TrailingCommaInHashLiteral
7
+ # rubocop:disable Metrics/ModuleLength
7
8
  module TrailingComma
8
9
  include ConfigurableEnforcedStyle
9
10
  include RangeHelp
@@ -57,6 +58,8 @@ module RuboCop
57
58
  ', unless each item is on its own line'
58
59
  when :consistent_comma
59
60
  ', unless items are split onto multiple lines'
61
+ when :diff_comma
62
+ ', unless that item immediately precedes a newline'
60
63
  else
61
64
  ''
62
65
  end
@@ -68,6 +71,8 @@ module RuboCop
68
71
  multiline?(node) && no_elements_on_same_line?(node)
69
72
  when :consistent_comma
70
73
  multiline?(node) && !method_name_and_arguments_on_same_line?(node)
74
+ when :diff_comma
75
+ multiline?(node) && last_item_precedes_newline?(node)
71
76
  else
72
77
  false
73
78
  end
@@ -130,6 +135,12 @@ module RuboCop
130
135
  range1.last_line == range2.line
131
136
  end
132
137
 
138
+ def last_item_precedes_newline?(node)
139
+ after_last_item =
140
+ range_between(node.children.last.source_range.end_pos, node.loc.end.begin_pos)
141
+ after_last_item.source =~ /\A,?\s*\n/
142
+ end
143
+
133
144
  def avoid_comma(kind, comma_begin_pos, extra_info)
134
145
  range = range_between(comma_begin_pos, comma_begin_pos + 1)
135
146
  article = kind.include?('array') ? 'an' : 'a'
@@ -181,7 +192,7 @@ module RuboCop
181
192
  # ...
182
193
  # SOURCE
183
194
  # })
184
- return heredoc?(node.children.last) if node.pair_type? || node.hash_type?
195
+ return heredoc?(node.children.last) if node.type?(:pair, :hash)
185
196
 
186
197
  false
187
198
  end
@@ -205,5 +216,6 @@ module RuboCop
205
216
  false
206
217
  end
207
218
  end
219
+ # rubocop:enable Metrics/ModuleLength
208
220
  end
209
221
  end
@@ -13,6 +13,20 @@ module RuboCop
13
13
  # The default variable name is `block`. If the name is already in use, it will not be
14
14
  # autocorrected.
15
15
  #
16
+ # [NOTE]
17
+ # ====
18
+ # Because of a bug in Ruby 3.3.0, when a block is referenced inside of another block,
19
+ # no offense will be registered until Ruby 3.4:
20
+ #
21
+ # [source,ruby]
22
+ # ----
23
+ # def foo(&block)
24
+ # # Using an anonymous block would be a syntax error on Ruby 3.3.0
25
+ # block_method { bar(&block) }
26
+ # end
27
+ # ----
28
+ # ====
29
+ #
16
30
  # @example EnforcedStyle: anonymous (default)
17
31
  #
18
32
  # # bad
@@ -90,21 +104,11 @@ module RuboCop
90
104
  last_argument.source == block_pass_node.source
91
105
  end
92
106
 
93
- # Prevents the following syntax error:
94
- #
95
- # # foo.rb
96
- # def foo(&)
97
- # block_method do
98
- # bar(&)
99
- # end
100
- # end
101
- #
102
- # $ ruby -vc foo.rb
103
- # ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
104
- # foo.rb: foo.rb:4: anonymous block parameter is also used within block (SyntaxError)
105
- #
107
+ # Ruby 3.3.0 had a bug where accessing an anonymous block argument inside of a block
108
+ # was a syntax error in unambiguous cases: https://bugs.ruby-lang.org/issues/20090
109
+ # We disallow this also for earlier Ruby versions so that code is forwards compatible.
106
110
  def invalidates_syntax?(block_pass_node)
107
- block_pass_node.each_ancestor(:block, :numblock).any?
111
+ target_ruby_version <= 3.3 && block_pass_node.each_ancestor(:any_block).any?
108
112
  end
109
113
 
110
114
  def use_kwarg_in_method_definition?(node)
@@ -138,7 +142,7 @@ module RuboCop
138
142
  def use_block_argument_as_local_variable?(node, last_argument)
139
143
  return false if node.body.nil?
140
144
 
141
- node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
145
+ node.body.each_node(:lvar, :lvasgn).any? do |lvar|
142
146
  !lvar.parent.block_pass_type? && lvar.node_parts[0].to_s == last_argument
143
147
  end
144
148
  end
@@ -17,6 +17,10 @@ module RuboCop
17
17
  # they end with a `?`. These methods should be changed to remove the
18
18
  # prefix.
19
19
  #
20
+ # When `UseSorbetSigs` set to true (optional), the cop will only report
21
+ # offenses if the method has a Sorbet `sig` with a return type of
22
+ # `T::Boolean`. Dynamic methods are not supported with this configuration.
23
+ #
20
24
  # @example NamePrefix: ['is_', 'has_', 'have_'] (default)
21
25
  # # bad
22
26
  # def is_even(value)
@@ -58,6 +62,30 @@ module RuboCop
58
62
  # def is_even?(value)
59
63
  # end
60
64
  #
65
+ # @example UseSorbetSigs: false (default)
66
+ # # bad
67
+ # sig { returns(String) }
68
+ # def is_this_thing_on
69
+ # "yes"
70
+ # end
71
+ #
72
+ # # good - Sorbet signature is not evaluated
73
+ # sig { returns(String) }
74
+ # def is_this_thing_on?
75
+ # "yes"
76
+ # end
77
+ #
78
+ # @example UseSorbetSigs: true
79
+ # # bad
80
+ # sig { returns(T::Boolean) }
81
+ # def odd(value)
82
+ # end
83
+ #
84
+ # # good
85
+ # sig { returns(T::Boolean) }
86
+ # def odd?(value)
87
+ # end
88
+ #
61
89
  # @example MethodDefinitionMacros: ['define_method', 'define_singleton_method'] (default)
62
90
  # # bad
63
91
  # define_method(:is_even) { |value| }
@@ -100,6 +128,7 @@ module RuboCop
100
128
  method_name = node.method_name.to_s
101
129
 
102
130
  next if allowed_method_name?(method_name, prefix)
131
+ next if use_sorbet_sigs? && !sorbet_sig?(node, return_type: 'T::Boolean')
103
132
 
104
133
  add_offense(
105
134
  node.loc.name,
@@ -121,6 +150,17 @@ module RuboCop
121
150
 
122
151
  private
123
152
 
153
+ # @!method sorbet_return_type(node)
154
+ def_node_matcher :sorbet_return_type, <<~PATTERN
155
+ (block (send nil? :sig) args (send _ :returns $_type))
156
+ PATTERN
157
+
158
+ def sorbet_sig?(node, return_type: nil)
159
+ return false unless (type = sorbet_return_type(node.left_sibling))
160
+
161
+ type.source == return_type
162
+ end
163
+
124
164
  def allowed_method_name?(method_name, prefix)
125
165
  !(method_name.start_with?(prefix) && # cheap check to avoid allocating Regexp
126
166
  method_name.match?(/^#{prefix}[^0-9]/)) ||
@@ -151,6 +191,10 @@ module RuboCop
151
191
  cop_config['NamePrefix']
152
192
  end
153
193
 
194
+ def use_sorbet_sigs?
195
+ cop_config['UseSorbetSigs']
196
+ end
197
+
154
198
  def method_definition_macros(macro_name)
155
199
  cop_config['MethodDefinitionMacros'].include?(macro_name.to_s)
156
200
  end
@@ -113,7 +113,7 @@ module RuboCop
113
113
  end
114
114
  end
115
115
 
116
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
116
+ # rubocop:disable Metrics/MethodLength
117
117
  def correct_node(corrector, node, offending_name, preferred_name)
118
118
  return unless node
119
119
 
@@ -129,13 +129,13 @@ module RuboCop
129
129
  end
130
130
  end
131
131
 
132
- if child_node.masgn_type? || child_node.lvasgn_type?
132
+ if child_node.type?(:masgn, :lvasgn)
133
133
  correct_reassignment(corrector, child_node, offending_name, preferred_name)
134
134
  break
135
135
  end
136
136
  end
137
137
  end
138
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
138
+ # rubocop:enable Metrics/MethodLength
139
139
 
140
140
  # If the exception variable is reassigned, that assignment needs to be corrected.
141
141
  # Further `lvar` nodes will not be corrected though since they now refer to a
@@ -3,8 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Naming
6
- # Makes sure that all variables use the configured style,
7
- # snake_case or camelCase, for their names.
6
+ # Checks that the configured style (snake_case or camelCase) is used for all variable names.
7
+ # This includes local variables, instance variables, class variables, method arguments
8
+ # (positional, keyword, rest or block), and block arguments.
9
+ #
10
+ # The cop can also be configured to forbid using specific names for variables, using
11
+ # `ForbiddenIdentifiers` or `ForbiddenPatterns`. In addition to the above, this applies
12
+ # to global variables as well.
13
+ #
14
+ # Method definitions and method calls are not affected by this cop.
8
15
  #
9
16
  # @example EnforcedStyle: snake_case (default)
10
17
  # # bad
@@ -26,7 +33,21 @@ module RuboCop
26
33
  #
27
34
  # @example AllowedPatterns: ['_v\d+\z']
28
35
  # # good (with EnforcedStyle: camelCase)
29
- # :release_v1
36
+ # release_v1 = true
37
+ #
38
+ # @example ForbiddenIdentifiers: ['fooBar']
39
+ # # bad (in all cases)
40
+ # fooBar = 1
41
+ # @fooBar = 1
42
+ # @@fooBar = 1
43
+ # $fooBar = 1
44
+ #
45
+ # @example ForbiddenPatterns: ['_v\d+\z']
46
+ # # bad (in all cases)
47
+ # release_v1 = true
48
+ # @release_v1 = true
49
+ # @@release_v1 = true
50
+ # $release_v1 = true
30
51
  #
31
52
  class VariableName < Base
32
53
  include AllowedIdentifiers
@@ -34,16 +55,21 @@ module RuboCop
34
55
  include AllowedPattern
35
56
 
36
57
  MSG = 'Use %<style>s for variable names.'
58
+ MSG_FORBIDDEN = '`%<identifier>s` is forbidden, use another name instead.'
37
59
 
38
60
  def valid_name?(node, name, given_style = style)
39
61
  super || matches_allowed_pattern?(name)
40
62
  end
41
63
 
42
64
  def on_lvasgn(node)
43
- return unless node.name
44
- return if allowed_identifier?(node.name)
65
+ return unless (name = node.name)
66
+ return if allowed_identifier?(name)
45
67
 
46
- check_name(node, node.name, node.loc.name)
68
+ if forbidden_name?(name)
69
+ register_forbidden_name(node)
70
+ else
71
+ check_name(node, name, node.loc.name)
72
+ end
47
73
  end
48
74
  alias on_ivasgn on_lvasgn
49
75
  alias on_cvasgn on_lvasgn
@@ -56,11 +82,43 @@ module RuboCop
56
82
  alias on_blockarg on_lvasgn
57
83
  alias on_lvar on_lvasgn
58
84
 
85
+ # Only forbidden names are checked for global variable assignment
86
+ def on_gvasgn(node)
87
+ return unless (name = node.name)
88
+ return unless forbidden_name?(name)
89
+
90
+ register_forbidden_name(node)
91
+ end
92
+
59
93
  private
60
94
 
61
95
  def message(style)
62
96
  format(MSG, style: style)
63
97
  end
98
+
99
+ def forbidden_identifiers
100
+ cop_config.fetch('ForbiddenIdentifiers', [])
101
+ end
102
+
103
+ def forbidden_patterns
104
+ cop_config.fetch('ForbiddenPatterns', [])
105
+ end
106
+
107
+ def matches_forbidden_pattern?(name)
108
+ forbidden_patterns.any? { |pattern| Regexp.new(pattern).match?(name) }
109
+ end
110
+
111
+ def forbidden_name?(name)
112
+ name = name.to_s.delete(SIGILS)
113
+
114
+ (forbidden_identifiers.any? && forbidden_identifiers.include?(name)) ||
115
+ (forbidden_patterns.any? && matches_forbidden_pattern?(name))
116
+ end
117
+
118
+ def register_forbidden_name(node)
119
+ message = format(MSG_FORBIDDEN, identifier: node.name)
120
+ add_offense(node.loc.name, message: message)
121
+ end
64
122
  end
65
123
  end
66
124
  end
@@ -100,6 +100,7 @@ module RuboCop
100
100
  add_offense(node, message: REDUNDANT_HASH_MSG)
101
101
  end
102
102
  end
103
+ alias on_csend on_send
103
104
  alias on_op_asgn on_send
104
105
  end
105
106
  end
@@ -112,6 +112,26 @@ module RuboCop
112
112
  # private attr :quux
113
113
  #
114
114
  # end
115
+ #
116
+ # @example AllowModifiersOnAliasMethod: true (default)
117
+ # # good
118
+ # class Foo
119
+ #
120
+ # public alias_method :bar, :foo
121
+ # protected alias_method :baz, :foo
122
+ # private alias_method :qux, :foo
123
+ #
124
+ # end
125
+ #
126
+ # @example AllowModifiersOnAliasMethod: false
127
+ # # bad
128
+ # class Foo
129
+ #
130
+ # public alias_method :bar, :foo
131
+ # protected alias_method :baz, :foo
132
+ # private alias_method :qux, :foo
133
+ #
134
+ # end
115
135
  class AccessModifierDeclarations < Base
116
136
  extend AutoCorrector
117
137
 
@@ -130,8 +150,6 @@ module RuboCop
130
150
 
131
151
  RESTRICT_ON_SEND = %i[private protected public module_function].freeze
132
152
 
133
- ALLOWED_NODE_TYPES = %i[pair block].freeze
134
-
135
153
  # @!method access_modifier_with_symbol?(node)
136
154
  def_node_matcher :access_modifier_with_symbol?, <<~PATTERN
137
155
  (send nil? {:private :protected :public :module_function}
@@ -145,6 +163,12 @@ module RuboCop
145
163
  (send nil? {:attr :attr_reader :attr_writer :attr_accessor} _+))
146
164
  PATTERN
147
165
 
166
+ # @!method access_modifier_with_alias_method?, <<~PATTERN
167
+ def_node_matcher :access_modifier_with_alias_method?, <<~PATTERN
168
+ (send nil? {:private :protected :public :module_function}
169
+ (send nil? :alias_method _ _))
170
+ PATTERN
171
+
148
172
  def on_send(node)
149
173
  return if allowed?(node)
150
174
 
@@ -162,9 +186,10 @@ module RuboCop
162
186
 
163
187
  def allowed?(node)
164
188
  !node.access_modifier? ||
165
- ALLOWED_NODE_TYPES.include?(node.parent&.type) ||
189
+ node.parent&.type?(:pair, :any_block) ||
166
190
  allow_modifiers_on_symbols?(node) ||
167
- allow_modifiers_on_attrs?(node)
191
+ allow_modifiers_on_attrs?(node) ||
192
+ allow_modifiers_on_alias_method?(node)
168
193
  end
169
194
 
170
195
  def autocorrect(corrector, node)
@@ -194,6 +219,10 @@ module RuboCop
194
219
  cop_config['AllowModifiersOnAttrs'] && access_modifier_with_attr?(node)
195
220
  end
196
221
 
222
+ def allow_modifiers_on_alias_method?(node)
223
+ cop_config['AllowModifiersOnAliasMethod'] && access_modifier_with_alias_method?(node)
224
+ end
225
+
197
226
  def offense?(node)
198
227
  (group_style? && access_modifier_is_inlined?(node) &&
199
228
  !node.parent&.if_type? && !right_siblings_same_inline_method?(node)) ||
@@ -281,7 +310,7 @@ module RuboCop
281
310
  argument_less_modifier_node = find_argument_less_modifier_node(node)
282
311
  if argument_less_modifier_node
283
312
  corrector.insert_after(argument_less_modifier_node, "\n\n#{source}")
284
- elsif (ancestor = node.each_ancestor(:block, :class, :module).first)
313
+ elsif (ancestor = node.each_ancestor(:class, :module).first)
285
314
 
286
315
  corrector.insert_before(ancestor.loc.end, "#{node.method_name}\n\n#{source}\n")
287
316
  else