rubocop 1.71.1 → 1.91.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 (661) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +883 -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 +7 -2
  10. data/lib/rubocop/changed_files.rb +112 -0
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  12. data/lib/rubocop/cli/command/execute_runner.rb +52 -1
  13. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  14. data/lib/rubocop/cli/command/lsp.rb +1 -1
  15. data/lib/rubocop/cli/command/mcp.rb +19 -0
  16. data/lib/rubocop/cli/command/show_cops.rb +2 -2
  17. data/lib/rubocop/cli/command/show_docs_url.rb +4 -8
  18. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  19. data/lib/rubocop/cli.rb +58 -17
  20. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  21. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  22. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  23. data/lib/rubocop/comment_config.rb +92 -48
  24. data/lib/rubocop/config.rb +137 -19
  25. data/lib/rubocop/config_finder.rb +1 -1
  26. data/lib/rubocop/config_loader.rb +72 -49
  27. data/lib/rubocop/config_loader_resolver.rb +94 -28
  28. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  29. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  30. data/lib/rubocop/config_obsoletion/removed_cop.rb +8 -0
  31. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  32. data/lib/rubocop/config_obsoletion.rb +47 -3
  33. data/lib/rubocop/config_store.rb +7 -2
  34. data/lib/rubocop/config_validator.rb +64 -12
  35. data/lib/rubocop/cop/autocorrect_logic.rb +35 -14
  36. data/lib/rubocop/cop/badge.rb +9 -1
  37. data/lib/rubocop/cop/base.rb +93 -21
  38. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -3
  39. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  40. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
  41. data/lib/rubocop/cop/bundler.rb +19 -0
  42. data/lib/rubocop/cop/commissioner.rb +13 -11
  43. data/lib/rubocop/cop/corrector.rb +4 -4
  44. data/lib/rubocop/cop/correctors/alignment_corrector.rb +79 -10
  45. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  46. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +1 -1
  47. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  48. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -1
  49. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  50. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  51. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +36 -2
  52. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  53. data/lib/rubocop/cop/correctors.rb +28 -0
  54. data/lib/rubocop/cop/documentation.rb +2 -3
  55. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  56. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  57. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  58. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  59. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
  60. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  61. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  62. data/lib/rubocop/cop/gemspec.rb +22 -0
  63. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  64. data/lib/rubocop/cop/generator.rb +5 -1
  65. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  66. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  67. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  68. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  69. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  70. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +14 -15
  71. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  72. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  73. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  74. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  75. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
  76. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  77. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  78. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  79. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  80. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  81. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  82. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  83. data/lib/rubocop/cop/layout/argument_alignment.rb +4 -2
  84. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  85. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  86. data/lib/rubocop/cop/layout/block_alignment.rb +59 -4
  87. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  88. data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
  89. data/lib/rubocop/cop/layout/class_structure.rb +163 -35
  90. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  91. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  92. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  93. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  94. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  95. data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
  96. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  97. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
  98. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  99. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  100. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  101. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  102. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  103. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  104. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +13 -2
  105. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  106. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  107. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  108. data/lib/rubocop/cop/layout/end_alignment.rb +9 -3
  109. data/lib/rubocop/cop/layout/extra_spacing.rb +105 -3
  110. data/lib/rubocop/cop/layout/first_argument_indentation.rb +56 -3
  111. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  112. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  113. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +20 -15
  114. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  115. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  116. data/lib/rubocop/cop/layout/hash_alignment.rb +11 -13
  117. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -3
  118. data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
  119. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  120. data/lib/rubocop/cop/layout/indentation_width.rb +157 -10
  121. data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
  122. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +2 -3
  123. data/lib/rubocop/cop/layout/line_length.rb +160 -23
  124. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
  125. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  126. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
  127. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
  128. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -1
  129. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +245 -40
  130. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  131. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  132. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  133. data/lib/rubocop/cop/layout/redundant_line_break.rb +89 -6
  134. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
  135. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  136. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  137. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +14 -3
  138. data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -3
  139. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  140. data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
  141. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  142. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  143. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  144. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +42 -36
  145. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
  146. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  147. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  148. data/lib/rubocop/cop/layout.rb +114 -0
  149. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  150. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  151. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  152. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +1 -10
  153. data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
  154. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  155. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  156. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  157. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  158. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  159. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  160. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  161. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  162. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
  163. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  164. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  165. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  166. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  167. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  168. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  169. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  170. data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
  171. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  172. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  173. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  174. data/lib/rubocop/cop/lint/empty_conditional_body.rb +20 -65
  175. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  176. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  177. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  178. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  179. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  180. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  181. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  182. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  183. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  184. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  185. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  186. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  187. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  188. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  189. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  190. data/lib/rubocop/cop/lint/literal_as_condition.rb +137 -11
  191. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  192. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +13 -19
  193. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +185 -0
  194. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +44 -22
  195. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  196. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  197. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  198. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  199. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  200. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  201. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  202. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  203. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  204. data/lib/rubocop/cop/lint/number_conversion.rb +19 -10
  205. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  206. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  207. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  208. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  209. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  210. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  211. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  212. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  213. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +149 -39
  214. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  215. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +15 -4
  216. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  217. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
  218. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
  219. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  220. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  221. data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
  222. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  223. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  224. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  225. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  226. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  227. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  228. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  229. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  230. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  231. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
  232. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +9 -5
  233. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  234. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  235. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  236. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  237. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  238. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  239. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  240. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  241. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  242. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  243. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  244. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  245. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  246. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  247. data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
  248. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  249. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  250. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  251. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +36 -10
  252. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  253. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  254. data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
  255. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  256. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  257. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  258. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  259. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  260. data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
  261. data/lib/rubocop/cop/lint/useless_assignment.rb +56 -27
  262. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  263. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  264. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  265. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  266. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  267. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
  268. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
  269. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  270. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  271. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  272. data/lib/rubocop/cop/lint/void.rb +60 -21
  273. data/lib/rubocop/cop/lint.rb +179 -0
  274. data/lib/rubocop/cop/message_annotator.rb +7 -3
  275. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  276. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  277. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  278. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  279. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  280. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  281. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  282. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  283. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  284. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  285. data/lib/rubocop/cop/metrics.rb +31 -0
  286. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  287. data/lib/rubocop/cop/migration.rb +13 -0
  288. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  289. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  290. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  291. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  292. data/lib/rubocop/cop/mixin/check_line_breakable.rb +27 -9
  293. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -7
  294. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  295. data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
  296. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  297. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  298. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  299. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  300. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  301. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  302. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  303. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  304. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  305. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  306. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +44 -16
  307. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +29 -26
  308. data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
  309. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  310. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  311. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  312. data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
  313. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  314. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  315. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  316. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  317. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  318. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +62 -6
  319. data/lib/rubocop/cop/mixin/project_index_help.rb +188 -0
  320. data/lib/rubocop/cop/mixin/range_help.rb +16 -5
  321. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +171 -0
  322. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  323. data/lib/rubocop/cop/mixin/statement_modifier.rb +47 -11
  324. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  325. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  326. data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
  327. data/lib/rubocop/cop/mixin.rb +91 -0
  328. data/lib/rubocop/cop/naming/accessor_method_name.rb +24 -0
  329. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  330. data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
  331. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  332. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  333. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  334. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
  335. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  336. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  337. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +80 -8
  338. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -6
  339. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  340. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  341. data/lib/rubocop/cop/naming.rb +31 -0
  342. data/lib/rubocop/cop/offense.rb +52 -9
  343. data/lib/rubocop/cop/registry.rb +233 -64
  344. data/lib/rubocop/cop/security/eval.rb +17 -3
  345. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  346. data/lib/rubocop/cop/security/json_load.rb +33 -11
  347. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  348. data/lib/rubocop/cop/security/open.rb +1 -0
  349. data/lib/rubocop/cop/security.rb +19 -0
  350. data/lib/rubocop/cop/severity.rb +12 -0
  351. data/lib/rubocop/cop/style/access_modifier_declarations.rb +47 -13
  352. data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
  353. data/lib/rubocop/cop/style/alias.rb +15 -3
  354. data/lib/rubocop/cop/style/and_or.rb +2 -1
  355. data/lib/rubocop/cop/style/arguments_forwarding.rb +49 -37
  356. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  357. data/lib/rubocop/cop/style/array_intersect.rb +136 -38
  358. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  359. data/lib/rubocop/cop/style/array_join.rb +4 -2
  360. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  361. data/lib/rubocop/cop/style/attr.rb +5 -2
  362. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  363. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  364. data/lib/rubocop/cop/style/bitwise_predicate.rb +7 -1
  365. data/lib/rubocop/cop/style/block_delimiters.rb +43 -38
  366. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  367. data/lib/rubocop/cop/style/case_like_if.rb +6 -8
  368. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  369. data/lib/rubocop/cop/style/class_and_module_children.rb +135 -21
  370. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  371. data/lib/rubocop/cop/style/class_methods_definitions.rb +11 -5
  372. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  373. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  374. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  375. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  376. data/lib/rubocop/cop/style/combinable_loops.rb +7 -2
  377. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  378. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  379. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  380. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  381. data/lib/rubocop/cop/style/concat_array_literals.rb +8 -3
  382. data/lib/rubocop/cop/style/conditional_assignment.rb +54 -24
  383. data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
  384. data/lib/rubocop/cop/style/copyright.rb +27 -12
  385. data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
  386. data/lib/rubocop/cop/style/date_time.rb +4 -4
  387. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  388. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  389. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  390. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  391. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +122 -14
  392. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  393. data/lib/rubocop/cop/style/documentation.rb +53 -6
  394. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  395. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  396. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  397. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  398. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  399. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  400. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  401. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  402. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  403. data/lib/rubocop/cop/style/empty_literal.rb +11 -2
  404. data/lib/rubocop/cop/style/empty_method.rb +12 -8
  405. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
  406. data/lib/rubocop/cop/style/encoding.rb +7 -1
  407. data/lib/rubocop/cop/style/end_block.rb +3 -1
  408. data/lib/rubocop/cop/style/endless_method.rb +191 -19
  409. data/lib/rubocop/cop/style/env_home.rb +4 -0
  410. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  411. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  412. data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -1
  413. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  414. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  415. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  416. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  417. data/lib/rubocop/cop/style/file_null.rb +6 -4
  418. data/lib/rubocop/cop/style/file_open.rb +84 -0
  419. data/lib/rubocop/cop/style/file_write.rb +21 -16
  420. data/lib/rubocop/cop/style/float_division.rb +25 -17
  421. data/lib/rubocop/cop/style/for.rb +9 -0
  422. data/lib/rubocop/cop/style/format_string.rb +17 -4
  423. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  424. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  425. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  426. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  427. data/lib/rubocop/cop/style/guard_clause.rb +32 -23
  428. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  429. data/lib/rubocop/cop/style/hash_conversion.rb +28 -12
  430. data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
  431. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  432. data/lib/rubocop/cop/style/hash_lookup_method.rb +105 -0
  433. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  434. data/lib/rubocop/cop/style/hash_syntax.rb +7 -3
  435. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  436. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  437. data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -9
  438. data/lib/rubocop/cop/style/if_inside_else.rb +25 -20
  439. data/lib/rubocop/cop/style/if_unless_modifier.rb +71 -46
  440. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +15 -19
  441. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  442. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -6
  443. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  444. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  445. data/lib/rubocop/cop/style/inverse_methods.rb +10 -6
  446. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  447. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  448. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  449. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  450. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  451. data/lib/rubocop/cop/style/keyword_parameters_order.rb +20 -10
  452. data/lib/rubocop/cop/style/lambda.rb +12 -1
  453. data/lib/rubocop/cop/style/lambda_call.rb +26 -10
  454. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  455. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  456. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  457. data/lib/rubocop/cop/style/map_into_array.rb +5 -2
  458. data/lib/rubocop/cop/style/map_join.rb +123 -0
  459. data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
  460. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  461. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +31 -15
  462. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  463. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +34 -5
  464. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -7
  465. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  466. data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -5
  467. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  468. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  469. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  470. data/lib/rubocop/cop/style/module_function.rb +4 -2
  471. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  472. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  473. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  474. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  475. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  476. data/lib/rubocop/cop/style/multiline_method_signature.rb +14 -18
  477. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  478. data/lib/rubocop/cop/style/mutable_constant.rb +111 -12
  479. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -2
  480. data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
  481. data/lib/rubocop/cop/style/nested_modifier.rb +9 -4
  482. data/lib/rubocop/cop/style/next.rb +44 -0
  483. data/lib/rubocop/cop/style/nil_comparison.rb +41 -13
  484. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  485. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  486. data/lib/rubocop/cop/style/not.rb +5 -1
  487. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  488. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  489. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  490. data/lib/rubocop/cop/style/object_then.rb +1 -0
  491. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  492. data/lib/rubocop/cop/style/one_line_conditional.rb +22 -13
  493. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  494. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  495. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  496. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  497. data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
  498. data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
  499. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  500. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +4 -0
  501. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  502. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  503. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  504. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  505. data/lib/rubocop/cop/style/proc.rb +4 -2
  506. data/lib/rubocop/cop/style/raise_args.rb +9 -9
  507. data/lib/rubocop/cop/style/reduce_to_hash.rb +200 -0
  508. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  509. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  510. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  511. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  512. data/lib/rubocop/cop/style/redundant_begin.rb +38 -3
  513. data/lib/rubocop/cop/style/redundant_condition.rb +63 -5
  514. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  515. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  516. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +11 -3
  517. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  518. data/lib/rubocop/cop/style/redundant_exception.rb +7 -1
  519. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -10
  520. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  521. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  522. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  523. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  524. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  525. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  526. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  527. data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
  528. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  529. data/lib/rubocop/cop/style/redundant_parentheses.rb +164 -82
  530. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  531. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
  532. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  533. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +8 -8
  534. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +12 -0
  535. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  536. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  537. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
  538. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  539. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  540. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  541. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  542. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  543. data/lib/rubocop/cop/style/regexp_literal.rb +32 -3
  544. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  545. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  546. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  547. data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
  548. data/lib/rubocop/cop/style/sample.rb +11 -6
  549. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  550. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  551. data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
  552. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  553. data/lib/rubocop/cop/style/semicolon.rb +45 -14
  554. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  555. data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
  556. data/lib/rubocop/cop/style/single_line_methods.rb +13 -8
  557. data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
  558. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  559. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -1
  560. data/lib/rubocop/cop/style/static_class.rb +21 -0
  561. data/lib/rubocop/cop/style/string_concatenation.rb +31 -15
  562. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  563. data/lib/rubocop/cop/style/struct_inheritance.rb +38 -2
  564. data/lib/rubocop/cop/style/super_arguments.rb +4 -6
  565. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  566. data/lib/rubocop/cop/style/symbol_proc.rb +11 -9
  567. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  568. data/lib/rubocop/cop/style/ternary_parentheses.rb +11 -0
  569. data/lib/rubocop/cop/style/time_now.rb +41 -0
  570. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  571. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  572. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  573. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  574. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  575. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  576. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +18 -19
  577. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  578. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  579. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  580. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  581. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  582. data/lib/rubocop/cop/style/word_array.rb +1 -0
  583. data/lib/rubocop/cop/style/yoda_condition.rb +2 -3
  584. data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
  585. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  586. data/lib/rubocop/cop/style.rb +311 -0
  587. data/lib/rubocop/cop/team.rb +163 -45
  588. data/lib/rubocop/cop/util.rb +7 -10
  589. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  590. data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
  591. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  592. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  593. data/lib/rubocop/cop/variable_force/variable.rb +28 -10
  594. data/lib/rubocop/cop/variable_force.rb +26 -9
  595. data/lib/rubocop/cops_documentation_generator.rb +49 -15
  596. data/lib/rubocop/directive_comment.rb +147 -5
  597. data/lib/rubocop/ext/regexp_node.rb +0 -1
  598. data/lib/rubocop/feature_loader.rb +0 -6
  599. data/lib/rubocop/file_patterns.rb +9 -1
  600. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  601. data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
  602. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  603. data/lib/rubocop/formatter/formatter_set.rb +3 -2
  604. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  605. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  606. data/lib/rubocop/formatter/html_formatter.rb +3 -5
  607. data/lib/rubocop/formatter/json_formatter.rb +11 -6
  608. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  609. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  610. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -3
  611. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  612. data/lib/rubocop/formatter/sarif_formatter.rb +181 -0
  613. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  614. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  615. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -3
  616. data/lib/rubocop/formatter.rb +23 -21
  617. data/lib/rubocop/lockfile.rb +18 -0
  618. data/lib/rubocop/lsp/diagnostic.rb +22 -41
  619. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  620. data/lib/rubocop/lsp/routes.rb +136 -33
  621. data/lib/rubocop/lsp/runtime.rb +23 -8
  622. data/lib/rubocop/lsp/server.rb +4 -2
  623. data/lib/rubocop/lsp/stdin_runner.rb +31 -18
  624. data/lib/rubocop/magic_comment.rb +55 -0
  625. data/lib/rubocop/mcp/server.rb +199 -0
  626. data/lib/rubocop/options.rb +129 -21
  627. data/lib/rubocop/path_util.rb +20 -5
  628. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  629. data/lib/rubocop/plugin/configuration_integrator.rb +146 -0
  630. data/lib/rubocop/plugin/load_error.rb +26 -0
  631. data/lib/rubocop/plugin/loader.rb +100 -0
  632. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  633. data/lib/rubocop/plugin.rb +46 -0
  634. data/lib/rubocop/project_index_loader.rb +82 -0
  635. data/lib/rubocop/rake_task.rb +6 -4
  636. data/lib/rubocop/remote_config.rb +14 -12
  637. data/lib/rubocop/result_cache.rb +90 -52
  638. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  639. data/lib/rubocop/rspec/expect_offense.rb +11 -7
  640. data/lib/rubocop/rspec/shared_contexts.rb +85 -3
  641. data/lib/rubocop/rspec/support.rb +4 -0
  642. data/lib/rubocop/runner.rb +294 -100
  643. data/lib/rubocop/server/cache.rb +67 -48
  644. data/lib/rubocop/server/cli.rb +2 -4
  645. data/lib/rubocop/server/client_command/base.rb +10 -0
  646. data/lib/rubocop/server/client_command/exec.rb +2 -1
  647. data/lib/rubocop/server/client_command/start.rb +11 -1
  648. data/lib/rubocop/server/core.rb +8 -0
  649. data/lib/rubocop/server.rb +14 -0
  650. data/lib/rubocop/target_finder.rb +25 -11
  651. data/lib/rubocop/target_ruby.rb +31 -14
  652. data/lib/rubocop/todo_audit.rb +111 -0
  653. data/lib/rubocop/unified_diff.rb +257 -0
  654. data/lib/rubocop/version.rb +48 -10
  655. data/lib/rubocop.rb +30 -682
  656. data/lib/ruby_lsp/rubocop/addon.rb +28 -17
  657. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  658. metadata +116 -19
  659. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
  660. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  661. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -3,15 +3,17 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Looks for uses of `\_.each_with_object({}) {...}`,
7
- # `\_.map {...}.to_h`, and `Hash[\_.map {...}]` that are actually just
6
+ # Looks for uses of `+_.each_with_object({}) {...}+`,
7
+ # `+_.map {...}.to_h+`, and `+Hash[_.map {...}]+` that are actually just
8
8
  # transforming the values of a hash, and tries to use a simpler & faster
9
9
  # call to `transform_values` instead.
10
10
  #
11
11
  # @safety
12
- # This cop is unsafe, as it can produce false positives if we are
13
- # transforming an enumerable of key-value-like pairs that isn't actually
14
- # a hash, e.g.: `[[k1, v1], [k2, v2], ...]`
12
+ # This cop identifies the receiver as a hash by checking for literal hash
13
+ # syntax and common methods that are known to return hashes (e.g. `to_h`,
14
+ # `merge`, `invert`, `group_by`, etc.). However, it is unsafe because it
15
+ # is possible for a custom class to define one of these methods and return
16
+ # something other than a hash.
15
17
  #
16
18
  # @example
17
19
  # # bad
@@ -19,10 +21,18 @@ module RuboCop
19
21
  # Hash[{a: 1, b: 2}.collect { |k, v| [k, foo(v)] }]
20
22
  # {a: 1, b: 2}.map { |k, v| [k, v * v] }.to_h
21
23
  # {a: 1, b: 2}.to_h { |k, v| [k, v * v] }
24
+ # foo.to_h.each_with_object({}) { |(k, v), h| h[k] = foo(v) }
25
+ # foo.merge(bar).map { |k, v| [k, v.to_s] }.to_h
22
26
  #
23
27
  # # good
24
28
  # {a: 1, b: 2}.transform_values { |v| foo(v) }
25
29
  # {a: 1, b: 2}.transform_values { |v| v * v }
30
+ # foo.to_h.transform_values { |v| foo(v) }
31
+ # foo.merge(bar).transform_values { |v| v.to_s }
32
+ #
33
+ # # Won't register an offense - receiver is not known to be a hash
34
+ # foo.bar.each_with_object({}) { |(k, v), h| h[k] = v.to_s }
35
+ # baz.map { |k, v| [k, v.to_s] }.to_h
26
36
  class HashTransformValues < Base
27
37
  include HashTransformMethod
28
38
  extend AutoCorrector
@@ -33,7 +43,7 @@ module RuboCop
33
43
  # @!method on_bad_each_with_object(node)
34
44
  def_node_matcher :on_bad_each_with_object, <<~PATTERN
35
45
  (block
36
- (call !#array_receiver? :each_with_object (hash))
46
+ (call #hash_receiver? :each_with_object (hash))
37
47
  (args
38
48
  (mlhs
39
49
  (arg _key)
@@ -48,7 +58,7 @@ module RuboCop
48
58
  (const _ :Hash)
49
59
  :[]
50
60
  (block
51
- (call !#array_receiver? {:map :collect})
61
+ (call #hash_receiver? {:map :collect})
52
62
  (args
53
63
  (arg _key)
54
64
  (arg $_))
@@ -59,7 +69,7 @@ module RuboCop
59
69
  def_node_matcher :on_bad_map_to_h, <<~PATTERN
60
70
  (call
61
71
  (block
62
- (call !#array_receiver? {:map :collect})
72
+ (call #hash_receiver? {:map :collect})
63
73
  (args
64
74
  (arg _key)
65
75
  (arg $_))
@@ -70,7 +80,7 @@ module RuboCop
70
80
  # @!method on_bad_to_h(node)
71
81
  def_node_matcher :on_bad_to_h, <<~PATTERN
72
82
  (block
73
- (call !#array_receiver? :to_h)
83
+ (call #hash_receiver? :to_h)
74
84
  (args
75
85
  (arg _key)
76
86
  (arg $_))
@@ -136,7 +136,7 @@ module RuboCop
136
136
 
137
137
  private
138
138
 
139
- # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
139
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
140
140
  def check_branches(node, branches)
141
141
  # return if any branch is empty. An empty branch can be an `if`
142
142
  # without an `else` or a branch that contains only comments.
@@ -168,7 +168,6 @@ module RuboCop
168
168
 
169
169
  check_expressions(node, heads, :before_condition)
170
170
  end
171
- # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
172
171
 
173
172
  def duplicated_expressions?(node, expressions)
174
173
  unique_expressions = expressions.uniq
@@ -189,7 +188,7 @@ module RuboCop
189
188
  end
190
189
  end
191
190
 
192
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
191
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
193
192
  def check_expressions(node, expressions, insert_position)
194
193
  return if expressions.any?(&:nil?)
195
194
 
@@ -197,7 +196,7 @@ module RuboCop
197
196
 
198
197
  expressions.each do |expression|
199
198
  add_offense(expression) do |corrector|
200
- next if node.if_type? && node.ternary?
199
+ next if node.if_type? && (node.ternary? || node.then?)
201
200
 
202
201
  range = range_by_whole_lines(expression.source_range, include_final_newline: true)
203
202
  corrector.remove(range)
@@ -213,26 +212,36 @@ module RuboCop
213
212
  end
214
213
  end
215
214
  end
216
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
217
215
 
218
216
  def correct_assignment(corrector, node, expression, insert_position)
217
+ indentation = indentation_of(node.parent)
218
+
219
219
  if insert_position == :after_condition
220
220
  assignment = node.parent.source_range.with(end_pos: node.source_range.begin_pos)
221
221
  corrector.remove(assignment)
222
- corrector.insert_after(node, "\n#{assignment.source}#{expression.source}")
222
+ corrector.insert_after(node, "\n#{indentation}#{assignment.source}#{expression.source}")
223
223
  else
224
- corrector.insert_before(node.parent, "#{expression.source}\n")
224
+ corrector.insert_before(node.parent, "#{expression.source}\n#{indentation}")
225
225
  end
226
226
  end
227
227
 
228
228
  def correct_no_assignment(corrector, node, expression, insert_position)
229
+ indentation = indentation_of(node)
230
+
229
231
  if insert_position == :after_condition
230
- corrector.insert_after(node, "\n#{expression.source}")
232
+ corrector.insert_after(node, "\n#{indentation}#{expression.source}")
231
233
  else
232
- corrector.insert_before(node, "#{expression.source}\n")
234
+ corrector.insert_before(node, "#{expression.source}\n#{indentation}")
233
235
  end
234
236
  end
235
237
 
238
+ # The leading indentation of the line the conditional starts on, so a
239
+ # hoisted expression keeps the surrounding nesting instead of landing
240
+ # at column zero.
241
+ def indentation_of(node)
242
+ ' ' * node.source_range.column
243
+ end
244
+
236
245
  def last_child_of_parent?(node)
237
246
  return true unless (parent = node.parent)
238
247
 
@@ -64,7 +64,7 @@ module RuboCop
64
64
 
65
65
  MSG = 'Convert `if` nested inside `else` to `elsif`.'
66
66
 
67
- # rubocop:disable Metrics/CyclomaticComplexity
67
+ # rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
68
68
  def on_if(node)
69
69
  return if node.ternary? || node.unless?
70
70
 
@@ -72,6 +72,7 @@ module RuboCop
72
72
 
73
73
  return unless else_branch&.if_type? && else_branch.if?
74
74
  return if allow_if_modifier_in_else_branch?(else_branch)
75
+ return if comments_between_else_and_if?(node, else_branch)
75
76
 
76
77
  add_offense(else_branch.loc.keyword) do |corrector|
77
78
  next if part_of_ignored_node?(node)
@@ -80,12 +81,11 @@ module RuboCop
80
81
  ignore_node(node)
81
82
  end
82
83
  end
83
- # rubocop:enable Metrics/CyclomaticComplexity
84
84
 
85
85
  private
86
86
 
87
87
  def autocorrect(corrector, node)
88
- if then?(node)
88
+ if node.then?
89
89
  # If the nested `if` is a then node, correct it first,
90
90
  # then the next pass will use `correct_to_elsif_from_if_inside_else_form`
91
91
  IfThenCorrector.new(node, indentation: 0).call(corrector)
@@ -97,38 +97,31 @@ module RuboCop
97
97
  else
98
98
  correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
99
99
  end
100
-
101
- corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
102
- return unless (if_branch = node.if_branch)
103
-
104
- range = range_by_whole_lines(if_branch.source_range, include_final_newline: true)
105
- corrector.remove(range)
106
100
  end
107
101
 
108
102
  def correct_to_elsif_from_modifier_form(corrector, node)
109
- corrector.replace(node.parent.loc.else, <<~RUBY.chop)
110
- elsif #{node.condition.source}
111
- #{indent(node.if_branch)}#{node.if_branch.source}
112
- end
113
- RUBY
103
+ corrector.replace(node.parent.loc.else, "elsif #{node.condition.source}")
104
+
105
+ condition_range = range_between(
106
+ node.if_branch.source_range.end_pos, node.condition.source_range.end_pos
107
+ )
108
+ corrector.remove(condition_range)
114
109
  end
115
110
 
116
- def correct_to_elsif_from_if_inside_else_form(corrector, node, condition)
111
+ def correct_to_elsif_from_if_inside_else_form(corrector, node, condition) # rubocop:disable Metrics/AbcSize
117
112
  corrector.replace(node.parent.loc.else, "elsif #{condition.source}")
118
113
 
119
114
  if_condition_range = if_condition_range(node, condition)
120
115
 
121
116
  if (if_branch = node.if_branch)
122
- corrector.replace(if_condition_range, if_branch.source)
117
+ corrector.replace(if_condition_range, range_with_comments(if_branch).source)
118
+ corrector.remove(range_with_comments_and_lines(if_branch))
123
119
  else
124
120
  corrector.remove(range_by_whole_lines(if_condition_range, include_final_newline: true))
125
121
  end
126
122
 
127
123
  corrector.remove(condition)
128
- end
129
-
130
- def then?(node)
131
- node.loc.begin&.source == 'then'
124
+ corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
132
125
  end
133
126
 
134
127
  def find_end_range(node)
@@ -142,6 +135,18 @@ module RuboCop
142
135
  range_between(node.loc.keyword.begin_pos, condition.source_range.end_pos)
143
136
  end
144
137
 
138
+ def comments_between_else_and_if?(node, else_branch)
139
+ return false if else_branch.modifier_form?
140
+
141
+ else_end = node.loc.else.end_pos
142
+ if_begin = else_branch.loc.keyword.begin_pos
143
+
144
+ processed_source.comments.any? do |comment|
145
+ comment_pos = comment.source_range.begin_pos
146
+ comment_pos > else_end && comment_pos < if_begin
147
+ end
148
+ end
149
+
145
150
  def allow_if_modifier_in_else_branch?(else_branch)
146
151
  allow_if_modifier? && else_branch&.modifier_form?
147
152
  end
@@ -23,6 +23,17 @@ module RuboCop
23
23
  # end
24
24
  # ----
25
25
  #
26
+ # The code `def method_name = body if condition` is considered a bad case by
27
+ # `Style/AmbiguousEndlessMethodDefinition` cop. So, to respect the user's intention to use
28
+ # an endless method definition in the `if` body, the following code is allowed:
29
+ #
30
+ # [source,ruby]
31
+ # ----
32
+ # if condition
33
+ # def method_name = body
34
+ # end
35
+ # ----
36
+ #
26
37
  # NOTE: It is allowed when `defined?` argument has an undefined value,
27
38
  # because using the modifier form causes the following incompatibility:
28
39
  #
@@ -60,10 +71,9 @@ module RuboCop
60
71
  # if short_condition # a long comment that makes it too long if it were just a single line
61
72
  # do_something
62
73
  # end
74
+ #
63
75
  class IfUnlessModifier < Base
64
76
  include StatementModifier
65
- include LineLengthHelp
66
- include AllowedPattern
67
77
  include RangeHelp
68
78
  include CommentsHelp
69
79
  extend AutoCorrector
@@ -71,20 +81,29 @@ module RuboCop
71
81
  MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
72
82
  'single-line body. Another good alternative is ' \
73
83
  'the usage of control flow `&&`/`||`.'
84
+ MSG_USE_MODIFIER_PARENS = 'Favor modifier `%<keyword>s` usage when having a ' \
85
+ 'single-line body. Wrap the expression in parentheses ' \
86
+ 'to keep the current behavior, as it is part of a ' \
87
+ 'larger expression.'
74
88
  MSG_USE_NORMAL = 'Modifier form of `%<keyword>s` makes the line too long.'
75
89
 
76
90
  def self.autocorrect_incompatible_with
77
- [Style::SoleNestedConditional]
91
+ [Style::Next, Style::SoleNestedConditional]
78
92
  end
79
93
 
94
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
80
95
  def on_if(node)
96
+ return if endless_method?(node.body) || node.each_ancestor(:dstr).any?
97
+
81
98
  condition = node.condition
82
99
  return if defined_nodes(condition).any? { |n| defined_argument_is_undefined?(node, n) } ||
83
100
  pattern_matching_nodes(condition).any?
101
+
84
102
  return unless (msg = message(node))
85
103
 
86
104
  add_offense(node.loc.keyword, message: format(msg, keyword: node.keyword)) do |corrector|
87
105
  next if part_of_ignored_node?(node)
106
+ next if another_modifier_if_on_same_line?(node)
88
107
 
89
108
  autocorrect(corrector, node)
90
109
  ignore_node(node)
@@ -93,11 +112,15 @@ module RuboCop
93
112
 
94
113
  private
95
114
 
115
+ def endless_method?(body)
116
+ body&.any_def_type? && body.endless?
117
+ end
118
+
96
119
  def defined_nodes(condition)
97
120
  if condition.defined_type?
98
121
  [condition]
99
122
  else
100
- condition.each_descendant.select(&:defined_type?)
123
+ condition.each_descendant(:defined?)
101
124
  end
102
125
  end
103
126
 
@@ -112,18 +135,16 @@ module RuboCop
112
135
  end
113
136
 
114
137
  def pattern_matching_nodes(condition)
115
- if condition.type?(:match_pattern, :match_pattern_p)
138
+ if condition.any_match_pattern_type?
116
139
  [condition]
117
140
  else
118
- condition.each_descendant.select do |node|
119
- node.type?(:match_pattern, :match_pattern_p)
120
- end
141
+ condition.each_descendant(:any_match_pattern)
121
142
  end
122
143
  end
123
144
 
124
145
  def message(node)
125
146
  if single_line_as_modifier?(node) && !named_capture_in_condition?(node)
126
- MSG_USE_MODIFIER
147
+ parenthesize?(node) ? MSG_USE_MODIFIER_PARENS : MSG_USE_MODIFIER
127
148
  elsif too_long_due_to_modifier?(node)
128
149
  MSG_USE_NORMAL
129
150
  end
@@ -164,64 +185,68 @@ module RuboCop
164
185
 
165
186
  def too_long_due_to_comment_after_modifier?(node, comment)
166
187
  source_length = processed_source.lines[node.first_line - 1].length
167
- source_length >= max_line_length &&
168
- source_length - comment.source_range.length <= max_line_length
169
- end
170
188
 
171
- def allowed_patterns
172
- line_length_config = config.for_cop('Layout/LineLength')
173
- line_length_config['AllowedPatterns'] || line_length_config['IgnoredPatterns'] || []
189
+ max_line_length.between?(source_length - comment.source_range.length, source_length)
174
190
  end
175
191
 
176
192
  def too_long_single_line?(node)
177
- return false unless max_line_length
178
-
179
193
  range = node.source_range
180
- return false unless range.single_line?
181
- return false unless line_length_enabled_at_line?(range.first_line)
194
+ range.single_line? && !acceptable_line_length?(range.source_line, range.first_line)
195
+ end
182
196
 
183
- line = range.source_line
184
- return false if line_length(line) <= max_line_length
197
+ def named_capture_in_condition?(node)
198
+ node.condition.match_with_lvasgn_type?
199
+ end
185
200
 
186
- too_long_line_based_on_config?(range, line)
201
+ def non_eligible_node?(node)
202
+ non_simple_if_unless?(node) || node.chained? || node.nested_conditional? ||
203
+ multiline_inside_collection?(node) || super
187
204
  end
188
205
 
189
- def too_long_line_based_on_config?(range, line)
190
- return false if matches_allowed_pattern?(line)
206
+ def multiline_inside_collection?(node)
207
+ return false if node.modifier_form?
208
+ return false unless (collection = find_containing_collection(node))
191
209
 
192
- too_long = too_long_line_based_on_ignore_cop_directives?(range, line)
193
- return too_long unless too_long == :undetermined
210
+ collection.children.any? { |child| sibling_if_shares_line?(child, node) }
211
+ end
194
212
 
195
- too_long_line_based_on_allow_uri?(line)
213
+ def sibling_if_shares_line?(child, node)
214
+ inner = unwrap_begin(child)
215
+ inner&.if_type? && !inner.ternary? && shares_line_with?(inner, node)
196
216
  end
197
217
 
198
- def too_long_line_based_on_ignore_cop_directives?(range, line)
199
- if ignore_cop_directives? && directive_on_source_line?(range.line - 1)
200
- return line_length_without_directive(line) > max_line_length
201
- end
218
+ def unwrap_begin(node)
219
+ return unless node.is_a?(RuboCop::AST::Node)
202
220
 
203
- :undetermined
221
+ node = node.value if node.pair_type?
222
+ node.begin_type? ? node.children.first : node
204
223
  end
205
224
 
206
- def too_long_line_based_on_allow_uri?(line)
207
- if allow_uri?
208
- uri_range = find_excessive_uri_range(line)
209
- return false if uri_range && allowed_uri_position?(line, uri_range)
210
- end
211
-
212
- true
225
+ def shares_line_with?(inner, node)
226
+ same_line?(inner, node.loc.end) || same_line?(inner.loc.end, node)
213
227
  end
214
228
 
215
- def line_length_enabled_at_line?(line)
216
- processed_source.comment_config.cop_enabled_at_line?('Layout/LineLength', line)
229
+ def find_containing_collection(node)
230
+ parent = node.parent
231
+ return collection_from_ancestor(parent) unless parent&.begin_type?
232
+
233
+ collection_from_ancestor(parent.parent)
217
234
  end
218
235
 
219
- def named_capture_in_condition?(node)
220
- node.condition.match_with_lvasgn_type?
236
+ def collection_from_ancestor(node)
237
+ return node if node&.type?(:array, :call)
238
+
239
+ node.parent if node&.type?(:pair)
221
240
  end
222
241
 
223
- def non_eligible_node?(node)
224
- non_simple_if_unless?(node) || node.chained? || node.nested_conditional? || super
242
+ def another_modifier_if_on_same_line?(node)
243
+ collection = find_containing_collection(node)
244
+ return false unless collection
245
+
246
+ line = node.source_range.line
247
+ collection.each_descendant(:if).any? do |sibling|
248
+ sibling != node && sibling.modifier_form? && sibling.source_range.line == line
249
+ end
225
250
  end
226
251
 
227
252
  def non_simple_if_unless?(node)
@@ -283,7 +308,7 @@ module RuboCop
283
308
  end
284
309
 
285
310
  def comment_on_node_line(node)
286
- processed_source.comments.find { |c| same_line?(c, node) }
311
+ processed_source.comment_at_line(node.first_line)
287
312
  end
288
313
 
289
314
  def remove_comment(corrector, _node, comment)
@@ -8,37 +8,33 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # # bad
12
- # tired? ? 'stop' : 'go faster' if running?
11
+ # # bad
12
+ # tired? ? 'stop' : 'go faster' if running?
13
13
  #
14
- # # bad
15
- # if tired?
16
- # "please stop"
17
- # else
18
- # "keep going"
19
- # end if running?
14
+ # # bad
15
+ # if tired?
16
+ # "please stop"
17
+ # else
18
+ # "keep going"
19
+ # end if running?
20
20
  #
21
- # # good
22
- # if running?
23
- # tired? ? 'stop' : 'go faster'
24
- # end
21
+ # # good
22
+ # if running?
23
+ # tired? ? 'stop' : 'go faster'
24
+ # end
25
25
  class IfUnlessModifierOfIfUnless < Base
26
26
  include StatementModifier
27
27
  extend AutoCorrector
28
28
 
29
29
  MSG = 'Avoid modifier `%<keyword>s` after another conditional.'
30
30
 
31
+ # rubocop:disable-next Metrics/AbcSize
31
32
  def on_if(node)
32
33
  return unless node.modifier_form? && node.body.if_type?
33
34
 
34
35
  add_offense(node.loc.keyword, message: format(MSG, keyword: node.keyword)) do |corrector|
35
- keyword = node.if? ? 'if' : 'unless'
36
-
37
- corrector.replace(node, <<~RUBY.chop)
38
- #{keyword} #{node.condition.source}
39
- #{node.if_branch.source}
40
- end
41
- RUBY
36
+ corrector.wrap(node.if_branch, "#{node.keyword} #{node.condition.source}\n", "\nend")
37
+ corrector.remove(node.if_branch.source_range.end.join(node.condition.source_range.end))
42
38
  end
43
39
  end
44
40
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # `nonzero?` method is allowed by default.
11
11
  # These are customizable with `AllowedMethods` option.
12
12
  #
13
- # This cop targets only `if`s with a single `elsif` or `else` branch. The following
13
+ # This cop targets only ``if``s with a single `elsif` or `else` branch. The following
14
14
  # code will be allowed, because it has two `elsif` branches:
15
15
  #
16
16
  # [source,ruby]
@@ -54,7 +54,10 @@ module RuboCop
54
54
  # # good (but potentially an unsafe correction)
55
55
  # foo.do_something?
56
56
  #
57
- # @example AllowedMethods: ['nonzero?'] (default)
57
+ # @example AllowedMethods: ['infinite?', 'nonzero?'] (default)
58
+ # # good
59
+ # num.infinite? ? true : false
60
+ #
58
61
  # # good
59
62
  # num.nonzero? ? true : false
60
63
  #
@@ -17,9 +17,9 @@ module RuboCop
17
17
  include OnNormalIfUnless
18
18
  extend AutoCorrector
19
19
 
20
- MSG_IF_ELSE = 'Do not use `if %<expr>s;` - use `if/else` instead.'
21
- MSG_NEWLINE = 'Do not use `if %<expr>s;` - use a newline instead.'
22
- MSG_TERNARY = 'Do not use `if %<expr>s;` - use a ternary operator instead.'
20
+ MSG_IF_ELSE = 'Do not use `%<keyword>s %<expr>s;` - use `if/else` instead.'
21
+ MSG_NEWLINE = 'Do not use `%<keyword>s %<expr>s;` - use a newline instead.'
22
+ MSG_TERNARY = 'Do not use `%<keyword>s %<expr>s;` - use a ternary operator instead.'
23
23
 
24
24
  def on_normal_if_unless(node)
25
25
  return if node.parent&.if_type?
@@ -49,7 +49,7 @@ module RuboCop
49
49
  MSG_TERNARY
50
50
  end
51
51
 
52
- format(template, expr: node.condition.source)
52
+ format(template, keyword: node.keyword, expr: node.condition.source)
53
53
  end
54
54
 
55
55
  def autocorrect(corrector, node)
@@ -71,7 +71,7 @@ module RuboCop
71
71
  end
72
72
 
73
73
  def use_return_with_argument?(node)
74
- node.if_branch&.return_type? && node.if_branch&.arguments&.any?
74
+ node.branches.compact.any? { |branch| branch.return_type? && branch.arguments.any? }
75
75
  end
76
76
 
77
77
  def replacement(node)
@@ -80,7 +80,9 @@ module RuboCop
80
80
  then_code = node.if_branch ? build_expression(node.if_branch) : 'nil'
81
81
  else_code = node.else_branch ? build_expression(node.else_branch) : 'nil'
82
82
 
83
- "#{node.condition.source} ? #{then_code} : #{else_code}"
83
+ then_code, else_code = else_code, then_code if node.unless?
84
+
85
+ "#{ternary_condition(node)} ? #{then_code} : #{else_code}"
84
86
  end
85
87
 
86
88
  def correct_elsif(node)
@@ -101,6 +103,14 @@ module RuboCop
101
103
  "#{method.source}(#{arguments.source})"
102
104
  end
103
105
 
106
+ # An assignment used as the condition must be parenthesized, otherwise the
107
+ # assignment would capture the whole ternary (`a = b ? c : d` instead of
108
+ # `(a = b) ? c : d`), changing what gets assigned.
109
+ def ternary_condition(node)
110
+ condition = node.condition
111
+ condition.assignment? ? "(#{condition.source})" : condition.source
112
+ end
113
+
104
114
  def build_else_branch(second_condition)
105
115
  result = <<~RUBY
106
116
  elsif #{second_condition.condition.source}
@@ -68,7 +68,7 @@ module RuboCop
68
68
  end
69
69
 
70
70
  def autocorrect(corrector, node)
71
- if node.type?(:while_post, :until_post)
71
+ if node.post_condition_loop?
72
72
  replace_begin_end_with_modifier(corrector, node)
73
73
  elsif node.modifier_form?
74
74
  replace_source(corrector, node.source_range, modifier_replacement(node))
@@ -3,7 +3,10 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for trailing inline comments.
6
+ # Checks for trailing inline comments. Inline comments can
7
+ # make lines harder to read, especially when they are long.
8
+ # Placing comments on their own line above the code they
9
+ # describe is often clearer.
7
10
  #
8
11
  # @example
9
12
  #
@@ -23,7 +26,7 @@ module RuboCop
23
26
  def on_new_investigation
24
27
  processed_source.comments.each do |comment|
25
28
  next if comment_line?(processed_source[comment.loc.line - 1]) ||
26
- comment.text.match?(/\A# rubocop:(enable|disable)/)
29
+ comment.text.match?(/\A# rubocop:(enable|disable|todo)/)
27
30
 
28
31
  add_offense(comment)
29
32
  end