rubocop 1.71.1 → 1.92.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 (705) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +885 -168
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +47 -4
  7. data/exe/rubocop +2 -9
  8. data/lib/rubocop/cache_config.rb +29 -0
  9. data/lib/rubocop/cached_data.rb +50 -5
  10. data/lib/rubocop/changed_files.rb +134 -0
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +36 -4
  12. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  13. data/lib/rubocop/cli/command/execute_runner.rb +54 -3
  14. data/lib/rubocop/cli/command/explain.rb +34 -0
  15. data/lib/rubocop/cli/command/list_enabled_cops_for.rb +40 -0
  16. data/lib/rubocop/cli/command/lsp.rb +1 -1
  17. data/lib/rubocop/cli/command/mcp.rb +19 -0
  18. data/lib/rubocop/cli/command/show_cops.rb +8 -2
  19. data/lib/rubocop/cli/command/show_docs_url.rb +8 -10
  20. data/lib/rubocop/cli/command/suggest_extensions.rb +8 -2
  21. data/lib/rubocop/cli.rb +59 -17
  22. data/lib/rubocop/comment_config/directive_range.rb +34 -0
  23. data/lib/rubocop/comment_config/disable_next.rb +143 -0
  24. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  25. data/lib/rubocop/comment_config.rb +98 -45
  26. data/lib/rubocop/config.rb +137 -19
  27. data/lib/rubocop/config_finder.rb +1 -1
  28. data/lib/rubocop/config_loader.rb +75 -49
  29. data/lib/rubocop/config_loader_resolver.rb +124 -33
  30. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  31. data/lib/rubocop/config_obsoletion/extracted_cop.rb +6 -3
  32. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  33. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  34. data/lib/rubocop/config_obsoletion.rb +47 -3
  35. data/lib/rubocop/config_store.rb +7 -2
  36. data/lib/rubocop/config_validator.rb +75 -12
  37. data/lib/rubocop/cop/autocorrect_logic.rb +43 -17
  38. data/lib/rubocop/cop/badge.rb +9 -1
  39. data/lib/rubocop/cop/base.rb +128 -35
  40. data/lib/rubocop/cop/bundler/gem_comment.rb +5 -4
  41. data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
  42. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -11
  43. data/lib/rubocop/cop/bundler.rb +19 -0
  44. data/lib/rubocop/cop/commissioner.rb +13 -11
  45. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  46. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  47. data/lib/rubocop/cop/corrector.rb +4 -4
  48. data/lib/rubocop/cop/correctors/alignment_corrector.rb +92 -11
  49. data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
  50. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
  51. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  52. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +7 -2
  53. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +29 -2
  54. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -5
  55. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +8 -1
  56. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +73 -2
  57. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  58. data/lib/rubocop/cop/correctors.rb +28 -0
  59. data/lib/rubocop/cop/documentation.rb +3 -4
  60. data/lib/rubocop/cop/exclude_limit.rb +31 -5
  61. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  62. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  63. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  64. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +49 -17
  65. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -9
  66. data/lib/rubocop/cop/gemspec/require_mfa.rb +22 -5
  67. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +12 -7
  68. data/lib/rubocop/cop/gemspec.rb +22 -0
  69. data/lib/rubocop/cop/generator/registration_injector.rb +188 -0
  70. data/lib/rubocop/cop/generator.rb +5 -1
  71. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  72. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
  73. data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
  74. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  75. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
  76. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +16 -20
  77. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
  78. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +1 -2
  79. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +6 -2
  80. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +85 -0
  81. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +2 -2
  82. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  83. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  84. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  85. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +5 -3
  86. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  87. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  88. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
  89. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  90. data/lib/rubocop/cop/internal_affairs.rb +3 -16
  91. data/lib/rubocop/cop/layout/argument_alignment.rb +4 -2
  92. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  93. data/lib/rubocop/cop/layout/begin_end_alignment.rb +1 -1
  94. data/lib/rubocop/cop/layout/block_alignment.rb +86 -4
  95. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  96. data/lib/rubocop/cop/layout/case_indentation.rb +28 -10
  97. data/lib/rubocop/cop/layout/class_structure.rb +172 -36
  98. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  99. data/lib/rubocop/cop/layout/comment_indentation.rb +17 -7
  100. data/lib/rubocop/cop/layout/condition_position.rb +13 -3
  101. data/lib/rubocop/cop/layout/def_end_alignment.rb +5 -1
  102. data/lib/rubocop/cop/layout/dot_position.rb +2 -2
  103. data/lib/rubocop/cop/layout/else_alignment.rb +3 -15
  104. data/lib/rubocop/cop/layout/empty_comment.rb +8 -10
  105. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +27 -9
  106. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +63 -5
  107. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
  108. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +46 -21
  109. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  110. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  111. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +34 -4
  112. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  113. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -0
  114. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +14 -3
  115. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +17 -3
  116. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  117. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  118. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
  119. data/lib/rubocop/cop/layout/end_alignment.rb +20 -8
  120. data/lib/rubocop/cop/layout/extra_spacing.rb +109 -3
  121. data/lib/rubocop/cop/layout/first_argument_indentation.rb +57 -3
  122. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -5
  123. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
  124. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +25 -18
  125. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
  126. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  127. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  128. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  129. data/lib/rubocop/cop/layout/hash_alignment.rb +20 -18
  130. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +5 -3
  131. data/lib/rubocop/cop/layout/heredoc_indentation.rb +48 -3
  132. data/lib/rubocop/cop/layout/indentation_style.rb +5 -2
  133. data/lib/rubocop/cop/layout/indentation_width.rb +159 -12
  134. data/lib/rubocop/cop/layout/leading_comment_space.rb +40 -1
  135. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +10 -4
  136. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  137. data/lib/rubocop/cop/layout/line_length.rb +201 -30
  138. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +69 -57
  139. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +8 -2
  140. data/lib/rubocop/cop/layout/multiline_block_layout.rb +11 -1
  141. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +63 -56
  142. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +7 -1
  143. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +259 -40
  144. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  145. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  146. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +9 -5
  147. data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
  148. data/lib/rubocop/cop/layout/redundant_line_break.rb +111 -7
  149. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +29 -9
  150. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  151. data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
  152. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  153. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  154. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  155. data/lib/rubocop/cop/layout/space_around_keyword.rb +20 -3
  156. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  157. data/lib/rubocop/cop/layout/space_around_operators.rb +30 -4
  158. data/lib/rubocop/cop/layout/space_before_block_braces.rb +5 -1
  159. data/lib/rubocop/cop/layout/space_before_brackets.rb +6 -39
  160. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
  161. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +55 -36
  162. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -8
  163. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
  164. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  165. data/lib/rubocop/cop/layout.rb +114 -0
  166. data/lib/rubocop/cop/lazy_loader.rb +41 -0
  167. data/lib/rubocop/cop/lint/ambiguous_assignment.rb +9 -17
  168. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +72 -1
  169. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  170. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +3 -11
  171. data/lib/rubocop/cop/lint/ambiguous_range.rb +6 -2
  172. data/lib/rubocop/cop/lint/argument_mismatch.rb +99 -0
  173. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +2 -3
  174. data/lib/rubocop/cop/lint/assignment_in_condition.rb +15 -1
  175. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  176. data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -8
  177. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +4 -3
  178. data/lib/rubocop/cop/lint/constant_reassignment.rb +94 -15
  179. data/lib/rubocop/cop/lint/constant_resolution.rb +31 -6
  180. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +240 -0
  181. data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
  182. data/lib/rubocop/cop/lint/debugger.rb +13 -4
  183. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  184. data/lib/rubocop/cop/lint/deprecated_constants.rb +2 -8
  185. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +5 -2
  186. data/lib/rubocop/cop/lint/deprecated_reference.rb +194 -0
  187. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
  188. data/lib/rubocop/cop/lint/duplicate_methods.rb +506 -41
  189. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +5 -42
  190. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  191. data/lib/rubocop/cop/lint/empty_block.rb +4 -4
  192. data/lib/rubocop/cop/lint/empty_conditional_body.rb +22 -65
  193. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  194. data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
  195. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  196. data/lib/rubocop/cop/lint/empty_when.rb +8 -1
  197. data/lib/rubocop/cop/lint/ensure_return.rb +19 -1
  198. data/lib/rubocop/cop/lint/erb_new_arguments.rb +4 -8
  199. data/lib/rubocop/cop/lint/float_comparison.rb +33 -10
  200. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
  201. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  202. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -2
  203. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -1
  204. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -2
  205. data/lib/rubocop/cop/lint/inherit_exception.rb +53 -7
  206. data/lib/rubocop/cop/lint/interpolation_check.rb +25 -6
  207. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  208. data/lib/rubocop/cop/lint/literal_as_condition.rb +152 -11
  209. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +11 -1
  210. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +75 -37
  211. data/lib/rubocop/cop/lint/loop.rb +24 -2
  212. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  213. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +60 -23
  214. data/lib/rubocop/cop/lint/missing_super.rb +31 -1
  215. data/lib/rubocop/cop/lint/mixed_case_range.rb +2 -2
  216. data/lib/rubocop/cop/lint/multiple_comparison.rb +2 -2
  217. data/lib/rubocop/cop/lint/name_typo.rb +270 -0
  218. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  219. data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
  220. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +20 -0
  221. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +4 -2
  222. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  223. data/lib/rubocop/cop/lint/number_conversion.rb +20 -11
  224. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  225. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +11 -0
  226. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  227. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +7 -7
  228. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +15 -4
  229. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -14
  230. data/lib/rubocop/cop/lint/raise_exception.rb +30 -11
  231. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  232. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +160 -39
  233. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +53 -19
  234. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +28 -6
  235. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  236. data/lib/rubocop/cop/lint/redundant_require_statement.rb +5 -25
  237. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +134 -12
  238. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -4
  239. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +267 -0
  240. data/lib/rubocop/cop/lint/redundant_with_index.rb +5 -3
  241. data/lib/rubocop/cop/lint/redundant_with_object.rb +8 -0
  242. data/lib/rubocop/cop/lint/refinement_import_methods.rb +8 -1
  243. data/lib/rubocop/cop/lint/regexp_as_condition.rb +9 -1
  244. data/lib/rubocop/cop/lint/require_parentheses.rb +13 -4
  245. data/lib/rubocop/cop/lint/require_range_parentheses.rb +3 -2
  246. data/lib/rubocop/cop/lint/require_relative_self_path.rb +7 -5
  247. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  248. data/lib/rubocop/cop/lint/rescue_type.rb +2 -2
  249. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  250. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +28 -4
  251. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +9 -5
  252. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  253. data/lib/rubocop/cop/lint/script_permission.rb +5 -1
  254. data/lib/rubocop/cop/lint/self_assignment.rb +63 -6
  255. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -1
  256. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  257. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  258. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -1
  259. data/lib/rubocop/cop/lint/shared_mutable_default.rb +14 -1
  260. data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
  261. data/lib/rubocop/cop/lint/super_argument_mismatch.rb +179 -0
  262. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  263. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +122 -0
  264. data/lib/rubocop/cop/lint/symbol_conversion.rb +21 -4
  265. data/lib/rubocop/cop/lint/syntax.rb +25 -1
  266. data/lib/rubocop/cop/lint/to_enum_arguments.rb +73 -5
  267. data/lib/rubocop/cop/lint/to_json.rb +20 -17
  268. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  269. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +5 -1
  270. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +54 -11
  271. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +2 -0
  272. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -1
  273. data/lib/rubocop/cop/lint/unreachable_code.rb +16 -9
  274. data/lib/rubocop/cop/lint/unreachable_loop.rb +5 -5
  275. data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
  276. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  277. data/lib/rubocop/cop/lint/unused_private_method.rb +234 -0
  278. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  279. data/lib/rubocop/cop/lint/useless_access_modifier.rb +31 -6
  280. data/lib/rubocop/cop/lint/useless_assignment.rb +63 -27
  281. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +107 -0
  282. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +92 -0
  283. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  284. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +11 -10
  285. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  286. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -3
  287. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +13 -7
  288. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -1
  289. data/lib/rubocop/cop/lint/useless_times.rb +22 -1
  290. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +201 -0
  291. data/lib/rubocop/cop/lint/void.rb +68 -22
  292. data/lib/rubocop/cop/lint.rb +179 -0
  293. data/lib/rubocop/cop/message_annotator.rb +7 -3
  294. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  295. data/lib/rubocop/cop/metrics/block_length.rb +2 -1
  296. data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
  297. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  298. data/lib/rubocop/cop/metrics/collection_literal_length.rb +1 -1
  299. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  300. data/lib/rubocop/cop/metrics/method_length.rb +3 -2
  301. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  302. data/lib/rubocop/cop/metrics/perceived_complexity.rb +37 -7
  303. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
  304. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
  305. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +1 -1
  306. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  307. data/lib/rubocop/cop/metrics.rb +31 -0
  308. data/lib/rubocop/cop/migration/department_name.rb +11 -5
  309. data/lib/rubocop/cop/migration.rb +13 -0
  310. data/lib/rubocop/cop/mixin/alignment.rb +7 -3
  311. data/lib/rubocop/cop/mixin/allowed_methods.rb +5 -5
  312. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -5
  313. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  314. data/lib/rubocop/cop/mixin/check_line_breakable.rb +44 -23
  315. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +10 -8
  316. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  317. data/lib/rubocop/cop/mixin/comments_help.rb +2 -3
  318. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -2
  319. data/lib/rubocop/cop/mixin/configurable_max.rb +6 -5
  320. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  321. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +13 -2
  322. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  323. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
  324. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +13 -5
  325. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  326. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +20 -0
  327. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
  328. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  329. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +59 -17
  330. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +52 -25
  331. data/lib/rubocop/cop/mixin/hash_subset.rb +28 -6
  332. data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
  333. data/lib/rubocop/cop/mixin/hash_transform_method.rb +32 -78
  334. data/lib/rubocop/cop/mixin/indexed_method_arity.rb +94 -0
  335. data/lib/rubocop/cop/mixin/line_length_help.rb +52 -11
  336. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  337. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  338. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  339. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
  340. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +10 -1
  341. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +2 -2
  342. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  343. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  344. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -8
  345. data/lib/rubocop/cop/mixin/project_index_help.rb +203 -0
  346. data/lib/rubocop/cop/mixin/range_help.rb +16 -5
  347. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +181 -0
  348. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  349. data/lib/rubocop/cop/mixin/statement_modifier.rb +66 -10
  350. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  351. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  352. data/lib/rubocop/cop/mixin/trailing_comma.rb +23 -6
  353. data/lib/rubocop/cop/mixin.rb +93 -0
  354. data/lib/rubocop/cop/naming/accessor_method_name.rb +8 -0
  355. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +17 -1
  356. data/lib/rubocop/cop/naming/block_forwarding.rb +7 -4
  357. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  358. data/lib/rubocop/cop/naming/file_name.rb +6 -5
  359. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  360. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  361. data/lib/rubocop/cop/naming/inclusive_language.rb +8 -2
  362. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +13 -6
  363. data/lib/rubocop/cop/naming/method_name.rb +190 -15
  364. data/lib/rubocop/cop/naming/predicate_method.rb +330 -0
  365. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +65 -8
  366. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -6
  367. data/lib/rubocop/cop/naming/variable_name.rb +51 -6
  368. data/lib/rubocop/cop/naming/variable_number.rb +3 -1
  369. data/lib/rubocop/cop/naming.rb +31 -0
  370. data/lib/rubocop/cop/offense.rb +108 -9
  371. data/lib/rubocop/cop/registry.rb +234 -65
  372. data/lib/rubocop/cop/security/eval.rb +17 -3
  373. data/lib/rubocop/cop/security/io_methods.rb +2 -2
  374. data/lib/rubocop/cop/security/json_load.rb +45 -11
  375. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  376. data/lib/rubocop/cop/security/open.rb +1 -0
  377. data/lib/rubocop/cop/security.rb +19 -0
  378. data/lib/rubocop/cop/severity.rb +12 -0
  379. data/lib/rubocop/cop/style/access_modifier_declarations.rb +54 -13
  380. data/lib/rubocop/cop/style/accessor_grouping.rb +47 -10
  381. data/lib/rubocop/cop/style/alias.rb +33 -8
  382. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  383. data/lib/rubocop/cop/style/and_or.rb +6 -1
  384. data/lib/rubocop/cop/style/arguments_forwarding.rb +52 -37
  385. data/lib/rubocop/cop/style/array_first_last.rb +13 -3
  386. data/lib/rubocop/cop/style/array_intersect.rb +136 -38
  387. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +50 -0
  388. data/lib/rubocop/cop/style/array_join.rb +4 -2
  389. data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
  390. data/lib/rubocop/cop/style/attr.rb +8 -6
  391. data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
  392. data/lib/rubocop/cop/style/begin_block.rb +3 -1
  393. data/lib/rubocop/cop/style/bitwise_predicate.rb +13 -5
  394. data/lib/rubocop/cop/style/block_delimiters.rb +71 -40
  395. data/lib/rubocop/cop/style/case_equality.rb +29 -15
  396. data/lib/rubocop/cop/style/case_like_if.rb +12 -11
  397. data/lib/rubocop/cop/style/character_literal.rb +2 -2
  398. data/lib/rubocop/cop/style/class_and_module_children.rb +179 -27
  399. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -14
  400. data/lib/rubocop/cop/style/class_methods_definitions.rb +19 -5
  401. data/lib/rubocop/cop/style/collection_compact.rb +37 -17
  402. data/lib/rubocop/cop/style/collection_methods.rb +1 -0
  403. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  404. data/lib/rubocop/cop/style/colon_method_call.rb +16 -7
  405. data/lib/rubocop/cop/style/combinable_loops.rb +88 -9
  406. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  407. data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
  408. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  409. data/lib/rubocop/cop/style/comparable_clamp.rb +12 -1
  410. data/lib/rubocop/cop/style/concat_array_literals.rb +53 -9
  411. data/lib/rubocop/cop/style/conditional_assignment.rb +58 -24
  412. data/lib/rubocop/cop/style/constant_visibility.rb +23 -12
  413. data/lib/rubocop/cop/style/copyright.rb +27 -12
  414. data/lib/rubocop/cop/style/data_inheritance.rb +25 -0
  415. data/lib/rubocop/cop/style/date_time.rb +4 -4
  416. data/lib/rubocop/cop/style/def_with_parentheses.rb +22 -5
  417. data/lib/rubocop/cop/style/dig_chain.rb +6 -1
  418. data/lib/rubocop/cop/style/dir_empty.rb +4 -0
  419. data/lib/rubocop/cop/style/directive_scope.rb +304 -0
  420. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +184 -20
  421. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +6 -1
  422. data/lib/rubocop/cop/style/documentation.rb +53 -6
  423. data/lib/rubocop/cop/style/documentation_method.rb +8 -12
  424. data/lib/rubocop/cop/style/double_negation.rb +14 -3
  425. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  426. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  427. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  428. data/lib/rubocop/cop/style/empty_case_condition.rb +13 -4
  429. data/lib/rubocop/cop/style/empty_class_definition.rb +126 -0
  430. data/lib/rubocop/cop/style/empty_heredoc.rb +4 -0
  431. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  432. data/lib/rubocop/cop/style/empty_literal.rb +12 -3
  433. data/lib/rubocop/cop/style/empty_method.rb +15 -9
  434. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +110 -0
  435. data/lib/rubocop/cop/style/encoding.rb +7 -1
  436. data/lib/rubocop/cop/style/end_block.rb +3 -1
  437. data/lib/rubocop/cop/style/endless_method.rb +252 -19
  438. data/lib/rubocop/cop/style/env_home.rb +4 -0
  439. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  440. data/lib/rubocop/cop/style/even_odd.rb +11 -1
  441. data/lib/rubocop/cop/style/exact_regexp_match.rb +52 -8
  442. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  443. data/lib/rubocop/cop/style/explicit_block_argument.rb +62 -9
  444. data/lib/rubocop/cop/style/exponential_notation.rb +5 -4
  445. data/lib/rubocop/cop/style/fetch_env_var.rb +33 -7
  446. data/lib/rubocop/cop/style/file_null.rb +6 -4
  447. data/lib/rubocop/cop/style/file_open.rb +84 -0
  448. data/lib/rubocop/cop/style/file_write.rb +21 -16
  449. data/lib/rubocop/cop/style/float_division.rb +43 -15
  450. data/lib/rubocop/cop/style/for.rb +48 -1
  451. data/lib/rubocop/cop/style/format_string.rb +44 -9
  452. data/lib/rubocop/cop/style/format_string_token.rb +86 -16
  453. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +5 -3
  454. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  455. data/lib/rubocop/cop/style/global_vars.rb +5 -2
  456. data/lib/rubocop/cop/style/guard_clause.rb +41 -24
  457. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
  458. data/lib/rubocop/cop/style/hash_conversion.rb +52 -16
  459. data/lib/rubocop/cop/style/hash_each_methods.rb +4 -4
  460. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  461. data/lib/rubocop/cop/style/hash_lookup_method.rb +128 -0
  462. data/lib/rubocop/cop/style/hash_slice.rb +16 -0
  463. data/lib/rubocop/cop/style/hash_syntax.rb +23 -6
  464. data/lib/rubocop/cop/style/hash_transform_keys.rb +19 -9
  465. data/lib/rubocop/cop/style/hash_transform_values.rb +19 -9
  466. data/lib/rubocop/cop/style/identical_conditional_branches.rb +39 -11
  467. data/lib/rubocop/cop/style/if_inside_else.rb +46 -21
  468. data/lib/rubocop/cop/style/if_unless_modifier.rb +90 -66
  469. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +19 -19
  470. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -2
  471. data/lib/rubocop/cop/style/if_with_semicolon.rb +61 -8
  472. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  473. data/lib/rubocop/cop/style/inline_comment.rb +5 -2
  474. data/lib/rubocop/cop/style/inverse_methods.rb +34 -8
  475. data/lib/rubocop/cop/style/invertible_unless_condition.rb +27 -7
  476. data/lib/rubocop/cop/style/ip_addresses.rb +3 -4
  477. data/lib/rubocop/cop/style/it_assignment.rb +69 -12
  478. data/lib/rubocop/cop/style/it_block_parameter.rb +150 -0
  479. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +4 -0
  480. data/lib/rubocop/cop/style/keyword_parameters_order.rb +23 -11
  481. data/lib/rubocop/cop/style/lambda.rb +30 -1
  482. data/lib/rubocop/cop/style/lambda_call.rb +31 -10
  483. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  484. data/lib/rubocop/cop/style/magic_comment_format.rb +4 -4
  485. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +11 -0
  486. data/lib/rubocop/cop/style/map_into_array.rb +6 -4
  487. data/lib/rubocop/cop/style/map_join.rb +123 -0
  488. data/lib/rubocop/cop/style/map_to_hash.rb +13 -5
  489. data/lib/rubocop/cop/style/map_to_set.rb +1 -3
  490. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +75 -24
  491. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
  492. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +58 -6
  493. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +36 -8
  494. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -1
  495. data/lib/rubocop/cop/style/method_def_parentheses.rb +36 -8
  496. data/lib/rubocop/cop/style/min_max_comparison.rb +17 -6
  497. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  498. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +40 -7
  499. data/lib/rubocop/cop/style/mixin_usage.rb +1 -1
  500. data/lib/rubocop/cop/style/module_function.rb +4 -2
  501. data/lib/rubocop/cop/style/module_member_existence_check.rb +110 -0
  502. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -1
  503. data/lib/rubocop/cop/style/multiline_if_modifier.rb +47 -5
  504. data/lib/rubocop/cop/style/multiline_if_then.rb +10 -4
  505. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  506. data/lib/rubocop/cop/style/multiline_memoization.rb +7 -1
  507. data/lib/rubocop/cop/style/multiline_method_signature.rb +15 -22
  508. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  509. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  510. data/lib/rubocop/cop/style/multiple_comparison.rb +33 -22
  511. data/lib/rubocop/cop/style/mutable_constant.rb +139 -13
  512. data/lib/rubocop/cop/style/negated_if_else_condition.rb +3 -3
  513. data/lib/rubocop/cop/style/negative_array_index.rb +228 -0
  514. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  515. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  516. data/lib/rubocop/cop/style/next.rb +68 -10
  517. data/lib/rubocop/cop/style/nil_comparison.rb +53 -13
  518. data/lib/rubocop/cop/style/nil_lambda.rb +9 -1
  519. data/lib/rubocop/cop/style/non_nil_check.rb +21 -11
  520. data/lib/rubocop/cop/style/not.rb +12 -3
  521. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  522. data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
  523. data/lib/rubocop/cop/style/numeric_predicate.rb +22 -6
  524. data/lib/rubocop/cop/style/object_then.rb +1 -0
  525. data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
  526. data/lib/rubocop/cop/style/one_line_conditional.rb +35 -15
  527. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  528. data/lib/rubocop/cop/style/operator_method_call.rb +10 -2
  529. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  530. data/lib/rubocop/cop/style/optional_arguments.rb +1 -0
  531. data/lib/rubocop/cop/style/parallel_assignment.rb +58 -27
  532. data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
  533. data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
  534. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +18 -3
  535. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  536. data/lib/rubocop/cop/style/perl_backrefs.rb +5 -3
  537. data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
  538. data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
  539. data/lib/rubocop/cop/style/proc.rb +4 -2
  540. data/lib/rubocop/cop/style/raise_args.rb +9 -9
  541. data/lib/rubocop/cop/style/reduce_to_hash.rb +216 -0
  542. data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
  543. data/lib/rubocop/cop/style/redundant_array_constructor.rb +2 -2
  544. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  545. data/lib/rubocop/cop/style/redundant_assignment.rb +12 -2
  546. data/lib/rubocop/cop/style/redundant_begin.rb +58 -6
  547. data/lib/rubocop/cop/style/redundant_condition.rb +93 -18
  548. data/lib/rubocop/cop/style/redundant_constant_base.rb +42 -6
  549. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +26 -4
  550. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -3
  551. data/lib/rubocop/cop/style/redundant_each.rb +4 -5
  552. data/lib/rubocop/cop/style/redundant_exception.rb +22 -4
  553. data/lib/rubocop/cop/style/redundant_fetch_block.rb +11 -11
  554. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +9 -0
  555. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  556. data/lib/rubocop/cop/style/redundant_format.rb +319 -0
  557. data/lib/rubocop/cop/style/redundant_freeze.rb +12 -3
  558. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +6 -1
  559. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  560. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
  561. data/lib/rubocop/cop/style/redundant_line_continuation.rb +83 -119
  562. data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
  563. data/lib/rubocop/cop/style/redundant_parentheses.rb +176 -83
  564. data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
  565. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +15 -0
  566. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  567. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +27 -7
  568. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +16 -0
  569. data/lib/rubocop/cop/style/redundant_return.rb +4 -3
  570. data/lib/rubocop/cop/style/redundant_self.rb +20 -7
  571. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -3
  572. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
  573. data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
  574. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  575. data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -2
  576. data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +133 -0
  577. data/lib/rubocop/cop/style/regexp_literal.rb +107 -29
  578. data/lib/rubocop/cop/style/require_order.rb +9 -0
  579. data/lib/rubocop/cop/style/rescue_modifier.rb +10 -12
  580. data/lib/rubocop/cop/style/return_nil.rb +19 -4
  581. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  582. data/lib/rubocop/cop/style/reverse_find.rb +51 -0
  583. data/lib/rubocop/cop/style/safe_navigation.rb +76 -20
  584. data/lib/rubocop/cop/style/sample.rb +19 -13
  585. data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
  586. data/lib/rubocop/cop/style/select_by_range.rb +197 -0
  587. data/lib/rubocop/cop/style/select_by_regexp.rb +54 -22
  588. data/lib/rubocop/cop/style/self_assignment.rb +13 -16
  589. data/lib/rubocop/cop/style/semicolon.rb +56 -14
  590. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
  591. data/lib/rubocop/cop/style/single_line_do_end_block.rb +22 -8
  592. data/lib/rubocop/cop/style/single_line_methods.rb +28 -11
  593. data/lib/rubocop/cop/style/sole_nested_conditional.rb +96 -104
  594. data/lib/rubocop/cop/style/special_global_vars.rb +7 -2
  595. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +32 -6
  596. data/lib/rubocop/cop/style/static_class.rb +21 -0
  597. data/lib/rubocop/cop/style/string_concatenation.rb +38 -16
  598. data/lib/rubocop/cop/style/string_hash_keys.rb +1 -0
  599. data/lib/rubocop/cop/style/struct_inheritance.rb +38 -2
  600. data/lib/rubocop/cop/style/super_arguments.rb +7 -6
  601. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  602. data/lib/rubocop/cop/style/symbol_proc.rb +34 -14
  603. data/lib/rubocop/cop/style/tally_method.rb +181 -0
  604. data/lib/rubocop/cop/style/ternary_parentheses.rb +34 -1
  605. data/lib/rubocop/cop/style/time_now.rb +41 -0
  606. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -2
  607. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +52 -1
  608. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  609. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +2 -2
  610. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  611. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
  612. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +35 -32
  613. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  614. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  615. data/lib/rubocop/cop/style/unless_logical_operators.rb +3 -3
  616. data/lib/rubocop/cop/style/while_until_do.rb +7 -0
  617. data/lib/rubocop/cop/style/while_until_modifier.rb +16 -1
  618. data/lib/rubocop/cop/style/word_array.rb +1 -0
  619. data/lib/rubocop/cop/style/yoda_condition.rb +26 -12
  620. data/lib/rubocop/cop/style/yoda_expression.rb +11 -2
  621. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -3
  622. data/lib/rubocop/cop/style.rb +311 -0
  623. data/lib/rubocop/cop/team.rb +172 -49
  624. data/lib/rubocop/cop/util.rb +7 -10
  625. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  626. data/lib/rubocop/cop/variable_force/assignment.rb +8 -4
  627. data/lib/rubocop/cop/variable_force/branch.rb +30 -6
  628. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  629. data/lib/rubocop/cop/variable_force/variable.rb +42 -11
  630. data/lib/rubocop/cop/variable_force.rb +26 -9
  631. data/lib/rubocop/cops_documentation_generator.rb +49 -15
  632. data/lib/rubocop/directive_comment.rb +147 -5
  633. data/lib/rubocop/ext/regexp_node.rb +0 -1
  634. data/lib/rubocop/feature_loader.rb +0 -6
  635. data/lib/rubocop/file_patterns.rb +9 -1
  636. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  637. data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
  638. data/lib/rubocop/formatter/disabled_config_formatter.rb +57 -14
  639. data/lib/rubocop/formatter/emacs_style_formatter.rb +3 -1
  640. data/lib/rubocop/formatter/formatter_set.rb +7 -2
  641. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  642. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  643. data/lib/rubocop/formatter/html_formatter.rb +3 -5
  644. data/lib/rubocop/formatter/json_formatter.rb +82 -7
  645. data/lib/rubocop/formatter/junit_formatter.rb +27 -10
  646. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  647. data/lib/rubocop/formatter/offense_count_formatter.rb +5 -4
  648. data/lib/rubocop/formatter/pacman_formatter.rb +5 -2
  649. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  650. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -5
  651. data/lib/rubocop/formatter/tap_formatter.rb +8 -3
  652. data/lib/rubocop/formatter/worst_offenders_formatter.rb +5 -4
  653. data/lib/rubocop/formatter.rb +23 -21
  654. data/lib/rubocop/lockfile.rb +18 -0
  655. data/lib/rubocop/lsp/diagnostic.rb +22 -41
  656. data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
  657. data/lib/rubocop/lsp/routes.rb +136 -33
  658. data/lib/rubocop/lsp/runtime.rb +66 -15
  659. data/lib/rubocop/lsp/server.rb +4 -2
  660. data/lib/rubocop/lsp/stdin_runner.rb +38 -19
  661. data/lib/rubocop/lsp.rb +5 -2
  662. data/lib/rubocop/magic_comment.rb +55 -0
  663. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  664. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  665. data/lib/rubocop/mcp/scope.rb +65 -0
  666. data/lib/rubocop/mcp/server.rb +307 -0
  667. data/lib/rubocop/mcp/source_files.rb +35 -0
  668. data/lib/rubocop/offense_limit.rb +30 -0
  669. data/lib/rubocop/options.rb +166 -23
  670. data/lib/rubocop/path_util.rb +20 -5
  671. data/lib/rubocop/pending_cops_reporter.rb +51 -0
  672. data/lib/rubocop/plugin/configuration_integrator.rb +153 -0
  673. data/lib/rubocop/plugin/load_error.rb +26 -0
  674. data/lib/rubocop/plugin/loader.rb +100 -0
  675. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  676. data/lib/rubocop/plugin.rb +46 -0
  677. data/lib/rubocop/project_index_loader.rb +82 -0
  678. data/lib/rubocop/rake_task.rb +6 -4
  679. data/lib/rubocop/remote_config.rb +18 -13
  680. data/lib/rubocop/result_cache.rb +110 -65
  681. data/lib/rubocop/rspec/cop_helper.rb +21 -1
  682. data/lib/rubocop/rspec/expect_offense.rb +11 -7
  683. data/lib/rubocop/rspec/shared_contexts.rb +85 -3
  684. data/lib/rubocop/rspec/support.rb +4 -0
  685. data/lib/rubocop/runner.rb +368 -106
  686. data/lib/rubocop/server/cache.rb +67 -48
  687. data/lib/rubocop/server/cli.rb +2 -4
  688. data/lib/rubocop/server/client_command/base.rb +10 -0
  689. data/lib/rubocop/server/client_command/exec.rb +2 -1
  690. data/lib/rubocop/server/client_command/start.rb +11 -1
  691. data/lib/rubocop/server/core.rb +8 -0
  692. data/lib/rubocop/server.rb +14 -0
  693. data/lib/rubocop/target_finder.rb +25 -11
  694. data/lib/rubocop/target_ruby.rb +31 -14
  695. data/lib/rubocop/todo_audit.rb +111 -0
  696. data/lib/rubocop/unified_diff.rb +257 -0
  697. data/lib/rubocop/util.rb +69 -0
  698. data/lib/rubocop/version.rb +48 -10
  699. data/lib/rubocop.rb +35 -682
  700. data/lib/ruby_lsp/rubocop/addon.rb +28 -17
  701. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  702. metadata +129 -21
  703. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
  704. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  705. data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +0 -50
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'erb'
4
4
  require 'yaml'
5
+ require_relative 'cache_config'
5
6
  require_relative 'config_finder'
6
7
 
7
8
  module RuboCop
@@ -22,41 +23,48 @@ module RuboCop
22
23
  class << self
23
24
  include FileFinder
24
25
 
25
- PENDING_BANNER = <<~BANNER
26
- The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
27
-
28
- Please also note that you can opt-in to new cops by default by adding this to your config:
29
- AllCops:
30
- NewCops: enable
31
- BANNER
32
-
33
26
  attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
34
- :ignore_unrecognized_cops
35
- attr_writer :default_configuration
36
- attr_reader :loaded_features
27
+ :enabled_by_default, :disabled_by_default, :ignore_unrecognized_cops,
28
+ :preview
29
+ attr_writer :default_configuration, :cache_root
30
+ attr_reader :loaded_plugins, :loaded_features
37
31
 
38
32
  alias debug? debug
39
33
  alias ignore_parent_exclusion? ignore_parent_exclusion
40
34
 
35
+ def cache_root(cache_root_override = nil)
36
+ @cache_root ||= CacheConfig.root_dir_from_toplevel_config(cache_root_override)
37
+ end
38
+
41
39
  def clear_options
42
40
  @debug = nil
41
+ @loaded_plugins = Set.new
43
42
  @loaded_features = Set.new
44
43
  @disable_pending_cops = nil
45
44
  @enable_pending_cops = nil
45
+ @preview = nil
46
+ @enabled_by_default = nil
47
+ @disabled_by_default = nil
46
48
  @ignore_parent_exclusion = nil
47
49
  @ignore_unrecognized_cops = nil
50
+ @cache_root = nil
48
51
  FileFinder.root_level = nil
49
52
  end
50
53
 
54
+ # rubocop:disable-next Metrics/AbcSize
51
55
  def load_file(file, check: true)
52
56
  path = file_path(file)
53
57
 
54
58
  hash = load_yaml_configuration(path)
55
59
 
60
+ rubocop_config = Config.create(hash, path, check: false)
61
+ plugins = hash.delete('plugins')
62
+ loaded_plugins = resolver.resolve_plugins(rubocop_config, plugins)
63
+ add_loaded_plugins(loaded_plugins)
64
+
56
65
  loaded_features = resolver.resolve_requires(path, hash)
57
66
  add_loaded_features(loaded_features)
58
67
 
59
- resolver.override_department_setting_for_cops({}, hash)
60
68
  resolver.resolve_inheritance_from_gems(hash)
61
69
  resolver.resolve_inheritance(path, hash, file, debug?)
62
70
  hash.delete('inherit_from')
@@ -76,7 +84,9 @@ module RuboCop
76
84
 
77
85
  puts "configuration from #{absolute_path}" if debug?
78
86
 
79
- raise(TypeError, "Malformed configuration in #{absolute_path}") unless hash.is_a?(Hash)
87
+ unless hash.is_a?(Hash)
88
+ raise(ValidationError, "Malformed configuration in #{absolute_path}")
89
+ end
80
90
 
81
91
  hash
82
92
  end
@@ -84,8 +94,12 @@ module RuboCop
84
94
  def add_missing_namespaces(path, hash)
85
95
  # Using `hash.each_key` will cause the
86
96
  # `can't add a new key into hash during iteration` error
97
+ obsoletion = ConfigObsoletion.new(hash)
98
+
87
99
  hash_keys = hash.keys
88
100
  hash_keys.each do |key|
101
+ next if obsoletion.deprecated_cop_name?(key)
102
+
89
103
  q = Cop::Registry.qualified_cop_name(key, path)
90
104
  next if q == key
91
105
 
@@ -110,7 +124,7 @@ module RuboCop
110
124
  end
111
125
 
112
126
  def configuration_from_file(config_file, check: true)
113
- return default_configuration if config_file == DEFAULT_FILE
127
+ return apply_default_overrides(default_configuration) if config_file == DEFAULT_FILE
114
128
 
115
129
  config = load_file(config_file, check: check)
116
130
  config.validate_after_resolution if check
@@ -121,21 +135,7 @@ module RuboCop
121
135
  add_excludes_from_files(config, config_file)
122
136
  end
123
137
 
124
- merge_with_default(config, config_file).tap do |merged_config|
125
- unless possible_new_cops?(merged_config)
126
- pending_cops = pending_cops_only_qualified(merged_config.pending_cops)
127
- warn_on_pending_cops(pending_cops) unless pending_cops.empty?
128
- end
129
- end
130
- end
131
-
132
- def pending_cops_only_qualified(pending_cops)
133
- pending_cops.select { |cop| Cop::Registry.qualified_cop?(cop.name) }
134
- end
135
-
136
- def possible_new_cops?(config)
137
- disable_pending_cops || enable_pending_cops ||
138
- config.disabled_new_cops? || config.enabled_new_cops?
138
+ merge_with_default(config, config_file)
139
139
  end
140
140
 
141
141
  def add_excludes_from_files(config, config_file)
@@ -155,13 +155,26 @@ module RuboCop
155
155
  end
156
156
  end
157
157
 
158
- # @api private
159
- def inject_defaults!(project_root)
160
- path = File.join(project_root, 'config', 'default.yml')
161
- config = load_file(path)
162
- new_config = ConfigLoader.merge_with_default(config, path)
163
- puts "configuration from #{path}" if debug?
164
- @default_configuration = new_config
158
+ # This API is primarily intended for testing and documenting plugins.
159
+ # When testing a plugin using `rubocop/rspec/support`, the plugin is loaded automatically,
160
+ # so this API is usually not needed. It is intended to be used only when implementing tests
161
+ # that do not use `rubocop/rspec/support`.
162
+ def inject_defaults!(config_yml_path)
163
+ if Pathname(config_yml_path).directory?
164
+ warn Rainbow(<<~MESSAGE).yellow, uplevel: 1
165
+ Use config YAML file path instead of project root directory.
166
+ e.g., `path/to/config/default.yml`
167
+ MESSAGE
168
+ raise ArgumentError,
169
+ 'Passing a project root directory to `inject_defaults!` is no longer supported.'
170
+ end
171
+
172
+ path = config_yml_path.to_s
173
+ hash = ConfigLoader.load_yaml_configuration(path)
174
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
175
+
176
+ @default_configuration =
177
+ ConfigLoader.merge_with_default(config, path, resolve_preview: false)
165
178
  end
166
179
 
167
180
  # Returns the path RuboCop inferred as the root of the project. No file
@@ -176,24 +189,37 @@ module RuboCop
176
189
  ConfigFinder.project_root
177
190
  end
178
191
 
179
- def warn_on_pending_cops(pending_cops)
180
- warn Rainbow(PENDING_BANNER).yellow
181
-
182
- pending_cops.each { |cop| warn_pending_cop cop }
183
-
184
- warn Rainbow('For more information: https://docs.rubocop.org/rubocop/versioning.html').yellow
192
+ # Merges the given configuration with the default one.
193
+ def merge_with_default(config, config_file, unset_nil: true, resolve_preview: true)
194
+ resolver.merge_with_default(
195
+ config, config_file, unset_nil: unset_nil, resolve_preview: resolve_preview
196
+ )
185
197
  end
186
198
 
187
- def warn_pending_cop(cop)
188
- version = cop.metadata['VersionAdded'] || 'N/A'
199
+ # Applies CLI overrides for `AllCops/EnabledByDefault` and
200
+ # `AllCops/DisabledByDefault` to the given configuration. Used when the
201
+ # configuration would otherwise be returned without going through
202
+ # `merge_with_default` (e.g. there is no user-supplied `.rubocop.yml`).
203
+ # Used when there is no configuration file, so the defaults are the whole
204
+ # configuration and still need the same treatment `merge_with_default`
205
+ # would have given them.
206
+ def apply_default_overrides(config)
207
+ hash = resolver.apply_preview_defaults(config, preview == true)
208
+
209
+ unless @enabled_by_default.nil? && @disabled_by_default.nil?
210
+ hash = hash.transform_values do |params|
211
+ params.is_a?(Hash) ? params.merge('Enabled' => !@disabled_by_default) : params
212
+ end
213
+ end
189
214
 
190
- warn Rainbow("#{cop.name}: # new in #{version}").yellow
191
- warn Rainbow(' Enabled: true').yellow
215
+ Config.new(hash, config.loaded_path)
192
216
  end
193
217
 
194
- # Merges the given configuration with the default one.
195
- def merge_with_default(config, config_file, unset_nil: true)
196
- resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
218
+ # @api private
219
+ # Used to add plugins that were required inside a config or from
220
+ # the CLI using `--plugin`.
221
+ def add_loaded_plugins(loaded_plugins)
222
+ @loaded_plugins.merge(Array(loaded_plugins))
197
223
  end
198
224
 
199
225
  # @api private
@@ -2,38 +2,59 @@
2
2
 
3
3
  require 'pathname'
4
4
  require 'yaml'
5
+ require_relative 'plugin'
5
6
 
6
7
  module RuboCop
7
8
  # A help class for ConfigLoader that handles configuration resolution.
8
9
  # @api private
9
10
  class ConfigLoaderResolver # rubocop:disable Metrics/ClassLength
11
+ def resolve_plugins(rubocop_config, plugins)
12
+ plugins = Array(plugins) - ConfigLoader.loaded_plugins.map { |plugin| plugin.about.name }
13
+ return if plugins.empty?
14
+
15
+ Plugin.integrate_plugins(rubocop_config, plugins)
16
+ end
17
+
10
18
  def resolve_requires(path, hash)
11
19
  config_dir = File.dirname(path)
12
20
  hash.delete('require').tap do |loaded_features|
13
21
  Array(loaded_features).each do |feature|
14
- FeatureLoader.load(config_directory_path: config_dir, feature: feature)
22
+ if Plugin.plugin_capable?(feature)
23
+ # NOTE: Compatibility for before plugins style.
24
+ warn Rainbow(<<~MESSAGE).yellow
25
+ #{feature} extension supports plugin, specify `plugins: #{feature}` instead of `require: #{feature}` in #{path}.
26
+ For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
27
+ MESSAGE
28
+ rubocop_config = Config.create(hash, path, check: false)
29
+
30
+ resolve_plugins(rubocop_config, feature)
31
+ else
32
+ FeatureLoader.load(config_directory_path: config_dir, feature: feature)
33
+ end
15
34
  end
16
35
  end
17
36
  end
18
37
 
19
38
  def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
20
39
  inherited_files = Array(hash['inherit_from'])
21
- base_configs(path, inherited_files, file)
22
- .each_with_index.reverse_each do |base_config, index|
40
+ base_configs = base_configs(path, inherited_files, file)
41
+ preview = inherited_preview?(hash, base_configs)
42
+ base_configs.each_with_index.reverse_each do |base_config, index|
23
43
  override_department_setting_for_cops(base_config, hash)
24
44
  override_enabled_for_disabled_departments(base_config, hash)
25
45
 
26
46
  base_config.each do |k, v|
27
47
  next unless v.is_a?(Hash)
28
48
 
49
+ only_base_has_include = v.key?('Include') && !hash.dig(k, 'Include')
29
50
  if hash.key?(k)
30
51
  v = merge(v, hash[k],
31
52
  cop_name: k, file: file, debug: debug,
32
53
  inherited_file: inherited_files[index],
33
- inherit_mode: determine_inherit_mode(hash, k))
54
+ inherit_mode: determine_inherit_mode(hash, k, preview))
34
55
  end
35
56
  hash[k] = v
36
- fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
57
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if only_base_has_include
37
58
  end
38
59
  end
39
60
  end
@@ -72,22 +93,30 @@ module RuboCop
72
93
  # only cops from user configuration are enabled. If
73
94
  # AllCops:EnabledByDefault is true, it changes the Enabled params so that
74
95
  # only cops explicitly disabled in user configuration are disabled.
75
- def merge_with_default(config, config_file, unset_nil:)
76
- default_configuration = ConfigLoader.default_configuration
77
-
78
- disabled_by_default = config.for_all_cops['DisabledByDefault']
79
- enabled_by_default = config.for_all_cops['EnabledByDefault']
96
+ # When the `--disable-all-cops` or `--enable-all-cops` CLI option is given,
97
+ # it takes precedence over the configuration values.
98
+ #
99
+ # With `resolve_preview: false` the `Preview` sections of the default
100
+ # configuration are left in place and preview is treated as off. That is
101
+ # what extending the default configuration itself needs: preview gets
102
+ # applied later, when a project configuration is resolved against it.
103
+ def merge_with_default(config, config_file, unset_nil:, resolve_preview: true)
104
+ base_defaults, preview = defaults_with_preview(config, resolve_preview)
105
+ default_configuration = base_defaults
106
+ disabled_by_default, enabled_by_default = resolve_default_overrides(config)
80
107
 
81
108
  if disabled_by_default || enabled_by_default
82
- default_configuration = transform(default_configuration) do |params|
109
+ default_configuration = transform(base_defaults) do |params|
83
110
  params.merge('Enabled' => !disabled_by_default)
84
111
  end
85
112
  end
86
113
 
87
- config = handle_disabled_by_default(config, default_configuration) if disabled_by_default
114
+ if disabled_by_default
115
+ config = handle_disabled_by_default(config, default_configuration, base_defaults)
116
+ end
88
117
  override_enabled_for_disabled_departments(default_configuration, config)
89
118
 
90
- opts = { inherit_mode: config['inherit_mode'] || {}, unset_nil: unset_nil }
119
+ opts = { inherit_mode: inherit_mode_for_default(config, preview), unset_nil: unset_nil }
91
120
  Config.new(merge(default_configuration, config, **opts), config_file)
92
121
  end
93
122
 
@@ -95,7 +124,7 @@ module RuboCop
95
124
  # with the addition that any value that is a hash, and occurs in both
96
125
  # arguments, will also be merged. And so on.
97
126
  #
98
- # rubocop:disable Metrics/AbcSize
127
+ # rubocop:disable-next Metrics/AbcSize
99
128
  def merge(base_hash, derived_hash, **opts)
100
129
  result = base_hash.merge(derived_hash)
101
130
  keys_appearing_in_both = base_hash.keys & derived_hash.keys
@@ -105,14 +134,13 @@ module RuboCop
105
134
  elsif merge_hashes?(base_hash, derived_hash, key)
106
135
  result[key] = merge(base_hash[key], derived_hash[key], **opts)
107
136
  elsif should_union?(derived_hash, base_hash, opts[:inherit_mode], key)
108
- result[key] = base_hash[key] | derived_hash[key]
137
+ result[key] = Array(base_hash[key]) | Array(derived_hash[key])
109
138
  elsif opts[:debug]
110
139
  warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
111
140
  end
112
141
  end
113
142
  result
114
143
  end
115
- # rubocop:enable Metrics/AbcSize
116
144
 
117
145
  # An `Enabled: true` setting in user configuration for a cop overrides an
118
146
  # `Enabled: false` setting for its department.
@@ -147,8 +175,63 @@ module RuboCop
147
175
  end
148
176
  end
149
177
 
178
+ # A cop's entry in the default configuration may carry a `Preview` section
179
+ # with the defaults it is expected to adopt in the next major release. Under
180
+ # `Preview` those replace the current defaults. The section is dropped either
181
+ # way, so the resolved configuration only ever shows what is in effect.
182
+ def apply_preview_defaults(default_configuration, preview)
183
+ transform(default_configuration) do |params|
184
+ next params unless params['Preview'].is_a?(Hash)
185
+
186
+ params = params.dup
187
+ preview_params = params.delete('Preview')
188
+ preview ? params.merge(preview_params) : params
189
+ end
190
+ end
191
+
150
192
  private
151
193
 
194
+ def defaults_with_preview(config, resolve_preview)
195
+ defaults = ConfigLoader.default_configuration
196
+ return [defaults, false] unless resolve_preview
197
+
198
+ preview = preview?(config)
199
+ [apply_preview_defaults(defaults, preview), preview]
200
+ end
201
+
202
+ def inherit_mode_for_default(config, preview)
203
+ with_preview_exclude_merge(config['inherit_mode'] || {}, preview)
204
+ end
205
+
206
+ # Under `Preview`, `Exclude` is merged rather than replaced, so that excluding
207
+ # one directory does not silently drop the excludes it would have inherited -
208
+ # from the default configuration or from a file named in `inherit_from`. An
209
+ # explicit `inherit_mode` still wins, in either direction.
210
+ def with_preview_exclude_merge(mode, preview)
211
+ return mode unless preview
212
+ return mode if Array(mode['override']).include?('Exclude')
213
+ return mode if Array(mode['merge']).include?('Exclude')
214
+
215
+ mode.merge('merge' => Array(mode['merge']) + ['Exclude'])
216
+ end
217
+
218
+ # `config` has already been through `handle_disabled_by_default` by this
219
+ # point, which returns a plain hash, so read `AllCops` directly rather than
220
+ # going through `Config#for_all_cops`.
221
+ def preview?(config)
222
+ return ConfigLoader.preview unless ConfigLoader.preview.nil?
223
+
224
+ (config['AllCops'] || {})['Preview'] == true
225
+ end
226
+
227
+ def resolve_default_overrides(config)
228
+ if ConfigLoader.disabled_by_default || ConfigLoader.enabled_by_default
229
+ [ConfigLoader.disabled_by_default, ConfigLoader.enabled_by_default]
230
+ else
231
+ [config.for_all_cops['DisabledByDefault'], config.for_all_cops['EnabledByDefault']]
232
+ end
233
+ end
234
+
152
235
  def disabled?(hash, department)
153
236
  hash[department].is_a?(Hash) && hash[department]['Enabled'] == false
154
237
  end
@@ -157,7 +240,7 @@ module RuboCop
157
240
  return false if inherited_file.nil? # Not inheritance resolving merge
158
241
  return false if inherited_file.start_with?('..') # Legitimate override
159
242
  return false if base_hash[key] == derived_hash[key] # Same value
160
- return false if remote_file?(inherited_file) # Can't change
243
+ return false if PathUtil.remote_file?(inherited_file) # Can't change
161
244
 
162
245
  Gem.path.none? { |dir| inherited_file.start_with?(dir) } # Can change?
163
246
  end
@@ -180,14 +263,25 @@ module RuboCop
180
263
  "the same parameter in #{opts[:inherited_file]}"
181
264
  end
182
265
 
183
- def determine_inherit_mode(hash, key)
266
+ # The `AllCops: Preview` in effect once inheritance is resolved: the file
267
+ # itself wins, then the files it inherits from, last one first. It has to be
268
+ # known before merging, since the keys are merged in whatever order they
269
+ # appear and `AllCops` may well come after the cops whose `Exclude` it affects.
270
+ def inherited_preview?(hash, base_configs)
271
+ all_cops = [hash, *base_configs.reverse].map { |config| config['AllCops'] }.find do |params|
272
+ params.is_a?(Hash) && params.key?('Preview')
273
+ end
274
+ preview?('AllCops' => all_cops)
275
+ end
276
+
277
+ def determine_inherit_mode(hash, key, preview)
184
278
  cop_cfg = hash[key]
185
279
  local_inherit = cop_cfg['inherit_mode'] if cop_cfg.is_a?(Hash)
186
- local_inherit || hash['inherit_mode'] || {}
280
+ with_preview_exclude_merge(local_inherit || hash['inherit_mode'] || {}, preview)
187
281
  end
188
282
 
189
283
  def should_union?(derived_hash, base_hash, root_mode, key)
190
- return false unless base_hash[key].is_a?(Array)
284
+ return false unless base_hash[key].is_a?(Array) || derived_hash[key].is_a?(Array)
191
285
 
192
286
  derived_mode = derived_hash['inherit_mode']
193
287
  return false if should_override?(derived_mode, key)
@@ -225,9 +319,9 @@ module RuboCop
225
319
  end
226
320
 
227
321
  def inherited_file(path, inherit_from, file)
228
- if remote_file?(inherit_from)
322
+ if PathUtil.remote_file?(inherit_from)
229
323
  # A remote configuration, e.g. `inherit_from: http://example.com/rubocop.yml`.
230
- RemoteConfig.new(inherit_from, File.dirname(path))
324
+ RemoteConfig.new(inherit_from, ConfigLoader.cache_root)
231
325
  elsif Pathname.new(inherit_from).absolute?
232
326
  # An absolute path to a config, e.g. `inherit_from: /Users/me/rubocop.yml`.
233
327
  # The path may come from `inherit_gem` option, where a gem name is expanded
@@ -237,7 +331,7 @@ module RuboCop
237
331
  elsif file.is_a?(RemoteConfig)
238
332
  # A path relative to a URL, e.g. `inherit_from: configs/default.yml`
239
333
  # in a config included with `inherit_from: http://example.com/rubocop.yml`
240
- file.inherit_from_remote(inherit_from, path)
334
+ file.inherit_from_remote(inherit_from)
241
335
  else
242
336
  # A local relative path, e.g. `inherit_from: default.yml`
243
337
  print 'Inheriting ' if ConfigLoader.debug?
@@ -245,15 +339,11 @@ module RuboCop
245
339
  end
246
340
  end
247
341
 
248
- def remote_file?(uri)
249
- uri.start_with?('http://', 'https://')
250
- end
251
-
252
342
  def remote_config?(file)
253
343
  file.is_a?(RemoteConfig)
254
344
  end
255
345
 
256
- def handle_disabled_by_default(config, new_default_configuration)
346
+ def handle_disabled_by_default(config, new_default_configuration, base_defaults)
257
347
  department_config = config.to_hash.reject { |cop| cop.include?('/') }
258
348
  department_config.each do |dept, dept_params|
259
349
  next unless dept_params['Enabled']
@@ -262,7 +352,7 @@ module RuboCop
262
352
  next unless cop.start_with?("#{dept}/")
263
353
 
264
354
  # Retain original default configuration for cops in the department.
265
- params['Enabled'] = ConfigLoader.default_configuration[cop]['Enabled']
355
+ params['Enabled'] = base_defaults[cop]['Enabled']
266
356
  end
267
357
  end
268
358
 
@@ -280,10 +370,11 @@ module RuboCop
280
370
  begin
281
371
  gem = Bundler.load.specs[gem_name].first
282
372
  gem_path = gem.full_gem_path if gem
283
- rescue Bundler::GemfileNotFound
284
- # No Gemfile found. Bundler may be loaded manually
285
- rescue Bundler::GitError
286
- # The Gemfile exists but contains an uninstalled git source
373
+ rescue StandardError
374
+ # The Gemfile has a problem, which could be one of:
375
+ # - No Gemfile found. Bundler may be loaded manually
376
+ # - The Gemfile exists but contains an uninstalled git source
377
+ # - The Gemfile exists but cannot be loaded for some other reason
287
378
  end
288
379
  end
289
380
 
@@ -20,7 +20,8 @@ module RuboCop
20
20
  rule_message + "\n(obsolete configuration found in #{smart_loaded_path}, please update it)"
21
21
  end
22
22
 
23
- # Cop rules currently can only be failures, not warnings
23
+ # Failure by default; rules that accept `severity: warning` say so
24
+ # themselves.
24
25
  def warning?
25
26
  false
26
27
  end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  end
16
16
 
17
17
  def violated?
18
- return false if feature_loaded?
18
+ return false if plugin_loaded?
19
19
 
20
20
  affected_cops.any?
21
21
  end
@@ -38,8 +38,11 @@ module RuboCop
38
38
  end
39
39
  end
40
40
 
41
- def feature_loaded?
42
- config.loaded_features.include?(gem)
41
+ def plugin_loaded?
42
+ # Plugins loaded via `plugins` are Plugin objects with an `about.name` attribute.
43
+ # Plugins loaded via `require` are included in `loaded_features` as strings.
44
+ config.loaded_plugins.any? { |plugin| plugin.about.name == gem } ||
45
+ config.loaded_features.include?(gem)
43
46
  end
44
47
  end
45
48
  end
@@ -20,15 +20,23 @@ module RuboCop
20
20
 
21
21
  if reason
22
22
  "#{base} since #{reason.chomp}."
23
- elsif alternatives
23
+ elsif alternatives.any?
24
24
  "#{base}. Please use #{to_sentence(alternatives, connector: 'and/or')} instead."
25
25
  else
26
26
  "#{base}."
27
27
  end
28
28
  end
29
29
 
30
+ def warning?
31
+ severity == 'warning'
32
+ end
33
+
30
34
  private
31
35
 
36
+ def severity
37
+ metadata['severity']
38
+ end
39
+
32
40
  def reason
33
41
  metadata['reason']
34
42
  end
@@ -6,17 +6,28 @@ module RuboCop
6
6
  # a cop or moving it to a new department.
7
7
  # @api private
8
8
  class RenamedCop < CopRule
9
- attr_reader :new_name
9
+ attr_reader :new_name, :metadata
10
10
 
11
- def initialize(config, old_name, new_name)
11
+ def initialize(config, old_name, name_or_hash)
12
12
  super(config, old_name)
13
- @new_name = new_name
13
+
14
+ if name_or_hash.is_a?(Hash)
15
+ @metadata = name_or_hash
16
+ @new_name = name_or_hash['new_name']
17
+ else
18
+ @metadata = {}
19
+ @new_name = name_or_hash
20
+ end
14
21
  end
15
22
 
16
23
  def rule_message
17
24
  "The `#{old_name}` cop has been #{verb} to `#{new_name}`."
18
25
  end
19
26
 
27
+ def warning?
28
+ severity == 'warning'
29
+ end
30
+
20
31
  private
21
32
 
22
33
  def moved?
@@ -29,6 +40,10 @@ module RuboCop
29
40
  def verb
30
41
  moved? ? 'moved' : 'renamed'
31
42
  end
43
+
44
+ def severity
45
+ metadata['severity']
46
+ end
32
47
  end
33
48
  end
34
49
  end
@@ -15,7 +15,7 @@ module RuboCop
15
15
  'changed_parameters' => ChangedParameter,
16
16
  'changed_enforced_styles' => ChangedEnforcedStyles
17
17
  }.freeze
18
- LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant
18
+ LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant -- a cache, written to at runtime
19
19
  private_constant :LOAD_RULES_CACHE
20
20
 
21
21
  attr_reader :rules, :warnings
@@ -23,9 +23,40 @@ module RuboCop
23
23
  class << self
24
24
  attr_accessor :files
25
25
 
26
+ def global
27
+ @global ||= new(Config.new)
28
+ end
29
+
30
+ def reset!
31
+ @global = nil
32
+ @deprecated_names = {}
33
+ LOAD_RULES_CACHE[rules_cache_key] = nil
34
+ end
35
+
36
+ def rules_cache_key
37
+ files.hash
38
+ end
39
+
26
40
  def legacy_cop_names
27
41
  # Used by DepartmentName#qualified_legacy_cop_name
28
- new(Config.new).rules.select(&:cop_rule?).map(&:old_name)
42
+ global.legacy_cop_names
43
+ end
44
+
45
+ def deprecated_cop_name?(name)
46
+ global.deprecated_cop_name?(name)
47
+ end
48
+
49
+ def deprecated_names_for(cop)
50
+ @deprecated_names ||= {}
51
+ return @deprecated_names[cop] if @deprecated_names.key?(cop)
52
+
53
+ @deprecated_names[cop] = global.rules.filter_map do |rule|
54
+ next unless rule.cop_rule?
55
+ next unless rule.respond_to?(:new_name)
56
+ next unless rule.new_name == cop
57
+
58
+ rule.old_name
59
+ end
29
60
  end
30
61
  end
31
62
 
@@ -45,12 +76,21 @@ module RuboCop
45
76
  raise ValidationError, messages.join("\n")
46
77
  end
47
78
 
79
+ def legacy_cop_names
80
+ # Used by DepartmentName#qualified_legacy_cop_name
81
+ cop_rules.map(&:old_name)
82
+ end
83
+
84
+ def deprecated_cop_name?(name)
85
+ legacy_cop_names.include?(name)
86
+ end
87
+
48
88
  private
49
89
 
50
90
  # Default rules for obsoletions are in config/obsoletion.yml
51
91
  # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
52
92
  def load_rules # rubocop:disable Metrics/AbcSize
53
- rules = LOAD_RULES_CACHE[self.class.files] ||=
93
+ rules = LOAD_RULES_CACHE[self.class.rules_cache_key] ||=
54
94
  self.class.files.each_with_object({}) do |filename, hash|
55
95
  hash.merge!(YAML.safe_load(File.read(filename)) || {}) do |_key, first, second|
56
96
  case first
@@ -107,5 +147,9 @@ module RuboCop
107
147
  rule.message
108
148
  end
109
149
  end
150
+
151
+ def cop_rules
152
+ rules.select(&:cop_rule?)
153
+ end
110
154
  end
111
155
  end