rubocop 1.67.0 → 1.82.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 (540) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +403 -75
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +12 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +21 -5
  15. data/lib/rubocop/comment_config.rb +64 -19
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +58 -49
  18. data/lib/rubocop/config_loader_resolver.rb +43 -16
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +57 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +9 -19
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
  42. data/lib/rubocop/cop/generator.rb +6 -0
  43. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  44. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  45. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  46. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  47. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  48. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  49. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  52. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  55. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  56. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  57. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  58. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  59. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  60. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  61. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  62. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  63. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  64. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  65. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  66. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  67. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  68. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  69. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  70. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  71. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  72. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  73. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  74. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  75. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  76. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  77. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  78. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +6 -3
  79. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  80. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  81. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  82. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  83. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  84. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  85. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  86. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  87. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  88. data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
  89. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  90. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  91. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  93. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  94. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  95. data/lib/rubocop/cop/layout/hash_alignment.rb +10 -11
  96. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -3
  97. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -4
  98. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  99. data/lib/rubocop/cop/layout/indentation_width.rb +20 -8
  100. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  101. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  102. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  103. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  104. data/lib/rubocop/cop/layout/line_length.rb +163 -11
  105. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
  106. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  107. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  108. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  109. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +9 -5
  110. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  111. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  112. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  113. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  114. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  115. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +16 -7
  116. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  118. data/lib/rubocop/cop/layout/space_after_comma.rb +3 -11
  119. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_after_semicolon.rb +12 -2
  121. data/lib/rubocop/cop/layout/space_around_keyword.rb +9 -3
  122. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  123. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  124. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  125. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  126. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  127. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  128. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  129. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  130. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  131. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  132. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  133. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  134. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  135. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  136. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  137. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  138. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  139. data/lib/rubocop/cop/lint/circular_argument_reference.rb +51 -4
  140. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  141. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  142. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  143. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  144. data/lib/rubocop/cop/lint/debugger.rb +3 -5
  145. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  146. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
  147. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  148. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +5 -5
  149. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  150. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  151. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  152. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  153. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  154. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  155. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  156. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  157. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  158. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  159. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  160. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  161. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  162. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  163. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  164. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  165. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  166. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  167. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  168. data/lib/rubocop/cop/lint/literal_as_condition.rb +129 -10
  169. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  170. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -7
  171. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
  172. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  173. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  174. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  175. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  176. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  177. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +6 -2
  178. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  179. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  180. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  181. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  182. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  183. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  184. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  185. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  186. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  187. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  188. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  189. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  190. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  191. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -23
  192. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  193. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +15 -8
  194. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  195. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  196. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  197. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  198. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  199. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  200. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  201. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  202. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  203. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  204. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  205. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  206. data/lib/rubocop/cop/lint/self_assignment.rb +47 -15
  207. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  208. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  209. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  210. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  211. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  212. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  213. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  214. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  215. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  216. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  217. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  218. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  219. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  220. data/lib/rubocop/cop/lint/unreachable_code.rb +54 -2
  221. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  222. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  223. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  224. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  225. data/lib/rubocop/cop/lint/useless_assignment.rb +47 -17
  226. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  227. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  228. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  229. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  230. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  231. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  232. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  233. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  234. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  235. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  236. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  237. data/lib/rubocop/cop/lint/void.rb +23 -12
  238. data/lib/rubocop/cop/message_annotator.rb +7 -3
  239. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  240. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  241. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  242. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  243. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  244. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  245. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  246. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  247. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  248. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +5 -4
  249. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  250. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  251. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  252. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  253. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  254. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  255. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +47 -0
  256. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  257. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  258. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  259. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  260. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  261. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  262. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  263. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  264. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  265. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  266. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  267. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  268. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  269. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  270. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  271. data/lib/rubocop/cop/mixin/line_length_help.rb +48 -12
  272. data/lib/rubocop/cop/mixin/method_complexity.rb +3 -2
  273. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +8 -10
  274. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  275. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  276. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  277. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  278. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  279. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  280. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  281. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -8
  282. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  283. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  284. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  285. data/lib/rubocop/cop/mixin/trailing_comma.rb +28 -9
  286. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  287. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  288. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  289. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  290. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  291. data/lib/rubocop/cop/naming/method_name.rb +187 -15
  292. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  293. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  294. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  295. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  296. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  297. data/lib/rubocop/cop/offense.rb +2 -3
  298. data/lib/rubocop/cop/registry.rb +9 -6
  299. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  300. data/lib/rubocop/cop/security/eval.rb +2 -1
  301. data/lib/rubocop/cop/security/json_load.rb +33 -11
  302. data/lib/rubocop/cop/security/open.rb +1 -0
  303. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  304. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  305. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  306. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  307. data/lib/rubocop/cop/style/and_or.rb +1 -1
  308. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  309. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  310. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  311. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  312. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
  313. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  314. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  315. data/lib/rubocop/cop/style/case_equality.rb +11 -13
  316. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  317. data/lib/rubocop/cop/style/class_and_module_children.rb +53 -11
  318. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  319. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  320. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  321. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  322. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  323. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  324. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  325. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  326. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  327. data/lib/rubocop/cop/style/conditional_assignment.rb +50 -42
  328. data/lib/rubocop/cop/style/constant_visibility.rb +19 -23
  329. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  330. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  331. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  332. data/lib/rubocop/cop/style/documentation.rb +1 -1
  333. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  334. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  335. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  336. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  337. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  338. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  339. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  340. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  341. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  342. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  343. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  344. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  345. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  346. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  347. data/lib/rubocop/cop/style/file_null.rb +89 -0
  348. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  349. data/lib/rubocop/cop/style/float_division.rb +23 -5
  350. data/lib/rubocop/cop/style/for.rb +1 -1
  351. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  352. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  353. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  354. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  355. data/lib/rubocop/cop/style/guard_clause.rb +17 -14
  356. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  357. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  358. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  359. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  360. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  361. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  362. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  363. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  364. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  365. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  366. data/lib/rubocop/cop/style/if_unless_modifier.rb +39 -12
  367. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  368. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  369. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  370. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  371. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  372. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  373. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  374. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  375. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  376. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  377. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  378. data/lib/rubocop/cop/style/lambda.rb +1 -0
  379. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  380. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  381. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  382. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  383. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  384. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  385. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
  386. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +35 -4
  387. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  388. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  389. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  390. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  391. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  392. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  393. data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
  394. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  395. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  396. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  397. data/lib/rubocop/cop/style/multiline_method_signature.rb +3 -13
  398. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  399. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  400. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  401. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  402. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  403. data/lib/rubocop/cop/style/next.rb +44 -0
  404. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  405. data/lib/rubocop/cop/style/not.rb +1 -1
  406. data/lib/rubocop/cop/style/object_then.rb +15 -15
  407. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  408. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  409. data/lib/rubocop/cop/style/operator_method_call.rb +16 -8
  410. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  411. data/lib/rubocop/cop/style/parallel_assignment.rb +43 -40
  412. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  413. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  414. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  415. data/lib/rubocop/cop/style/proc.rb +2 -2
  416. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  417. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  418. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  419. data/lib/rubocop/cop/style/redundant_argument.rb +5 -1
  420. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  421. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  422. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  423. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  424. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  425. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  426. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  427. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  428. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  429. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  430. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  431. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  432. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  433. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  434. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  435. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  436. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +13 -0
  437. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  438. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  439. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  440. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  441. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  442. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  443. data/lib/rubocop/cop/style/redundant_sort.rb +10 -10
  444. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  445. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  446. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  447. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  448. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  449. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  450. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  451. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  452. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  453. data/lib/rubocop/cop/style/semicolon.rb +24 -8
  454. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  455. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  456. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  457. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  458. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  459. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  460. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  461. data/lib/rubocop/cop/style/sole_nested_conditional.rb +75 -102
  462. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  463. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  464. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  465. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  466. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  467. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  468. data/lib/rubocop/cop/style/super_arguments.rb +68 -21
  469. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  470. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  471. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  472. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  473. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  474. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  475. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  476. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  477. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  478. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +15 -15
  479. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  480. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  481. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  482. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  483. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  484. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  485. data/lib/rubocop/cop/team.rb +1 -1
  486. data/lib/rubocop/cop/util.rb +14 -8
  487. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  488. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  489. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  490. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  491. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  492. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  493. data/lib/rubocop/cop/variable_force.rb +30 -19
  494. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  495. data/lib/rubocop/directive_comment.rb +88 -11
  496. data/lib/rubocop/ext/regexp_node.rb +0 -1
  497. data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
  498. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  499. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  500. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  501. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  502. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  503. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  504. data/lib/rubocop/lsp/diagnostic.rb +185 -0
  505. data/lib/rubocop/lsp/logger.rb +2 -2
  506. data/lib/rubocop/lsp/routes.rb +37 -24
  507. data/lib/rubocop/lsp/runtime.rb +18 -50
  508. data/lib/rubocop/lsp/server.rb +0 -2
  509. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  510. data/lib/rubocop/magic_comment.rb +31 -3
  511. data/lib/rubocop/options.rb +28 -12
  512. data/lib/rubocop/path_util.rb +15 -8
  513. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  514. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  515. data/lib/rubocop/plugin/load_error.rb +26 -0
  516. data/lib/rubocop/plugin/loader.rb +100 -0
  517. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  518. data/lib/rubocop/plugin.rb +46 -0
  519. data/lib/rubocop/rake_task.rb +5 -2
  520. data/lib/rubocop/remote_config.rb +7 -8
  521. data/lib/rubocop/result_cache.rb +61 -48
  522. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  523. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  524. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  525. data/lib/rubocop/rspec/support.rb +4 -2
  526. data/lib/rubocop/runner.rb +35 -18
  527. data/lib/rubocop/server/cache.rb +51 -13
  528. data/lib/rubocop/server/cli.rb +2 -2
  529. data/lib/rubocop/server/client_command/base.rb +10 -0
  530. data/lib/rubocop/server/client_command/exec.rb +2 -1
  531. data/lib/rubocop/server/client_command/start.rb +11 -1
  532. data/lib/rubocop/target_finder.rb +14 -9
  533. data/lib/rubocop/target_ruby.rb +27 -3
  534. data/lib/rubocop/version.rb +53 -12
  535. data/lib/rubocop.rb +45 -2
  536. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  537. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  538. metadata +92 -21
  539. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  540. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -72,9 +72,15 @@ module RuboCop
72
72
  #
73
73
  # expect_no_corrections
74
74
  #
75
- # If your code has variables of different lengths, you can use `%{foo}`,
76
- # `^{foo}`, and `_{foo}` to format your template; you can also abbreviate
77
- # offense messages with `[...]`:
75
+ # If your code has variables of different lengths, you can use the
76
+ # following markers to format your template by passing the variables as a
77
+ # keyword arguments:
78
+ #
79
+ # - `%{foo}`: Interpolates `foo`
80
+ # - `^{foo}`: Inserts `'^' * foo.size` for dynamic offense range length
81
+ # - `_{foo}`: Inserts `' ' * foo.size` for dynamic offense range indentation
82
+ #
83
+ # You can also abbreviate offense messages with `[...]`.
78
84
  #
79
85
  # %w[raise fail].each do |keyword|
80
86
  # expect_offense(<<~RUBY, keyword: keyword)
@@ -190,7 +196,10 @@ module RuboCop
190
196
  def expect_no_offenses(source, file = nil)
191
197
  offenses = inspect_source(source, file)
192
198
 
193
- expected_annotations = AnnotatedSource.parse(source)
199
+ # Since source given `expect_no_offenses` does not have annotations, we do not need to parse
200
+ # for them, and can just build an `AnnotatedSource` object from the source lines.
201
+ # This also prevents treating source lines that begin with a caret as an annotation.
202
+ expected_annotations = AnnotatedSource.new(source.each_line.to_a, [])
194
203
  actual_annotations = expected_annotations.with_offense_annotations(offenses)
195
204
  expect(actual_annotations.to_s).to eq(source)
196
205
  end
@@ -221,7 +230,8 @@ module RuboCop
221
230
 
222
231
  # Parsed representation of code annotated with the `^^^ Message` style
223
232
  class AnnotatedSource
224
- ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) ?/.freeze
233
+ # Ignore escaped carets, don't treat as annotations
234
+ ANNOTATION_PATTERN = /\A\s*((?<!\\)\^+|\^{}) ?/.freeze
225
235
  ABBREV = "[...]\n"
226
236
 
227
237
  # @param annotated_source [String] string passed to the matchers
@@ -80,6 +80,21 @@ RSpec.shared_context 'maintain registry' do
80
80
  end
81
81
  end
82
82
 
83
+ RSpec.shared_context 'maintain default configuration' do
84
+ around(:each) do |example|
85
+ # Make a copy of the current configuration that will not change when source hash changes
86
+ default_configuration = RuboCop::ConfigLoader.default_configuration
87
+ config = RuboCop::Config.create(
88
+ default_configuration.to_h.clone,
89
+ default_configuration.loaded_path
90
+ )
91
+
92
+ example.run
93
+
94
+ RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
95
+ end
96
+ end
97
+
83
98
  # This context assumes nothing and defines `cop`, among others.
84
99
  RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
85
100
  ### Meant to be overridden at will
@@ -98,6 +113,8 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
98
113
 
99
114
  let(:cop_options) { {} }
100
115
 
116
+ let(:gem_versions) { {} }
117
+
101
118
  ### Utilities
102
119
 
103
120
  def source_range(range, buffer: source_buffer)
@@ -138,7 +155,8 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
138
155
 
139
156
  allow(config).to receive(:gem_versions_in_target).and_return(
140
157
  {
141
- 'railties' => rails_version_in_gemfile
158
+ 'railties' => rails_version_in_gemfile,
159
+ **gem_versions.transform_values { |value| Gem::Version.new(value) }
142
160
  }
143
161
  )
144
162
 
@@ -160,6 +178,21 @@ RSpec.shared_context 'mock console output' do
160
178
  end
161
179
  end
162
180
 
181
+ RSpec.shared_context 'mock obsoletion' do
182
+ include_context 'mock console output'
183
+
184
+ let(:obsoletion_configuration_path) { 'obsoletions.yml' }
185
+
186
+ before do
187
+ RuboCop::ConfigObsoletion.reset!
188
+ allow(RuboCop::ConfigObsoletion).to receive(:files).and_return([obsoletion_configuration_path])
189
+ end
190
+
191
+ after do
192
+ RuboCop::ConfigObsoletion.reset!
193
+ end
194
+ end
195
+
163
196
  RSpec.shared_context 'lsp' do
164
197
  before do
165
198
  RuboCop::LSP.enable
@@ -232,3 +265,7 @@ end
232
265
  RSpec.shared_context 'ruby 3.4' do
233
266
  let(:ruby_version) { 3.4 }
234
267
  end
268
+
269
+ RSpec.shared_context 'ruby 4.0' do
270
+ let(:ruby_version) { 4.0 }
271
+ end
@@ -4,18 +4,19 @@
4
4
 
5
5
  require_relative 'cop_helper'
6
6
  require_relative 'expect_offense'
7
- require_relative 'host_environment_simulation_helper'
8
7
  require_relative 'parallel_formatter'
9
8
  require_relative 'shared_contexts'
10
9
 
11
10
  RSpec.configure do |config|
12
11
  config.include CopHelper
13
- config.include HostEnvironmentSimulatorHelper
12
+ config.include RuboCop::RSpec::ExpectOffense
14
13
  config.include_context 'config', :config
15
14
  config.include_context 'isolated environment', :isolated_environment
16
15
  config.include_context 'isolated bundler', :isolated_bundler
17
16
  config.include_context 'lsp', :lsp
18
17
  config.include_context 'maintain registry', :restore_registry
18
+ config.include_context 'maintain default configuration', :restore_configuration
19
+ config.include_context 'mock obsoletion', :mock_obsoletion
19
20
  config.include_context 'ruby 2.0', :ruby20
20
21
  config.include_context 'ruby 2.1', :ruby21
21
22
  config.include_context 'ruby 2.2', :ruby22
@@ -29,4 +30,5 @@ RSpec.configure do |config|
29
30
  config.include_context 'ruby 3.2', :ruby32
30
31
  config.include_context 'ruby 3.3', :ruby33
31
32
  config.include_context 'ruby 3.4', :ruby34
33
+ config.include_context 'ruby 4.0', :ruby40
32
34
  end
@@ -20,11 +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
- 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)
23
+ super(message)
28
24
  end
29
25
  end
30
26
 
@@ -69,6 +65,10 @@ module RuboCop
69
65
  end
70
66
 
71
67
  def run(paths)
68
+ # Compute the cache source checksum once to avoid potential
69
+ # inconsistencies between workers.
70
+ ResultCache.source_checksum
71
+
72
72
  target_files = find_target_files(paths)
73
73
  if @options[:list_target_files]
74
74
  list_files(target_files)
@@ -139,7 +139,7 @@ module RuboCop
139
139
  offenses = process_file(file)
140
140
  yield file
141
141
 
142
- if offenses.any? { |o| considered_failure?(o) }
142
+ if offenses.any? { |o| considered_failure?(o) && offense_displayed?(o) }
143
143
  break false if @options[:fail_fast]
144
144
 
145
145
  next false
@@ -157,8 +157,11 @@ module RuboCop
157
157
  file_started(file)
158
158
  offenses = file_offenses(file)
159
159
  rescue InfiniteCorrectionLoop => e
160
+ raise e if @options[:raise_cop_error]
161
+
162
+ errors << e
163
+ warn Rainbow(e.message).red
160
164
  offenses = e.offenses.compact.sort.freeze
161
- raise
162
165
  ensure
163
166
  file_finished(file, offenses || [])
164
167
  end
@@ -274,7 +277,8 @@ module RuboCop
274
277
  end
275
278
 
276
279
  def do_inspection_loop(file)
277
- processed_source = get_processed_source(file)
280
+ # We can reuse the prism result since the source did not change yet.
281
+ processed_source = get_processed_source(file, @prism_result)
278
282
  # This variable is 2d array used to track corrected offenses after each
279
283
  # inspection iteration. This is used to output meaningful infinite loop
280
284
  # error message.
@@ -296,7 +300,8 @@ module RuboCop
296
300
  # loop if we find any.
297
301
  break unless updated_source_file
298
302
 
299
- processed_source = get_processed_source(file)
303
+ # Autocorrect has happened, don't use the prism result since it is stale.
304
+ processed_source = get_processed_source(file, nil)
300
305
  end
301
306
 
302
307
  # Return summary of corrected offenses after all iterations
@@ -363,8 +368,12 @@ module RuboCop
363
368
  result = ruby_extractor.call(processed_source)
364
369
  break result if result
365
370
  rescue StandardError
366
- raise Error, "Ruby extractor #{ruby_extractor.source_location[0]} failed to process " \
367
- "#{processed_source.path}."
371
+ location = if ruby_extractor.is_a?(Proc)
372
+ ruby_extractor.source_location
373
+ else
374
+ ruby_extractor.method(:call).source_location
375
+ end
376
+ raise Error, "Ruby extractor #{location[0]} failed to process #{processed_source.path}."
368
377
  end
369
378
  end
370
379
 
@@ -436,18 +445,22 @@ module RuboCop
436
445
  !offense.corrected? && offense.severity >= minimum_severity_to_fail
437
446
  end
438
447
 
439
- def offenses_to_report(offenses)
448
+ def offense_displayed?(offense)
440
449
  if @options[:display_only_fail_level_offenses]
441
- offenses.select { |o| considered_failure?(o) }
450
+ considered_failure?(offense)
442
451
  elsif @options[:display_only_safe_correctable]
443
- offenses.select { |o| supports_safe_autocorrect?(o) }
452
+ supports_safe_autocorrect?(offense)
444
453
  elsif @options[:display_only_correctable]
445
- offenses.select(&:correctable?)
454
+ offense.correctable?
446
455
  else
447
- offenses
456
+ true
448
457
  end
449
458
  end
450
459
 
460
+ def offenses_to_report(offenses)
461
+ offenses.select { |o| offense_displayed?(o) }
462
+ end
463
+
451
464
  def supports_safe_autocorrect?(offense)
452
465
  cop_class = Cop::Registry.global.find_by_cop_name(offense.cop_name)
453
466
  default_cfg = default_config(offense.cop_name)
@@ -475,14 +488,18 @@ module RuboCop
475
488
  end
476
489
 
477
490
  # rubocop:disable Metrics/MethodLength
478
- def get_processed_source(file)
491
+ def get_processed_source(file, prism_result)
479
492
  config = @config_store.for_file(file)
480
493
  ruby_version = config.target_ruby_version
481
494
  parser_engine = config.parser_engine
482
495
 
483
496
  processed_source = if @options[:stdin]
484
497
  ProcessedSource.new(
485
- @options[:stdin], ruby_version, file, parser_engine: parser_engine
498
+ @options[:stdin],
499
+ ruby_version,
500
+ file,
501
+ parser_engine: parser_engine,
502
+ prism_result: prism_result
486
503
  )
487
504
  else
488
505
  begin
@@ -2,8 +2,10 @@
2
2
 
3
3
  require 'digest'
4
4
  require 'pathname'
5
+ require 'yaml'
5
6
  require_relative '../cache_config'
6
7
  require_relative '../config_finder'
8
+ require_relative '../path_util'
7
9
 
8
10
  #
9
11
  # This code is based on https://github.com/fohte/rubocop-daemon.
@@ -44,15 +46,20 @@ module RuboCop
44
46
  end
45
47
 
46
48
  # rubocop:disable Metrics/AbcSize
47
- def restart_key
49
+ def restart_key(args_config_file_path: nil)
48
50
  lockfile_path = LOCKFILE_NAMES.map do |lockfile_name|
49
51
  Pathname(project_dir).join(lockfile_name)
50
52
  end.find(&:exist?)
51
53
  version_data = lockfile_path&.read || RuboCop::Version::STRING
52
- config_data = Pathname(ConfigFinder.find_config_path(Dir.pwd)).read
53
- todo_data = (rubocop_todo = Pathname('.rubocop_todo.yml')).exist? ? rubocop_todo.read : ''
54
+ config_data = Pathname(
55
+ args_config_file_path || ConfigFinder.find_config_path(Dir.pwd)
56
+ ).read
57
+ yaml = load_erb_templated_yaml(config_data)
54
58
 
55
- Digest::SHA1.hexdigest(version_data + config_data + todo_data)
59
+ inherit_from_data = inherit_from_data(yaml)
60
+ require_data = require_data(yaml)
61
+
62
+ Digest::SHA1.hexdigest(version_data + config_data + inherit_from_data + require_data)
56
63
  end
57
64
  # rubocop:enable Metrics/AbcSize
58
65
 
@@ -72,7 +79,6 @@ module RuboCop
72
79
  File.expand_path(File.join(cache_root_dir, 'server'))
73
80
  end
74
81
 
75
- # rubocop:disable Metrics/MethodLength
76
82
  def cache_root_dir_from_config
77
83
  CacheConfig.root_dir do
78
84
  # `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
@@ -83,13 +89,7 @@ module RuboCop
83
89
  # Returns early if `CacheRootDirectory` is not used before requiring `erb` or `yaml`.
84
90
  next unless file_contents.include?('CacheRootDirectory')
85
91
 
86
- require 'erb'
87
- yaml_code = ERB.new(file_contents).result
88
-
89
- require 'yaml'
90
- config_yaml = YAML.safe_load(
91
- yaml_code, permitted_classes: [Regexp, Symbol], aliases: true
92
- )
92
+ config_yaml = load_erb_templated_yaml(file_contents)
93
93
 
94
94
  # For compatibility with Ruby 3.0 or lower.
95
95
  if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
@@ -99,7 +99,6 @@ module RuboCop
99
99
  config_yaml&.dig('AllCops', 'CacheRootDirectory')
100
100
  end
101
101
  end
102
- # rubocop:enable Metrics/MethodLength
103
102
 
104
103
  def port_path
105
104
  dir.join('port')
@@ -164,6 +163,45 @@ module RuboCop
164
163
  def write_version_file(version)
165
164
  version_path.write(version)
166
165
  end
166
+
167
+ def inherit_from_data(yaml)
168
+ return '' unless (inherit_from_paths = yaml['inherit_from'])
169
+
170
+ Array(inherit_from_paths).map do |path|
171
+ next if PathUtil.remote_file?(path)
172
+
173
+ path = Pathname(path)
174
+
175
+ path.exist? ? path.read : ''
176
+ end.join
177
+ end
178
+
179
+ def require_data(yaml)
180
+ return '' unless (require_paths = yaml['require'])
181
+
182
+ Array(require_paths).map do |path|
183
+ # NOTE: This targets only relative or absolute path specifications.
184
+ # For example, specifications like `require: rubocop-performance`,
185
+ # which can be loaded from `$LOAD_PATH`, are ignored.
186
+ next unless path.start_with?('.', '/')
187
+
188
+ # NOTE: `.so` files are not typically specified, so only `.rb` files are targeted.
189
+ path = "#{path}.rb" unless path.end_with?('.rb')
190
+ path = Pathname(path)
191
+
192
+ path.exist? ? path.read : ''
193
+ end.join
194
+ end
195
+
196
+ private
197
+
198
+ def load_erb_templated_yaml(content)
199
+ require 'erb'
200
+ yaml_code = ERB.new(content).result
201
+
202
+ require 'yaml'
203
+ YAML.safe_load(yaml_code, permitted_classes: [Regexp, Symbol], aliases: true)
204
+ end
167
205
  end
168
206
  end
169
207
  end
@@ -86,7 +86,7 @@ module RuboCop
86
86
  end
87
87
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
88
88
 
89
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength:
89
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
90
90
  def run_command(server_command, detach:)
91
91
  case server_command
92
92
  when '--server'
@@ -107,7 +107,7 @@ module RuboCop
107
107
  Server::ClientCommand::Status.new.run
108
108
  end
109
109
  end
110
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength:
110
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
111
111
 
112
112
  def fetch_cache_root_path_from(arguments)
113
113
  cache_root = arguments.detect { |argument| argument.start_with?('--cache-root') }
@@ -38,6 +38,16 @@ module RuboCop
38
38
  warn 'RuboCop server is not running.' unless running
39
39
  end
40
40
  end
41
+
42
+ class << self
43
+ def args_config_file_path
44
+ first_args_config_key_index = ARGV.index { |value| ['-c', '--config'].include?(value) }
45
+
46
+ return if first_args_config_key_index.nil?
47
+
48
+ ARGV[first_args_config_key_index + 1]
49
+ end
50
+ end
41
51
  end
42
52
  end
43
53
  end
@@ -41,7 +41,8 @@ module RuboCop
41
41
  end
42
42
 
43
43
  def incompatible_version?
44
- Cache.version_path.read != Cache.restart_key
44
+ Cache.version_path.read !=
45
+ Cache.restart_key(args_config_file_path: self.class.args_config_file_path)
45
46
  end
46
47
 
47
48
  def stderr
@@ -34,7 +34,7 @@ module RuboCop
34
34
  exit 0
35
35
  end
36
36
 
37
- Cache.write_version_file(Cache.restart_key)
37
+ write_version_file
38
38
 
39
39
  host = ENV.fetch('RUBOCOP_SERVER_HOST', '127.0.0.1')
40
40
  port = ENV.fetch('RUBOCOP_SERVER_PORT', 0)
@@ -42,6 +42,16 @@ module RuboCop
42
42
  Server::Core.new.start(host, port, detach: @detach)
43
43
  end
44
44
  end
45
+
46
+ private
47
+
48
+ def write_version_file
49
+ Cache.write_version_file(
50
+ Cache.restart_key(
51
+ args_config_file_path: self.class.args_config_file_path
52
+ )
53
+ )
54
+ end
45
55
  end
46
56
  end
47
57
  end
@@ -42,11 +42,13 @@ module RuboCop
42
42
  # Support Windows: Backslashes from command-line -> forward slashes
43
43
  base_dir = base_dir.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
44
44
  all_files = find_files(base_dir, File::FNM_DOTMATCH)
45
- # use file.include? for performance optimization
46
- hidden_files = all_files.select { |file| file.include?(HIDDEN_PATH_SUBSTRING) }.sort
47
45
  base_dir_config = @config_store.for(base_dir)
48
46
 
49
- target_files = all_files.select { |file| to_inspect?(file, hidden_files, base_dir_config) }
47
+ target_files = if hidden_path?(base_dir)
48
+ all_files.select { |file| ruby_file?(file) }
49
+ else
50
+ all_files.select { |file| to_inspect?(file, base_dir_config) }
51
+ end
50
52
 
51
53
  target_files.sort_by!(&order)
52
54
  end
@@ -70,18 +72,20 @@ module RuboCop
70
72
 
71
73
  private
72
74
 
73
- def to_inspect?(file, hidden_files, base_dir_config)
75
+ def to_inspect?(file, base_dir_config)
74
76
  return false if base_dir_config.file_to_exclude?(file)
75
- return true if !hidden_files.bsearch do |hidden_file|
76
- file <=> hidden_file
77
- end && ruby_file?(file)
77
+ return true if !hidden_path?(file) && ruby_file?(file)
78
78
 
79
79
  base_dir_config.file_to_include?(file)
80
80
  end
81
81
 
82
+ def hidden_path?(path)
83
+ path.include?(HIDDEN_PATH_SUBSTRING)
84
+ end
85
+
82
86
  def wanted_dir_patterns(base_dir, exclude_pattern, flags)
83
87
  # Escape glob characters in base_dir to avoid unwanted behavior.
84
- base_dir = base_dir.gsub(/[\\\{\}\[\]\*\?]/) do |reserved_glob_character|
88
+ base_dir = base_dir.gsub(/[\\{}\[\]*?]/) do |reserved_glob_character|
85
89
  "\\#{reserved_glob_character}"
86
90
  end
87
91
 
@@ -127,6 +131,7 @@ module RuboCop
127
131
  if mode == :only_recognized_file_types || force_exclusion?
128
132
  files.select! { |file| included_file?(file) }
129
133
  end
134
+ files.reject! { |file| FileTest.directory?(file) }
130
135
 
131
136
  force_exclusion? ? without_excluded(files) : files
132
137
  end
@@ -174,7 +179,7 @@ module RuboCop
174
179
  end
175
180
 
176
181
  def ruby_executable?(file)
177
- return false unless File.extname(file).empty? && File.exist?(file)
182
+ return false if !File.extname(file).empty? || !File.exist?(file) || File.empty?(file)
178
183
 
179
184
  first_line = File.open(file, &:readline)
180
185
  /#!.*(#{ruby_interpreters(file).join('|')})/.match?(first_line)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  # The kind of Ruby that code inspected by RuboCop is written in.
5
5
  # @api private
6
6
  class TargetRuby
7
- KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4].freeze
7
+ KNOWN_RUBIES = [2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, 4.0].freeze
8
8
  DEFAULT_VERSION = 2.7
9
9
 
10
10
  OBSOLETE_RUBIES = {
@@ -34,6 +34,20 @@ module RuboCop
34
34
  end
35
35
  end
36
36
 
37
+ # The target ruby version may be configured by setting the
38
+ # `RUBOCOP_TARGET_RUBY_VERSION` environment variable.
39
+ class RuboCopEnvVar < Source
40
+ def name
41
+ '`RUBOCOP_TARGET_RUBY_VERSION` environment variable'
42
+ end
43
+
44
+ private
45
+
46
+ def find_version
47
+ ENV.fetch('RUBOCOP_TARGET_RUBY_VERSION', nil)&.to_f
48
+ end
49
+ end
50
+
37
51
  # The target ruby version may be configured in RuboCop's config.
38
52
  # @api private
39
53
  class RuboCopConfig < Source
@@ -96,8 +110,17 @@ module RuboCop
96
110
  end
97
111
 
98
112
  def version_from_gemspec_file(file)
113
+ # When using parser_prism, we need to use a Ruby version that Prism supports (3.3+)
114
+ # for parsing the gemspec file. This doesn't affect the detected Ruby version,
115
+ # it's just for the parsing step.
116
+ ruby_version_for_parsing = if @config.parser_engine == :parser_prism
117
+ 3.3
118
+ else
119
+ DEFAULT_VERSION
120
+ end
121
+
99
122
  processed_source = ProcessedSource.from_file(
100
- file, DEFAULT_VERSION, parser_engine: @config.parser_engine
123
+ file, ruby_version_for_parsing, parser_engine: @config.parser_engine
101
124
  )
102
125
  return unless processed_source.valid_syntax?
103
126
 
@@ -246,6 +269,7 @@ module RuboCop
246
269
  end
247
270
 
248
271
  SOURCES = [
272
+ RuboCopEnvVar,
249
273
  RuboCopConfig,
250
274
  GemspecFile,
251
275
  RubyVersionFile,
@@ -273,7 +297,7 @@ module RuboCop
273
297
 
274
298
  def rubocop_version_with_support
275
299
  if supported?
276
- RuboCop::Version.version
300
+ RuboCop::Version::STRING
277
301
  else
278
302
  OBSOLETE_RUBIES[version]
279
303
  end