rubocop 1.71.1 → 1.92.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (712) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +886 -168
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +47 -4
  7. data/exe/rubocop +2 -9
  8. data/lib/rubocop/cache_config.rb +29 -0
  9. data/lib/rubocop/cached_data.rb +50 -5
  10. data/lib/rubocop/changed_files.rb +134 -0
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  12. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  13. data/lib/rubocop/cli/command/execute_runner.rb +54 -3
  14. data/lib/rubocop/cli/command/explain.rb +34 -0
  15. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  16. data/lib/rubocop/cli/command/lsp.rb +1 -1
  17. data/lib/rubocop/cli/command/mcp.rb +19 -0
  18. data/lib/rubocop/cli/command/show_cops.rb +8 -2
  19. data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
  20. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  21. data/lib/rubocop/cli.rb +59 -17
  22. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  23. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  24. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  25. data/lib/rubocop/comment_config.rb +98 -45
  26. data/lib/rubocop/config.rb +137 -19
  27. data/lib/rubocop/config_finder.rb +1 -1
  28. data/lib/rubocop/config_loader.rb +75 -49
  29. data/lib/rubocop/config_loader_resolver.rb +124 -33
  30. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  31. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  32. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  33. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  34. data/lib/rubocop/config_obsoletion.rb +47 -3
  35. data/lib/rubocop/config_store.rb +7 -2
  36. data/lib/rubocop/config_validator.rb +75 -12
  37. data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
  38. data/lib/rubocop/cop/badge.rb +10 -2
  39. data/lib/rubocop/cop/base.rb +128 -35
  40. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
  41. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  42. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
  43. data/lib/rubocop/cop/bundler.rb +19 -0
  44. data/lib/rubocop/cop/commissioner.rb +13 -11
  45. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  46. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  47. data/lib/rubocop/cop/corrector.rb +4 -4
  48. data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
  49. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  50. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +37 -7
  51. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +31 -4
  54. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +35 -5
  55. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  56. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +73 -2
  57. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  58. data/lib/rubocop/cop/correctors.rb +28 -0
  59. data/lib/rubocop/cop/documentation.rb +3 -4
  60. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  61. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  62. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  63. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  64. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  65. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -9
  66. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  67. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  68. data/lib/rubocop/cop/gemspec.rb +22 -0
  69. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  70. data/lib/rubocop/cop/generator.rb +5 -1
  71. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  72. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  73. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  74. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  75. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  76. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +16 -20
  77. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  78. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  79. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  80. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +85 -0
  81. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
  82. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  83. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  84. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  85. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  86. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  87. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  88. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  89. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  90. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  91. data/lib/rubocop/cop/layout/argument_alignment.rb +9 -3
  92. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  93. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  94. data/lib/rubocop/cop/layout/block_alignment.rb +86 -4
  95. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  96. data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
  97. data/lib/rubocop/cop/layout/class_structure.rb +191 -41
  98. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  99. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  100. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  101. data/lib/rubocop/cop/layout/def_end_alignment.rb +5 -1
  102. data/lib/rubocop/cop/layout/dot_position.rb +27 -17
  103. data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
  104. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  105. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
  106. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  107. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
  108. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  109. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  110. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  111. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  112. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  113. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +22 -5
  115. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  116. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  117. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  118. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  119. data/lib/rubocop/cop/layout/end_alignment.rb +23 -15
  120. data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
  121. data/lib/rubocop/cop/layout/first_argument_indentation.rb +82 -3
  122. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  123. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +41 -0
  124. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +36 -23
  125. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  126. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  127. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  128. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  129. data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
  130. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +9 -5
  131. data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
  132. data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
  133. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  134. data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
  135. data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
  136. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
  137. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  138. data/lib/rubocop/cop/layout/line_length.rb +300 -31
  139. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
  140. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  141. data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
  142. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +65 -56
  143. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
  144. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +270 -40
  145. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  146. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  147. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  148. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  149. data/lib/rubocop/cop/layout/redundant_line_break.rb +111 -7
  150. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
  151. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  152. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  153. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  154. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  155. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  156. data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -3
  157. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  158. data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
  159. data/lib/rubocop/cop/layout/space_before_block_braces.rb +5 -1
  160. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  161. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  162. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +55 -36
  163. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
  164. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  165. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
  166. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  167. data/lib/rubocop/cop/layout.rb +114 -0
  168. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  169. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  170. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  171. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  172. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
  173. data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
  174. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +6 -1
  175. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  176. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  177. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  178. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  179. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  180. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  181. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  182. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  183. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
  184. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  185. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  186. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  187. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  188. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  189. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  190. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  191. data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
  192. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  193. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  194. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  195. data/lib/rubocop/cop/lint/empty_conditional_body.rb +22 -65
  196. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  197. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  198. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  199. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  200. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  201. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  202. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  203. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  204. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
  205. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  206. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  207. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  208. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  209. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  210. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  211. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  212. data/lib/rubocop/cop/lint/literal_as_condition.rb +152 -11
  213. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  214. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
  215. data/lib/rubocop/cop/lint/loop.rb +24 -2
  216. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  217. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
  218. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  219. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  220. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  221. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  222. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  223. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  224. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  225. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  226. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  227. data/lib/rubocop/cop/lint/number_conversion.rb +22 -11
  228. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  229. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  230. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  231. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  232. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  233. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  234. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  235. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  236. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
  237. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  238. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
  239. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  240. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
  241. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
  242. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  243. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  244. data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
  245. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  246. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  247. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  248. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  249. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  250. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  251. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  252. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  253. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  254. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
  255. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +56 -6
  256. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  257. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  258. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  259. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  260. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  261. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  262. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  263. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  264. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  265. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  266. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  267. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  268. data/lib/rubocop/cop/lint/symbol_conversion.rb +22 -4
  269. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  270. data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
  271. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  272. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  273. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  274. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
  275. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  276. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  277. data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
  278. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  279. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  280. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  281. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  282. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  283. data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
  284. data/lib/rubocop/cop/lint/useless_assignment.rb +63 -27
  285. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  286. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  287. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  288. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  289. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  290. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
  291. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
  292. data/lib/rubocop/cop/lint/useless_setter_call.rb +11 -5
  293. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  294. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  295. data/lib/rubocop/cop/lint/void.rb +68 -22
  296. data/lib/rubocop/cop/lint.rb +179 -0
  297. data/lib/rubocop/cop/message_annotator.rb +7 -3
  298. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  299. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  300. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  301. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  302. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  303. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  304. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  305. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  306. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  307. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  308. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  309. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  310. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  311. data/lib/rubocop/cop/metrics.rb +31 -0
  312. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  313. data/lib/rubocop/cop/migration.rb +13 -0
  314. data/lib/rubocop/cop/mixin/alignment.rb +7 -3
  315. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  316. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  317. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  318. data/lib/rubocop/cop/mixin/check_line_breakable.rb +50 -28
  319. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +13 -9
  320. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  321. data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
  322. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  323. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  324. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  325. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +13 -2
  326. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  327. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
  328. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  329. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  330. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  331. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  332. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  333. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +68 -21
  334. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
  335. data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
  336. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  337. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  338. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  339. data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
  340. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  341. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  342. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  343. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  344. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
  345. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
  346. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  347. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  348. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
  349. data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
  350. data/lib/rubocop/cop/mixin/range_help.rb +16 -5
  351. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
  352. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  353. data/lib/rubocop/cop/mixin/statement_modifier.rb +69 -12
  354. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  355. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  356. data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
  357. data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
  358. data/lib/rubocop/cop/mixin.rb +93 -0
  359. data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
  360. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  361. data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
  362. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  363. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  364. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  365. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  366. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  367. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
  368. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  369. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  370. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +65 -8
  371. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -7
  372. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  373. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  374. data/lib/rubocop/cop/naming.rb +31 -0
  375. data/lib/rubocop/cop/offense.rb +108 -9
  376. data/lib/rubocop/cop/registry.rb +234 -65
  377. data/lib/rubocop/cop/security/eval.rb +17 -3
  378. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  379. data/lib/rubocop/cop/security/json_load.rb +45 -11
  380. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  381. data/lib/rubocop/cop/security/open.rb +1 -0
  382. data/lib/rubocop/cop/security.rb +19 -0
  383. data/lib/rubocop/cop/severity.rb +12 -0
  384. data/lib/rubocop/cop/style/access_modifier_declarations.rb +83 -14
  385. data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
  386. data/lib/rubocop/cop/style/alias.rb +33 -8
  387. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  388. data/lib/rubocop/cop/style/and_or.rb +8 -3
  389. data/lib/rubocop/cop/style/arguments_forwarding.rb +80 -39
  390. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  391. data/lib/rubocop/cop/style/array_intersect.rb +136 -38
  392. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  393. data/lib/rubocop/cop/style/array_join.rb +4 -2
  394. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  395. data/lib/rubocop/cop/style/attr.rb +8 -6
  396. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  397. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  398. data/lib/rubocop/cop/style/bitwise_predicate.rb +13 -5
  399. data/lib/rubocop/cop/style/block_delimiters.rb +77 -40
  400. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  401. data/lib/rubocop/cop/style/case_like_if.rb +12 -11
  402. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  403. data/lib/rubocop/cop/style/class_and_module_children.rb +181 -27
  404. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  405. data/lib/rubocop/cop/style/class_methods_definitions.rb +26 -5
  406. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  407. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  408. data/lib/rubocop/cop/style/collection_querying.rb +200 -0
  409. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  410. data/lib/rubocop/cop/style/combinable_loops.rb +92 -9
  411. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  412. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  413. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  414. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  415. data/lib/rubocop/cop/style/concat_array_literals.rb +65 -9
  416. data/lib/rubocop/cop/style/conditional_assignment.rb +58 -24
  417. data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
  418. data/lib/rubocop/cop/style/copyright.rb +27 -12
  419. data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
  420. data/lib/rubocop/cop/style/date_time.rb +4 -4
  421. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  422. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  423. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  424. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  425. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
  426. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  427. data/lib/rubocop/cop/style/documentation.rb +53 -6
  428. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  429. data/lib/rubocop/cop/style/double_negation.rb +14 -3
  430. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  431. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  432. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  433. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  434. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  435. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  436. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  437. data/lib/rubocop/cop/style/empty_literal.rb +12 -3
  438. data/lib/rubocop/cop/style/empty_method.rb +15 -9
  439. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +152 -0
  440. data/lib/rubocop/cop/style/encoding.rb +7 -1
  441. data/lib/rubocop/cop/style/end_block.rb +3 -1
  442. data/lib/rubocop/cop/style/endless_method.rb +256 -19
  443. data/lib/rubocop/cop/style/env_home.rb +4 -0
  444. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  445. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  446. data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
  447. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  448. data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
  449. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  450. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  451. data/lib/rubocop/cop/style/file_null.rb +6 -4
  452. data/lib/rubocop/cop/style/file_open.rb +84 -0
  453. data/lib/rubocop/cop/style/file_write.rb +21 -16
  454. data/lib/rubocop/cop/style/float_division.rb +43 -15
  455. data/lib/rubocop/cop/style/for.rb +61 -1
  456. data/lib/rubocop/cop/style/format_string.rb +44 -9
  457. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  458. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
  459. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  460. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  461. data/lib/rubocop/cop/style/guard_clause.rb +58 -40
  462. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +31 -9
  463. data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
  464. data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
  465. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  466. data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
  467. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  468. data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
  469. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  470. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  471. data/lib/rubocop/cop/style/identical_conditional_branches.rb +39 -11
  472. data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
  473. data/lib/rubocop/cop/style/if_unless_modifier.rb +101 -70
  474. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
  475. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  476. data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
  477. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  478. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  479. data/lib/rubocop/cop/style/inverse_methods.rb +34 -8
  480. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  481. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  482. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  483. data/lib/rubocop/cop/style/it_block_parameter.rb +211 -0
  484. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  485. data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
  486. data/lib/rubocop/cop/style/lambda.rb +46 -2
  487. data/lib/rubocop/cop/style/lambda_call.rb +31 -10
  488. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  489. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  490. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  491. data/lib/rubocop/cop/style/map_into_array.rb +6 -4
  492. data/lib/rubocop/cop/style/map_join.rb +123 -0
  493. data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
  494. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  495. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +110 -27
  496. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  497. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -6
  498. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
  499. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  500. data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
  501. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  502. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  503. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  504. data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
  505. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  506. data/lib/rubocop/cop/style/module_function.rb +4 -2
  507. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  508. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  509. data/lib/rubocop/cop/style/multiline_if_modifier.rb +47 -5
  510. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  511. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  512. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  513. data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
  514. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  515. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  516. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  517. data/lib/rubocop/cop/style/mutable_constant.rb +158 -14
  518. data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
  519. data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
  520. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  521. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  522. data/lib/rubocop/cop/style/next.rb +68 -10
  523. data/lib/rubocop/cop/style/nil_comparison.rb +53 -13
  524. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  525. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  526. data/lib/rubocop/cop/style/not.rb +12 -3
  527. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  528. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  529. data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
  530. data/lib/rubocop/cop/style/object_then.rb +1 -0
  531. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  532. data/lib/rubocop/cop/style/one_line_conditional.rb +35 -15
  533. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  534. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  535. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  536. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  537. data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
  538. data/lib/rubocop/cop/style/parentheses_around_condition.rb +7 -2
  539. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  540. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
  541. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  542. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  543. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  544. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  545. data/lib/rubocop/cop/style/proc.rb +4 -2
  546. data/lib/rubocop/cop/style/raise_args.rb +28 -18
  547. data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
  548. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  549. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  550. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  551. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  552. data/lib/rubocop/cop/style/redundant_begin.rb +60 -7
  553. data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
  554. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  555. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  556. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
  557. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  558. data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
  559. data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
  560. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  561. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  562. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  563. data/lib/rubocop/cop/style/redundant_freeze.rb +13 -5
  564. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  565. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  566. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +49 -10
  567. data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
  568. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  569. data/lib/rubocop/cop/style/redundant_parentheses.rb +176 -83
  570. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  571. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
  572. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  573. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
  574. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -0
  575. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  576. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  577. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
  578. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +27 -4
  579. data/lib/rubocop/cop/style/redundant_sort.rb +45 -11
  580. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  581. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  582. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  583. data/lib/rubocop/cop/style/regexp_literal.rb +107 -29
  584. data/lib/rubocop/cop/style/require_order.rb +25 -8
  585. data/lib/rubocop/cop/style/rescue_modifier.rb +16 -12
  586. data/lib/rubocop/cop/style/return_nil.rb +19 -4
  587. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  588. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  589. data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
  590. data/lib/rubocop/cop/style/sample.rb +19 -13
  591. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  592. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  593. data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
  594. data/lib/rubocop/cop/style/self_assignment.rb +13 -16
  595. data/lib/rubocop/cop/style/semicolon.rb +56 -14
  596. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +4 -0
  597. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  598. data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
  599. data/lib/rubocop/cop/style/single_line_methods.rb +33 -11
  600. data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
  601. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  602. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +32 -6
  603. data/lib/rubocop/cop/style/static_class.rb +21 -0
  604. data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
  605. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  606. data/lib/rubocop/cop/style/struct_inheritance.rb +44 -2
  607. data/lib/rubocop/cop/style/super_arguments.rb +7 -6
  608. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  609. data/lib/rubocop/cop/style/symbol_proc.rb +35 -15
  610. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  611. data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
  612. data/lib/rubocop/cop/style/time_now.rb +41 -0
  613. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  614. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  615. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  616. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  617. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  618. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  619. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
  620. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  621. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  622. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  623. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  624. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  625. data/lib/rubocop/cop/style/word_array.rb +1 -0
  626. data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
  627. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  628. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  629. data/lib/rubocop/cop/style.rb +311 -0
  630. data/lib/rubocop/cop/team.rb +172 -49
  631. data/lib/rubocop/cop/util.rb +7 -10
  632. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  633. data/lib/rubocop/cop/variable_force/assignment.rb +8 -4
  634. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  635. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  636. data/lib/rubocop/cop/variable_force/variable.rb +42 -11
  637. data/lib/rubocop/cop/variable_force.rb +26 -9
  638. data/lib/rubocop/cops_documentation_generator.rb +49 -15
  639. data/lib/rubocop/directive_comment.rb +147 -5
  640. data/lib/rubocop/ext/regexp_node.rb +0 -1
  641. data/lib/rubocop/feature_loader.rb +0 -6
  642. data/lib/rubocop/file_patterns.rb +9 -1
  643. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  644. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  645. data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
  646. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  647. data/lib/rubocop/formatter/formatter_set.rb +7 -2
  648. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  649. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  650. data/lib/rubocop/formatter/html_formatter.rb +3 -5
  651. data/lib/rubocop/formatter/json_formatter.rb +82 -7
  652. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  653. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  654. data/lib/rubocop/formatter/offense_count_formatter.rb +5 -4
  655. data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
  656. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  657. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  658. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  659. data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
  660. data/lib/rubocop/formatter.rb +23 -21
  661. data/lib/rubocop/lockfile.rb +18 -0
  662. data/lib/rubocop/lsp/diagnostic.rb +22 -41
  663. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  664. data/lib/rubocop/lsp/routes.rb +158 -55
  665. data/lib/rubocop/lsp/runtime.rb +66 -15
  666. data/lib/rubocop/lsp/server.rb +4 -2
  667. data/lib/rubocop/lsp/stdin_runner.rb +38 -19
  668. data/lib/rubocop/lsp.rb +5 -2
  669. data/lib/rubocop/magic_comment.rb +55 -0
  670. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  671. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  672. data/lib/rubocop/mcp/scope.rb +65 -0
  673. data/lib/rubocop/mcp/server.rb +307 -0
  674. data/lib/rubocop/mcp/source_files.rb +35 -0
  675. data/lib/rubocop/offense_limit.rb +30 -0
  676. data/lib/rubocop/options.rb +166 -23
  677. data/lib/rubocop/path_util.rb +20 -5
  678. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  679. data/lib/rubocop/plugin/configuration_integrator.rb +153 -0
  680. data/lib/rubocop/plugin/load_error.rb +26 -0
  681. data/lib/rubocop/plugin/loader.rb +100 -0
  682. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  683. data/lib/rubocop/plugin.rb +46 -0
  684. data/lib/rubocop/project_index_loader.rb +82 -0
  685. data/lib/rubocop/rake_task.rb +6 -4
  686. data/lib/rubocop/remote_config.rb +18 -13
  687. data/lib/rubocop/result_cache.rb +110 -65
  688. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  689. data/lib/rubocop/rspec/expect_offense.rb +11 -7
  690. data/lib/rubocop/rspec/shared_contexts.rb +85 -3
  691. data/lib/rubocop/rspec/support.rb +4 -0
  692. data/lib/rubocop/runner.rb +368 -106
  693. data/lib/rubocop/server/cache.rb +67 -48
  694. data/lib/rubocop/server/cli.rb +2 -4
  695. data/lib/rubocop/server/client_command/base.rb +10 -0
  696. data/lib/rubocop/server/client_command/exec.rb +2 -1
  697. data/lib/rubocop/server/client_command/start.rb +11 -1
  698. data/lib/rubocop/server/core.rb +8 -0
  699. data/lib/rubocop/server.rb +14 -0
  700. data/lib/rubocop/target_finder.rb +25 -11
  701. data/lib/rubocop/target_ruby.rb +52 -23
  702. data/lib/rubocop/todo_audit.rb +111 -0
  703. data/lib/rubocop/unified_diff.rb +257 -0
  704. data/lib/rubocop/util.rb +69 -0
  705. data/lib/rubocop/version.rb +48 -10
  706. data/lib/rubocop.rb +35 -682
  707. data/lib/ruby_lsp/rubocop/addon.rb +28 -17
  708. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  709. metadata +129 -21
  710. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
  711. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  712. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -3,12 +3,17 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for inheritance from Struct.new.
6
+ # Checks for inheritance from `Struct.new`. Inheriting from `Struct.new`
7
+ # adds a superfluous level in inheritance tree.
7
8
  #
8
9
  # @safety
9
10
  # Autocorrection is unsafe because it will change the inheritance
10
11
  # tree (e.g. return value of `Module#ancestors`) of the constant.
11
12
  #
13
+ # It is also unsafe because constants that the class body resolves through its
14
+ # ancestors (e.g. one provided by an included module) fall out of scope inside
15
+ # the block.
16
+ #
12
17
  # @example
13
18
  # # bad
14
19
  # class Person < Struct.new(:first_name, :last_name)
@@ -17,12 +22,18 @@ module RuboCop
17
22
  # end
18
23
  # end
19
24
  #
25
+ # Person.ancestors
26
+ # # => [Person, #<Class:0x000000010b4e14a0>, Struct, (...)]
27
+ #
20
28
  # # good
21
29
  # Person = Struct.new(:first_name, :last_name) do
22
30
  # def age
23
31
  # 42
24
32
  # end
25
33
  # end
34
+ #
35
+ # Person.ancestors
36
+ # # => [Person, Struct, (...)]
26
37
  class StructInheritance < Base
27
38
  include RangeHelp
28
39
  extend AutoCorrector
@@ -30,11 +41,20 @@ module RuboCop
30
41
  MSG = "Don't extend an instance initialized by `Struct.new`. " \
31
42
  'Use a block to customize the struct.'
32
43
 
44
+ # When the closing parenthesis of `Struct.new` is on its own line, omitting the
45
+ # parentheses in the same pass leaves a line break before the appended `do`.
46
+ def self.autocorrect_incompatible_with
47
+ [Style::MethodCallWithArgsParentheses]
48
+ end
49
+
33
50
  def on_class(node)
34
51
  return unless struct_constructor?(node.parent_class)
52
+ return if defines_constants?(node.body)
35
53
 
36
54
  add_offense(node.parent_class) do |corrector|
37
- corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
55
+ corrector.remove(
56
+ range_with_surrounding_space(node.loc.keyword, side: :right, newlines: false)
57
+ )
38
58
  corrector.replace(node.loc.operator, '=')
39
59
 
40
60
  correct_parent(node.parent_class, corrector)
@@ -49,11 +69,22 @@ module RuboCop
49
69
 
50
70
  private
51
71
 
72
+ # Constants, including nested classes and modules, are scoped to the class when they
73
+ # are defined in a class body, but leak into the enclosing namespace once moved into a
74
+ # `Struct.new` block, so such a class cannot be rewritten as an assignment.
75
+ def defines_constants?(class_body)
76
+ return false unless class_body
77
+
78
+ class_body.each_node(:casgn, :class, :module).any?
79
+ end
80
+
52
81
  def correct_parent(parent, corrector)
53
82
  if parent.block_type?
54
83
  corrector.remove(range_with_surrounding_space(parent.loc.end, newlines: false))
55
84
  elsif (class_node = parent.parent).body.nil?
56
85
  corrector.remove(range_for_empty_class_body(class_node, parent))
86
+ elsif unparenthesized_struct_new?(parent)
87
+ wrap_unparenthesized_call_with_do(corrector, parent)
57
88
  else
58
89
  corrector.insert_after(parent, ' do')
59
90
  end
@@ -66,6 +97,17 @@ module RuboCop
66
97
  range_by_whole_lines(class_node.loc.end, include_final_newline: true)
67
98
  end
68
99
  end
100
+
101
+ def unparenthesized_struct_new?(parent)
102
+ parent.send_type? && parent.arguments.any? && !parent.parenthesized?
103
+ end
104
+
105
+ def wrap_unparenthesized_call_with_do(corrector, parent)
106
+ args_source = parent.arguments.map(&:source).join(', ')
107
+ range = parent.loc.selector.end.join(parent.source_range.end)
108
+
109
+ corrector.replace(range, "(#{args_source}) do")
110
+ end
69
111
  end
70
112
  end
71
113
  end
@@ -68,7 +68,6 @@ module RuboCop
68
68
  class SuperArguments < Base
69
69
  extend AutoCorrector
70
70
 
71
- DEF_TYPES = %i[def defs].freeze
72
71
  ASSIGN_TYPES = %i[or_asgn lvasgn].freeze
73
72
 
74
73
  MSG = 'Call `super` without arguments and parentheses when the signature is identical.'
@@ -77,6 +76,9 @@ module RuboCop
77
76
 
78
77
  def on_super(super_node)
79
78
  return unless (def_node = find_def_node(super_node))
79
+ # Zsuper passes a destructured argument as the original value, while
80
+ # `argument_list` flattens it into its parts.
81
+ return if def_node.arguments.any?(&:mlhs_type?)
80
82
 
81
83
  def_node_args = def_node.arguments.argument_list
82
84
  super_args = preprocess_super_args(super_node.arguments)
@@ -100,17 +102,17 @@ module RuboCop
100
102
  # `super` used within the block is always allowed.
101
103
  break if node.any_block_type? && !block_sends_to_super?(super_node, node)
102
104
 
103
- break node if DEF_TYPES.include?(node.type)
105
+ break node if node.any_def_type?
104
106
  end
105
107
  end
106
108
 
107
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
109
+ # rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
108
110
  def arguments_identical?(def_node, super_node, def_args, super_args)
109
111
  return false if argument_list_size_differs?(def_args, super_args, super_node)
110
112
 
111
113
  def_args.zip(super_args).each do |def_arg, super_arg|
112
114
  next if positional_arg_same?(def_arg, super_arg)
113
- next if positional_rest_arg_same(def_arg, super_arg)
115
+ next if positional_rest_arg_same?(def_arg, super_arg)
114
116
  next if keyword_arg_same?(def_arg, super_arg)
115
117
  next if keyword_rest_arg_same?(def_arg, super_arg)
116
118
  next if block_arg_same?(def_node, super_node, def_arg, super_arg)
@@ -121,7 +123,6 @@ module RuboCop
121
123
 
122
124
  true
123
125
  end
124
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
125
126
 
126
127
  def argument_list_size_differs?(def_args, super_args, super_node)
127
128
  # If the def node has a block argument and the super node has an explicit block,
@@ -148,7 +149,7 @@ module RuboCop
148
149
  def_arg.name == super_arg.children.first
149
150
  end
150
151
 
151
- def positional_rest_arg_same(def_arg, super_arg)
152
+ def positional_rest_arg_same?(def_arg, super_arg)
152
153
  return false unless def_arg.restarg_type?
153
154
  # anonymous forwarding
154
155
  return true if def_arg.name.nil? && super_arg.forwarded_restarg_type?
@@ -81,7 +81,7 @@ module RuboCop
81
81
 
82
82
  content = *sym
83
83
  content = content.map { |c| c.is_a?(AST::Node) ? c.source : c }.join
84
- content_without_delimiter_pairs = content.gsub(/(\[[^\s\[\]]*\])|(\([^\s\(\)]*\))/, '')
84
+ content_without_delimiter_pairs = content.gsub(/(\[[^\s\[\]]*\])|(\([^\s()]*\))/, '')
85
85
 
86
86
  content.include?(' ') || DELIMITERS.any? do |delimiter|
87
87
  content_without_delimiter_pairs.include?(delimiter)
@@ -142,9 +142,11 @@ module RuboCop
142
142
  include RangeHelp
143
143
  include AllowedMethods
144
144
  include AllowedPattern
145
+ include PatternMatchingHelp
145
146
  extend AutoCorrector
146
147
 
147
148
  MSG = 'Pass `&:%<method>s` as an argument to `%<block_method>s` instead of a block.'
149
+ MSG_LAMBDA_LITERAL = 'Use `lambda(&:%<method>s)` instead of %<original>s.'
148
150
  SUPER_TYPES = %i[super zsuper].freeze
149
151
  LAMBDA_OR_PROC = %i[lambda proc].freeze
150
152
 
@@ -159,32 +161,35 @@ module RuboCop
159
161
  {
160
162
  (block $#symbol_proc_receiver? $(args (arg _var)) (send (lvar _var) $_))
161
163
  (numblock $#symbol_proc_receiver? $1 (send (lvar :_1) $_))
164
+ (itblock $#symbol_proc_receiver? $_ (send (lvar :it) $_))
162
165
  }
163
166
  PATTERN
164
167
 
165
168
  def self.autocorrect_incompatible_with
166
- [Layout::SpaceBeforeBlockBraces]
169
+ [Layout::SpaceBeforeBlockBraces, Style::TrailingCommaInArguments]
167
170
  end
168
171
 
169
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
172
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
170
173
  def on_block(node)
171
174
  symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
172
175
  if active_support_extensions_enabled?
173
176
  return if proc_node?(dispatch_node)
174
177
  return if LAMBDA_OR_PROC.include?(dispatch_node.method_name)
175
178
  end
179
+ # A pattern accepts a lambda literal, but not `lambda(&:foo)`.
180
+ return if in_pattern?(node)
176
181
  return if unsafe_hash_usage?(dispatch_node)
177
182
  return if unsafe_array_usage?(dispatch_node)
178
183
  return if allowed_method_name?(dispatch_node.method_name)
179
184
  return if allow_if_method_has_argument?(node.send_node)
180
185
  return if node.block_type? && destructuring_block_argument?(arguments_node)
181
- return if allow_comments? && contains_comments?(node)
186
+ return if allow_comments?(node)
182
187
 
183
188
  register_offense(node, method_name, dispatch_node.method_name)
184
189
  end
185
190
  end
186
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
187
191
  alias on_numblock on_block
192
+ alias on_itblock on_block
188
193
 
189
194
  def destructuring_block_argument?(argument_node)
190
195
  argument_node.one? && argument_node.source.include?(',')
@@ -206,12 +211,26 @@ module RuboCop
206
211
  end
207
212
 
208
213
  def register_offense(node, method_name, block_method_name)
209
- block_start = node.loc.begin.begin_pos
210
- block_end = node.loc.end.end_pos
211
- range = range_between(block_start, block_end)
212
- message = format(MSG, method: method_name, block_method: block_method_name)
214
+ range = if node.send_node.lambda_literal?
215
+ node.source_range
216
+ else
217
+ node.loc.begin.begin.join(node.loc.end.end)
218
+ end
219
+ message = message(node, method_name, block_method_name)
213
220
 
214
- add_offense(range, message: message) { |corrector| autocorrect(corrector, node) }
221
+ add_offense(range, message: message) do |corrector|
222
+ autocorrect(corrector, node)
223
+ end
224
+ end
225
+
226
+ def message(node, method_name, block_method_name)
227
+ if node.send_node.lambda_literal?
228
+ original = node.single_line? ? "`#{node.source}`" : 'a lambda literal with a block'
229
+
230
+ format(MSG_LAMBDA_LITERAL, method: method_name, original: original)
231
+ else
232
+ format(MSG, method: method_name, block_method: block_method_name)
233
+ end
215
234
  end
216
235
 
217
236
  def autocorrect(corrector, node)
@@ -258,21 +277,22 @@ module RuboCop
258
277
  end
259
278
 
260
279
  def begin_pos_for_replacement(node)
261
- expr = node.send_node.source_range
280
+ send_node = node.send_node
262
281
 
263
- if (paren_pos = (expr.source =~ /\(\s*\)$/))
264
- expr.begin_pos + paren_pos
282
+ if send_node.parenthesized? && send_node.arguments.empty?
283
+ send_node.loc.begin.begin_pos
265
284
  else
266
285
  node.loc.begin.begin_pos
267
286
  end
268
287
  end
269
288
 
270
289
  def allow_if_method_has_argument?(send_node)
271
- !!cop_config.fetch('AllowMethodsWithArguments', false) && !send_node.arguments.count.zero?
290
+ !!cop_config.fetch('AllowMethodsWithArguments', false) && send_node.arguments.any?
272
291
  end
273
292
 
274
- def allow_comments?
275
- cop_config.fetch('AllowComments', false)
293
+ def allow_comments?(node)
294
+ cop_config.fetch('AllowComments', false) && contains_comments?(node) &&
295
+ !comments_contain_disables?(node, name)
276
296
  end
277
297
  end
278
298
  end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for manual counting patterns that can be replaced by `Enumerable#tally`.
7
+ #
8
+ # The cop detects the following patterns:
9
+ #
10
+ # - `each_with_object(Hash.new(0)) { |item, counts| counts[item] += 1 }`
11
+ # - `group_by(&:itself).transform_values(&:count)`
12
+ # - `group_by { |x| x }.transform_values(&:size)`
13
+ # - `group_by { |x| x }.transform_values { |v| v.length }`
14
+ #
15
+ # @safety
16
+ # This cop is unsafe because it cannot guarantee that the receiver
17
+ # is an `Enumerable` by static analysis, so the correction may
18
+ # not be actually equivalent.
19
+ #
20
+ # @example
21
+ # # bad
22
+ # array.each_with_object(Hash.new(0)) { |item, counts| counts[item] += 1 }
23
+ #
24
+ # # bad
25
+ # array.group_by(&:itself).transform_values(&:count)
26
+ #
27
+ # # bad
28
+ # array.group_by { |item| item }.transform_values(&:size)
29
+ #
30
+ # # bad
31
+ # array.group_by { |item| item }.transform_values { |v| v.length }
32
+ #
33
+ # # good
34
+ # array.tally
35
+ #
36
+ class TallyMethod < Base
37
+ extend AutoCorrector
38
+ extend TargetRubyVersion
39
+ include RangeHelp
40
+
41
+ minimum_target_ruby_version 2.7
42
+
43
+ MSG_EACH_WITH_OBJECT = 'Use `tally` instead of `each_with_object`.'
44
+ MSG_GROUP_BY = 'Use `tally` instead of `group_by` and `transform_values`.'
45
+ RESTRICT_ON_SEND = %i[each_with_object transform_values].freeze
46
+ COUNTING_METHODS = %i[count size length].to_set.freeze
47
+
48
+ # Pattern 1: collection.each_with_object(Hash.new(0)) { |elem, hash| hash[elem] += 1 }
49
+ # @!method tally_each_with_object?(node)
50
+ def_node_matcher :tally_each_with_object?, <<~PATTERN
51
+ {
52
+ (block
53
+ (call _ :each_with_object
54
+ (send (const {nil? cbase} :Hash) :new (int 0)))
55
+ (args (arg _elem) (arg _hash))
56
+ (op_asgn
57
+ (send (lvar _hash) :[] (lvar _elem)) :+ (int 1)))
58
+ (numblock
59
+ (call _ :each_with_object
60
+ (send (const {nil? cbase} :Hash) :new (int 0)))
61
+ 2
62
+ (op_asgn
63
+ (send (lvar :_2) :[] (lvar :_1)) :+ (int 1)))
64
+ }
65
+ PATTERN
66
+
67
+ # Pattern 2: collection.group_by(&:itself).transform_values(&:count/size/length)
68
+ # @!method tally_group_by_symbol?(node)
69
+ def_node_matcher :tally_group_by_symbol?, <<~PATTERN
70
+ (call
71
+ (call _ :group_by (block_pass (sym :itself)))
72
+ :transform_values
73
+ (block_pass (sym %COUNTING_METHODS)))
74
+ PATTERN
75
+
76
+ # Pattern 3: collection.group_by { |x| x }.transform_values(&:count/size/length)
77
+ # @!method tally_group_by_identity_block?(node)
78
+ def_node_matcher :tally_group_by_identity_block?, <<~PATTERN
79
+ (call
80
+ {
81
+ (block (call _ :group_by) (args (arg _x)) (lvar _x))
82
+ (numblock (call _ :group_by) 1 (lvar :_1))
83
+ (itblock (call _ :group_by) :it (lvar :it))
84
+ }
85
+ :transform_values
86
+ (block_pass (sym %COUNTING_METHODS)))
87
+ PATTERN
88
+
89
+ # Pattern 4: collection.group_by(&:itself).transform_values { |v| v.count/size/length }
90
+ # collection.group_by { |x| x }.transform_values { |v| v.count/size/length }
91
+ # @!method tally_group_by_transform_block?(node)
92
+ def_node_matcher :tally_group_by_transform_block?, <<~PATTERN
93
+ {
94
+ (block
95
+ (call
96
+ {
97
+ (call _ :group_by (block_pass (sym :itself)))
98
+ (block (call _ :group_by) (args (arg _x)) (lvar _x))
99
+ (numblock (call _ :group_by) 1 (lvar :_1))
100
+ (itblock (call _ :group_by) :it (lvar :it))
101
+ }
102
+ :transform_values)
103
+ (args (arg _v))
104
+ (send (lvar _v) %COUNTING_METHODS))
105
+ (numblock
106
+ (call
107
+ {
108
+ (call _ :group_by (block_pass (sym :itself)))
109
+ (block (call _ :group_by) (args (arg _x)) (lvar _x))
110
+ (numblock (call _ :group_by) 1 (lvar :_1))
111
+ (itblock (call _ :group_by) :it (lvar :it))
112
+ }
113
+ :transform_values)
114
+ 1
115
+ (send (lvar :_1) %COUNTING_METHODS))
116
+ (itblock
117
+ (call
118
+ {
119
+ (call _ :group_by (block_pass (sym :itself)))
120
+ (block (call _ :group_by) (args (arg _x)) (lvar _x))
121
+ (numblock (call _ :group_by) 1 (lvar :_1))
122
+ (itblock (call _ :group_by) :it (lvar :it))
123
+ }
124
+ :transform_values)
125
+ :it
126
+ (send (lvar :it) %COUNTING_METHODS))
127
+ }
128
+ PATTERN
129
+ def on_send(node)
130
+ if node.method?(:each_with_object)
131
+ check_each_with_object(node)
132
+ elsif node.method?(:transform_values)
133
+ check_transform_values(node)
134
+ end
135
+ end
136
+ alias on_csend on_send
137
+
138
+ private
139
+
140
+ def check_each_with_object(node)
141
+ block_node = node.block_node
142
+ return unless block_node
143
+ return unless tally_each_with_object?(block_node)
144
+
145
+ add_offense(node.loc.selector, message: MSG_EACH_WITH_OBJECT) do |corrector|
146
+ corrector.replace(replacement_range(node, block_node), 'tally')
147
+ end
148
+ end
149
+
150
+ def check_transform_values(node)
151
+ if tally_group_by_symbol?(node) || tally_group_by_identity_block?(node)
152
+ register_group_by_offense(node, node)
153
+ elsif (block_node = node.block_node) && tally_group_by_transform_block?(block_node)
154
+ register_group_by_offense(node, block_node)
155
+ end
156
+ end
157
+
158
+ def register_group_by_offense(transform_node, end_node)
159
+ group_by_node = group_by_send_node(transform_node)
160
+
161
+ add_offense(group_by_node.loc.selector, message: MSG_GROUP_BY) do |corrector|
162
+ corrector.replace(replacement_range(group_by_node, end_node), 'tally')
163
+ end
164
+ end
165
+
166
+ def group_by_send_node(transform_node)
167
+ receiver = transform_node.receiver
168
+ if receiver.type?(:any_block)
169
+ receiver.send_node
170
+ else
171
+ receiver
172
+ end
173
+ end
174
+
175
+ def replacement_range(start_node, end_node)
176
+ range_between(start_node.loc.selector.begin_pos, end_node.source_range.end_pos)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -58,6 +58,7 @@ module RuboCop
58
58
  include SafeAssignment
59
59
  include ConfigurableEnforcedStyle
60
60
  include SurroundingSpace
61
+ include ReparsedEquivalence
61
62
  extend AutoCorrector
62
63
 
63
64
  VARIABLE_TYPES = AST::Node::VARIABLES
@@ -101,7 +102,8 @@ module RuboCop
101
102
  condition = node.condition
102
103
 
103
104
  return nil if parenthesized?(condition) &&
104
- (safe_assignment?(condition) || unsafe_autocorrect?(condition))
105
+ (safe_assignment?(condition) || unsafe_autocorrect?(condition) ||
106
+ verified_by_reparse([condition]).empty?)
105
107
 
106
108
  if parenthesized?(condition)
107
109
  correct_parenthesized(corrector, condition)
@@ -113,6 +115,10 @@ module RuboCop
113
115
  def offense?(node)
114
116
  condition = node.condition
115
117
 
118
+ # A modifier `if`/`unless` requires the parentheses, e.g. `(a if b) ? x : y`,
119
+ # so removing them would change the meaning. Don't flag it.
120
+ return false if parenthesized_modifier_condition?(condition)
121
+
116
122
  if safe_assignment?(condition)
117
123
  !safe_assignment_allowed?
118
124
  else
@@ -174,6 +180,13 @@ module RuboCop
174
180
  condition.children.any? { |child| below_ternary_precedence?(child) }
175
181
  end
176
182
 
183
+ def parenthesized_modifier_condition?(condition)
184
+ return false unless condition.begin_type?
185
+
186
+ inner = condition.children.first
187
+ inner&.if_type? && inner.modifier_form?
188
+ end
189
+
177
190
  def unparenthesized_method_call?(child)
178
191
  /^[a-z]/i.match?(method_name(child)) && !child.parenthesized?
179
192
  end
@@ -207,6 +220,26 @@ module RuboCop
207
220
  end
208
221
  end
209
222
 
223
+ # Whatever binds looser than the ternary operator (`n += 1`, `a rescue b`,
224
+ # a nested ternary, `yield a`, several statements, ...) changes
225
+ # meaning without the parentheses, so their removal is verified by
226
+ # reparsing.
227
+ def apply_reparse_correction(corrector, condition)
228
+ correct_parenthesized(corrector, condition)
229
+ end
230
+
231
+ # The removed parentheses are the only expected difference.
232
+ def normalize_reparsed_ast(node)
233
+ return node unless node.is_a?(::Parser::AST::Node)
234
+
235
+ children = node.children.map { |child| normalize_reparsed_ast(child) }
236
+ if node.begin_type? && children.one? && children.first.is_a?(::Parser::AST::Node)
237
+ children.first
238
+ else
239
+ node.updated(nil, children)
240
+ end
241
+ end
242
+
210
243
  def correct_unparenthesized(corrector, condition)
211
244
  corrector.wrap(condition, '(', ')')
212
245
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for `Time.new` without arguments, which is an implicit way
7
+ # to retrieve the current system time. Prefer the more explicit `Time.now`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # Time.new
12
+ #
13
+ # # good
14
+ # Time.now
15
+ #
16
+ # # good - `Time.new` with arguments constructs a specific time
17
+ # Time.new(2026, 8, 19)
18
+ #
19
+ class TimeNow < Base
20
+ extend AutoCorrector
21
+
22
+ MSG = 'Prefer `Time.now` over `Time.new` to retrieve the current time.'
23
+ RESTRICT_ON_SEND = %i[new].freeze
24
+
25
+ # @!method time_new?(node)
26
+ def_node_matcher :time_new?, <<~PATTERN
27
+ (call (const {nil? cbase} :Time) :new)
28
+ PATTERN
29
+
30
+ def on_send(node)
31
+ return unless time_new?(node)
32
+
33
+ add_offense(node) do |corrector|
34
+ corrector.replace(node.loc.selector.join(node.source_range.end), 'now')
35
+ end
36
+ end
37
+ alias on_csend on_send
38
+ end
39
+ end
40
+ end
41
+ end
@@ -3,11 +3,11 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Newcomers to ruby applications may write top-level methods,
6
+ # Newcomers to Ruby applications may write top-level methods,
7
7
  # when ideally they should be organized in appropriate classes or modules.
8
8
  # This cop looks for definitions of top-level methods and warns about them.
9
9
  #
10
- # However for ruby scripts it is perfectly fine to use top-level methods.
10
+ # However, for Ruby scripts it is perfectly fine to use top-level methods.
11
11
  # Hence this cop is disabled by default.
12
12
  #
13
13
  # @example
@@ -64,6 +64,7 @@ module RuboCop
64
64
  end
65
65
 
66
66
  alias on_numblock on_block
67
+ alias on_itblock on_block
67
68
 
68
69
  private
69
70
 
@@ -10,6 +10,9 @@ module RuboCop
10
10
  # for all parenthesized multi-line method calls with arguments.
11
11
  # * `comma`: Requires a comma after the last argument, but only for
12
12
  # parenthesized method calls where each argument is on its own line.
13
+ # * `diff_comma`: Requires a comma after the last argument, but only
14
+ # when that argument is followed by an immediate newline, even if
15
+ # there is an inline comment on the same line.
13
16
  # * `no_comma`: Requires that there is no comma after the last
14
17
  # argument.
15
18
  #
@@ -75,14 +78,62 @@ module RuboCop
75
78
  # 2,
76
79
  # )
77
80
  #
81
+ # @example EnforcedStyleForMultiline: diff_comma
82
+ # # bad
83
+ # method(1, 2,)
84
+ #
85
+ # # good
86
+ # method(1, 2)
87
+ #
88
+ # # good
89
+ # method(
90
+ # 1, 2,
91
+ # 3,
92
+ # )
93
+ #
94
+ # # good
95
+ # method(
96
+ # 1, 2, 3,
97
+ # )
98
+ #
99
+ # # good
100
+ # method(
101
+ # 1,
102
+ # 2,
103
+ # )
104
+ #
105
+ # # bad
106
+ # method(1, [
107
+ # 2,
108
+ # ],)
109
+ #
110
+ # # good
111
+ # method(1, [
112
+ # 2,
113
+ # ])
114
+ #
115
+ # # bad
116
+ # object[1, 2,
117
+ # 3, 4,]
118
+ #
119
+ # # good
120
+ # object[1, 2,
121
+ # 3, 4]
122
+ #
78
123
  # @example EnforcedStyleForMultiline: no_comma (default)
79
124
  # # bad
80
125
  # method(1, 2,)
81
126
  #
127
+ # # bad
128
+ # object[1, 2,]
129
+ #
82
130
  # # good
83
131
  # method(1, 2)
84
132
  #
85
133
  # # good
134
+ # object[1, 2]
135
+ #
136
+ # # good
86
137
  # method(
87
138
  # 1,
88
139
  # 2
@@ -96,7 +147,7 @@ module RuboCop
96
147
  end
97
148
 
98
149
  def on_send(node)
99
- return unless node.arguments? && node.parenthesized?
150
+ return unless node.arguments? && (node.parenthesized? || node.method?(:[]))
100
151
 
101
152
  check(node, node.arguments, 'parameter of %<article>s method call',
102
153
  node.last_argument.source_range.end_pos,