rubocop 1.48.1 → 1.62.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +7 -5
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +217 -35
  7. data/config/obsoletion.yml +5 -0
  8. data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
  9. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  10. data/lib/rubocop/cli/command/lsp.rb +19 -0
  11. data/lib/rubocop/cli.rb +16 -8
  12. data/lib/rubocop/config.rb +9 -3
  13. data/lib/rubocop/config_finder.rb +14 -4
  14. data/lib/rubocop/config_loader.rb +8 -9
  15. data/lib/rubocop/config_loader_resolver.rb +4 -3
  16. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  17. data/lib/rubocop/config_obsoletion.rb +13 -10
  18. data/lib/rubocop/config_validator.rb +14 -7
  19. data/lib/rubocop/cop/autocorrect_logic.rb +36 -13
  20. data/lib/rubocop/cop/base.rb +23 -4
  21. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  22. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  23. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  24. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  26. data/lib/rubocop/cop/cop.rb +2 -2
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
  28. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  30. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  31. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  32. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  33. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
  35. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -3
  36. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  37. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  38. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  39. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/cop_description.rb +33 -9
  41. data/lib/rubocop/cop/internal_affairs/example_description.rb +45 -24
  42. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +2 -2
  43. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  44. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  45. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  46. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  47. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  48. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +127 -33
  49. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +29 -2
  52. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  53. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  54. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  55. data/lib/rubocop/cop/layout/class_structure.rb +8 -0
  56. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  57. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  58. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  59. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  60. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  61. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +27 -4
  62. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  63. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  64. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  65. data/lib/rubocop/cop/layout/end_alignment.rb +20 -4
  66. data/lib/rubocop/cop/layout/extra_spacing.rb +3 -4
  67. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
  68. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +22 -7
  69. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  70. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  71. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  72. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  73. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +6 -6
  75. data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -1
  76. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  77. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  78. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  79. data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
  80. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
  81. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  82. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  83. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  84. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  85. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  86. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  87. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  88. data/lib/rubocop/cop/layout/redundant_line_break.rb +33 -11
  89. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  90. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  91. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  92. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  93. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  94. data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
  95. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  96. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  97. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -0
  98. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  99. data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
  100. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  101. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  102. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  103. data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -4
  104. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  105. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  106. data/lib/rubocop/cop/lint/debugger.rb +19 -5
  107. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +3 -3
  108. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  109. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  110. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
  111. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  112. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  113. data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
  114. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  115. data/lib/rubocop/cop/lint/erb_new_arguments.rb +6 -7
  116. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  117. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  118. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  119. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  120. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  121. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  122. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  123. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  124. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  125. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  126. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  127. data/lib/rubocop/cop/lint/mixed_case_range.rb +111 -0
  128. data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
  129. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
  130. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  131. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  132. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  133. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  135. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  136. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +1 -1
  137. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  138. data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -3
  139. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  140. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  141. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -2
  142. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  143. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  144. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
  145. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  146. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  147. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  148. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  149. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  150. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  151. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  152. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  153. data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
  154. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  155. data/lib/rubocop/cop/lint/to_enum_arguments.rb +19 -6
  156. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  157. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  158. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  159. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -3
  160. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  161. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  162. data/lib/rubocop/cop/lint/useless_method_definition.rb +10 -2
  163. data/lib/rubocop/cop/lint/useless_times.rb +2 -2
  164. data/lib/rubocop/cop/lint/void.rb +104 -14
  165. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  166. data/lib/rubocop/cop/metrics/block_length.rb +1 -1
  167. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  168. data/lib/rubocop/cop/metrics/class_length.rb +8 -2
  169. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  170. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  171. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +31 -3
  172. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  173. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  174. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  175. data/lib/rubocop/cop/mixin/comments_help.rb +19 -11
  176. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  177. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  178. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  179. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +14 -11
  180. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  181. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  182. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  183. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  184. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  185. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  186. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  187. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  188. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  189. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  190. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  191. data/lib/rubocop/cop/naming/block_forwarding.rb +13 -5
  192. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  193. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  194. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  195. data/lib/rubocop/cop/naming/inclusive_language.rb +23 -4
  196. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  197. data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
  198. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -3
  199. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  200. data/lib/rubocop/cop/registry.rb +1 -1
  201. data/lib/rubocop/cop/security/open.rb +2 -2
  202. data/lib/rubocop/cop/style/access_modifier_declarations.rb +2 -2
  203. data/lib/rubocop/cop/style/accessor_grouping.rb +6 -2
  204. data/lib/rubocop/cop/style/alias.rb +9 -8
  205. data/lib/rubocop/cop/style/arguments_forwarding.rb +411 -63
  206. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  207. data/lib/rubocop/cop/style/array_intersect.rb +13 -5
  208. data/lib/rubocop/cop/style/attr.rb +11 -1
  209. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  210. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  211. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  212. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  213. data/lib/rubocop/cop/style/block_delimiters.rb +5 -4
  214. data/lib/rubocop/cop/style/case_like_if.rb +5 -5
  215. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -2
  216. data/lib/rubocop/cop/style/class_check.rb +1 -0
  217. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
  218. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  219. data/lib/rubocop/cop/style/collection_compact.rb +35 -12
  220. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  221. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  222. data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
  223. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  224. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
  225. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -10
  226. data/lib/rubocop/cop/style/copyright.rb +6 -3
  227. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  228. data/lib/rubocop/cop/style/date_time.rb +5 -4
  229. data/lib/rubocop/cop/style/dir.rb +1 -1
  230. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  231. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  232. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +2 -2
  233. data/lib/rubocop/cop/style/documentation.rb +1 -1
  234. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  235. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
  236. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  237. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  238. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  239. data/lib/rubocop/cop/style/eval_with_location.rb +8 -19
  240. data/lib/rubocop/cop/style/exact_regexp_match.rb +69 -0
  241. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  242. data/lib/rubocop/cop/style/file_empty.rb +3 -3
  243. data/lib/rubocop/cop/style/file_read.rb +2 -2
  244. data/lib/rubocop/cop/style/for.rb +3 -1
  245. data/lib/rubocop/cop/style/format_string.rb +24 -3
  246. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
  247. data/lib/rubocop/cop/style/guard_clause.rb +28 -0
  248. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  249. data/lib/rubocop/cop/style/hash_each_methods.rb +106 -33
  250. data/lib/rubocop/cop/style/hash_except.rb +25 -13
  251. data/lib/rubocop/cop/style/hash_syntax.rb +9 -2
  252. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  253. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  254. data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
  255. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  256. data/lib/rubocop/cop/style/if_unless_modifier.rb +41 -12
  257. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  258. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  259. data/lib/rubocop/cop/style/invertible_unless_condition.rb +54 -8
  260. data/lib/rubocop/cop/style/lambda.rb +3 -3
  261. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  262. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
  263. data/lib/rubocop/cop/style/map_to_hash.rb +19 -6
  264. data/lib/rubocop/cop/style/map_to_set.rb +4 -1
  265. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -16
  266. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +45 -40
  267. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
  268. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  269. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  270. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  271. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  272. data/lib/rubocop/cop/style/multiline_method_signature.rb +16 -4
  273. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  274. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  275. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  276. data/lib/rubocop/cop/style/next.rb +1 -1
  277. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  278. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  279. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  280. data/lib/rubocop/cop/style/object_then.rb +5 -3
  281. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  282. data/lib/rubocop/cop/style/operator_method_call.rb +8 -2
  283. data/lib/rubocop/cop/style/parallel_assignment.rb +29 -23
  284. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  285. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  286. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  287. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  288. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  289. data/lib/rubocop/cop/style/redundant_argument.rb +10 -4
  290. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  291. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  292. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  293. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
  294. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
  295. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
  296. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  297. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  298. data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -7
  299. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  300. data/lib/rubocop/cop/style/redundant_line_continuation.rb +203 -0
  301. data/lib/rubocop/cop/style/redundant_parentheses.rb +72 -23
  302. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  303. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  304. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +2 -2
  305. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  306. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +3 -2
  307. data/lib/rubocop/cop/style/redundant_return.rb +14 -3
  308. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  309. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  310. data/lib/rubocop/cop/style/redundant_sort.rb +10 -9
  311. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  312. data/lib/rubocop/cop/style/redundant_string_escape.rb +5 -4
  313. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  314. data/lib/rubocop/cop/style/require_order.rb +11 -5
  315. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  316. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  317. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  318. data/lib/rubocop/cop/style/sample.rb +3 -4
  319. data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
  320. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  321. data/lib/rubocop/cop/style/semicolon.rb +20 -4
  322. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  323. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  324. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  325. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  326. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  327. data/lib/rubocop/cop/style/sole_nested_conditional.rb +8 -4
  328. data/lib/rubocop/cop/style/special_global_vars.rb +3 -4
  329. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  330. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  331. data/lib/rubocop/cop/style/strip.rb +7 -4
  332. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  333. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  334. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  335. data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
  336. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  337. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  338. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  339. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  340. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  341. data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
  342. data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
  343. data/lib/rubocop/cop/team.rb +1 -1
  344. data/lib/rubocop/cop/util.rb +1 -1
  345. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  346. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  347. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  348. data/lib/rubocop/cop/variable_force.rb +1 -0
  349. data/lib/rubocop/cops_documentation_generator.rb +26 -7
  350. data/lib/rubocop/directive_comment.rb +10 -8
  351. data/lib/rubocop/ext/regexp_node.rb +10 -5
  352. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  353. data/lib/rubocop/file_finder.rb +4 -7
  354. data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
  355. data/lib/rubocop/formatter/html_formatter.rb +35 -14
  356. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  357. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  358. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  359. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  360. data/lib/rubocop/formatter.rb +1 -1
  361. data/lib/rubocop/lsp/logger.rb +22 -0
  362. data/lib/rubocop/lsp/routes.rb +246 -0
  363. data/lib/rubocop/lsp/runtime.rb +99 -0
  364. data/lib/rubocop/lsp/server.rb +71 -0
  365. data/lib/rubocop/lsp/severity.rb +27 -0
  366. data/lib/rubocop/lsp.rb +29 -0
  367. data/lib/rubocop/magic_comment.rb +13 -11
  368. data/lib/rubocop/options.rb +26 -10
  369. data/lib/rubocop/path_util.rb +6 -2
  370. data/lib/rubocop/result_cache.rb +6 -3
  371. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  372. data/lib/rubocop/rspec/expect_offense.rb +8 -8
  373. data/lib/rubocop/rspec/shared_contexts.rb +42 -18
  374. data/lib/rubocop/rspec/support.rb +2 -0
  375. data/lib/rubocop/runner.rb +15 -6
  376. data/lib/rubocop/server/cache.rb +1 -1
  377. data/lib/rubocop/server/client_command/exec.rb +3 -3
  378. data/lib/rubocop/server/helper.rb +1 -1
  379. data/lib/rubocop/server/server_command/exec.rb +1 -2
  380. data/lib/rubocop/string_interpreter.rb +3 -3
  381. data/lib/rubocop/target_finder.rb +91 -81
  382. data/lib/rubocop/target_ruby.rb +85 -78
  383. data/lib/rubocop/version.rb +27 -8
  384. data/lib/rubocop.rb +22 -0
  385. metadata +59 -14
  386. /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,12 +49,14 @@ 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)
@@ -66,6 +68,7 @@ module RuboCop
66
68
  add_profile_options(opts) if RUBY_ENGINE == 'ruby' && !Platform.windows?
67
69
  end
68
70
  end
71
+ # rubocop:enable Metrics/AbcSize
69
72
 
70
73
  def add_check_options(opts) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
71
74
  section(opts, 'Basic Options') do # rubocop:disable Metrics/BlockLength
@@ -92,6 +95,7 @@ module RuboCop
92
95
  option(opts, '--ignore-unrecognized-cops')
93
96
  option(opts, '--force-default-config')
94
97
  option(opts, '-s', '--stdin FILE')
98
+ option(opts, '--editor-mode')
95
99
  option(opts, '-P', '--[no-]parallel')
96
100
  option(opts, '--raise-cop-error')
97
101
  add_severity_option(opts)
@@ -182,7 +186,10 @@ module RuboCop
182
186
  raise OptionArgumentError, message
183
187
  end
184
188
 
185
- @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
186
193
  end
187
194
  end
188
195
 
@@ -202,6 +209,12 @@ module RuboCop
202
209
  end
203
210
  end
204
211
 
212
+ def add_lsp_option(opts)
213
+ section(opts, 'LSP Option') do
214
+ option(opts, '--lsp')
215
+ end
216
+ end
217
+
205
218
  def add_server_options(opts)
206
219
  section(opts, 'Server Options') do
207
220
  option(opts, '--[no-]server')
@@ -352,15 +365,12 @@ module RuboCop
352
365
  raise OptionArgumentError, '-C/--cache argument must be true or false'
353
366
  end
354
367
 
355
- if display_only_fail_level_offenses_with_autocorrect?
356
- raise OptionArgumentError, '--autocorrect cannot be used with ' \
357
- '--display-only-fail-level-offenses.'
358
- end
359
368
  validate_auto_gen_config
360
369
  validate_autocorrect
361
370
  validate_display_only_failed
362
371
  validate_display_only_failed_and_display_only_correctable
363
372
  validate_display_only_correctable_and_autocorrect
373
+ validate_lsp_and_editor_mode
364
374
  disable_parallel_when_invalid_option_combo
365
375
 
366
376
  return if incompatible_options.size <= 1
@@ -408,6 +418,13 @@ module RuboCop
408
418
  format('--display-only-failed cannot be used together with other display options.')
409
419
  end
410
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
+
411
428
  def validate_autocorrect
412
429
  if @options.key?(:safe_autocorrect) && @options.key?(:autocorrect_all)
413
430
  message = Rainbow(<<~MESSAGE).red
@@ -448,10 +465,6 @@ module RuboCop
448
465
  (@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
449
466
  end
450
467
 
451
- def display_only_fail_level_offenses_with_autocorrect?
452
- @options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
453
- end
454
-
455
468
  def except_syntax?
456
469
  @options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
457
470
  end
@@ -605,6 +618,8 @@ module RuboCop
605
618
  'parallel. Default is true.'],
606
619
  stdin: ['Pipe source from STDIN, using FILE in offense',
607
620
  'reports. This is useful for editor integration.'],
621
+ editor_mode: ['Optimize real-time feedback in editors,',
622
+ 'adjusting behaviors for editing experience.'],
608
623
  init: 'Generate a .rubocop.yml file in the current directory.',
609
624
  server: ['If a server process has not been started yet, start',
610
625
  'the server process and execute inspection with server.',
@@ -617,6 +632,7 @@ module RuboCop
617
632
  stop_server: 'Stop server process.',
618
633
  server_status: 'Show server status.',
619
634
  no_detach: 'Run the server process in the foreground.',
635
+ lsp: 'Start a language server listening on STDIN.',
620
636
  raise_cop_error: ['Raise cop-related errors with cause and location.',
621
637
  'This is used to prevent cops from failing silently.',
622
638
  'Default is false.'],
@@ -44,7 +44,7 @@ module RuboCop
44
44
  end
45
45
  end
46
46
 
47
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
47
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48
48
  def match_path?(pattern, path)
49
49
  case pattern
50
50
  when String
@@ -52,6 +52,10 @@ module RuboCop
52
52
  if pattern == path
53
53
  true
54
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
+
55
59
  File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
56
60
  end
57
61
 
@@ -66,7 +70,7 @@ module RuboCop
66
70
  end
67
71
  end
68
72
  end
69
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
73
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
70
74
 
71
75
  # Returns true for an absolute Unix or Windows path.
72
76
  def absolute?(path)
@@ -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
@@ -126,7 +126,7 @@ module RuboCop
126
126
  @offenses
127
127
  end
128
128
 
129
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
129
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
130
130
  def expect_correction(correction, loop: true, source: nil)
131
131
  if source
132
132
  expected_annotations = parse_annotations(source, raise_error: false)
@@ -148,7 +148,6 @@ module RuboCop
148
148
 
149
149
  break corrected_source unless loop
150
150
  break corrected_source if @last_corrector.empty?
151
- break corrected_source if corrected_source == @processed_source.buffer.source
152
151
 
153
152
  if iteration > RuboCop::Runner::MAX_ITERATIONS
154
153
  raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
@@ -163,19 +162,20 @@ module RuboCop
163
162
 
164
163
  expect(new_source).to eq(correction)
165
164
  end
166
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
165
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
167
166
 
168
167
  def expect_no_corrections
169
168
  raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
170
169
 
171
170
  return if @last_corrector.empty?
172
171
 
173
- # In order to print a nice diff, e.g. what source got corrected to,
174
- # we need to run the actual corrections
175
-
172
+ # This is just here for a pretty diff if the source actually got changed
176
173
  new_source = @last_corrector.rewrite
177
-
178
174
  expect(new_source).to eq(@processed_source.buffer.source)
175
+
176
+ # There is an infinite loop if a corrector is present that did not make
177
+ # any changes. It will cause the same offense/correction on the next loop.
178
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
179
179
  end
180
180
 
181
181
  def expect_no_offenses(source, file = nil)
@@ -212,7 +212,7 @@ module RuboCop
212
212
 
213
213
  # Parsed representation of code annotated with the `^^^ Message` style
214
214
  class AnnotatedSource
215
- ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) /.freeze
215
+ ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) ?/.freeze
216
216
  ABBREV = "[...]\n"
217
217
 
218
218
  # @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,10 +100,10 @@ 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
 
@@ -129,50 +128,75 @@ RSpec.shared_context 'mock console output' do
129
128
  end
130
129
  end
131
130
 
131
+ RSpec.shared_context 'lsp' do
132
+ before do
133
+ RuboCop::LSP.enable
134
+ end
135
+
136
+ after do
137
+ RuboCop::LSP.disable
138
+ end
139
+ end
140
+
132
141
  RSpec.shared_context 'ruby 2.0' do
133
- let(:ruby_version) { 2.0 }
142
+ # Prism supports parsing Ruby 3.3+.
143
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.0 }
134
144
  end
135
145
 
136
146
  RSpec.shared_context 'ruby 2.1' do
137
- let(:ruby_version) { 2.1 }
147
+ # Prism supports parsing Ruby 3.3+.
148
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.1 }
138
149
  end
139
150
 
140
151
  RSpec.shared_context 'ruby 2.2' do
141
- let(:ruby_version) { 2.2 }
152
+ # Prism supports parsing Ruby 3.3+.
153
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.2 }
142
154
  end
143
155
 
144
156
  RSpec.shared_context 'ruby 2.3' do
145
- let(:ruby_version) { 2.3 }
157
+ # Prism supports parsing Ruby 3.3+.
158
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.3 }
146
159
  end
147
160
 
148
161
  RSpec.shared_context 'ruby 2.4' do
149
- let(:ruby_version) { 2.4 }
162
+ # Prism supports parsing Ruby 3.3+.
163
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.4 }
150
164
  end
151
165
 
152
166
  RSpec.shared_context 'ruby 2.5' do
153
- let(:ruby_version) { 2.5 }
167
+ # Prism supports parsing Ruby 3.3+.
168
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.5 }
154
169
  end
155
170
 
156
171
  RSpec.shared_context 'ruby 2.6' do
157
- let(:ruby_version) { 2.6 }
172
+ # Prism supports parsing Ruby 3.3+.
173
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.6 }
158
174
  end
159
175
 
160
176
  RSpec.shared_context 'ruby 2.7' do
161
- let(:ruby_version) { 2.7 }
177
+ # Prism supports parsing Ruby 3.3+.
178
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.7 }
162
179
  end
163
180
 
164
181
  RSpec.shared_context 'ruby 3.0' do
165
- let(:ruby_version) { 3.0 }
182
+ # Prism supports parsing Ruby 3.3+.
183
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.0 }
166
184
  end
167
185
 
168
186
  RSpec.shared_context 'ruby 3.1' do
169
- let(:ruby_version) { 3.1 }
187
+ # Prism supports parsing Ruby 3.3+.
188
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.1 }
170
189
  end
171
190
 
172
191
  RSpec.shared_context 'ruby 3.2' do
173
- let(:ruby_version) { 3.2 }
192
+ # Prism supports parsing Ruby 3.3+.
193
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.2 }
174
194
  end
175
195
 
176
196
  RSpec.shared_context 'ruby 3.3' do
177
197
  let(:ruby_version) { 3.3 }
178
198
  end
199
+
200
+ RSpec.shared_context 'ruby 3.4' do
201
+ let(:ruby_version) { 3.4 }
202
+ 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
@@ -26,4 +27,5 @@ RSpec.configure do |config|
26
27
  config.include_context 'ruby 3.1', :ruby31
27
28
  config.include_context 'ruby 3.2', :ruby32
28
29
  config.include_context 'ruby 3.3', :ruby33
30
+ config.include_context 'ruby 3.4', :ruby34
29
31
  end
@@ -20,7 +20,7 @@ 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
+ super(message)
24
24
  end
25
25
  end
26
26
 
@@ -421,10 +421,10 @@ module RuboCop
421
421
  end
422
422
 
423
423
  def considered_failure?(offense)
424
- # For :autocorrect level, any offense - corrected or not - is a failure.
425
424
  return false if offense.disabled?
426
425
 
427
- return true if @options[:fail_level] == :autocorrect
426
+ # For :autocorrect level, any correctable offense is a failure, regardless of severity
427
+ return true if @options[:fail_level] == :autocorrect && offense.correctable?
428
428
 
429
429
  !offense.corrected? && offense.severity >= minimum_severity_to_fail
430
430
  end
@@ -461,19 +461,27 @@ module RuboCop
461
461
  @minimum_severity_to_fail ||= begin
462
462
  # Unless given explicitly as `fail_level`, `:info` severity offenses do not fail
463
463
  name = @options[:fail_level] || :refactor
464
- RuboCop::Cop::Severity.new(name)
464
+
465
+ # autocorrect is a fake level - use the default
466
+ RuboCop::Cop::Severity.new(name == :autocorrect ? :refactor : name)
465
467
  end
466
468
  end
467
469
 
470
+ # rubocop:disable Metrics/MethodLength
468
471
  def get_processed_source(file)
469
472
  config = @config_store.for_file(file)
470
473
  ruby_version = config.target_ruby_version
474
+ parser_engine = config.parser_engine
471
475
 
472
476
  processed_source = if @options[:stdin]
473
- ProcessedSource.new(@options[:stdin], ruby_version, file)
477
+ ProcessedSource.new(
478
+ @options[:stdin], ruby_version, file, parser_engine: parser_engine
479
+ )
474
480
  else
475
481
  begin
476
- ProcessedSource.from_file(file, ruby_version)
482
+ ProcessedSource.from_file(
483
+ file, ruby_version, parser_engine: parser_engine
484
+ )
477
485
  rescue Errno::ENOENT
478
486
  raise RuboCop::Error, "No such file or directory: #{file}"
479
487
  end
@@ -482,6 +490,7 @@ module RuboCop
482
490
  processed_source.registry = mobilized_cop_classes(config)
483
491
  processed_source
484
492
  end
493
+ # rubocop:enable Metrics/MethodLength
485
494
 
486
495
  # A Cop::Team instance is stateful and may change when inspecting.
487
496
  # The "standby" team for a given config is an initialized but
@@ -116,7 +116,7 @@ module RuboCop
116
116
 
117
117
  def pid_running?
118
118
  Process.kill(0, pid_path.read.to_i) == 1
119
- rescue Errno::ESRCH, Errno::ENOENT
119
+ rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS
120
120
  false
121
121
  end
122
122
 
@@ -17,11 +17,11 @@ module RuboCop
17
17
  class Exec < Base
18
18
  def run
19
19
  ensure_server!
20
- Cache.status_path.delete if Cache.status_path.file?
20
+ read_stdin = ARGV.include?('-s') || ARGV.include?('--stdin')
21
21
  send_request(
22
22
  command: 'exec',
23
23
  args: ARGV.dup,
24
- body: $stdin.tty? ? '' : $stdin.read
24
+ body: read_stdin ? $stdin.read : ''
25
25
  )
26
26
  warn stderr unless stderr.empty?
27
27
  status
@@ -31,7 +31,7 @@ module RuboCop
31
31
 
32
32
  def ensure_server!
33
33
  if incompatible_version?
34
- puts 'RuboCop version incompatibility found, RuboCop server restarting...'
34
+ warn 'RuboCop version incompatibility found, RuboCop server restarting...'
35
35
  ClientCommand::Stop.new.run
36
36
  elsif check_running_server
37
37
  return
@@ -11,7 +11,7 @@
11
11
  #
12
12
  module RuboCop
13
13
  module Server
14
- # This module has a helper memthod for `RuboCop::Server::SocketReader`.
14
+ # This module has a helper method for `RuboCop::Server::SocketReader`.
15
15
  # @api private
16
16
  module Helper
17
17
  def self.redirect(stdin: $stdin, stdout: $stdout, stderr: $stderr, &_block)
@@ -16,12 +16,11 @@ module RuboCop
16
16
  # @api private
17
17
  class Exec < Base
18
18
  def run
19
- Cache.status_path.delete if Cache.status_path.file?
20
19
  # RuboCop output is colorized by default where there is a TTY.
21
20
  # We must pass the --color option to preserve this behavior.
22
21
  @args.unshift('--color') unless %w[--color --no-color].any? { |f| @args.include?(f) }
23
22
  status = RuboCop::CLI.new.run(@args)
24
- # This status file is read by `rubocop --server` (`RuboCop::Server::Clientcommand::Exec`).
23
+ # This status file is read by `rubocop --server` (`RuboCop::Server::ClientCommand::Exec`).
25
24
  # so that they use the correct exit code.
26
25
  # Status is 1 when there are any issues, and 0 otherwise.
27
26
  Cache.write_status_file(status)
@@ -32,9 +32,9 @@ module RuboCop
32
32
 
33
33
  def interpret_string_escape(escape)
34
34
  case escape[1]
35
- when 'u' then interpret_unicode(escape)
36
- when 'x' then interpret_hex(escape)
37
- when /\d/ then interpret_octal(escape)
35
+ when 'u' then interpret_unicode(escape)
36
+ when 'x' then interpret_hex(escape)
37
+ when /\d/ then interpret_octal(escape)
38
38
  else
39
39
  escape[1] # literal escaped char, like \\
40
40
  end