rubocop 1.53.1 → 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 +25 -3
  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 +20 -2
  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
@@ -7,6 +7,10 @@ module RuboCop
7
7
  # `shuffle.last`, and `shuffle[]` and change them to use
8
8
  # `sample` instead.
9
9
  #
10
+ # NOTE: An offense involving a `random:` argument is registered but not autocorrected:
11
+ # `shuffle` and `sample` consume the given generator differently, so for a seeded generator
12
+ # the correction would select different elements.
13
+ #
10
14
  # @example
11
15
  # # bad
12
16
  # [1, 2, 3].shuffle.first
@@ -35,7 +39,7 @@ module RuboCop
35
39
 
36
40
  # @!method sample_candidate?(node)
37
41
  def_node_matcher :sample_candidate?, <<~PATTERN
38
- (send $(send _ :shuffle $...) ${:#{RESTRICT_ON_SEND.join(' :')}} $...)
42
+ (call $(call _ :shuffle $...) ${:#{RESTRICT_ON_SEND.join(' :')}} $...)
39
43
  PATTERN
40
44
 
41
45
  def on_send(node)
@@ -45,13 +49,16 @@ module RuboCop
45
49
  range = source_range(shuffle_node, node)
46
50
  message = message(shuffle_arg, method, method_args, range)
47
51
 
48
- add_offense(range, message: message) do |corrector|
49
- corrector.replace(
50
- source_range(shuffle_node, node), correction(shuffle_arg, method, method_args)
51
- )
52
+ if shuffle_arg.empty?
53
+ add_offense(range, message: message) do |corrector|
54
+ corrector.replace(range, correction(shuffle_arg, method, method_args))
55
+ end
56
+ else
57
+ add_offense(range, message: message)
52
58
  end
53
59
  end
54
60
  end
61
+ alias on_csend on_send
55
62
 
56
63
  private
57
64
 
@@ -91,7 +98,7 @@ module RuboCop
91
98
  second.int_type? ? second.to_a.first : :unknown
92
99
  end
93
100
 
94
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
101
+ # rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
95
102
  def range_size(range_node)
96
103
  vals = range_node.to_a
97
104
  return :unknown unless vals.all? { |val| val.nil? || val.int_type? }
@@ -106,12 +113,9 @@ module RuboCop
106
113
  (low..high).size
107
114
  end
108
115
  end
109
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
110
116
 
111
117
  def source_range(shuffle_node, node)
112
- Parser::Source::Range.new(shuffle_node.source_range.source_buffer,
113
- shuffle_node.loc.selector.begin_pos,
114
- node.source_range.end_pos)
118
+ shuffle_node.loc.selector.join(node.source_range.end)
115
119
  end
116
120
 
117
121
  def message(shuffle_arg, method, method_args, range)
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Looks for places where a subset of an Enumerable (array,
7
+ # range, set, etc.; see note below) is calculated based on a class type
8
+ # check, and suggests `grep` or `grep_v` instead.
9
+ #
10
+ # NOTE: Hashes do not behave as you may expect with `grep`, which
11
+ # means that `hash.grep` is not equivalent to `hash.select`. Although
12
+ # RuboCop is limited by static analysis, this cop attempts to avoid
13
+ # registering an offense when the receiver is a hash (hash literal,
14
+ # `Hash.new`, `Hash#[]`, or `to_h`/`to_hash`).
15
+ #
16
+ # @safety
17
+ # Autocorrection is marked as unsafe because the cop cannot guarantee
18
+ # that the receiver is actually an array by static analysis, so the
19
+ # correction may not be actually equivalent.
20
+ #
21
+ # @example
22
+ # # bad (select or find_all)
23
+ # array.select { |x| x.is_a?(Foo) }
24
+ # array.select { |x| x.kind_of?(Foo) }
25
+ #
26
+ # # bad (reject)
27
+ # array.reject { |x| x.is_a?(Foo) }
28
+ #
29
+ # # bad (negative form)
30
+ # array.reject { |x| !x.is_a?(Foo) }
31
+ #
32
+ # # good
33
+ # array.grep(Foo)
34
+ # array.grep_v(Foo)
35
+ class SelectByKind < Base
36
+ extend AutoCorrector
37
+ include RangeHelp
38
+
39
+ MSG = 'Prefer `%<replacement>s` to `%<original_method>s` with a kind check.'
40
+ RESTRICT_ON_SEND = %i[select filter find_all reject].freeze
41
+ SELECT_METHODS = %i[select filter find_all].freeze
42
+ CLASS_CHECK_METHODS = %i[is_a? kind_of?].to_set.freeze
43
+
44
+ # @!method class_check?(node)
45
+ def_node_matcher :class_check?, <<~PATTERN
46
+ {
47
+ (block call (args (arg $_)) ${(send (lvar _) %CLASS_CHECK_METHODS _)})
48
+ (block call (args (arg $_)) ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)})
49
+ (numblock call $1 ${(send (lvar _) %CLASS_CHECK_METHODS _)})
50
+ (numblock call $1 ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)})
51
+ (itblock call $_ ${(send (lvar _) %CLASS_CHECK_METHODS _)})
52
+ (itblock call $_ ${(send (send (lvar _) %CLASS_CHECK_METHODS _) :!)})
53
+ }
54
+ PATTERN
55
+
56
+ # Returns true if a node appears to return a hash
57
+ # @!method creates_hash?(node)
58
+ def_node_matcher :creates_hash?, <<~PATTERN
59
+ {
60
+ (call (const _ :Hash) {:new :[]} ...)
61
+ (block (call (const _ :Hash) :new ...) ...)
62
+ (call _ { :to_h :to_hash } ...)
63
+ }
64
+ PATTERN
65
+
66
+ # @!method env_const?(node)
67
+ def_node_matcher :env_const?, <<~PATTERN
68
+ (const {nil? cbase} :ENV)
69
+ PATTERN
70
+
71
+ # @!method calls_lvar?(node, name)
72
+ def_node_matcher :calls_lvar?, <<~PATTERN
73
+ (send (lvar %1) %CLASS_CHECK_METHODS _)
74
+ PATTERN
75
+
76
+ # @!method negated_calls_lvar?(node, name)
77
+ def_node_matcher :negated_calls_lvar?, <<~PATTERN
78
+ (send (send (lvar %1) %CLASS_CHECK_METHODS _) :!)
79
+ PATTERN
80
+
81
+ def on_send(node)
82
+ return unless (block_node = node.block_node)
83
+ return if block_node.body&.begin_type?
84
+ return if receiver_allowed?(block_node.receiver)
85
+ return unless (class_check_send_node = extract_send_node(block_node))
86
+
87
+ replacement = replacement(class_check_send_node, node)
88
+ class_constant = find_class_constant(class_check_send_node)
89
+
90
+ register_offense(node, block_node, class_constant, replacement)
91
+ end
92
+ alias on_csend on_send
93
+
94
+ private
95
+
96
+ def receiver_allowed?(node)
97
+ return false unless node
98
+
99
+ node.hash_type? || creates_hash?(node) || env_const?(node)
100
+ end
101
+
102
+ def replacement(class_check_send_node, node)
103
+ negated = negated?(class_check_send_node)
104
+
105
+ method_name = node.method_name
106
+
107
+ if SELECT_METHODS.include?(method_name)
108
+ negated ? 'grep_v' : 'grep'
109
+ else # reject
110
+ negated ? 'grep' : 'grep_v'
111
+ end
112
+ end
113
+
114
+ def register_offense(node, block_node, class_constant, replacement)
115
+ message = format(MSG, replacement: replacement, original_method: node.method_name)
116
+
117
+ add_offense(block_node, message: message) do |corrector|
118
+ if class_constant
119
+ range = range_between(node.loc.selector.begin_pos, block_node.loc.end.end_pos)
120
+ corrector.replace(range, "#{replacement}(#{class_constant.source})")
121
+ end
122
+ end
123
+ end
124
+
125
+ def extract_send_node(block_node)
126
+ return unless (block_arg_name, class_check_send_node = class_check?(block_node))
127
+
128
+ block_arg_name = :"_#{block_arg_name}" if block_node.numblock_type?
129
+ block_arg_name = :it if block_node.type?(:itblock)
130
+
131
+ inner_node = unwrap_negation(class_check_send_node)
132
+
133
+ if calls_lvar?(inner_node, block_arg_name) ||
134
+ negated_calls_lvar?(class_check_send_node, block_arg_name)
135
+ class_check_send_node
136
+ end
137
+ end
138
+
139
+ def negated?(class_check_send_node)
140
+ class_check_send_node.send_type? && class_check_send_node.method?(:!)
141
+ end
142
+
143
+ def unwrap_negation(node)
144
+ if node.send_type? && node.method?(:!)
145
+ node.receiver
146
+ else
147
+ node
148
+ end
149
+ end
150
+
151
+ def find_class_constant(node)
152
+ inner_node = unwrap_negation(node)
153
+ inner_node.first_argument if inner_node.send_type?
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Looks for places where a subset of an Enumerable (array,
7
+ # range, set, etc.; see note below) is calculated based on a range
8
+ # check, and suggests `grep` or `grep_v` instead.
9
+ #
10
+ # NOTE: Hashes do not behave as you may expect with `grep`, which
11
+ # means that `hash.grep` is not equivalent to `hash.select`. Although
12
+ # RuboCop is limited by static analysis, this cop attempts to avoid
13
+ # registering an offense when the receiver is a hash (hash literal,
14
+ # `Hash.new`, `Hash#[]`, or `to_h`/`to_hash`).
15
+ #
16
+ # @safety
17
+ # Autocorrection is marked as unsafe because the cop cannot guarantee
18
+ # that the receiver is actually an array by static analysis, so the
19
+ # correction may not be actually equivalent.
20
+ #
21
+ # @example
22
+ # # bad (select or find_all)
23
+ # array.select { |x| x.between?(1, 10) }
24
+ # array.select { |x| (1..10).cover?(x) }
25
+ # array.select { |x| (1..10).include?(x) }
26
+ #
27
+ # # bad (reject)
28
+ # array.reject { |x| x.between?(1, 10) }
29
+ #
30
+ # # bad (find or detect)
31
+ # array.find { |x| x.between?(1, 10) }
32
+ # array.detect { |x| (1..10).cover?(x) }
33
+ #
34
+ # # bad (negative form)
35
+ # array.reject { |x| !x.between?(1, 10) }
36
+ # array.find { |x| !(1..10).cover?(x) }
37
+ #
38
+ # # good
39
+ # array.grep(1..10)
40
+ # array.grep_v(1..10)
41
+ # array.grep(1..10).first
42
+ # array.grep_v(1..10).first
43
+ class SelectByRange < Base
44
+ extend AutoCorrector
45
+ include RangeHelp
46
+
47
+ MSG = 'Prefer `%<replacement>s` to `%<original_method>s` with a range check.'
48
+ RESTRICT_ON_SEND = %i[select filter find_all reject find detect].freeze
49
+ SELECT_METHODS = %i[select filter find_all].freeze
50
+ FIND_METHODS = %i[find detect].freeze
51
+
52
+ # @!method range_check?(node)
53
+ # Matches: x.between?(min, max) or (min..max).cover?(x) or (min..max).include?(x)
54
+ def_node_matcher :range_check?, <<~PATTERN
55
+ {
56
+ (block call (args (arg $_)) ${(send (lvar _) :between? _ _)})
57
+ (block call (args (arg $_)) ${(send {range (begin range)} {:cover? :include?} (lvar _))})
58
+ (block call (args (arg $_)) ${(send (send (lvar _) :between? _ _) :!)})
59
+ (block call (args (arg $_)) ${(send (send {range (begin range)} {:cover? :include?} (lvar _)) :!)})
60
+ (block call (args (arg $_)) ${(send (begin (send (lvar _) :between? _ _)) :!)})
61
+ (block call (args (arg $_)) ${(send (begin (send {range (begin range)} {:cover? :include?} (lvar _))) :!)})
62
+ (numblock call $1 ${(send (lvar _) :between? _ _)})
63
+ (numblock call $1 ${(send {range (begin range)} {:cover? :include?} (lvar _))})
64
+ (numblock call $1 ${(send (send (lvar _) :between? _ _) :!)})
65
+ (numblock call $1 ${(send (send {range (begin range)} {:cover? :include?} (lvar _)) :!)})
66
+ (numblock call $1 ${(send (begin (send (lvar _) :between? _ _)) :!)})
67
+ (numblock call $1 ${(send (begin (send {range (begin range)} {:cover? :include?} (lvar _))) :!)})
68
+ (itblock call $_ ${(send (lvar _) :between? _ _)})
69
+ (itblock call $_ ${(send {range (begin range)} {:cover? :include?} (lvar _))})
70
+ (itblock call $_ ${(send (send (lvar _) :between? _ _) :!)})
71
+ (itblock call $_ ${(send (send {range (begin range)} {:cover? :include?} (lvar _)) :!)})
72
+ (itblock call $_ ${(send (begin (send (lvar _) :between? _ _)) :!)})
73
+ (itblock call $_ ${(send (begin (send {range (begin range)} {:cover? :include?} (lvar _))) :!)})
74
+ }
75
+ PATTERN
76
+
77
+ # Returns true if a node appears to return a hash
78
+ # @!method creates_hash?(node)
79
+ def_node_matcher :creates_hash?, <<~PATTERN
80
+ {
81
+ (call (const _ :Hash) {:new :[]} ...)
82
+ (block (call (const _ :Hash) :new ...) ...)
83
+ (call _ { :to_h :to_hash } ...)
84
+ }
85
+ PATTERN
86
+
87
+ # @!method env_const?(node)
88
+ def_node_matcher :env_const?, <<~PATTERN
89
+ (const {nil? cbase} :ENV)
90
+ PATTERN
91
+
92
+ # @!method between_call?(node, name)
93
+ def_node_matcher :between_call?, <<~PATTERN
94
+ (send (lvar %1) :between? _ _)
95
+ PATTERN
96
+
97
+ # @!method range_cover_call?(node, name)
98
+ def_node_matcher :range_cover_call?, <<~PATTERN
99
+ (send {range (begin range)} {:cover? :include?} (lvar %1))
100
+ PATTERN
101
+
102
+ def on_send(node)
103
+ return unless (block_node = node.block_node)
104
+ return if block_node.body&.begin_type?
105
+ return if receiver_allowed?(block_node.receiver)
106
+ return unless (range_check_send_node = extract_send_node(block_node))
107
+
108
+ replacement = replacement(range_check_send_node, node)
109
+ range_literal = find_range(range_check_send_node)
110
+
111
+ register_offense(node, block_node, range_literal, replacement)
112
+ end
113
+ alias on_csend on_send
114
+
115
+ private
116
+
117
+ def receiver_allowed?(node)
118
+ return false unless node
119
+
120
+ node.hash_type? || creates_hash?(node) || env_const?(node)
121
+ end
122
+
123
+ def replacement(range_check_send_node, node)
124
+ negated = negated?(range_check_send_node)
125
+ method_name = node.method_name
126
+
127
+ if SELECT_METHODS.include?(method_name)
128
+ negated ? 'grep_v' : 'grep'
129
+ elsif FIND_METHODS.include?(method_name)
130
+ negated ? 'grep_v(...).first' : 'grep(...).first'
131
+ else # reject
132
+ negated ? 'grep' : 'grep_v'
133
+ end
134
+ end
135
+
136
+ def register_offense(node, block_node, range_literal, replacement)
137
+ message = format(MSG, replacement: replacement, original_method: node.method_name)
138
+
139
+ add_offense(block_node, message: message) do |corrector|
140
+ if range_literal
141
+ range = range_between(node.loc.selector.begin_pos, block_node.loc.end.end_pos)
142
+ grep_method = replacement.include?('grep_v') ? 'grep_v' : 'grep'
143
+ suffix = replacement.include?('.first') ? '.first' : ''
144
+ corrector.replace(range, "#{grep_method}(#{range_literal})#{suffix}")
145
+ end
146
+ end
147
+ end
148
+
149
+ def extract_send_node(block_node)
150
+ return unless (block_arg_name, range_check_send_node = range_check?(block_node))
151
+
152
+ block_arg_name = :"_#{block_arg_name}" if block_node.numblock_type?
153
+ block_arg_name = :it if block_node.type?(:itblock)
154
+
155
+ inner_node = unwrap_negation(range_check_send_node)
156
+
157
+ range_check_send_node if calls_lvar_in_range_check?(inner_node, block_arg_name)
158
+ end
159
+
160
+ def calls_lvar_in_range_check?(node, block_arg_name)
161
+ between_call?(node, block_arg_name) || range_cover_call?(node, block_arg_name)
162
+ end
163
+
164
+ def negated?(range_check_send_node)
165
+ range_check_send_node.send_type? && range_check_send_node.method?(:!)
166
+ end
167
+
168
+ def unwrap_negation(node)
169
+ if node.send_type? && node.method?(:!)
170
+ receiver = node.receiver
171
+ receiver = receiver.children.first if receiver.begin_type?
172
+ receiver
173
+ else
174
+ node
175
+ end
176
+ end
177
+
178
+ def find_range(node)
179
+ inner = unwrap_negation(node)
180
+
181
+ if inner.method?(:between?)
182
+ # x.between?(min, max) -> min..max
183
+ min = inner.first_argument.source
184
+ max = inner.arguments[1].source
185
+ "#{min}..#{max}"
186
+ else
187
+ # (min..max).cover?(x) or (min..max).include?(x)
188
+ receiver = inner.receiver
189
+ # Unwrap begin node from parentheses
190
+ receiver = receiver.children.first if receiver.begin_type?
191
+ receiver.source
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Looks for places where an subset of an Enumerable (array,
6
+ # Looks for places where a subset of an Enumerable (array,
7
7
  # range, set, etc.; see note below) is calculated based on a `Regexp`
8
8
  # match, and suggests `grep` or `grep_v` instead.
9
9
  #
@@ -27,7 +27,7 @@ module RuboCop
27
27
  # so the correction may not be actually equivalent.
28
28
  #
29
29
  # @example
30
- # # bad (select or find_all)
30
+ # # bad (select, filter, or find_all)
31
31
  # array.select { |x| x.match? /regexp/ }
32
32
  # array.select { |x| /regexp/.match?(x) }
33
33
  # array.select { |x| x =~ /regexp/ }
@@ -39,6 +39,9 @@ module RuboCop
39
39
  # array.reject { |x| x =~ /regexp/ }
40
40
  # array.reject { |x| /regexp/ =~ x }
41
41
  #
42
+ # # bad (negative form)
43
+ # array.reject { |x| !x.match? /regexp/ }
44
+ #
42
45
  # # good
43
46
  # array.grep(regexp)
44
47
  # array.grep_v(regexp)
@@ -47,16 +50,20 @@ module RuboCop
47
50
  include RangeHelp
48
51
 
49
52
  MSG = 'Prefer `%<replacement>s` to `%<original_method>s` with a regexp match.'
50
- RESTRICT_ON_SEND = %i[select find_all reject].freeze
51
- REPLACEMENTS = { select: 'grep', find_all: 'grep', reject: 'grep_v' }.freeze
52
- OPPOSITE_REPLACEMENTS = { select: 'grep_v', find_all: 'grep_v', reject: 'grep' }.freeze
53
- REGEXP_METHODS = %i[match? =~ !~].to_set.freeze
53
+ RESTRICT_ON_SEND = %i[select filter find_all reject].freeze
54
+ SELECT_METHODS = %i[select filter find_all].freeze
55
+ REGEXP_METHODS = %i[match? =~].to_set.freeze
56
+ REGEXP_METHODS_NEGATED = %i[!~].to_set.freeze
54
57
 
55
58
  # @!method regexp_match?(node)
56
59
  def_node_matcher :regexp_match?, <<~PATTERN
57
60
  {
58
- (block send (args (arg $_)) ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
59
- (numblock send $1 ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
61
+ (block call (args (arg $_)) ${(send _ %REGEXP_METHODS _) (send _ %REGEXP_METHODS_NEGATED _) match-with-lvasgn})
62
+ (block call (args (arg $_)) ${(send (send _ %REGEXP_METHODS _) :!) (send (begin (send _ %REGEXP_METHODS _)) :!) (send match-with-lvasgn :!) (send (begin match-with-lvasgn) :!)})
63
+ (numblock call $1 ${(send _ %REGEXP_METHODS _) (send _ %REGEXP_METHODS_NEGATED _) match-with-lvasgn})
64
+ (numblock call $1 ${(send (send _ %REGEXP_METHODS _) :!) (send (begin (send _ %REGEXP_METHODS _)) :!) (send match-with-lvasgn :!) (send (begin match-with-lvasgn) :!)})
65
+ (itblock call $_ ${(send _ %REGEXP_METHODS _) (send _ %REGEXP_METHODS_NEGATED _) match-with-lvasgn})
66
+ (itblock call $_ ${(send (send _ %REGEXP_METHODS _) :!) (send (begin (send _ %REGEXP_METHODS _)) :!) (send match-with-lvasgn :!) (send (begin match-with-lvasgn) :!)})
60
67
  }
61
68
  PATTERN
62
69
 
@@ -64,9 +71,9 @@ module RuboCop
64
71
  # @!method creates_hash?(node)
65
72
  def_node_matcher :creates_hash?, <<~PATTERN
66
73
  {
67
- (send (const _ :Hash) {:new :[]} ...)
68
- (block (send (const _ :Hash) :new ...) ...)
69
- (send _ { :to_h :to_hash } ...)
74
+ (call (const _ :Hash) {:new :[]} ...)
75
+ (block (call (const _ :Hash) :new ...) ...)
76
+ (call _ { :to_h :to_hash } ...)
70
77
  }
71
78
  PATTERN
72
79
 
@@ -81,11 +88,18 @@ module RuboCop
81
88
  (send (lvar %1) ...)
82
89
  (send ... (lvar %1))
83
90
  (match-with-lvasgn regexp (lvar %1))
91
+ (send (send (lvar %1) ...) :!)
92
+ (send (send ... (lvar %1)) :!)
93
+ (send (match-with-lvasgn regexp (lvar %1)) :!)
94
+ (send (begin (send (lvar %1) ...)) :!)
95
+ (send (begin (send ... (lvar %1))) :!)
96
+ (send (begin (match-with-lvasgn regexp (lvar %1))) :!)
84
97
  }
85
98
  PATTERN
86
99
 
87
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
100
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
88
101
  def on_send(node)
102
+ return if target_ruby_version < 2.6 && node.method?(:filter)
89
103
  return unless (block_node = node.block_node)
90
104
  return if block_node.body&.begin_type?
91
105
  return if receiver_allowed?(block_node.receiver)
@@ -93,13 +107,13 @@ module RuboCop
93
107
  return if match_predicate_without_receiver?(regexp_method_send_node)
94
108
 
95
109
  replacement = replacement(regexp_method_send_node, node)
96
- return if target_ruby_version <= 2.2 && replacement == 'grep_v'
110
+ return if target_ruby_version <= 2.2 && replacement.include?('grep_v')
97
111
 
98
112
  regexp = find_regexp(regexp_method_send_node, block_node)
99
113
 
100
114
  register_offense(node, block_node, regexp, replacement)
101
115
  end
102
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
116
+ alias on_csend on_send
103
117
 
104
118
  private
105
119
 
@@ -110,11 +124,14 @@ module RuboCop
110
124
  end
111
125
 
112
126
  def replacement(regexp_method_send_node, node)
113
- opposite = opposite?(regexp_method_send_node)
114
-
127
+ negated = negated?(regexp_method_send_node)
115
128
  method_name = node.method_name
116
129
 
117
- opposite ? OPPOSITE_REPLACEMENTS[method_name] : REPLACEMENTS[method_name]
130
+ if SELECT_METHODS.include?(method_name)
131
+ negated ? 'grep_v' : 'grep'
132
+ else # reject
133
+ negated ? 'grep' : 'grep_v'
134
+ end
118
135
  end
119
136
 
120
137
  def register_offense(node, block_node, regexp, replacement)
@@ -133,28 +150,47 @@ module RuboCop
133
150
  return unless (block_arg_name, regexp_method_send_node = regexp_match?(block_node))
134
151
 
135
152
  block_arg_name = :"_#{block_arg_name}" if block_node.numblock_type?
153
+ block_arg_name = :it if block_node.type?(:itblock)
154
+
136
155
  return unless calls_lvar?(regexp_method_send_node, block_arg_name)
137
156
 
138
157
  regexp_method_send_node
139
158
  end
140
159
 
141
- def opposite?(regexp_method_send_node)
142
- regexp_method_send_node.send_type? && regexp_method_send_node.method?(:!~)
160
+ def negated?(regexp_method_send_node)
161
+ return true if regexp_method_send_node.send_type? && regexp_method_send_node.method?(:!)
162
+
163
+ inner = unwrap_negation(regexp_method_send_node)
164
+ inner.send_type? && inner.method?(:!~)
165
+ end
166
+
167
+ def unwrap_negation(node)
168
+ if node.send_type? && node.method?(:!)
169
+ receiver = node.receiver
170
+ receiver = receiver.children.first if receiver.begin_type?
171
+ receiver
172
+ else
173
+ node
174
+ end
143
175
  end
144
176
 
145
177
  def find_regexp(node, block)
146
- return node.child_nodes.first if node.match_with_lvasgn_type?
178
+ inner = unwrap_negation(node)
179
+
180
+ return inner.child_nodes.first if inner.match_with_lvasgn_type?
147
181
 
148
- if node.receiver.lvar_type? &&
149
- (block.numblock_type? || node.receiver.source == block.arguments.first.source)
150
- node.first_argument
151
- elsif node.first_argument.lvar_type?
152
- node.receiver
182
+ if inner.receiver.lvar_type? &&
183
+ (block.type?(:numblock, :itblock) ||
184
+ inner.receiver.source == block.first_argument.source)
185
+ inner.first_argument
186
+ elsif inner.first_argument&.lvar_type?
187
+ inner.receiver
153
188
  end
154
189
  end
155
190
 
156
191
  def match_predicate_without_receiver?(node)
157
- node.send_type? && node.method?(:match?) && node.receiver.nil?
192
+ inner = unwrap_negation(node)
193
+ inner.send_type? && inner.method?(:match?) && inner.receiver.nil?
158
194
  end
159
195
  end
160
196
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Enforces the use the shorthand for self-assignment.
6
+ # Enforces the use of the shorthand for self-assignment.
7
7
  #
8
8
  # @example
9
9
  #
@@ -16,7 +16,7 @@ module RuboCop
16
16
  extend AutoCorrector
17
17
 
18
18
  MSG = 'Use self-assignment shorthand `%<method>s=`.'
19
- OPS = %i[+ - * ** / | &].freeze
19
+ OPS = %i[+ - * ** / % ^ << >> | &].freeze
20
20
 
21
21
  def self.autocorrect_incompatible_with
22
22
  [Layout::SpaceAroundOperators]
@@ -37,33 +37,29 @@ module RuboCop
37
37
  private
38
38
 
39
39
  def check(node, var_type)
40
- var_name, rhs = *node
41
- return unless rhs
40
+ return unless (rhs = node.expression)
42
41
 
43
- if rhs.send_type?
44
- check_send_node(node, rhs, var_name, var_type)
42
+ if rhs.send_type? && rhs.arguments.one?
43
+ check_send_node(node, rhs, node.name, var_type)
45
44
  elsif rhs.operator_keyword?
46
- check_boolean_node(node, rhs, var_name, var_type)
45
+ check_boolean_node(node, rhs, node.name, var_type)
47
46
  end
48
47
  end
49
48
 
50
49
  def check_send_node(node, rhs, var_name, var_type)
51
- receiver, method_name, *_args = *rhs
52
- return unless OPS.include?(method_name)
50
+ return unless OPS.include?(rhs.method_name)
53
51
 
54
52
  target_node = s(var_type, var_name)
55
- return unless receiver == target_node
53
+ return unless rhs.receiver == target_node
56
54
 
57
- add_offense(node, message: format(MSG, method: method_name)) do |corrector|
55
+ add_offense(node, message: format(MSG, method: rhs.method_name)) do |corrector|
58
56
  autocorrect(corrector, node)
59
57
  end
60
58
  end
61
59
 
62
60
  def check_boolean_node(node, rhs, var_name, var_type)
63
- first_operand, _second_operand = *rhs
64
-
65
61
  target_node = s(var_type, var_name)
66
- return unless first_operand == target_node
62
+ return unless rhs.lhs == target_node
67
63
 
68
64
  operator = rhs.loc.operator.source
69
65
  add_offense(node, message: format(MSG, method: operator)) do |corrector|
@@ -72,7 +68,7 @@ module RuboCop
72
68
  end
73
69
 
74
70
  def autocorrect(corrector, node)
75
- _var_name, rhs = *node
71
+ rhs = node.expression
76
72
 
77
73
  if rhs.send_type?
78
74
  autocorrect_send_node(corrector, node, rhs)
@@ -82,13 +78,11 @@ module RuboCop
82
78
  end
83
79
 
84
80
  def autocorrect_send_node(corrector, node, rhs)
85
- _receiver, method_name, args = *rhs
86
- apply_autocorrect(corrector, node, rhs, method_name.to_s, args)
81
+ apply_autocorrect(corrector, node, rhs, rhs.method_name, rhs.first_argument)
87
82
  end
88
83
 
89
84
  def autocorrect_boolean_node(corrector, node, rhs)
90
- _first_operand, second_operand = *rhs
91
- apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, second_operand)
85
+ apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, rhs.rhs)
92
86
  end
93
87
 
94
88
  def apply_autocorrect(corrector, node, rhs, operator, new_rhs)