rubocop 1.42.0 → 1.64.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +7 -6
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +342 -64
  7. data/config/obsoletion.yml +5 -0
  8. data/lib/rubocop/cached_data.rb +11 -3
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +27 -6
  10. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  11. data/lib/rubocop/cli/command/lsp.rb +19 -0
  12. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  13. data/lib/rubocop/cli.rb +68 -10
  14. data/lib/rubocop/comment_config.rb +19 -0
  15. data/lib/rubocop/config.rb +43 -15
  16. data/lib/rubocop/config_finder.rb +14 -4
  17. data/lib/rubocop/config_loader.rb +20 -24
  18. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  19. data/lib/rubocop/config_obsoletion.rb +13 -10
  20. data/lib/rubocop/config_validator.rb +14 -7
  21. data/lib/rubocop/cop/autocorrect_logic.rb +37 -14
  22. data/lib/rubocop/cop/base.rb +97 -28
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  24. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  25. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  26. data/lib/rubocop/cop/bundler/gem_version.rb +5 -7
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  28. data/lib/rubocop/cop/commissioner.rb +8 -2
  29. data/lib/rubocop/cop/cop.rb +25 -5
  30. data/lib/rubocop/cop/corrector.rb +11 -3
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  32. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  33. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +6 -14
  34. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  37. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  38. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  39. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  40. data/lib/rubocop/cop/documentation.rb +16 -6
  41. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  42. data/lib/rubocop/cop/force.rb +12 -0
  43. data/lib/rubocop/cop/gemspec/dependency_version.rb +6 -8
  44. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -3
  45. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  46. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  47. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  48. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
  50. data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
  51. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  52. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  54. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  55. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  56. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  57. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  58. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +128 -34
  59. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  60. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  61. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  62. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  63. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  64. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  66. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  67. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  68. data/lib/rubocop/cop/internal_affairs.rb +5 -0
  69. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  70. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
  72. data/lib/rubocop/cop/layout/class_structure.rb +15 -19
  73. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
  74. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  75. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  76. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  77. data/lib/rubocop/cop/layout/empty_comment.rb +6 -4
  78. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  79. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  80. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
  81. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  82. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  83. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  84. data/lib/rubocop/cop/layout/end_alignment.rb +23 -3
  85. data/lib/rubocop/cop/layout/extra_spacing.rb +3 -4
  86. data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
  87. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
  88. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  89. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  90. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  91. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  92. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  93. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +12 -6
  94. data/lib/rubocop/cop/layout/heredoc_indentation.rb +12 -12
  95. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  97. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  98. data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
  99. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
  100. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +12 -8
  101. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  102. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  105. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  106. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  107. data/lib/rubocop/cop/layout/redundant_line_break.rb +33 -11
  108. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -6
  109. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  110. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  111. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  114. data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
  115. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  116. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  118. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
  119. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
  120. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  121. data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
  122. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  123. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  125. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +6 -6
  126. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  127. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  128. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  129. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  130. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
  131. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  132. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  133. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  134. data/lib/rubocop/cop/lint/debugger.rb +49 -26
  135. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  136. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  137. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  138. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  139. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  140. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
  141. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  142. data/lib/rubocop/cop/lint/empty_block.rb +2 -2
  143. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -4
  144. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  145. data/lib/rubocop/cop/lint/erb_new_arguments.rb +27 -21
  146. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  147. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  148. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  149. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
  150. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  151. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  152. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  153. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  154. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  156. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  157. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  158. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
  159. data/lib/rubocop/cop/lint/missing_super.rb +63 -5
  160. data/lib/rubocop/cop/lint/mixed_case_range.rb +116 -0
  161. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  162. data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
  163. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
  164. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  165. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  166. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  167. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  168. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  169. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  170. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +8 -12
  171. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  172. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  173. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
  174. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  175. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  176. data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
  177. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  178. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  179. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  180. data/lib/rubocop/cop/lint/redundant_with_index.rb +7 -3
  181. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -3
  182. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  183. data/lib/rubocop/cop/lint/rescue_type.rb +2 -4
  184. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
  185. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  186. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  187. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  188. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  189. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  190. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
  191. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  192. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  193. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  194. data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
  195. data/lib/rubocop/cop/lint/syntax.rb +10 -3
  196. data/lib/rubocop/cop/lint/to_enum_arguments.rb +23 -6
  197. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  198. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  199. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  200. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
  201. data/lib/rubocop/cop/lint/unreachable_loop.rb +11 -5
  202. data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -9
  203. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  204. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  205. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  206. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +9 -1
  207. data/lib/rubocop/cop/lint/useless_times.rb +3 -3
  208. data/lib/rubocop/cop/lint/void.rb +119 -20
  209. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  210. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  211. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  212. data/lib/rubocop/cop/metrics/class_length.rb +8 -2
  213. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  214. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  215. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  216. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  217. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +3 -7
  218. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +38 -10
  219. data/lib/rubocop/cop/migration/department_name.rb +3 -3
  220. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  221. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  222. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  223. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  224. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  225. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  226. data/lib/rubocop/cop/mixin/comments_help.rb +21 -11
  227. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  228. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  229. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  230. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  231. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  232. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +78 -29
  233. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  234. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  235. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
  236. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  237. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  238. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  239. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  240. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  241. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  242. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  243. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  244. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  245. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  246. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  247. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
  248. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  249. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  250. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  251. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  252. data/lib/rubocop/cop/naming/block_forwarding.rb +38 -7
  253. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  254. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  255. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  256. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  257. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  258. data/lib/rubocop/cop/naming/inclusive_language.rb +24 -6
  259. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  260. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  261. data/lib/rubocop/cop/naming/predicate_name.rb +3 -3
  262. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  263. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  264. data/lib/rubocop/cop/registry.rb +16 -9
  265. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  266. data/lib/rubocop/cop/security/open.rb +2 -2
  267. data/lib/rubocop/cop/style/access_modifier_declarations.rb +78 -13
  268. data/lib/rubocop/cop/style/accessor_grouping.rb +44 -18
  269. data/lib/rubocop/cop/style/alias.rb +10 -8
  270. data/lib/rubocop/cop/style/arguments_forwarding.rb +414 -62
  271. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  272. data/lib/rubocop/cop/style/array_intersect.rb +14 -6
  273. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  274. data/lib/rubocop/cop/style/attr.rb +11 -1
  275. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  276. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  277. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +3 -3
  278. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  279. data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
  280. data/lib/rubocop/cop/style/case_like_if.rb +25 -8
  281. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
  282. data/lib/rubocop/cop/style/class_check.rb +1 -0
  283. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
  284. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  285. data/lib/rubocop/cop/style/collection_compact.rb +37 -14
  286. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  287. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  288. data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
  289. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  290. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  291. data/lib/rubocop/cop/style/commented_keyword.rb +7 -4
  292. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  293. data/lib/rubocop/cop/style/concat_array_literals.rb +12 -3
  294. data/lib/rubocop/cop/style/conditional_assignment.rb +15 -20
  295. data/lib/rubocop/cop/style/copyright.rb +37 -24
  296. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  297. data/lib/rubocop/cop/style/date_time.rb +5 -4
  298. data/lib/rubocop/cop/style/dir.rb +1 -1
  299. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  300. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  301. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
  302. data/lib/rubocop/cop/style/documentation.rb +36 -30
  303. data/lib/rubocop/cop/style/documentation_method.rb +30 -4
  304. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  305. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
  306. data/lib/rubocop/cop/style/each_with_object.rb +3 -3
  307. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  308. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  309. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  310. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  311. data/lib/rubocop/cop/style/eval_with_location.rb +14 -23
  312. data/lib/rubocop/cop/style/exact_regexp_match.rb +70 -0
  313. data/lib/rubocop/cop/style/explicit_block_argument.rb +3 -3
  314. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  315. data/lib/rubocop/cop/style/file_read.rb +3 -3
  316. data/lib/rubocop/cop/style/file_write.rb +1 -1
  317. data/lib/rubocop/cop/style/for.rb +3 -1
  318. data/lib/rubocop/cop/style/format_string.rb +33 -12
  319. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
  320. data/lib/rubocop/cop/style/guard_clause.rb +29 -1
  321. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  322. data/lib/rubocop/cop/style/hash_each_methods.rb +106 -21
  323. data/lib/rubocop/cop/style/hash_except.rb +25 -13
  324. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  325. data/lib/rubocop/cop/style/hash_syntax.rb +29 -3
  326. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  327. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  328. data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
  329. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  330. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  331. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +7 -3
  332. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  333. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  334. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  335. data/lib/rubocop/cop/style/invertible_unless_condition.rb +160 -0
  336. data/lib/rubocop/cop/style/lambda.rb +3 -3
  337. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  338. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
  339. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  340. data/lib/rubocop/cop/style/map_to_hash.rb +20 -7
  341. data/lib/rubocop/cop/style/map_to_set.rb +5 -2
  342. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +48 -28
  343. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -41
  344. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +22 -0
  345. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  346. data/lib/rubocop/cop/style/min_max.rb +3 -3
  347. data/lib/rubocop/cop/style/min_max_comparison.rb +11 -1
  348. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  349. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  350. data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
  351. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  352. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  353. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  354. data/lib/rubocop/cop/style/multiline_method_signature.rb +17 -5
  355. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +21 -4
  356. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  357. data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
  358. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  359. data/lib/rubocop/cop/style/next.rb +1 -1
  360. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  361. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  362. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  363. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  364. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  365. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  366. data/lib/rubocop/cop/style/object_then.rb +5 -3
  367. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -7
  368. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  369. data/lib/rubocop/cop/style/operator_method_call.rb +24 -4
  370. data/lib/rubocop/cop/style/parallel_assignment.rb +32 -24
  371. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  372. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  373. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  374. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  375. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  376. data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
  377. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  378. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  379. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  380. data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
  381. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
  382. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
  383. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +103 -9
  384. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  385. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  386. data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -7
  387. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  388. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  389. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  390. data/lib/rubocop/cop/style/redundant_line_continuation.rb +200 -0
  391. data/lib/rubocop/cop/style/redundant_parentheses.rb +73 -24
  392. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
  393. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  394. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
  395. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  396. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
  397. data/lib/rubocop/cop/style/redundant_return.rb +14 -3
  398. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  399. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  400. data/lib/rubocop/cop/style/redundant_sort.rb +13 -12
  401. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  402. data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -5
  403. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  404. data/lib/rubocop/cop/style/require_order.rb +12 -15
  405. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  406. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  407. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  408. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  409. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  410. data/lib/rubocop/cop/style/sample.rb +3 -4
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
  412. data/lib/rubocop/cop/style/self_assignment.rb +3 -3
  413. data/lib/rubocop/cop/style/semicolon.rb +43 -5
  414. data/lib/rubocop/cop/style/send.rb +4 -4
  415. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +90 -0
  416. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  417. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  418. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  419. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  420. data/lib/rubocop/cop/style/slicing_with_range.rb +77 -11
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
  422. data/lib/rubocop/cop/style/special_global_vars.rb +4 -6
  423. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  424. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  425. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  426. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  427. data/lib/rubocop/cop/style/strip.rb +7 -4
  428. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  429. data/lib/rubocop/cop/style/super_arguments.rb +156 -0
  430. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  431. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  432. data/lib/rubocop/cop/style/symbol_proc.rb +68 -5
  433. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  434. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  435. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  436. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  437. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  438. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  439. data/lib/rubocop/cop/style/word_array.rb +18 -6
  440. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  441. data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
  442. data/lib/rubocop/cop/style/yoda_expression.rb +26 -9
  443. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  444. data/lib/rubocop/cop/team.rb +36 -23
  445. data/lib/rubocop/cop/util.rb +14 -5
  446. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  447. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  448. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  449. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  450. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
  451. data/lib/rubocop/cop/variable_force.rb +2 -1
  452. data/lib/rubocop/cops_documentation_generator.rb +26 -7
  453. data/lib/rubocop/directive_comment.rb +13 -11
  454. data/lib/rubocop/ext/comment.rb +18 -0
  455. data/lib/rubocop/ext/regexp_node.rb +10 -5
  456. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  457. data/lib/rubocop/file_finder.rb +4 -7
  458. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  459. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  460. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  461. data/lib/rubocop/formatter/html_formatter.rb +35 -14
  462. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  463. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  464. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  465. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  466. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  467. data/lib/rubocop/formatter.rb +1 -2
  468. data/lib/rubocop/lockfile.rb +56 -7
  469. data/lib/rubocop/lsp/logger.rb +22 -0
  470. data/lib/rubocop/lsp/routes.rb +243 -0
  471. data/lib/rubocop/lsp/runtime.rb +99 -0
  472. data/lib/rubocop/lsp/server.rb +73 -0
  473. data/lib/rubocop/lsp/severity.rb +27 -0
  474. data/lib/rubocop/lsp.rb +36 -0
  475. data/lib/rubocop/magic_comment.rb +13 -11
  476. data/lib/rubocop/options.rb +49 -12
  477. data/lib/rubocop/path_util.rb +17 -8
  478. data/lib/rubocop/rake_task.rb +1 -1
  479. data/lib/rubocop/result_cache.rb +6 -3
  480. data/lib/rubocop/rspec/cop_helper.rb +9 -3
  481. data/lib/rubocop/rspec/expect_offense.rb +18 -8
  482. data/lib/rubocop/rspec/shared_contexts.rb +59 -19
  483. data/lib/rubocop/rspec/support.rb +3 -0
  484. data/lib/rubocop/runner.rb +59 -10
  485. data/lib/rubocop/server/cache.rb +11 -4
  486. data/lib/rubocop/server/cli.rb +37 -18
  487. data/lib/rubocop/server/client_command/exec.rb +4 -4
  488. data/lib/rubocop/server/client_command/start.rb +6 -1
  489. data/lib/rubocop/server/core.rb +24 -9
  490. data/lib/rubocop/server/helper.rb +1 -1
  491. data/lib/rubocop/server/server_command/exec.rb +1 -2
  492. data/lib/rubocop/string_interpreter.rb +3 -3
  493. data/lib/rubocop/target_finder.rb +91 -81
  494. data/lib/rubocop/target_ruby.rb +85 -78
  495. data/lib/rubocop/version.rb +27 -8
  496. data/lib/rubocop.rb +35 -0
  497. metadata +76 -35
  498. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -16,7 +16,7 @@ module RuboCop
16
16
  'root of the project. RuboCop will use this path to determine which ' \
17
17
  'cops are enabled (via eg. Include/Exclude), and so that certain cops ' \
18
18
  'like Naming/FileName can be checked.'
19
- EXITING_OPTIONS = %i[version verbose_version show_cops show_docs_url].freeze
19
+ EXITING_OPTIONS = %i[version verbose_version show_cops show_docs_url lsp].freeze
20
20
  DEFAULT_MAXIMUM_EXCLUSION_ITEMS = 15
21
21
 
22
22
  def initialize
@@ -49,20 +49,26 @@ module RuboCop
49
49
 
50
50
  private
51
51
 
52
+ # rubocop:disable Metrics/AbcSize
52
53
  def define_options
53
54
  OptionParser.new do |opts|
54
55
  opts.banner = rainbow.wrap('Usage: rubocop [options] [file1, file2, ...]').bright
55
56
 
56
57
  add_check_options(opts)
57
58
  add_cache_options(opts)
59
+ add_lsp_option(opts)
58
60
  add_server_options(opts)
59
61
  add_output_options(opts)
60
62
  add_autocorrection_options(opts)
61
63
  add_config_generation_options(opts)
62
64
  add_additional_modes(opts)
63
65
  add_general_options(opts)
66
+
67
+ # `stackprof` is not supported on JRuby and Windows.
68
+ add_profile_options(opts) if RUBY_ENGINE == 'ruby' && !Platform.windows?
64
69
  end
65
70
  end
71
+ # rubocop:enable Metrics/AbcSize
66
72
 
67
73
  def add_check_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
68
74
  section(opts, 'Basic Options') do # rubocop:disable Metrics/BlockLength
@@ -89,6 +95,7 @@ module RuboCop
89
95
  option(opts, '--ignore-unrecognized-cops')
90
96
  option(opts, '--force-default-config')
91
97
  option(opts, '-s', '--stdin FILE')
98
+ option(opts, '--editor-mode')
92
99
  option(opts, '-P', '--[no-]parallel')
93
100
  option(opts, '--raise-cop-error')
94
101
  add_severity_option(opts)
@@ -179,7 +186,10 @@ module RuboCop
179
186
  raise OptionArgumentError, message
180
187
  end
181
188
 
182
- @options[:"#{option}"] = list.empty? ? [''] : list.split(',')
189
+ cop_names = list.empty? ? [''] : list.split(',')
190
+ cop_names.unshift('Lint/Syntax') if option == 'only' && !cop_names.include?('Lint/Syntax')
191
+
192
+ @options[:"#{option}"] = cop_names
183
193
  end
184
194
  end
185
195
 
@@ -199,6 +209,12 @@ module RuboCop
199
209
  end
200
210
  end
201
211
 
212
+ def add_lsp_option(opts)
213
+ section(opts, 'LSP Option') do
214
+ option(opts, '--lsp')
215
+ end
216
+ end
217
+
202
218
  def add_server_options(opts)
203
219
  section(opts, 'Server Options') do
204
220
  option(opts, '--[no-]server')
@@ -206,6 +222,7 @@ module RuboCop
206
222
  option(opts, '--start-server')
207
223
  option(opts, '--stop-server')
208
224
  option(opts, '--server-status')
225
+ option(opts, '--no-detach')
209
226
  end
210
227
  end
211
228
 
@@ -233,6 +250,16 @@ module RuboCop
233
250
  end
234
251
  end
235
252
 
253
+ def add_profile_options(opts)
254
+ section(opts, 'Profiling Options') do
255
+ option(opts, '--profile') do
256
+ @options[:profile] = true
257
+ @options[:cache] = 'false' unless @options.key?(:cache)
258
+ end
259
+ option(opts, '--memory')
260
+ end
261
+ end
262
+
236
263
  def handle_deprecated_option(old_option, new_option)
237
264
  warn rainbow.wrap("#{old_option} is deprecated; use #{new_option} instead.").yellow
238
265
  @options[long_opt_symbol([new_option])] = @options.delete(long_opt_symbol([old_option]))
@@ -338,15 +365,12 @@ module RuboCop
338
365
  raise OptionArgumentError, '-C/--cache argument must be true or false'
339
366
  end
340
367
 
341
- if display_only_fail_level_offenses_with_autocorrect?
342
- raise OptionArgumentError, '--autocorrect cannot be used with ' \
343
- '--display-only-fail-level-offenses.'
344
- end
345
368
  validate_auto_gen_config
346
369
  validate_autocorrect
347
370
  validate_display_only_failed
348
371
  validate_display_only_failed_and_display_only_correctable
349
372
  validate_display_only_correctable_and_autocorrect
373
+ validate_lsp_and_editor_mode
350
374
  disable_parallel_when_invalid_option_combo
351
375
 
352
376
  return if incompatible_options.size <= 1
@@ -394,6 +418,13 @@ module RuboCop
394
418
  format('--display-only-failed cannot be used together with other display options.')
395
419
  end
396
420
 
421
+ def validate_lsp_and_editor_mode
422
+ return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
423
+
424
+ raise OptionArgumentError,
425
+ format('Do not specify `--editor-mode` as it is redundant in `--lsp`.')
426
+ end
427
+
397
428
  def validate_autocorrect
398
429
  if @options.key?(:safe_autocorrect) && @options.key?(:autocorrect_all)
399
430
  message = Rainbow(<<~MESSAGE).red
@@ -424,6 +455,8 @@ module RuboCop
424
455
  def invalid_arguments_for_parallel
425
456
  [('--auto-gen-config' if @options.key?(:auto_gen_config)),
426
457
  ('-F/--fail-fast' if @options.key?(:fail_fast)),
458
+ ('--profile' if @options[:profile]),
459
+ ('--memory' if @options[:memory]),
427
460
  ('--cache false' if @options > { cache: 'false' })].compact
428
461
  end
429
462
 
@@ -432,10 +465,6 @@ module RuboCop
432
465
  (@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
433
466
  end
434
467
 
435
- def display_only_fail_level_offenses_with_autocorrect?
436
- @options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
437
- end
438
-
439
468
  def except_syntax?
440
469
  @options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
441
470
  end
@@ -465,6 +494,7 @@ module RuboCop
465
494
 
466
495
  # This module contains help texts for command line options.
467
496
  # @api private
497
+ # rubocop:disable Metrics/ModuleLength
468
498
  module OptionsHelp
469
499
  MAX_EXCL = RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS.to_s
470
500
  FORMATTER_OPTION_LIST = RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys
@@ -543,7 +573,7 @@ module RuboCop
543
573
  'cops. Only valid for --format junit.'],
544
574
  display_only_fail_level_offenses:
545
575
  ['Only output offense messages at',
546
- 'the specified --fail-level or above'],
576
+ 'the specified --fail-level or above.'],
547
577
  display_only_correctable: ['Only output correctable offense messages.'],
548
578
  display_only_safe_correctable: ['Only output safe-correctable offense messages',
549
579
  'when combined with --display-only-correctable.'],
@@ -588,6 +618,8 @@ module RuboCop
588
618
  'parallel. Default is true.'],
589
619
  stdin: ['Pipe source from STDIN, using FILE in offense',
590
620
  'reports. This is useful for editor integration.'],
621
+ editor_mode: ['Optimize real-time feedback in editors,',
622
+ 'adjusting behaviors for editing experience.'],
591
623
  init: 'Generate a .rubocop.yml file in the current directory.',
592
624
  server: ['If a server process has not been started yet, start',
593
625
  'the server process and execute inspection with server.',
@@ -599,9 +631,14 @@ module RuboCop
599
631
  start_server: 'Start server process.',
600
632
  stop_server: 'Stop server process.',
601
633
  server_status: 'Show server status.',
634
+ no_detach: 'Run the server process in the foreground.',
635
+ lsp: 'Start a language server listening on STDIN.',
602
636
  raise_cop_error: ['Raise cop-related errors with cause and location.',
603
637
  'This is used to prevent cops from failing silently.',
604
- 'Default is false.']
638
+ 'Default is false.'],
639
+ profile: 'Profile rubocop.',
640
+ memory: 'Profile rubocop memory usage.'
605
641
  }.freeze
606
642
  end
643
+ # rubocop:enable Metrics/ModuleLength
607
644
  end
@@ -28,18 +28,23 @@ module RuboCop
28
28
  end
29
29
  end
30
30
 
31
+ SMART_PATH_CACHE = {} # rubocop:disable Style/MutableConstant
32
+ private_constant :SMART_PATH_CACHE
33
+
31
34
  def smart_path(path)
32
- # Ideally, we calculate this relative to the project root.
33
- base_dir = Dir.pwd
35
+ SMART_PATH_CACHE[path] ||= begin
36
+ # Ideally, we calculate this relative to the project root.
37
+ base_dir = Dir.pwd
34
38
 
35
- if path.start_with? base_dir
36
- relative_path(path, base_dir)
37
- else
38
- path
39
+ if path.start_with? base_dir
40
+ relative_path(path, base_dir)
41
+ else
42
+ path
43
+ end
39
44
  end
40
45
  end
41
46
 
42
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
47
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
43
48
  def match_path?(pattern, path)
44
49
  case pattern
45
50
  when String
@@ -47,6 +52,10 @@ module RuboCop
47
52
  if pattern == path
48
53
  true
49
54
  elsif glob?(pattern)
55
+ # File name matching doesn't really work with relative patterns that start with "..". We
56
+ # get around that problem by converting the pattern to an absolute path.
57
+ pattern = File.expand_path(pattern) if pattern.start_with?('..')
58
+
50
59
  File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
51
60
  end
52
61
 
@@ -61,7 +70,7 @@ module RuboCop
61
70
  end
62
71
  end
63
72
  end
64
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
73
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
65
74
 
66
75
  # Returns true for an absolute Unix or Windows path.
67
76
  def absolute?(path)
@@ -44,7 +44,7 @@ module RuboCop
44
44
  def run_cli(verbose, options)
45
45
  # We lazy-load RuboCop so that the task doesn't dramatically impact the
46
46
  # load time of your Rakefile.
47
- require 'rubocop'
47
+ require_relative '../rubocop'
48
48
 
49
49
  cli = CLI.new
50
50
  puts 'Running RuboCop...' if verbose
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'digest/sha1'
4
- require 'etc'
5
4
  require 'find'
6
5
  require 'zlib'
7
6
  require_relative 'cache_config'
@@ -83,10 +82,10 @@ module RuboCop
83
82
  config_store.for_pwd.for_all_cops['AllowSymlinksInCacheRootDirectory']
84
83
  end
85
84
 
86
- attr :path
85
+ attr_reader :path
87
86
 
88
87
  def initialize(file, team, options, config_store, cache_root = nil)
89
- cache_root ||= options[:cache_root]
88
+ cache_root ||= File.join(options[:cache_root], 'rubocop_cache') if options[:cache_root]
90
89
  cache_root ||= ResultCache.cache_root(config_store)
91
90
  @allow_symlinks_in_cache_location =
92
91
  ResultCache.allow_symlinks_in_cache_location?(config_store)
@@ -202,6 +201,10 @@ module RuboCop
202
201
  lib_root = File.join(File.dirname(__FILE__), '..')
203
202
  exe_root = File.join(lib_root, '..', 'exe')
204
203
 
204
+ # Make sure to use an absolute path to prevent errors on Windows
205
+ # when traversing the relative paths with symlinks.
206
+ exe_root = File.absolute_path(exe_root)
207
+
205
208
  # These are all the files we have `require`d plus everything in the
206
209
  # exe directory. A change to any of them could affect the cop output
207
210
  # so we include them in the cache hash.
@@ -6,7 +6,11 @@ require 'tempfile'
6
6
  module CopHelper
7
7
  extend RSpec::SharedContext
8
8
 
9
- let(:ruby_version) { 2.6 }
9
+ let(:ruby_version) do
10
+ # The minimum version Prism can parse is 3.3.
11
+ ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
12
+ end
13
+ let(:parser_engine) { ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym }
10
14
  let(:rails_version) { false }
11
15
 
12
16
  def inspect_source(source, file = nil)
@@ -28,7 +32,9 @@ module CopHelper
28
32
  file = file.path
29
33
  end
30
34
 
31
- processed_source = RuboCop::ProcessedSource.new(source, ruby_version, file)
35
+ processed_source = RuboCop::ProcessedSource.new(
36
+ source, ruby_version, file, parser_engine: parser_engine
37
+ )
32
38
  processed_source.config = configuration
33
39
  processed_source.registry = registry
34
40
  processed_source
@@ -69,7 +75,7 @@ module CopHelper
69
75
  end
70
76
 
71
77
  def _investigate(cop, processed_source)
72
- team = RuboCop::Cop::Team.new([cop], nil, raise_error: true)
78
+ team = RuboCop::Cop::Team.new([cop], configuration, raise_error: true)
73
79
  report = team.investigate(processed_source)
74
80
  @last_corrector = report.correctors.first || RuboCop::Cop::Corrector.new(processed_source)
75
81
  report.offenses.reject(&:disabled?)
@@ -6,7 +6,7 @@ module RuboCop
6
6
  #
7
7
  # This mixin makes it easier to specify strict offense expectations
8
8
  # in a declarative and visual fashion. Just type out the code that
9
- # should generate a offense, annotate code by writing '^'s
9
+ # should generate an offense, annotate code by writing '^'s
10
10
  # underneath each character that should be highlighted, and follow
11
11
  # the carets with a string (separated by a space) that is the
12
12
  # message of the offense. You can include multiple offenses in
@@ -111,6 +111,7 @@ module RuboCop
111
111
  source
112
112
  end
113
113
 
114
+ # rubocop:disable Metrics/AbcSize
114
115
  def expect_offense(source, file = nil, severity: nil, chomp: false, **replacements)
115
116
  expected_annotations = parse_annotations(source, **replacements)
116
117
  source = expected_annotations.plain_source
@@ -123,8 +124,15 @@ module RuboCop
123
124
  expect(actual_annotations).to eq(expected_annotations), ''
124
125
  expect(@offenses.map(&:severity).uniq).to eq([severity]) if severity
125
126
 
127
+ # Validate that all offenses have a range that formatters can display
128
+ expect do
129
+ @offenses.each { |offense| offense.location.source_line }
130
+ end.not_to raise_error, 'One of the offenses has a misconstructed range, for ' \
131
+ 'example if the offense is on line 1 and the source is empty'
132
+
126
133
  @offenses
127
134
  end
135
+ # rubocop:enable Metrics/AbcSize
128
136
 
129
137
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
130
138
  def expect_correction(correction, loop: true, source: nil)
@@ -138,6 +146,8 @@ module RuboCop
138
146
 
139
147
  source = @processed_source.raw_source
140
148
 
149
+ raise 'Use `expect_no_corrections` if the code will not change' if correction == source
150
+
141
151
  iteration = 0
142
152
  new_source = loop do
143
153
  iteration += 1
@@ -146,7 +156,6 @@ module RuboCop
146
156
 
147
157
  break corrected_source unless loop
148
158
  break corrected_source if @last_corrector.empty?
149
- break corrected_source if corrected_source == @processed_source.buffer.source
150
159
 
151
160
  if iteration > RuboCop::Runner::MAX_ITERATIONS
152
161
  raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
@@ -157,7 +166,7 @@ module RuboCop
157
166
  _investigate(cop, @processed_source)
158
167
  end
159
168
 
160
- raise 'Use `expect_no_corrections` if the code will not change' if new_source == source
169
+ raise 'Expected correction but no corrections were made' if new_source == source
161
170
 
162
171
  expect(new_source).to eq(correction)
163
172
  end
@@ -168,12 +177,13 @@ module RuboCop
168
177
 
169
178
  return if @last_corrector.empty?
170
179
 
171
- # In order to print a nice diff, e.g. what source got corrected to,
172
- # we need to run the actual corrections
173
-
180
+ # This is just here for a pretty diff if the source actually got changed
174
181
  new_source = @last_corrector.rewrite
175
-
176
182
  expect(new_source).to eq(@processed_source.buffer.source)
183
+
184
+ # There is an infinite loop if a corrector is present that did not make
185
+ # any changes. It will cause the same offense/correction on the next loop.
186
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
177
187
  end
178
188
 
179
189
  def expect_no_offenses(source, file = nil)
@@ -210,7 +220,7 @@ module RuboCop
210
220
 
211
221
  # Parsed representation of code annotated with the `^^^ Message` style
212
222
  class AnnotatedSource
213
- ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) /.freeze
223
+ ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) ?/.freeze
214
224
  ABBREV = "[...]\n"
215
225
 
216
226
  # @param annotated_source [String] string passed to the matchers
@@ -11,6 +11,8 @@ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLe
11
11
  # Make sure to expand all symlinks in the path first. Otherwise we may
12
12
  # get mismatched pathnames when loading config files later on.
13
13
  tmpdir = File.realpath(tmpdir)
14
+ # Make upwards search for .rubocop.yml files stop at this directory.
15
+ RuboCop::FileFinder.root_level = tmpdir
14
16
 
15
17
  virtual_home = File.expand_path(File.join(tmpdir, 'home'))
16
18
  Dir.mkdir(virtual_home)
@@ -21,9 +23,6 @@ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLe
21
23
  root = example.metadata[:root]
22
24
  working_dir = root ? File.join(base_dir, 'work', root) : File.join(base_dir, 'work')
23
25
 
24
- # Make upwards search for .rubocop.yml files stop at this directory.
25
- RuboCop::FileFinder.root_level = working_dir
26
-
27
26
  begin
28
27
  FileUtils.mkdir_p(working_dir)
29
28
 
@@ -101,17 +100,29 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
101
100
  let(:cur_cop_config) do
102
101
  RuboCop::ConfigLoader
103
102
  .default_configuration.for_cop(cop_class)
104
- .merge({
105
- 'Enabled' => true, # in case it is 'pending'
106
- 'AutoCorrect' => true # in case defaults set it to false
107
- })
103
+ .merge(
104
+ 'Enabled' => true, # in case it is 'pending'
105
+ 'AutoCorrect' => 'always' # in case defaults set it to 'disabled' or false
106
+ )
108
107
  .merge(cop_config)
109
108
  end
110
109
 
111
110
  let(:config) do
112
111
  hash = { 'AllCops' => all_cops_config, cop_class.cop_name => cur_cop_config }.merge!(other_cops)
113
112
 
114
- RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
113
+ config = RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
114
+
115
+ rails_version_in_gemfile = Gem::Version.new(
116
+ rails_version || RuboCop::Config::DEFAULT_RAILS_VERSION
117
+ )
118
+
119
+ allow(config).to receive(:gem_versions_in_target).and_return(
120
+ {
121
+ 'railties' => rails_version_in_gemfile
122
+ }
123
+ )
124
+
125
+ config
115
126
  end
116
127
 
117
128
  let(:cop) { cop_class.new(config, cop_options) }
@@ -129,46 +140,75 @@ RSpec.shared_context 'mock console output' do
129
140
  end
130
141
  end
131
142
 
143
+ RSpec.shared_context 'lsp' do
144
+ before do
145
+ RuboCop::LSP.enable
146
+ end
147
+
148
+ after do
149
+ RuboCop::LSP.disable
150
+ end
151
+ end
152
+
132
153
  RSpec.shared_context 'ruby 2.0' do
133
- let(:ruby_version) { 2.0 }
154
+ # Prism supports parsing Ruby 3.3+.
155
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.0 }
134
156
  end
135
157
 
136
158
  RSpec.shared_context 'ruby 2.1' do
137
- let(:ruby_version) { 2.1 }
159
+ # Prism supports parsing Ruby 3.3+.
160
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.1 }
138
161
  end
139
162
 
140
163
  RSpec.shared_context 'ruby 2.2' do
141
- let(:ruby_version) { 2.2 }
164
+ # Prism supports parsing Ruby 3.3+.
165
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.2 }
142
166
  end
143
167
 
144
168
  RSpec.shared_context 'ruby 2.3' do
145
- let(:ruby_version) { 2.3 }
169
+ # Prism supports parsing Ruby 3.3+.
170
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.3 }
146
171
  end
147
172
 
148
173
  RSpec.shared_context 'ruby 2.4' do
149
- let(:ruby_version) { 2.4 }
174
+ # Prism supports parsing Ruby 3.3+.
175
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.4 }
150
176
  end
151
177
 
152
178
  RSpec.shared_context 'ruby 2.5' do
153
- let(:ruby_version) { 2.5 }
179
+ # Prism supports parsing Ruby 3.3+.
180
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.5 }
154
181
  end
155
182
 
156
183
  RSpec.shared_context 'ruby 2.6' do
157
- let(:ruby_version) { 2.6 }
184
+ # Prism supports parsing Ruby 3.3+.
185
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.6 }
158
186
  end
159
187
 
160
188
  RSpec.shared_context 'ruby 2.7' do
161
- let(:ruby_version) { 2.7 }
189
+ # Prism supports parsing Ruby 3.3+.
190
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.7 }
162
191
  end
163
192
 
164
193
  RSpec.shared_context 'ruby 3.0' do
165
- let(:ruby_version) { 3.0 }
194
+ # Prism supports parsing Ruby 3.3+.
195
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.0 }
166
196
  end
167
197
 
168
198
  RSpec.shared_context 'ruby 3.1' do
169
- let(:ruby_version) { 3.1 }
199
+ # Prism supports parsing Ruby 3.3+.
200
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.1 }
170
201
  end
171
202
 
172
203
  RSpec.shared_context 'ruby 3.2' do
173
- let(:ruby_version) { 3.2 }
204
+ # Prism supports parsing Ruby 3.3+.
205
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.2 }
206
+ end
207
+
208
+ RSpec.shared_context 'ruby 3.3' do
209
+ let(:ruby_version) { 3.3 }
210
+ end
211
+
212
+ RSpec.shared_context 'ruby 3.4' do
213
+ let(:ruby_version) { 3.4 }
174
214
  end
@@ -13,6 +13,7 @@ RSpec.configure do |config|
13
13
  config.include HostEnvironmentSimulatorHelper
14
14
  config.include_context 'config', :config
15
15
  config.include_context 'isolated environment', :isolated_environment
16
+ config.include_context 'lsp', :lsp
16
17
  config.include_context 'maintain registry', :restore_registry
17
18
  config.include_context 'ruby 2.0', :ruby20
18
19
  config.include_context 'ruby 2.1', :ruby21
@@ -25,4 +26,6 @@ RSpec.configure do |config|
25
26
  config.include_context 'ruby 3.0', :ruby30
26
27
  config.include_context 'ruby 3.1', :ruby31
27
28
  config.include_context 'ruby 3.2', :ruby32
29
+ config.include_context 'ruby 3.3', :ruby33
30
+ config.include_context 'ruby 3.4', :ruby34
28
31
  end
@@ -20,7 +20,32 @@ module RuboCop
20
20
  message = 'Infinite loop detected'
21
21
  message += " in #{path}" if path
22
22
  message += " and caused by #{root_cause}" if root_cause
23
- super message
23
+ message += "\n"
24
+ hint = 'Hint: Please update to the latest RuboCop version if not already in use, ' \
25
+ "and report a bug if the issue still occurs on this version.\n" \
26
+ 'Please check the latest version at https://rubygems.org/gems/rubocop.'
27
+ super(Rainbow(message).red + Rainbow(hint).yellow)
28
+ end
29
+ end
30
+
31
+ class << self
32
+ # @return [Array<#call>]
33
+ def ruby_extractors
34
+ @ruby_extractors ||= [default_ruby_extractor]
35
+ end
36
+
37
+ private
38
+
39
+ # @return [#call]
40
+ def default_ruby_extractor
41
+ lambda do |processed_source|
42
+ [
43
+ {
44
+ offset: 0,
45
+ processed_source: processed_source
46
+ }
47
+ ]
48
+ end
24
49
  end
25
50
  end
26
51
 
@@ -319,10 +344,25 @@ module RuboCop
319
344
  end
320
345
 
321
346
  def inspect_file(processed_source, team = mobilize_team(processed_source))
322
- report = team.investigate(processed_source)
323
- @errors.concat(team.errors)
324
- @warnings.concat(team.warnings)
325
- [report.offenses, team.updated_source_file?]
347
+ extracted_ruby_sources = extract_ruby_sources(processed_source)
348
+ offenses = extracted_ruby_sources.flat_map do |extracted_ruby_source|
349
+ report = team.investigate(
350
+ extracted_ruby_source[:processed_source],
351
+ offset: extracted_ruby_source[:offset],
352
+ original: processed_source
353
+ )
354
+ @errors.concat(team.errors)
355
+ @warnings.concat(team.warnings)
356
+ report.offenses
357
+ end
358
+ [offenses, team.updated_source_file?]
359
+ end
360
+
361
+ def extract_ruby_sources(processed_source)
362
+ self.class.ruby_extractors.find do |ruby_extractor|
363
+ result = ruby_extractor.call(processed_source)
364
+ break result if result
365
+ end
326
366
  end
327
367
 
328
368
  def mobilize_team(processed_source)
@@ -385,10 +425,10 @@ module RuboCop
385
425
  end
386
426
 
387
427
  def considered_failure?(offense)
388
- # For :autocorrect level, any offense - corrected or not - is a failure.
389
428
  return false if offense.disabled?
390
429
 
391
- return true if @options[:fail_level] == :autocorrect
430
+ # For :autocorrect level, any correctable offense is a failure, regardless of severity
431
+ return true if @options[:fail_level] == :autocorrect && offense.correctable?
392
432
 
393
433
  !offense.corrected? && offense.severity >= minimum_severity_to_fail
394
434
  end
@@ -425,19 +465,27 @@ module RuboCop
425
465
  @minimum_severity_to_fail ||= begin
426
466
  # Unless given explicitly as `fail_level`, `:info` severity offenses do not fail
427
467
  name = @options[:fail_level] || :refactor
428
- RuboCop::Cop::Severity.new(name)
468
+
469
+ # autocorrect is a fake level - use the default
470
+ RuboCop::Cop::Severity.new(name == :autocorrect ? :refactor : name)
429
471
  end
430
472
  end
431
473
 
474
+ # rubocop:disable Metrics/MethodLength
432
475
  def get_processed_source(file)
433
476
  config = @config_store.for_file(file)
434
477
  ruby_version = config.target_ruby_version
478
+ parser_engine = config.parser_engine
435
479
 
436
480
  processed_source = if @options[:stdin]
437
- ProcessedSource.new(@options[:stdin], ruby_version, file)
481
+ ProcessedSource.new(
482
+ @options[:stdin], ruby_version, file, parser_engine: parser_engine
483
+ )
438
484
  else
439
485
  begin
440
- ProcessedSource.from_file(file, ruby_version)
486
+ ProcessedSource.from_file(
487
+ file, ruby_version, parser_engine: parser_engine
488
+ )
441
489
  rescue Errno::ENOENT
442
490
  raise RuboCop::Error, "No such file or directory: #{file}"
443
491
  end
@@ -446,6 +494,7 @@ module RuboCop
446
494
  processed_source.registry = mobilized_cop_classes(config)
447
495
  processed_source
448
496
  end
497
+ # rubocop:enable Metrics/MethodLength
449
498
 
450
499
  # A Cop::Team instance is stateful and may change when inspecting.
451
500
  # The "standby" team for a given config is an initialized but