rubocop 1.53.0 → 1.90.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 (797) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +93 -88
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +949 -185
  7. data/config/internal_affairs.yml +31 -0
  8. data/config/obsoletion.yml +43 -4
  9. data/exe/rubocop +2 -8
  10. data/lib/rubocop/cache_config.rb +29 -0
  11. data/lib/rubocop/cached_data.rb +28 -7
  12. data/lib/rubocop/cli/command/auto_generate_config.rb +63 -18
  13. data/lib/rubocop/cli/command/execute_runner.rb +35 -4
  14. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  15. data/lib/rubocop/cli/command/lsp.rb +4 -4
  16. data/lib/rubocop/cli/command/mcp.rb +19 -0
  17. data/lib/rubocop/cli/command/show_cops.rb +26 -4
  18. data/lib/rubocop/cli/command/show_docs_url.rb +5 -9
  19. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  20. data/lib/rubocop/cli/command/version.rb +2 -2
  21. data/lib/rubocop/cli.rb +60 -16
  22. data/lib/rubocop/comment_config/directive_range.rb +32 -0
  23. data/lib/rubocop/comment_config/disable_next.rb +97 -0
  24. data/lib/rubocop/comment_config.rb +123 -49
  25. data/lib/rubocop/config.rb +180 -35
  26. data/lib/rubocop/config_finder.rb +15 -5
  27. data/lib/rubocop/config_loader.rb +83 -59
  28. data/lib/rubocop/config_loader_resolver.rb +65 -25
  29. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  30. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  31. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  32. data/lib/rubocop/config_obsoletion.rb +56 -9
  33. data/lib/rubocop/config_store.rb +7 -2
  34. data/lib/rubocop/config_validator.rb +76 -21
  35. data/lib/rubocop/cop/autocorrect_logic.rb +70 -25
  36. data/lib/rubocop/cop/badge.rb +8 -0
  37. data/lib/rubocop/cop/base.rb +151 -30
  38. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -2
  39. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  40. data/lib/rubocop/cop/bundler/gem_comment.rb +6 -4
  41. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  42. data/lib/rubocop/cop/bundler/gem_version.rb +32 -33
  43. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  44. data/lib/rubocop/cop/bundler/ordered_gems.rb +11 -4
  45. data/lib/rubocop/cop/bundler.rb +19 -0
  46. data/lib/rubocop/cop/commissioner.rb +13 -11
  47. data/lib/rubocop/cop/cop.rb +30 -4
  48. data/lib/rubocop/cop/corrector.rb +4 -4
  49. data/lib/rubocop/cop/correctors/alignment_corrector.rb +80 -22
  50. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  51. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +5 -9
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +13 -16
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +14 -5
  54. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  55. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  56. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  57. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +37 -3
  58. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  59. data/lib/rubocop/cop/correctors.rb +28 -0
  60. data/lib/rubocop/cop/documentation.rb +31 -5
  61. data/lib/rubocop/cop/exclude_limit.rb +32 -6
  62. data/lib/rubocop/cop/force.rb +12 -0
  63. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  64. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  65. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  66. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -4
  67. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  68. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +51 -19
  69. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +11 -4
  70. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  71. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -3
  72. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +15 -10
  73. data/lib/rubocop/cop/gemspec.rb +22 -0
  74. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  75. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  76. data/lib/rubocop/cop/generator.rb +10 -0
  77. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  78. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  79. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  80. data/lib/rubocop/cop/internal_affairs/example_description.rb +51 -25
  81. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  82. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  83. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  84. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  85. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +7 -5
  86. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  87. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  88. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +54 -0
  89. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +132 -39
  90. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  91. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +130 -0
  92. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  93. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  94. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  95. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  96. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  97. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  98. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  99. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  100. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  101. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  102. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  103. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  104. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  105. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  106. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  107. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  108. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +23 -2
  109. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +6 -9
  110. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  111. data/lib/rubocop/cop/internal_affairs.rb +10 -0
  112. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  113. data/lib/rubocop/cop/layout/argument_alignment.rb +4 -11
  114. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  115. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  116. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -2
  117. data/lib/rubocop/cop/layout/block_alignment.rb +89 -17
  118. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  119. data/lib/rubocop/cop/layout/case_indentation.rb +4 -2
  120. data/lib/rubocop/cop/layout/class_structure.rb +171 -43
  121. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  122. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -3
  123. data/lib/rubocop/cop/layout/condition_position.rb +13 -7
  124. data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
  125. data/lib/rubocop/cop/layout/dot_position.rb +3 -7
  126. data/lib/rubocop/cop/layout/else_alignment.rb +2 -15
  127. data/lib/rubocop/cop/layout/empty_comment.rb +11 -11
  128. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +66 -15
  129. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +75 -10
  130. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  131. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +71 -20
  132. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  133. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  134. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  135. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  136. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  137. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
  138. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  139. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +12 -8
  140. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  141. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  142. data/lib/rubocop/cop/layout/end_alignment.rb +24 -6
  143. data/lib/rubocop/cop/layout/extra_spacing.rb +110 -14
  144. data/lib/rubocop/cop/layout/first_argument_indentation.rb +59 -11
  145. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +20 -11
  146. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  147. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +22 -22
  148. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +26 -26
  149. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  150. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +3 -3
  151. data/lib/rubocop/cop/layout/hash_alignment.rb +11 -12
  152. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +6 -5
  153. data/lib/rubocop/cop/layout/heredoc_indentation.rb +38 -5
  154. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  155. data/lib/rubocop/cop/layout/indentation_width.rb +168 -22
  156. data/lib/rubocop/cop/layout/leading_comment_space.rb +111 -2
  157. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +28 -11
  158. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +9 -4
  159. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +4 -2
  160. data/lib/rubocop/cop/layout/line_length.rb +271 -37
  161. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  162. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  163. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
  164. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  165. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  166. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  167. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +3 -2
  168. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +252 -32
  169. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  170. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  171. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  172. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  173. data/lib/rubocop/cop/layout/redundant_line_break.rb +117 -42
  174. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +17 -9
  175. data/lib/rubocop/cop/layout/single_line_block_chain.rb +6 -1
  176. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  177. data/lib/rubocop/cop/layout/space_after_comma.rb +3 -3
  178. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  179. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  180. data/lib/rubocop/cop/layout/space_after_semicolon.rb +12 -2
  181. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  182. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -4
  183. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +3 -3
  184. data/lib/rubocop/cop/layout/space_around_operators.rb +94 -38
  185. data/lib/rubocop/cop/layout/space_before_block_braces.rb +20 -10
  186. data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -41
  187. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  188. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  189. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  190. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +48 -36
  191. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  192. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +8 -1
  193. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  194. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -5
  195. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  196. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  197. data/lib/rubocop/cop/layout.rb +114 -0
  198. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  199. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  200. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  201. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +73 -4
  202. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  203. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  204. data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -1
  205. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  206. data/lib/rubocop/cop/lint/argument_mismatch.rb +89 -0
  207. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  208. data/lib/rubocop/cop/lint/assignment_in_condition.rb +20 -10
  209. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  210. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +11 -13
  211. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -4
  212. data/lib/rubocop/cop/lint/circular_argument_reference.rb +49 -17
  213. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  214. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  215. data/lib/rubocop/cop/lint/constant_reassignment.rb +227 -0
  216. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  217. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +166 -0
  218. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  219. data/lib/rubocop/cop/lint/debugger.rb +53 -9
  220. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -2
  221. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  222. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -13
  223. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  224. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  225. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  226. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
  227. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +5 -5
  228. data/lib/rubocop/cop/lint/duplicate_methods.rb +504 -49
  229. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  230. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  231. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  232. data/lib/rubocop/cop/lint/else_layout.rb +19 -2
  233. data/lib/rubocop/cop/lint/empty_block.rb +5 -5
  234. data/lib/rubocop/cop/lint/empty_conditional_body.rb +33 -57
  235. data/lib/rubocop/cop/lint/empty_ensure.rb +2 -12
  236. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  237. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  238. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  239. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -5
  240. data/lib/rubocop/cop/lint/empty_when.rb +9 -4
  241. data/lib/rubocop/cop/lint/ensure_return.rb +20 -10
  242. data/lib/rubocop/cop/lint/erb_new_arguments.rb +28 -25
  243. data/lib/rubocop/cop/lint/float_comparison.rb +59 -15
  244. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -8
  245. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -12
  246. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  247. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  248. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  249. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +22 -12
  250. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  251. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -9
  252. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  253. data/lib/rubocop/cop/lint/interpolation_check.rb +30 -6
  254. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +50 -0
  255. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  256. data/lib/rubocop/cop/lint/literal_as_condition.rb +133 -12
  257. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +95 -0
  258. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +61 -30
  259. data/lib/rubocop/cop/lint/loop.rb +6 -12
  260. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
  261. data/lib/rubocop/cop/lint/missing_super.rb +33 -3
  262. data/lib/rubocop/cop/lint/mixed_case_range.rb +16 -12
  263. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  264. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  265. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  266. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -12
  267. data/lib/rubocop/cop/lint/next_without_accumulator.rb +8 -25
  268. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +22 -7
  269. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +22 -10
  270. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -10
  271. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  272. data/lib/rubocop/cop/lint/number_conversion.rb +28 -15
  273. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -3
  274. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +104 -0
  275. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  276. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  277. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +18 -6
  278. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +9 -24
  279. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  280. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  281. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  282. data/lib/rubocop/cop/lint/rand_one.rb +1 -5
  283. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +126 -30
  284. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +57 -21
  285. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  286. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +12 -2
  287. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -21
  288. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +206 -15
  289. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +20 -10
  290. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -6
  291. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  292. data/lib/rubocop/cop/lint/redundant_with_index.rb +9 -3
  293. data/lib/rubocop/cop/lint/redundant_with_object.rb +10 -2
  294. data/lib/rubocop/cop/lint/refinement_import_methods.rb +9 -2
  295. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -2
  296. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -8
  297. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  298. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  299. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -9
  300. data/lib/rubocop/cop/lint/rescue_type.rb +6 -12
  301. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -13
  302. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +55 -13
  303. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +113 -41
  304. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  305. data/lib/rubocop/cop/lint/script_permission.rb +7 -3
  306. data/lib/rubocop/cop/lint/self_assignment.rb +103 -10
  307. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  308. data/lib/rubocop/cop/lint/shadowed_argument.rb +8 -7
  309. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
  310. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +40 -12
  311. data/lib/rubocop/cop/lint/shared_mutable_default.rb +78 -0
  312. data/lib/rubocop/cop/lint/struct_new_override.rb +29 -13
  313. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  314. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  315. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  316. data/lib/rubocop/cop/lint/symbol_conversion.rb +26 -4
  317. data/lib/rubocop/cop/lint/syntax.rb +35 -5
  318. data/lib/rubocop/cop/lint/to_enum_arguments.rb +77 -9
  319. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  320. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  321. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  322. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +114 -0
  323. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  324. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  325. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -3
  326. data/lib/rubocop/cop/lint/unreachable_code.rb +68 -15
  327. data/lib/rubocop/cop/lint/unreachable_loop.rb +14 -8
  328. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  329. data/lib/rubocop/cop/lint/unused_method_argument.rb +28 -2
  330. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  331. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  332. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  333. data/lib/rubocop/cop/lint/useless_access_modifier.rb +37 -12
  334. data/lib/rubocop/cop/lint/useless_assignment.rb +92 -34
  335. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  336. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  337. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  338. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -4
  339. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  340. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +79 -0
  341. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  342. data/lib/rubocop/cop/lint/useless_rescue.rb +3 -4
  343. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -8
  344. data/lib/rubocop/cop/lint/useless_setter_call.rb +17 -29
  345. data/lib/rubocop/cop/lint/useless_times.rb +24 -3
  346. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  347. data/lib/rubocop/cop/lint/void.rb +127 -29
  348. data/lib/rubocop/cop/lint.rb +178 -0
  349. data/lib/rubocop/cop/message_annotator.rb +7 -3
  350. data/lib/rubocop/cop/metrics/abc_size.rb +4 -4
  351. data/lib/rubocop/cop/metrics/block_length.rb +9 -7
  352. data/lib/rubocop/cop/metrics/block_nesting.rb +43 -8
  353. data/lib/rubocop/cop/metrics/class_length.rb +23 -17
  354. data/lib/rubocop/cop/metrics/collection_literal_length.rb +8 -1
  355. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  356. data/lib/rubocop/cop/metrics/method_length.rb +17 -8
  357. data/lib/rubocop/cop/metrics/module_length.rb +7 -6
  358. data/lib/rubocop/cop/metrics/perceived_complexity.rb +38 -8
  359. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +5 -4
  360. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +39 -12
  361. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  362. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  363. data/lib/rubocop/cop/metrics.rb +31 -0
  364. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  365. data/lib/rubocop/cop/migration.rb +13 -0
  366. data/lib/rubocop/cop/mixin/alignment.rb +8 -4
  367. data/lib/rubocop/cop/mixin/allowed_methods.rb +12 -6
  368. data/lib/rubocop/cop/mixin/allowed_pattern.rb +20 -4
  369. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  370. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  371. data/lib/rubocop/cop/mixin/check_line_breakable.rb +46 -18
  372. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +47 -0
  373. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  374. data/lib/rubocop/cop/mixin/comments_help.rb +22 -14
  375. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  376. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  377. data/lib/rubocop/cop/mixin/configurable_max.rb +11 -6
  378. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  379. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  380. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  381. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  382. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +32 -0
  383. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  384. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  385. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -12
  386. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  387. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +33 -15
  388. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +49 -40
  389. data/lib/rubocop/cop/mixin/hash_subset.rb +210 -0
  390. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  391. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  392. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  393. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  394. data/lib/rubocop/cop/mixin/line_length_help.rb +61 -14
  395. data/lib/rubocop/cop/mixin/method_complexity.rb +17 -7
  396. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +11 -12
  397. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  398. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  399. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  400. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  401. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +120 -39
  402. data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
  403. data/lib/rubocop/cop/mixin/range_help.rb +16 -6
  404. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
  405. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  406. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  407. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  408. data/lib/rubocop/cop/mixin/statement_modifier.rb +57 -15
  409. data/lib/rubocop/cop/mixin/string_help.rb +5 -3
  410. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  411. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  412. data/lib/rubocop/cop/mixin/trailing_comma.rb +27 -10
  413. data/lib/rubocop/cop/mixin.rb +91 -0
  414. data/lib/rubocop/cop/naming/accessor_method_name.rb +35 -6
  415. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  416. data/lib/rubocop/cop/naming/block_forwarding.rb +39 -8
  417. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  418. data/lib/rubocop/cop/naming/constant_name.rb +7 -9
  419. data/lib/rubocop/cop/naming/file_name.rb +9 -10
  420. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  421. data/lib/rubocop/cop/naming/inclusive_language.rb +21 -7
  422. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +25 -19
  423. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  424. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  425. data/lib/rubocop/cop/naming/predicate_prefix.rb +232 -0
  426. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +23 -17
  427. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  428. data/lib/rubocop/cop/naming/variable_number.rb +5 -4
  429. data/lib/rubocop/cop/naming.rb +31 -0
  430. data/lib/rubocop/cop/offense.rb +56 -14
  431. data/lib/rubocop/cop/registry.rb +225 -64
  432. data/lib/rubocop/cop/security/compound_hash.rb +4 -2
  433. data/lib/rubocop/cop/security/eval.rb +17 -3
  434. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  435. data/lib/rubocop/cop/security/json_load.rb +33 -11
  436. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  437. data/lib/rubocop/cop/security/open.rb +3 -2
  438. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  439. data/lib/rubocop/cop/security.rb +19 -0
  440. data/lib/rubocop/cop/style/access_modifier_declarations.rb +184 -33
  441. data/lib/rubocop/cop/style/accessor_grouping.rb +56 -11
  442. data/lib/rubocop/cop/style/alias.rb +26 -12
  443. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  444. data/lib/rubocop/cop/style/and_or.rb +3 -2
  445. data/lib/rubocop/cop/style/arguments_forwarding.rb +487 -63
  446. data/lib/rubocop/cop/style/array_first_last.rb +90 -0
  447. data/lib/rubocop/cop/style/array_intersect.rb +148 -41
  448. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  449. data/lib/rubocop/cop/style/array_join.rb +4 -2
  450. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  451. data/lib/rubocop/cop/style/attr.rb +5 -2
  452. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  453. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  454. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  455. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  456. data/lib/rubocop/cop/style/bitwise_predicate.rb +106 -0
  457. data/lib/rubocop/cop/style/block_delimiters.rb +89 -53
  458. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  459. data/lib/rubocop/cop/style/case_like_if.rb +16 -21
  460. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  461. data/lib/rubocop/cop/style/class_and_module_children.rb +139 -22
  462. data/lib/rubocop/cop/style/class_check.rb +1 -0
  463. data/lib/rubocop/cop/style/class_equality_comparison.rb +29 -14
  464. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  465. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  466. data/lib/rubocop/cop/style/collection_compact.rb +53 -23
  467. data/lib/rubocop/cop/style/collection_methods.rb +4 -1
  468. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  469. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  470. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  471. data/lib/rubocop/cop/style/combinable_loops.rb +29 -9
  472. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  473. data/lib/rubocop/cop/style/commented_keyword.rb +30 -4
  474. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  475. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  476. data/lib/rubocop/cop/style/concat_array_literals.rb +11 -5
  477. data/lib/rubocop/cop/style/conditional_assignment.rb +85 -56
  478. data/lib/rubocop/cop/style/constant_visibility.rb +21 -23
  479. data/lib/rubocop/cop/style/copyright.rb +49 -24
  480. data/lib/rubocop/cop/style/data_inheritance.rb +12 -1
  481. data/lib/rubocop/cop/style/date_time.rb +8 -7
  482. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -7
  483. data/lib/rubocop/cop/style/dig_chain.rb +94 -0
  484. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  485. data/lib/rubocop/cop/style/directive_scope.rb +171 -0
  486. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +77 -13
  487. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  488. data/lib/rubocop/cop/style/documentation.rb +76 -29
  489. data/lib/rubocop/cop/style/documentation_method.rb +24 -0
  490. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  491. data/lib/rubocop/cop/style/each_for_simple_loop.rb +12 -16
  492. data/lib/rubocop/cop/style/each_with_object.rb +5 -4
  493. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  494. data/lib/rubocop/cop/style/empty_case_condition.rb +16 -2
  495. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  496. data/lib/rubocop/cop/style/empty_else.rb +10 -7
  497. data/lib/rubocop/cop/style/empty_heredoc.rb +5 -14
  498. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  499. data/lib/rubocop/cop/style/empty_literal.rb +43 -25
  500. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  501. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
  502. data/lib/rubocop/cop/style/encoding.rb +7 -1
  503. data/lib/rubocop/cop/style/end_block.rb +3 -1
  504. data/lib/rubocop/cop/style/endless_method.rb +164 -24
  505. data/lib/rubocop/cop/style/env_home.rb +4 -0
  506. data/lib/rubocop/cop/style/eval_with_location.rb +23 -31
  507. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  508. data/lib/rubocop/cop/style/exact_regexp_match.rb +13 -5
  509. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  510. data/lib/rubocop/cop/style/explicit_block_argument.rb +19 -6
  511. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  512. data/lib/rubocop/cop/style/fetch_env_var.rb +35 -8
  513. data/lib/rubocop/cop/style/file_null.rb +91 -0
  514. data/lib/rubocop/cop/style/file_open.rb +84 -0
  515. data/lib/rubocop/cop/style/file_read.rb +2 -5
  516. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  517. data/lib/rubocop/cop/style/file_write.rb +23 -21
  518. data/lib/rubocop/cop/style/float_division.rb +23 -5
  519. data/lib/rubocop/cop/style/for.rb +7 -2
  520. data/lib/rubocop/cop/style/format_string.rb +47 -13
  521. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  522. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -3
  523. data/lib/rubocop/cop/style/global_std_stream.rb +10 -1
  524. data/lib/rubocop/cop/style/global_vars.rb +6 -5
  525. data/lib/rubocop/cop/style/guard_clause.rb +67 -21
  526. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  527. data/lib/rubocop/cop/style/hash_conversion.rb +38 -13
  528. data/lib/rubocop/cop/style/hash_each_methods.rb +109 -12
  529. data/lib/rubocop/cop/style/hash_except.rb +38 -146
  530. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  531. data/lib/rubocop/cop/style/hash_lookup_method.rb +102 -0
  532. data/lib/rubocop/cop/style/hash_slice.rb +96 -0
  533. data/lib/rubocop/cop/style/hash_syntax.rb +36 -7
  534. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  535. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  536. data/lib/rubocop/cop/style/identical_conditional_branches.rb +62 -9
  537. data/lib/rubocop/cop/style/if_inside_else.rb +26 -22
  538. data/lib/rubocop/cop/style/if_unless_modifier.rb +72 -47
  539. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +15 -19
  540. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +12 -9
  541. data/lib/rubocop/cop/style/if_with_semicolon.rb +75 -11
  542. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  543. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  544. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  545. data/lib/rubocop/cop/style/inverse_methods.rb +22 -18
  546. data/lib/rubocop/cop/style/invertible_unless_condition.rb +71 -9
  547. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  548. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  549. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  550. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +71 -0
  551. data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
  552. data/lib/rubocop/cop/style/lambda.rb +16 -5
  553. data/lib/rubocop/cop/style/lambda_call.rb +33 -11
  554. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  555. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  556. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +93 -50
  557. data/lib/rubocop/cop/style/map_into_array.rb +236 -0
  558. data/lib/rubocop/cop/style/map_join.rb +123 -0
  559. data/lib/rubocop/cop/style/map_to_hash.rb +28 -10
  560. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  561. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +77 -28
  562. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  563. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +38 -9
  564. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +37 -15
  565. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  566. data/lib/rubocop/cop/style/method_def_parentheses.rb +8 -6
  567. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  568. data/lib/rubocop/cop/style/missing_else.rb +2 -4
  569. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +75 -12
  570. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  571. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  572. data/lib/rubocop/cop/style/module_function.rb +4 -2
  573. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  574. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  575. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  576. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  577. data/lib/rubocop/cop/style/multiline_memoization.rb +9 -3
  578. data/lib/rubocop/cop/style/multiline_method_signature.rb +18 -13
  579. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  580. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  581. data/lib/rubocop/cop/style/multiple_comparison.rb +63 -59
  582. data/lib/rubocop/cop/style/mutable_constant.rb +117 -19
  583. data/lib/rubocop/cop/style/negated_if_else_condition.rb +6 -5
  584. data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
  585. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  586. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  587. data/lib/rubocop/cop/style/nested_ternary_operator.rb +8 -15
  588. data/lib/rubocop/cop/style/next.rb +45 -1
  589. data/lib/rubocop/cop/style/nil_comparison.rb +12 -10
  590. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  591. data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
  592. data/lib/rubocop/cop/style/not.rb +3 -1
  593. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  594. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  595. data/lib/rubocop/cop/style/numeric_predicate.rb +13 -5
  596. data/lib/rubocop/cop/style/object_then.rb +16 -14
  597. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  598. data/lib/rubocop/cop/style/one_line_conditional.rb +50 -16
  599. data/lib/rubocop/cop/style/open_struct_use.rb +6 -6
  600. data/lib/rubocop/cop/style/operator_method_call.rb +40 -8
  601. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  602. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  603. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  604. data/lib/rubocop/cop/style/parallel_assignment.rb +69 -48
  605. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  606. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  607. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -1
  608. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  609. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  610. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  611. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  612. data/lib/rubocop/cop/style/proc.rb +5 -4
  613. data/lib/rubocop/cop/style/quoted_symbols.rb +2 -4
  614. data/lib/rubocop/cop/style/raise_args.rb +19 -14
  615. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  616. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  617. data/lib/rubocop/cop/style/redundant_argument.rb +37 -4
  618. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  619. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  620. data/lib/rubocop/cop/style/redundant_assignment.rb +21 -3
  621. data/lib/rubocop/cop/style/redundant_begin.rb +53 -6
  622. data/lib/rubocop/cop/style/redundant_condition.rb +98 -25
  623. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
  624. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  625. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +31 -7
  626. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +88 -5
  627. data/lib/rubocop/cop/style/redundant_each.rb +11 -9
  628. data/lib/rubocop/cop/style/redundant_exception.rb +39 -13
  629. data/lib/rubocop/cop/style/redundant_fetch_block.rb +5 -13
  630. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +10 -1
  631. data/lib/rubocop/cop/style/redundant_filter_chain.rb +23 -6
  632. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  633. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  634. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  635. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  636. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  637. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +62 -0
  638. data/lib/rubocop/cop/style/redundant_line_continuation.rb +92 -72
  639. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  640. data/lib/rubocop/cop/style/redundant_parentheses.rb +203 -84
  641. data/lib/rubocop/cop/style/redundant_percent_q.rb +6 -4
  642. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +33 -4
  643. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  644. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +2 -2
  645. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +20 -24
  646. data/lib/rubocop/cop/style/redundant_return.rb +20 -8
  647. data/lib/rubocop/cop/style/redundant_self.rb +43 -22
  648. data/lib/rubocop/cop/style/redundant_self_assignment.rb +19 -32
  649. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +9 -9
  650. data/lib/rubocop/cop/style/redundant_sort.rb +17 -16
  651. data/lib/rubocop/cop/style/redundant_sort_by.rb +19 -3
  652. data/lib/rubocop/cop/style/redundant_string_escape.rb +4 -5
  653. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  654. data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
  655. data/lib/rubocop/cop/style/require_order.rb +2 -2
  656. data/lib/rubocop/cop/style/rescue_modifier.rb +20 -7
  657. data/lib/rubocop/cop/style/return_nil.rb +8 -4
  658. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +67 -11
  659. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  660. data/lib/rubocop/cop/style/safe_navigation.rb +176 -66
  661. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  662. data/lib/rubocop/cop/style/sample.rb +14 -10
  663. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  664. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  665. data/lib/rubocop/cop/style/select_by_regexp.rb +62 -26
  666. data/lib/rubocop/cop/style/self_assignment.rb +13 -19
  667. data/lib/rubocop/cop/style/semicolon.rb +53 -17
  668. data/lib/rubocop/cop/style/send.rb +4 -4
  669. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +105 -0
  670. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  671. data/lib/rubocop/cop/style/single_argument_dig.rb +16 -8
  672. data/lib/rubocop/cop/style/single_line_block_params.rb +3 -3
  673. data/lib/rubocop/cop/style/single_line_do_end_block.rb +90 -0
  674. data/lib/rubocop/cop/style/single_line_methods.rb +16 -12
  675. data/lib/rubocop/cop/style/slicing_with_range.rb +105 -10
  676. data/lib/rubocop/cop/style/sole_nested_conditional.rb +103 -91
  677. data/lib/rubocop/cop/style/special_global_vars.rb +8 -4
  678. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -1
  679. data/lib/rubocop/cop/style/static_class.rb +21 -0
  680. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  681. data/lib/rubocop/cop/style/string_concatenation.rb +34 -17
  682. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  683. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  684. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  685. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  686. data/lib/rubocop/cop/style/strip.rb +7 -4
  687. data/lib/rubocop/cop/style/struct_inheritance.rb +25 -3
  688. data/lib/rubocop/cop/style/super_arguments.rb +220 -0
  689. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  690. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  691. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  692. data/lib/rubocop/cop/style/symbol_proc.rb +86 -14
  693. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  694. data/lib/rubocop/cop/style/ternary_parentheses.rb +37 -5
  695. data/lib/rubocop/cop/style/time_now.rb +41 -0
  696. data/lib/rubocop/cop/style/top_level_method_definition.rb +4 -3
  697. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  698. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  699. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  700. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  701. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  702. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +21 -22
  703. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -3
  704. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  705. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  706. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  707. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  708. data/lib/rubocop/cop/style/while_until_do.rb +7 -2
  709. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -2
  710. data/lib/rubocop/cop/style/word_array.rb +1 -0
  711. data/lib/rubocop/cop/style/yoda_condition.rb +12 -7
  712. data/lib/rubocop/cop/style/yoda_expression.rb +11 -9
  713. data/lib/rubocop/cop/style/zero_length_predicate.rb +38 -27
  714. data/lib/rubocop/cop/style.rb +312 -0
  715. data/lib/rubocop/cop/team.rb +188 -46
  716. data/lib/rubocop/cop/util.rb +23 -13
  717. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  718. data/lib/rubocop/cop/variable_force/assignment.rb +35 -7
  719. data/lib/rubocop/cop/variable_force/branch.rb +31 -7
  720. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  721. data/lib/rubocop/cop/variable_force/variable.rb +32 -10
  722. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  723. data/lib/rubocop/cop/variable_force.rb +43 -20
  724. data/lib/rubocop/cops_documentation_generator.rb +137 -63
  725. data/lib/rubocop/core_ext/string.rb +2 -6
  726. data/lib/rubocop/directive_comment.rb +135 -19
  727. data/lib/rubocop/ext/regexp_node.rb +17 -35
  728. data/lib/rubocop/ext/regexp_parser.rb +4 -21
  729. data/lib/rubocop/feature_loader.rb +0 -6
  730. data/lib/rubocop/file_finder.rb +11 -9
  731. data/lib/rubocop/file_patterns.rb +9 -1
  732. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -9
  733. data/lib/rubocop/formatter/disabled_config_formatter.rb +62 -22
  734. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  735. data/lib/rubocop/formatter/formatter_set.rb +10 -4
  736. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  737. data/lib/rubocop/formatter/html_formatter.rb +38 -17
  738. data/lib/rubocop/formatter/json_formatter.rb +11 -7
  739. data/lib/rubocop/formatter/junit_formatter.rb +94 -30
  740. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  741. data/lib/rubocop/formatter/offense_count_formatter.rb +14 -5
  742. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  743. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  744. data/lib/rubocop/formatter/tap_formatter.rb +11 -10
  745. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
  746. data/lib/rubocop/formatter.rb +22 -21
  747. data/lib/rubocop/lockfile.rb +76 -7
  748. data/lib/rubocop/lsp/diagnostic.rb +170 -0
  749. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  750. data/lib/rubocop/lsp/logger.rb +3 -3
  751. data/lib/rubocop/lsp/routes.rb +163 -56
  752. data/lib/rubocop/lsp/runtime.rb +47 -44
  753. data/lib/rubocop/lsp/server.rb +18 -6
  754. data/lib/rubocop/lsp/severity.rb +1 -1
  755. data/lib/rubocop/lsp/stdin_runner.rb +96 -0
  756. data/lib/rubocop/lsp.rb +36 -0
  757. data/lib/rubocop/magic_comment.rb +44 -14
  758. data/lib/rubocop/mcp/server.rb +199 -0
  759. data/lib/rubocop/options.rb +88 -32
  760. data/lib/rubocop/path_util.rb +33 -11
  761. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  762. data/lib/rubocop/plugin/configuration_integrator.rb +146 -0
  763. data/lib/rubocop/plugin/load_error.rb +26 -0
  764. data/lib/rubocop/plugin/loader.rb +100 -0
  765. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  766. data/lib/rubocop/plugin.rb +46 -0
  767. data/lib/rubocop/project_index_loader.rb +82 -0
  768. data/lib/rubocop/rake_task.rb +7 -5
  769. data/lib/rubocop/remote_config.rb +15 -9
  770. data/lib/rubocop/result_cache.rb +85 -61
  771. data/lib/rubocop/rspec/cop_helper.rb +28 -2
  772. data/lib/rubocop/rspec/expect_offense.rb +29 -12
  773. data/lib/rubocop/rspec/shared_contexts.rb +165 -24
  774. data/lib/rubocop/rspec/support.rb +8 -2
  775. data/lib/rubocop/runner.rb +273 -99
  776. data/lib/rubocop/server/cache.rb +76 -42
  777. data/lib/rubocop/server/cli.rb +2 -4
  778. data/lib/rubocop/server/client_command/base.rb +10 -0
  779. data/lib/rubocop/server/client_command/exec.rb +4 -4
  780. data/lib/rubocop/server/client_command/start.rb +11 -1
  781. data/lib/rubocop/server/core.rb +13 -0
  782. data/lib/rubocop/server/server_command/exec.rb +0 -1
  783. data/lib/rubocop/server.rb +14 -0
  784. data/lib/rubocop/string_interpreter.rb +3 -3
  785. data/lib/rubocop/target_finder.rb +111 -86
  786. data/lib/rubocop/target_ruby.rb +131 -89
  787. data/lib/rubocop/todo_audit.rb +111 -0
  788. data/lib/rubocop/version.rb +84 -10
  789. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  790. data/lib/rubocop.rb +33 -648
  791. data/lib/ruby_lsp/rubocop/addon.rb +89 -0
  792. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  793. metadata +169 -50
  794. data/lib/rubocop/cop/naming/predicate_name.rb +0 -134
  795. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -100
  796. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
  797. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -6,6 +6,14 @@ module RuboCop
6
6
  # Checks whether some constant value isn't a
7
7
  # mutable literal (e.g. array or hash).
8
8
  #
9
+ # When the `Recursive` option is enabled, mutable literals nested inside
10
+ # arrays and hashes are also frozen, so an offense on the outermost
11
+ # unfrozen literal will autocorrect every nested mutable literal as well.
12
+ # When the outer literal already has `.freeze` appended, the cop descends
13
+ # into it and reports each outermost unfrozen literal underneath. The
14
+ # option is disabled by default to preserve existing behavior; opt in to
15
+ # get strict nested freezing.
16
+ #
9
17
  # Strict mode can be used to freeze all constants, rather than
10
18
  # just literals.
11
19
  # Strict mode is considered an experimental feature. It has not been
@@ -19,7 +27,7 @@ module RuboCop
19
27
  # acceptable value other than none, it will suppress the offenses
20
28
  # raised by this cop. It enforces frozen state.
21
29
  #
22
- # NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
30
+ # NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
23
31
  #
24
32
  # NOTE: From Ruby 3.0, interpolated strings are not frozen when
25
33
  # `# frozen-string-literal: true` is used, so this cop enforces explicit
@@ -49,6 +57,17 @@ module RuboCop
49
57
  # CONST = Something.new
50
58
  #
51
59
  #
60
+ # @example Recursive: false (default)
61
+ # # good - only the outer container needs to be frozen
62
+ # CONST = [{ a: [], b: 'foo' }].freeze
63
+ #
64
+ # @example Recursive: true
65
+ # # bad - nested mutable literals must be frozen too
66
+ # CONST = [{ a: [], b: 'foo' }].freeze
67
+ #
68
+ # # good
69
+ # CONST = [{ a: [].freeze, b: 'foo'.freeze }.freeze].freeze
70
+ #
52
71
  # @example EnforcedStyle: strict
53
72
  # # bad
54
73
  # CONST = Something.new
@@ -70,6 +89,9 @@ module RuboCop
70
89
  # end
71
90
  # end.freeze
72
91
  #
92
+ # # good - `Data.define` declares an immutable value type
93
+ # CONST = Data.define(:foo, :bar)
94
+ #
73
95
  # @example
74
96
  # # Magic comment - shareable_constant_value: literal
75
97
  #
@@ -125,24 +147,43 @@ module RuboCop
125
147
  MSG = 'Freeze mutable objects assigned to constants.'
126
148
 
127
149
  def on_casgn(node)
128
- _scope, _const_name, value = *node
129
- if value.nil? # This is only the case for `CONST += ...` or similarg66
150
+ if node.expression.nil? # This is only the case for `CONST += ...` or similar
130
151
  parent = node.parent
131
152
  return unless parent.or_asgn_type? # We only care about `CONST ||= ...`
132
153
 
133
- value = parent.children.last
154
+ on_assignment(parent.children.last)
155
+ else
156
+ on_assignment(node.expression)
134
157
  end
135
-
136
- on_assignment(value)
137
158
  end
138
159
 
139
160
  private
140
161
 
141
162
  def on_assignment(value)
142
- if style == :strict
143
- strict_check(value)
163
+ nodes = mutable_nodes(value) do |node|
164
+ if style == :strict
165
+ strict_check(node)
166
+ else
167
+ literal_check(node)
168
+ end
169
+ end
170
+
171
+ nodes.each do |node|
172
+ add_offense(node) { |corrector| autocorrect(corrector, node) }
173
+ end
174
+ end
175
+
176
+ def mutable_nodes(value, &block)
177
+ if recursive? && explicitly_frozen_literal?(value)
178
+ literal_children(value.receiver).flat_map { |c| mutable_nodes(c, &block) }
144
179
  else
145
- check(value)
180
+ node_offending = yield(value)
181
+
182
+ if node_offending
183
+ [value]
184
+ else
185
+ []
186
+ end
146
187
  end
147
188
  end
148
189
 
@@ -152,18 +193,20 @@ module RuboCop
152
193
  return if frozen_string_literal?(value)
153
194
  return if shareable_constant_value?(value)
154
195
 
155
- add_offense(value) { |corrector| autocorrect(corrector, value) }
196
+ true
156
197
  end
157
198
 
158
- def check(value)
159
- range_enclosed_in_parentheses = range_enclosed_in_parentheses?(value)
160
- return unless mutable_literal?(value) ||
161
- (target_ruby_version <= 2.7 && range_enclosed_in_parentheses)
162
-
199
+ def literal_check(value)
200
+ return unless mutable_or_unfrozen_range?(value)
163
201
  return if frozen_string_literal?(value)
164
202
  return if shareable_constant_value?(value)
165
203
 
166
- add_offense(value) { |corrector| autocorrect(corrector, value) }
204
+ true
205
+ end
206
+
207
+ def mutable_or_unfrozen_range?(value)
208
+ mutable_literal?(value) ||
209
+ (target_ruby_version <= 2.7 && range_enclosed_in_parentheses?(value))
167
210
  end
168
211
 
169
212
  def autocorrect(corrector, node)
@@ -172,13 +215,66 @@ module RuboCop
172
215
  splat_value = splat_value(node)
173
216
  if splat_value
174
217
  correct_splat_expansion(corrector, expr, splat_value)
175
- elsif node.array_type? && !node.bracketed?
218
+ corrector.insert_after(expr, '.freeze')
219
+ return
220
+ end
221
+
222
+ if node.array_type? && !node.bracketed?
176
223
  corrector.wrap(expr, '[', ']')
177
224
  elsif requires_parentheses?(node)
178
225
  corrector.wrap(expr, '(', ')')
179
226
  end
180
227
 
181
228
  corrector.insert_after(expr, '.freeze')
229
+
230
+ freeze_nested_literals(corrector, node) if recursive?
231
+ end
232
+
233
+ # Recursively freezes every nested mutable literal inside an array or
234
+ # hash literal. Already-frozen subtrees are not re-frozen, but their
235
+ # children are still inspected for unfrozen literals deeper down.
236
+ def freeze_nested_literals(corrector, node)
237
+ literal_children(node).each do |child|
238
+ if explicitly_frozen_literal?(child)
239
+ freeze_nested_literals(corrector, child.receiver)
240
+ elsif freezable_nested_literal?(child)
241
+ autocorrect(corrector, child)
242
+ end
243
+ end
244
+ end
245
+
246
+ def freezable_nested_literal?(node)
247
+ return false if frozen_string_literal?(node)
248
+ return false if shareable_constant_value?(node)
249
+
250
+ mutable_literal?(node)
251
+ end
252
+
253
+ # Returns the child literals of an array or hash node that may
254
+ # themselves need freezing. For hashes, both keys and values are
255
+ # included. Percent-literal arrays (e.g. `%w(a b)`) are skipped because
256
+ # `.freeze` cannot be appended to their contents.
257
+ def literal_children(node)
258
+ case node.type
259
+ when :array
260
+ return [] if node.percent_literal?
261
+
262
+ node.children
263
+ when :hash
264
+ node.children.flat_map { |child| child.pair_type? ? child.children : [] }
265
+ else
266
+ []
267
+ end
268
+ end
269
+
270
+ def explicitly_frozen_literal?(node)
271
+ return false unless node.send_type? && node.method?(:freeze)
272
+
273
+ node.receiver && mutable_literal?(node.receiver)
274
+ end
275
+
276
+ def recursive?
277
+ cop_config.fetch('Recursive', false)
182
278
  end
183
279
 
184
280
  def mutable_literal?(value)
@@ -198,7 +294,7 @@ module RuboCop
198
294
  end
199
295
 
200
296
  def frozen_regexp_or_range_literals?(node)
201
- target_ruby_version >= 3.0 && (node.regexp_type? || node.range_type?)
297
+ target_ruby_version >= 3.0 && node.type?(:regexp, :range)
202
298
  end
203
299
 
204
300
  def requires_parentheses?(node)
@@ -226,6 +322,8 @@ module RuboCop
226
322
  (const _ _)
227
323
  (send (const {nil? cbase} :Struct) :new ...)
228
324
  (block (send (const {nil? cbase} :Struct) :new ...) ...)
325
+ (send (const {nil? cbase} :Data) :define ...)
326
+ (block (send (const {nil? cbase} :Data) :define ...) ...)
229
327
  (send _ :freeze)
230
328
  (send {float int} {:+ :- :* :** :/ :% :<<} _)
231
329
  (send _ {:+ :- :* :** :/ :%} {float int})
@@ -239,7 +337,7 @@ module RuboCop
239
337
 
240
338
  # @!method range_enclosed_in_parentheses?(node)
241
339
  def_node_matcher :range_enclosed_in_parentheses?, <<~PATTERN
242
- (begin ({irange erange} _ _))
340
+ (begin (range _ _))
243
341
  PATTERN
244
342
  end
245
343
  end
@@ -46,10 +46,12 @@ module RuboCop
46
46
  @corrected_nodes = nil
47
47
  end
48
48
 
49
+ # rubocop:disable-next Metrics/AbcSize,Metrics/CyclomaticComplexity
49
50
  def on_if(node)
50
51
  return unless if_else?(node)
51
52
  return unless (condition = unwrap_begin_nodes(node.condition))
52
53
  return if double_negation?(condition) || !negated_condition?(condition)
54
+ return unless condition.arguments.size < 2
53
55
 
54
56
  message = message(node)
55
57
  add_offense(node, message: message) do |corrector|
@@ -71,7 +73,7 @@ module RuboCop
71
73
  end
72
74
 
73
75
  def unwrap_begin_nodes(node)
74
- node = node.children.first while node && (node.begin_type? || node.kwbegin_type?)
76
+ node = node.children.first while node&.type?(:begin, :kwbegin)
75
77
 
76
78
  node
77
79
  end
@@ -92,13 +94,12 @@ module RuboCop
92
94
  end
93
95
 
94
96
  def correct_negated_condition(corrector, node)
95
- receiver, method_name, rhs = *node
96
97
  replacement =
97
98
  if node.negation_method?
98
- receiver.source
99
+ node.receiver.source
99
100
  else
100
- inverted_method = method_name.to_s.sub('!', '=')
101
- "#{receiver.source} #{inverted_method} #{rhs.source}"
101
+ inverted_method = node.method_name.to_s.sub('!', '=')
102
+ "#{node.receiver.source} #{inverted_method} #{node.first_argument.source}"
102
103
  end
103
104
 
104
105
  corrector.replace(node, replacement)
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Identifies usages of `arr[arr.length - n]`, `arr[arr.size - n]`, or
7
+ # `arr[arr.count - n]` and suggests to change them to use `arr[-n]` instead.
8
+ # Also handles range patterns like `arr[0..(arr.length - n)]`.
9
+ #
10
+ # The cop recognizes preserving methods (`sort`, `reverse`, `shuffle`, `rotate`)
11
+ # and their combinations, allowing safe replacement when the receiver matches.
12
+ # It works with variables, instance variables, class variables, and constants.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # arr[arr.count - 2]
17
+ # arr[0..(arr.length - 2)]
18
+ # arr[0...(arr.length - 4)]
19
+ # arr.sort[arr.reverse.length - 2]
20
+ # arr.sort.reverse[arr.sort.size - 2]
21
+ #
22
+ # # good
23
+ # arr[-2]
24
+ # arr[0..-2]
25
+ # arr[0...-4]
26
+ # arr.sort[-2]
27
+ # arr.sort.reverse[-2]
28
+ #
29
+ class NegativeArrayIndex < Base
30
+ extend AutoCorrector
31
+ include RangeHelp
32
+
33
+ MSG = 'Use `%<receiver>s[-%<index>s]` instead of `%<current>s`.'
34
+ MSG_RANGE = 'Use `%<receiver>s[%<start>s%<range_op>s-%<index>s]` instead of `%<current>s`.'
35
+ RESTRICT_ON_SEND = %i[[]].freeze
36
+
37
+ LENGTH_METHODS = %i[length size count].freeze
38
+
39
+ PRESERVING_METHODS = %i[sort reverse shuffle rotate].freeze
40
+
41
+ # @!method length_subtraction?(node)
42
+ def_node_matcher :length_subtraction?, <<~PATTERN
43
+ (send
44
+ (send $_ {:length :size :count}) :-
45
+ (int $_))
46
+ PATTERN
47
+
48
+ def on_send(node)
49
+ return if node.arguments.empty?
50
+
51
+ index_arg = node.first_argument
52
+ range_node = extract_range_from_begin(index_arg)
53
+ if range_with_length_subtraction?(range_node, node.receiver)
54
+ receiver = node.receiver.source
55
+ return handle_range_pattern(receiver, range_node, index_arg)
56
+ end
57
+
58
+ handle_simple_index_pattern(node, index_arg)
59
+ end
60
+
61
+ alias on_csend on_send
62
+
63
+ private
64
+
65
+ def handle_simple_index_pattern(node, index_arg)
66
+ length_receiver, negative_index = length_subtraction?(index_arg)
67
+
68
+ return unless negative_index&.positive?
69
+ return unless receivers_match?(length_receiver, node.receiver)
70
+
71
+ add_offense_for_subtraction(node, index_arg, negative_index)
72
+ end
73
+
74
+ def extract_range_from_begin(node)
75
+ node.begin_type? ? node.children.first : node
76
+ end
77
+
78
+ def extract_inner_end(node)
79
+ node.children.size == 1 ? node.children.first : node
80
+ end
81
+
82
+ def add_offense_for_subtraction(node, index_arg, negative_index)
83
+ receiver = node.receiver.source
84
+ offense_range = index_arg.source_range
85
+ current = "#{receiver}[#{index_arg.source}]"
86
+
87
+ message = format(MSG, receiver: receiver, index: negative_index, current: current)
88
+
89
+ add_offense(offense_range, message: message) do |corrector|
90
+ corrector.replace(offense_range, "-#{negative_index}")
91
+ end
92
+ end
93
+
94
+ # rubocop:disable-next Metrics/CyclomaticComplexity
95
+ def range_with_length_subtraction?(range_node, array_receiver)
96
+ return false unless range_node&.range_type?
97
+
98
+ range_end = range_node.end
99
+ range_start = range_node.begin
100
+ return false unless range_end && range_start
101
+
102
+ return false unless preserving_method?(range_start)
103
+
104
+ inner_end = extract_inner_end(range_end)
105
+ length_receiver, negative_index = length_subtraction?(inner_end)
106
+
107
+ return false unless negative_index&.positive?
108
+
109
+ receivers_match_strict?(length_receiver, array_receiver)
110
+ end
111
+
112
+ def handle_range_pattern(receiver, range_node, index_arg)
113
+ range_end = range_node.end
114
+ inner_end = extract_inner_end(range_end)
115
+ _length_receiver, negative_index = length_subtraction?(inner_end)
116
+
117
+ message, replacement = build_range_offense_data(
118
+ receiver, range_node, range_end, inner_end, negative_index, index_arg
119
+ )
120
+
121
+ add_offense(range_end, message: message) do |corrector|
122
+ corrector.replace(index_arg, replacement)
123
+ end
124
+ end
125
+
126
+ # rubocop:disable-next Metrics/ParameterLists
127
+ def build_range_offense_data(receiver, range_node, range_end, inner_end, negative_index,
128
+ index_arg)
129
+ range_op = range_node.erange_type? ? '...' : '..'
130
+ range_start = range_node.begin.source
131
+
132
+ range_without_parens =
133
+ build_range_without_parens(range_start, range_op, range_end, inner_end)
134
+ current_source = build_current_source(receiver, range_without_parens, index_arg)
135
+ start, index = format_range_message_parts(range_start, negative_index, index_arg)
136
+
137
+ message = build_message_for_range(receiver, start, range_op, index, current_source)
138
+ replacement = build_replacement_string(range_start, range_op, negative_index, index_arg)
139
+
140
+ [message, replacement]
141
+ end
142
+
143
+ def format_range_message_parts(range_start, negative_index, index_arg)
144
+ has_parentheses = index_arg.begin_type?
145
+ start = has_parentheses ? "(#{range_start}" : range_start
146
+ index = has_parentheses ? "#{negative_index})" : negative_index
147
+
148
+ [start, index]
149
+ end
150
+
151
+ def build_message_for_range(receiver, start, range_op, index, current)
152
+ format(
153
+ MSG_RANGE,
154
+ receiver: receiver, start: start, range_op: range_op, index: index, current: current
155
+ )
156
+ end
157
+
158
+ def build_replacement_string(range_start, range_op, negative_index, index_arg)
159
+ has_parentheses = index_arg.begin_type?
160
+
161
+ if has_parentheses
162
+ "(#{range_start}#{range_op}-#{negative_index})"
163
+ else
164
+ "#{range_start}#{range_op}-#{negative_index}"
165
+ end
166
+ end
167
+
168
+ def build_current_source(receiver, range_without_parens, index_arg)
169
+ has_parentheses = index_arg.begin_type?
170
+
171
+ if has_parentheses
172
+ "#{receiver}[(#{range_without_parens})]"
173
+ else
174
+ "#{receiver}[#{range_without_parens}]"
175
+ end
176
+ end
177
+
178
+ def build_range_without_parens(range_start, range_op, range_end, inner_end)
179
+ end_expression = range_end.begin_type? ? range_end.source : inner_end.source
180
+
181
+ "#{range_start}#{range_op}#{end_expression}"
182
+ end
183
+
184
+ def receivers_match?(length_receiver, array_receiver)
185
+ return array_receiver.self_type? unless length_receiver
186
+
187
+ unless preserving_method?(array_receiver) && preserving_method?(length_receiver)
188
+ return false
189
+ end
190
+ return true if length_receiver.source == array_receiver.source
191
+
192
+ !extract_base_receiver(array_receiver).nil?
193
+ end
194
+
195
+ def receivers_match_strict?(length_receiver, array_receiver)
196
+ preserving_method?(array_receiver) &&
197
+ length_receiver.source == array_receiver.source
198
+ end
199
+
200
+ def extract_base_receiver(node)
201
+ receiver = node.receiver
202
+
203
+ return nil unless receiver
204
+ return receiver unless receiver.receiver
205
+
206
+ extract_base_receiver(receiver)
207
+ end
208
+
209
+ def preserving_method?(node)
210
+ return true if node.receiver.nil?
211
+
212
+ method_name = node.method_name
213
+ return false unless PRESERVING_METHODS.include?(method_name)
214
+
215
+ preserving_method?(node.receiver)
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
@@ -36,7 +36,7 @@ module RuboCop
36
36
  end
37
37
 
38
38
  def modifier?(node)
39
- node&.basic_conditional? && node&.modifier_form?
39
+ node&.basic_conditional? && node.modifier_form?
40
40
  end
41
41
 
42
42
  def autocorrect(corrector, node)
@@ -35,11 +35,11 @@ module RuboCop
35
35
  def on_send(node)
36
36
  return unless node.parenthesized?
37
37
 
38
- node.each_child_node(:send, :csend) do |nested|
38
+ node.each_child_node(:call) do |nested|
39
39
  next if allowed_omission?(nested)
40
40
 
41
41
  message = format(MSG, source: nested.source)
42
- add_offense(nested.source_range, message: message) do |corrector|
42
+ add_offense(nested, message: message) do |corrector|
43
43
  autocorrect(corrector, nested)
44
44
  end
45
45
  end
@@ -18,7 +18,6 @@ module RuboCop
18
18
  class NestedTernaryOperator < Base
19
19
  extend AutoCorrector
20
20
  include RangeHelp
21
- include IgnoredNode
22
21
 
23
22
  MSG = 'Ternary operators must not be nested. Prefer `if` or `else` constructs instead.'
24
23
 
@@ -27,24 +26,16 @@ module RuboCop
27
26
 
28
27
  node.each_descendant(:if).select(&:ternary?).each do |nested_ternary|
29
28
  add_offense(nested_ternary) do |corrector|
30
- if_node = if_node(nested_ternary)
31
- next if part_of_ignored_node?(if_node)
29
+ next if part_of_ignored_node?(node)
32
30
 
33
- autocorrect(corrector, if_node)
34
- ignore_node(if_node)
31
+ autocorrect(corrector, node)
32
+ ignore_node(node)
35
33
  end
36
34
  end
37
35
  end
38
36
 
39
37
  private
40
38
 
41
- def if_node(node)
42
- node = node.parent
43
- return node if node.if_type?
44
-
45
- if_node(node)
46
- end
47
-
48
39
  def autocorrect(corrector, if_node)
49
40
  replace_loc_and_whitespace(corrector, if_node.loc.question, "\n")
50
41
  replace_loc_and_whitespace(corrector, if_node.loc.colon, "\nelse\n")
@@ -53,9 +44,11 @@ module RuboCop
53
44
  end
54
45
 
55
46
  def remove_parentheses(source)
56
- return source unless source.start_with?('(')
57
-
58
- source.delete_prefix('(').delete_suffix(')')
47
+ if source.start_with?('(') && source.end_with?(')')
48
+ source.delete_prefix('(').delete_suffix(')')
49
+ else
50
+ source
51
+ end
59
52
  end
60
53
 
61
54
  def replace_loc_and_whitespace(corrector, range, replacement)
@@ -46,6 +46,38 @@ module RuboCop
46
46
  # next unless a == 1
47
47
  # puts a
48
48
  # end
49
+ #
50
+ # @example AllowConsecutiveConditionals: false (default)
51
+ # # bad
52
+ # [1, 2].each do |a|
53
+ # if a == 1
54
+ # puts a
55
+ # end
56
+ # if a == 2
57
+ # puts a
58
+ # end
59
+ # end
60
+ #
61
+ # # good
62
+ # [1, 2].each do |a|
63
+ # if a == 1
64
+ # puts a
65
+ # end
66
+ # next unless a == 2
67
+ # puts a
68
+ # end
69
+ #
70
+ # @example AllowConsecutiveConditionals: true
71
+ # # good
72
+ # [1, 2].each do |a|
73
+ # if a == 1
74
+ # puts a
75
+ # end
76
+ # if a == 2
77
+ # puts a
78
+ # end
79
+ # end
80
+ #
49
81
  class Next < Base
50
82
  include ConfigurableEnforcedStyle
51
83
  include MinBodyLength
@@ -66,12 +98,13 @@ module RuboCop
66
98
  end
67
99
 
68
100
  def on_block(node)
69
- return unless node.send_node.send_type? && node.send_node.enumerator_method?
101
+ return unless node.send_node.call_type? && node.send_node.enumerator_method?
70
102
 
71
103
  check(node)
72
104
  end
73
105
 
74
106
  alias on_numblock on_block
107
+ alias on_itblock on_block
75
108
 
76
109
  def on_while(node)
77
110
  check(node)
@@ -86,6 +119,9 @@ module RuboCop
86
119
 
87
120
  offending_node = offense_node(node.body)
88
121
 
122
+ return if allowed_consecutive_conditionals? &&
123
+ consecutive_conditionals?(offending_node)
124
+
89
125
  add_offense(offense_location(offending_node)) do |corrector|
90
126
  if offending_node.modifier_form?
91
127
  autocorrect_modifier(corrector, offending_node)
@@ -227,6 +263,14 @@ module RuboCop
227
263
 
228
264
  corrector.remove_leading(buffer.line_range(lineno), adjustment) if adjustment.positive?
229
265
  end
266
+
267
+ def consecutive_conditionals?(if_node)
268
+ if_node.parent&.begin_type? && if_node.left_sibling&.if_type?
269
+ end
270
+
271
+ def allowed_consecutive_conditionals?
272
+ cop_config.fetch('AllowConsecutiveConditionals', false)
273
+ end
230
274
  end
231
275
  end
232
276
  end
@@ -4,9 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for comparison of something with nil using `==` and
7
- # `nil?`.
8
- #
9
- # Supported styles are: predicate, comparison.
7
+ # `nil?`. Enforcing a consistent style (either the `nil?`
8
+ # predicate or `==` comparison) improves readability.
10
9
  #
11
10
  # @example EnforcedStyle: predicate (default)
12
11
  #
@@ -43,16 +42,19 @@ module RuboCop
43
42
  # @!method nil_check?(node)
44
43
  def_node_matcher :nil_check?, '(send _ :nil?)'
45
44
 
45
+ # rubocop:disable-next Metrics/AbcSize
46
46
  def on_send(node)
47
+ return unless node.receiver
48
+
47
49
  style_check?(node) do
48
50
  add_offense(node.loc.selector) do |corrector|
49
- new_code = if prefer_comparison?
50
- node.source.sub('.nil?', ' == nil')
51
- else
52
- node.source.sub(/\s*={2,3}\s*nil/, '.nil?')
53
- end
54
-
55
- corrector.replace(node, new_code)
51
+ if prefer_comparison?
52
+ range = node.loc.dot.join(node.loc.selector.end)
53
+ corrector.replace(range, ' == nil')
54
+ else
55
+ range = node.receiver.source_range.end.join(node.source_range.end)
56
+ corrector.replace(range, '.nil?')
57
+ end
56
58
 
57
59
  parent = node.parent
58
60
  corrector.wrap(node, '(', ')') if parent.respond_to?(:method?) && parent.method?(:!)