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
data/lib/rubocop/cli.rb CHANGED
@@ -12,8 +12,8 @@ module RuboCop
12
12
  STATUS_INTERRUPTED = Signal.list['INT'] + 128
13
13
  DEFAULT_PARALLEL_OPTIONS = %i[
14
14
  color config debug display_style_guide display_time display_only_fail_level_offenses
15
- display_only_failed editor_mode except extra_details fail_level fix_layout format
16
- ignore_disable_comments lint only only_guide_cops require safe
15
+ display_only_failed editor_mode except extra_details fail_level fix_layout format formatters
16
+ ignore_disable_comments lint only only_guide_cops out preview require safe
17
17
  autocorrect safe_autocorrect autocorrect_all
18
18
  ].freeze
19
19
 
@@ -35,8 +35,10 @@ module RuboCop
35
35
  # @param args [Array<String>] command line arguments
36
36
  # @return [Integer] UNIX exit code
37
37
  #
38
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
38
+ # rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
39
39
  def run(args = ARGV)
40
+ time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
41
+
40
42
  @options, paths = Options.new.parse(args)
41
43
  @env = Environment.new(@options, @config_store, paths)
42
44
 
@@ -48,11 +50,12 @@ module RuboCop
48
50
  validate_options_vs_config
49
51
  parallel_by_default!
50
52
  apply_default_formatter
53
+ report_pending_cops
51
54
  execute_runners
52
55
  end
53
56
  end
54
57
  rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e
55
- warn e.message
58
+ warn Rainbow(e.message).red
56
59
  STATUS_ERROR
57
60
  rescue RuboCop::Error => e
58
61
  warn Rainbow("Error: #{e.message}").red
@@ -63,7 +66,7 @@ module RuboCop
63
66
  STATUS_INTERRUPTED
64
67
  rescue Finished
65
68
  STATUS_SUCCESS
66
- rescue OptionParser::InvalidOption => e
69
+ rescue OptionParser::ParseError => e
67
70
  warn e.message
68
71
  warn 'For usage information, use --help'
69
72
  STATUS_ERROR
@@ -71,12 +74,16 @@ module RuboCop
71
74
  warn e.message
72
75
  warn e.backtrace
73
76
  STATUS_ERROR
77
+ ensure
78
+ elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start
79
+ if @options[:debug] || @options[:display_time]
80
+ puts "Finished in #{elapsed_time.round(5)} seconds"
81
+ end
74
82
  end
75
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
76
83
 
77
84
  private
78
85
 
79
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
86
+ # rubocop:disable-next Metrics/MethodLength, Metrics/AbcSize
80
87
  def profile_if_needed
81
88
  return yield unless @options[:profile]
82
89
 
@@ -108,7 +115,6 @@ module RuboCop
108
115
  end
109
116
  status
110
117
  end
111
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
112
118
 
113
119
  def require_gem(name)
114
120
  require name
@@ -155,10 +161,14 @@ module RuboCop
155
161
 
156
162
  def act_on_options
157
163
  set_options_to_config_loader
164
+ set_options_to_pending_cops_reporter
158
165
  handle_editor_mode
159
166
 
160
- @config_store.options_config = @options[:config] if @options[:config]
161
- @config_store.force_default_config! if @options[:force_default_config]
167
+ @config_store.apply_options!(@options)
168
+ # Set cache root after apply_options! to ensure force_default_config is applied first.
169
+ early_cache_root = ConfigLoader.cache_root(@options[:cache_root])
170
+ ConfigLoader.cache_root = ResultCache.cache_root(@config_store, @options[:cache_root])
171
+ warn_if_cache_root_changed(early_cache_root, ConfigLoader.cache_root)
162
172
 
163
173
  handle_exiting_options
164
174
 
@@ -173,27 +183,38 @@ module RuboCop
173
183
 
174
184
  def set_options_to_config_loader
175
185
  ConfigLoader.debug = @options[:debug]
176
- ConfigLoader.disable_pending_cops = @options[:disable_pending_cops]
177
- ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
178
186
  ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion]
179
187
  ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops]
188
+ set_cop_selection_options_to_config_loader
189
+ end
190
+
191
+ # Options that decide which cops run, as opposed to how configuration is loaded.
192
+ def set_cop_selection_options_to_config_loader
193
+ ConfigLoader.disable_pending_cops = @options[:disable_pending_cops]
194
+ ConfigLoader.enable_pending_cops = @options[:enable_pending_cops]
195
+ ConfigLoader.enabled_by_default = @options[:enable_all_cops]
196
+ ConfigLoader.disabled_by_default = @options[:disable_all_cops]
197
+ ConfigLoader.preview = @options[:preview]
198
+ end
199
+
200
+ def set_options_to_pending_cops_reporter
201
+ PendingCopsReporter.disable_pending_cops = @options[:disable_pending_cops]
202
+ PendingCopsReporter.enable_pending_cops = @options[:enable_pending_cops]
180
203
  end
181
204
 
182
205
  def handle_editor_mode
183
206
  RuboCop::LSP.enable if @options[:editor_mode]
184
207
  end
185
208
 
186
- # rubocop:disable Metrics/CyclomaticComplexity
187
209
  def handle_exiting_options
188
210
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
189
211
 
190
212
  run_command(:version) if @options[:version] || @options[:verbose_version]
191
- run_command(:show_cops) if @options[:show_cops]
192
- run_command(:show_docs_url) if @options[:show_docs_url]
193
- run_command(:lsp) if @options[:lsp]
213
+ %i[show_cops list_enabled_cops_for show_docs_url lsp mcp].each do |name|
214
+ run_command(name) if @options[name]
215
+ end
194
216
  raise Finished
195
217
  end
196
- # rubocop:enable Metrics/CyclomaticComplexity
197
218
 
198
219
  def apply_default_formatter
199
220
  # This must be done after the options have already been processed,
@@ -208,5 +229,25 @@ module RuboCop
208
229
  [[formatter, @options[:output_path]]]
209
230
  end
210
231
  end
232
+
233
+ def report_pending_cops
234
+ PendingCopsReporter.warn_if_needed(@config_store.for_pwd)
235
+ end
236
+
237
+ def warn_if_cache_root_changed(early, desired)
238
+ return if early == desired
239
+ # Normalize paths to avoid false positives from symlink resolution differences
240
+ if File.exist?(early) && File.exist?(desired) &&
241
+ File.realpath(early) == File.realpath(desired)
242
+ return
243
+ end
244
+
245
+ warn Rainbow(
246
+ "Warning: Remote configuration cache files were stored in `#{early}` " \
247
+ "because a desired cache root (`#{desired}`) was not set at the top level. " \
248
+ 'Consider setting `AllCops: CacheRootDirectory` in your toplevel configuration file, ' \
249
+ 'using the `RUBOCOP_CACHE_ROOT` environment variable, or using CLI options.'
250
+ ).yellow
251
+ end
211
252
  end
212
253
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CommentConfig
5
+ # A disabled line range that remembers the directive comment that opened
6
+ # it. Value-equal to a plain `Range`, so consumers comparing or hashing
7
+ # ranges are unaffected.
8
+ # @api private
9
+ class DirectiveRange < Range
10
+ attr_reader :directive
11
+
12
+ def initialize(first_line, last_line, directive)
13
+ super(first_line, last_line)
14
+ @directive = directive
15
+ end
16
+ end
17
+
18
+ # The per-cop state accumulated while analyzing directives: the disabled
19
+ # ranges so far, plus the line and directive of the currently open
20
+ # disable, if any.
21
+ # @api private
22
+ CopAnalysis = Struct.new(:line_ranges, :start_line_number, :start_directive) do
23
+ # The open range (if any) closed at the given line, appended to the
24
+ # accumulated ranges, each remembering the directive that opened it.
25
+ # Closing above the opening line (e.g. a `pop` directly below a
26
+ # statement whose disable a `next +Cop` suspended) yields no range.
27
+ def close(line)
28
+ return line_ranges if !start_line_number || line < start_line_number
29
+
30
+ line_ranges + [DirectiveRange.new(start_line_number, line, start_directive)]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CommentConfig
5
+ # Handling of next-statement directives (`disable-next`, `todo-next` and
6
+ # `next`): computing the statement scope they apply to and tracking
7
+ # directives that attached to nothing.
8
+ # The scope is the whole statement starting on the next line bearing
9
+ # code. Comment-only lines between the directive and the code chain (so
10
+ # several directives can stack), while a blank line breaks the attachment.
11
+ # @api private
12
+ module DisableNext
13
+ # Next-statement directives that affect nothing: nothing follows
14
+ # them, or they sit at the end of a code line.
15
+ def detached_next_directives
16
+ cop_disabled_line_ranges # ensure the analysis that collects them ran
17
+ @detached_next_directives
18
+ end
19
+
20
+ # The line range of the statement a `disable-next` directive on the
21
+ # given line scopes to (or would scope to), or `nil` when no statement
22
+ # is attached. A directive is only honored on a comment-only line.
23
+ # Stacked directives share the target, so the computation is memoized.
24
+ # @api private
25
+ def statement_scope_after(line)
26
+ return nil unless comment_only_line?(line)
27
+
28
+ code_line = attached_code_line(line)
29
+ return nil unless code_line
30
+
31
+ (@statement_bounds ||= {})[code_line] ||= statement_bounds_at(code_line)
32
+ end
33
+
34
+ private
35
+
36
+ def apply_disable_next(analyses, directive)
37
+ bounds = statement_scope_after(directive.line_number)
38
+ return @detached_next_directives << directive unless bounds
39
+
40
+ range = DirectiveRange.new(bounds.begin, bounds.end, directive)
41
+ directive.cop_names.each do |cop_name|
42
+ add_next_range(analyses, qualified_cop_name(cop_name), range)
43
+ end
44
+ end
45
+
46
+ def add_next_range(analyses, cop_name, range)
47
+ analysis = analyses[cop_name]
48
+ analyses[cop_name] = CopAnalysis.new(analysis.line_ranges + [range],
49
+ analysis.start_line_number, analysis.start_directive)
50
+ end
51
+
52
+ # Applies a `next` directive: `-` cops are disabled for the attached
53
+ # statement (exactly like `disable-next`), `+` cops have any open
54
+ # disable suspended for it. The `resolved_cops` come pre-expanded and
55
+ # qualified, mirroring `push`.
56
+ def apply_next_directive(analyses, resolved_cops, directive)
57
+ bounds = statement_scope_after(directive.line_number)
58
+ return @detached_next_directives << directive unless bounds
59
+
60
+ range = DirectiveRange.new(bounds.begin, bounds.end, directive)
61
+ resolved_cops.each do |op, cops|
62
+ cops.each do |cop|
63
+ if op == '-'
64
+ add_next_range(analyses, cop, range)
65
+ else
66
+ suspend_disable(analyses, cop, bounds)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Applies an `enable-next` directive: every listed cop (departments
73
+ # and `all` included) has any open disable suspended for the attached
74
+ # statement.
75
+ def apply_enable_next(analyses, directive)
76
+ bounds = statement_scope_after(directive.line_number)
77
+ return @detached_next_directives << directive unless bounds
78
+
79
+ directive.cop_names.each do |cop_name|
80
+ suspend_disable(analyses, qualified_cop_name(cop_name), bounds)
81
+ end
82
+ end
83
+
84
+ # Punches a statement-sized hole into the currently open disable of the
85
+ # cop (whether opened by a directive or injected for a config-disabled
86
+ # cop): the open range closes just above the statement and reopens
87
+ # right below it, still attributed to its opening directive. Aligned
88
+ # with `push`, a `+` for a cop that is not disabled is a no-op.
89
+ def suspend_disable(analyses, cop, bounds)
90
+ analysis = analyses[cop]
91
+ return unless analysis.start_line_number
92
+
93
+ analyses[cop] = CopAnalysis.new(analysis.close(bounds.begin - 1),
94
+ bounds.end + 1, analysis.start_directive)
95
+ end
96
+
97
+ def attached_code_line(directive_line)
98
+ ((directive_line + 1)..processed_source.lines.size).each do |line|
99
+ return line unless comment_only_line?(line)
100
+ return nil if processed_source[line - 1].blank?
101
+ end
102
+
103
+ nil
104
+ end
105
+
106
+ def statement_bounds_at(line)
107
+ statement = statement_starting_at(line)
108
+ # A code line where no statement starts (e.g. a lone `end`) scopes
109
+ # the directive to that line alone.
110
+ return (line..line) unless statement
111
+
112
+ (line..statement_end_line(statement))
113
+ end
114
+
115
+ def statement_start_line?(node, line)
116
+ # Synthetic nodes (e.g. parentheses-less argument lists) have no
117
+ # source range. `begin` nodes are sequences of statements, not
118
+ # statements themselves - taking one would scope the directive to
119
+ # everything up to the last statement of the sequence.
120
+ node.source_range && node.first_line == line && !node.begin_type?
121
+ end
122
+
123
+ def statement_starting_at(line)
124
+ ast = processed_source.ast
125
+ return nil unless ast
126
+
127
+ ast.each_node.select { |node| statement_start_line?(node, line) }.max_by(&:last_line)
128
+ end
129
+
130
+ def statement_end_line(statement)
131
+ statement.each_node.filter_map do |node|
132
+ next unless node.source_range
133
+
134
+ heredoc?(node) ? node.loc.heredoc_end.line : node.last_line
135
+ end.max
136
+ end
137
+
138
+ def heredoc?(node)
139
+ node.respond_to?(:heredoc?) && node.heredoc?
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ class CommentConfig
5
+ # Handling of `push`/`pop` directives and their signed cop arguments:
6
+ # saving and restoring the per-cop analysis state, and resolving the
7
+ # `+`/`-` argument lists (shared with the `next` directive).
8
+ # @api private
9
+ module PushPop
10
+ private
11
+
12
+ def resolve_push_cops(directive)
13
+ directive.push_args.transform_values do |names|
14
+ names.flat_map { |name| expand_cop_name(name) }
15
+ end
16
+ end
17
+
18
+ def expand_cop_name(name)
19
+ registry = Cop::Registry.global
20
+ cops = registry.department?(name) ? registry.names_for_department(name) : [name]
21
+ cops.map { |c| qualified_cop_name(c) }
22
+ end
23
+
24
+ def apply_push(analyses, resolved_cops, directive)
25
+ resolved_cops.each do |op, cops|
26
+ cops.each { |cop| apply_cop_op(analyses, op, cop, directive) }
27
+ end
28
+ end
29
+
30
+ def apply_cop_op(analyses, operation, cop, directive)
31
+ analysis = analyses[cop]
32
+ line = directive.line_number
33
+ if operation == '-' && !analysis.start_line_number
34
+ analyses[cop] = CopAnalysis.new(analysis.line_ranges, line, directive)
35
+ elsif operation == '+' && analysis.start_line_number
36
+ analyses[cop] = CopAnalysis.new(analysis.close(line), nil)
37
+ end
38
+ end
39
+
40
+ def pop_state(analyses, line)
41
+ restore_point = @stack.pop
42
+ (restore_point.keys | analyses.keys).each do |cop|
43
+ analyses[cop] = popped_analysis(analyses[cop], restore_point[cop], line)
44
+ end
45
+ end
46
+
47
+ def popped_analysis(current, restored, line)
48
+ ranges = current.close(line - 1)
49
+ return CopAnalysis.new(ranges, nil) unless restored&.start_line_number
50
+
51
+ CopAnalysis.new(ranges, line, restored.start_directive)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -5,6 +5,8 @@ module RuboCop
5
5
  # and provides a way to check if each cop is enabled at arbitrary line.
6
6
  class CommentConfig
7
7
  extend SimpleForwardable
8
+ include DisableNext
9
+ include PushPop
8
10
 
9
11
  CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY
10
12
 
@@ -25,8 +27,6 @@ module RuboCop
25
27
  end
26
28
  end
27
29
 
28
- CopAnalysis = Struct.new(:line_ranges, :start_line_number)
29
-
30
30
  attr_reader :processed_source
31
31
 
32
32
  def_delegators :@processed_source, :config, :registry
@@ -34,14 +34,26 @@ module RuboCop
34
34
  def initialize(processed_source)
35
35
  @processed_source = processed_source
36
36
  @no_directives = !processed_source.raw_source.include?('rubocop')
37
+ @stack = []
38
+ @detached_next_directives = []
37
39
  end
38
40
 
39
41
  def cop_enabled_at_line?(cop, line_number)
42
+ cop_enabled_at_lines?(cop, line_number, line_number)
43
+ end
44
+
45
+ # Whether the cop is enabled for all of the given line span. The cop
46
+ # counts as disabled for the span when any of its disabled ranges
47
+ # overlaps it, so that a directive on any line of a multi-line offense
48
+ # suppresses the offense.
49
+ def cop_enabled_at_lines?(cop, first_line, last_line)
40
50
  cop = cop.cop_name if cop.respond_to?(:cop_name)
41
51
  disabled_line_ranges = cop_disabled_line_ranges[cop]
42
52
  return true unless disabled_line_ranges
43
53
 
44
- disabled_line_ranges.none? { |range| range.include?(line_number) }
54
+ disabled_line_ranges.none? do |range|
55
+ range.end >= first_line && range.begin <= last_line
56
+ end
45
57
  end
46
58
 
47
59
  def cop_opted_in?(cop)
@@ -54,8 +66,8 @@ module RuboCop
54
66
 
55
67
  def extra_enabled_comments
56
68
  disable_count = Hash.new(0)
57
- registry.disabled(config).each do |cop|
58
- disable_count[cop.cop_name] += 1
69
+ registry.disabled_names(config).each do |cop_name|
70
+ disable_count[cop_name] += 1
59
71
  end
60
72
  extra_enabled_comments_with_names(extras: Hash.new { |h, k| h[k] = [] }, names: disable_count)
61
73
  end
@@ -64,11 +76,32 @@ module RuboCop
64
76
  non_comment_token_line_numbers.none?(line_number)
65
77
  end
66
78
 
79
+ # The names of the cops that are opted in by an `enable` comment directive
80
+ # or a `+` argument of a `push`/`next` directive, used to mobilize cops
81
+ # disabled in the config on demand.
82
+ #
83
+ # @api private
84
+ # @return [Set<String>]
85
+ def opt_in_cops
86
+ @opt_in_cops ||= begin
87
+ cops = Set.new
88
+ each_directive do |directive|
89
+ if directive.enabled?
90
+ cops.merge(directive.raw_cop_names) unless directive.all_cops?
91
+ elsif directive.push? || directive.next?
92
+ cops.merge(directive.signed_args.fetch('+', []))
93
+ end
94
+ end
95
+ cops
96
+ end
97
+ end
98
+
67
99
  private
68
100
 
69
101
  def extra_enabled_comments_with_names(extras:, names:)
70
102
  each_directive do |directive|
71
103
  next unless comment_only_line?(directive.line_number)
104
+ next if self_closing_directive?(directive)
72
105
 
73
106
  if directive.enabled_all?
74
107
  handle_enable_all(directive, names, extras)
@@ -80,43 +113,47 @@ module RuboCop
80
113
  extras
81
114
  end
82
115
 
83
- def opt_in_cops
84
- @opt_in_cops ||= begin
85
- cops = Set.new
86
- each_directive do |directive|
87
- next unless directive.enabled?
88
- next if directive.all_cops?
89
-
90
- cops.merge(directive.raw_cop_names)
91
- end
92
- cops
93
- end
94
- end
95
-
96
- def analyze # rubocop:todo Metrics/AbcSize
116
+ # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
117
+ def analyze
97
118
  return {} if @no_directives
98
119
 
99
120
  analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) }
100
121
  inject_disabled_cops_directives(analyses)
101
122
 
102
123
  each_directive do |directive|
103
- directive.cop_names.each do |cop_name|
104
- cop_name = qualified_cop_name(cop_name)
105
- analyses[cop_name] = analyze_cop(analyses[cop_name], directive)
124
+ if directive.push?
125
+ restore_point = analyses.transform_values(&:dup)
126
+ @stack.push(restore_point)
127
+ apply_push(analyses, resolve_push_cops(directive), directive)
128
+ elsif directive.pop?
129
+ pop_state(analyses, directive.line_number) if @stack.any?
130
+ elsif directive.disable_next?
131
+ apply_disable_next(analyses, directive)
132
+ elsif directive.next?
133
+ apply_next_directive(analyses, resolve_push_cops(directive), directive)
134
+ elsif directive.enable_next?
135
+ apply_enable_next(analyses, directive)
136
+ else
137
+ directive.cop_names.each do |cop_name|
138
+ cop_name = qualified_cop_name(cop_name)
139
+ analyses[cop_name] = analyze_cop(analyses[cop_name], directive)
140
+ end
106
141
  end
107
142
  end
108
143
 
109
144
  analyses.each_with_object({}) do |element, hash|
110
145
  cop_name, analysis = *element
146
+ next if prevent_directive_disabling?(cop_name)
147
+
111
148
  hash[cop_name] = cop_line_ranges(analysis)
112
149
  end
113
150
  end
114
151
 
115
152
  def inject_disabled_cops_directives(analyses)
116
- registry.disabled(config).each do |cop|
117
- analyses[cop.cop_name] = analyze_cop(
118
- analyses[cop.cop_name],
119
- DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(cop.cop_name))
153
+ registry.disabled_names(config).each do |cop_name|
154
+ analyses[cop_name] = analyze_cop(
155
+ analyses[cop_name],
156
+ DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(cop_name))
120
157
  )
121
158
  end
122
159
  end
@@ -136,35 +173,21 @@ module RuboCop
136
173
  return analysis unless directive.disabled?
137
174
 
138
175
  line = directive.line_number
139
- start_line = analysis.start_line_number
140
-
141
- CopAnalysis.new(analysis.line_ranges + [(line..line)], start_line)
176
+ range = DirectiveRange.new(line, line, directive)
177
+ CopAnalysis.new(analysis.line_ranges + [range], analysis.start_line_number,
178
+ analysis.start_directive)
142
179
  end
143
180
 
144
181
  def analyze_disabled(analysis, directive)
145
- line = directive.line_number
146
- start_line = analysis.start_line_number
147
-
148
- # Cop already disabled on this line, so we end the current disabled
149
- # range before we start a new range.
150
- return CopAnalysis.new(analysis.line_ranges + [start_line..line], line) if start_line
151
-
152
- CopAnalysis.new(analysis.line_ranges, line)
182
+ CopAnalysis.new(analysis.close(directive.line_number), directive.line_number, directive)
153
183
  end
154
184
 
155
185
  def analyze_rest(analysis, directive)
156
- line = directive.line_number
157
- start_line = analysis.start_line_number
158
-
159
- return CopAnalysis.new(analysis.line_ranges + [start_line..line], nil) if start_line
160
-
161
- CopAnalysis.new(analysis.line_ranges, nil)
186
+ CopAnalysis.new(analysis.close(directive.line_number), nil)
162
187
  end
163
188
 
164
189
  def cop_line_ranges(analysis)
165
- return analysis.line_ranges unless analysis.start_line_number
166
-
167
- analysis.line_ranges + [(analysis.start_line_number..Float::INFINITY)]
190
+ analysis.close(Float::INFINITY)
168
191
  end
169
192
 
170
193
  def each_directive
@@ -176,8 +199,29 @@ module RuboCop
176
199
  end
177
200
  end
178
201
 
202
+ # Push/pop and next-statement directives close themselves, so they
203
+ # play no part in the disable/enable pairing.
204
+ def self_closing_directive?(directive)
205
+ directive.push? || directive.pop? || directive.disable_next? ||
206
+ directive.next? || directive.enable_next?
207
+ end
208
+
179
209
  def qualified_cop_name(cop_name)
180
- Cop::Registry.qualified_cop_name(cop_name.strip, processed_source.file_path)
210
+ # A directive naming a cop under the wrong department is not honored -
211
+ # the mistake is surfaced by `Lint/RedundantCopDisableDirective` (with a
212
+ # did-you-mean hint) instead of a stderr warning that is easy to miss
213
+ # and disappears entirely on cached runs.
214
+ Cop::Registry.qualified_cop_name(cop_name.strip, processed_source.file_path,
215
+ correct_namespace: false)
216
+ end
217
+
218
+ # `Style/DisableCopsWithinSourceCodeDirective` cannot be disabled via
219
+ # directive comments when it is explicitly enabled with `Enabled: true`.
220
+ # This prevents users from bypassing the cop by writing a disable
221
+ # directive that targets this cop itself.
222
+ def prevent_directive_disabling?(cop_name)
223
+ cop_name == DirectiveComment::STYLE_DISABLE_COPS_DIRECTIVE_COP &&
224
+ config.dig(cop_name, 'Enabled') == true
181
225
  end
182
226
 
183
227
  def non_comment_token_line_numbers
@@ -205,7 +249,7 @@ module RuboCop
205
249
  directive.cop_names.each do |name|
206
250
  if directive.disabled?
207
251
  names[name] += 1
208
- elsif (names[name]).positive?
252
+ elsif names[name].positive?
209
253
  names[name] -= 1
210
254
  else
211
255
  extras[directive.comment] << name