rubocop 1.48.1 → 1.62.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 (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
@@ -224,6 +224,11 @@ changed_parameters:
224
224
  - AllowedMethods
225
225
  - AllowedPatterns
226
226
  severity: warning
227
+ - cops: Style/ArgumentsForwarding
228
+ parameters: AllowOnlyRestArgument
229
+ reason: "`AllowOnlyRestArgument` has no effect with TargetRubyVersion >= 3.2."
230
+ severity: warning
231
+ minimum_ruby_version: 3.2
227
232
 
228
233
  # Enforced styles that have been removed or replaced
229
234
  changed_enforced_styles:
@@ -10,13 +10,17 @@ module RuboCop
10
10
 
11
11
  AUTO_GENERATED_FILE = '.rubocop_todo.yml'
12
12
  YAML_OPTIONAL_DOC_START = /\A---(\s+#|\s*\z)/.freeze
13
+ PLACEHOLDER = '###rubocop:inherit_here'
13
14
 
14
15
  PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop'
15
16
  PHASE_2 = 'Phase 2 of 2: run all cops'
16
17
 
17
18
  PHASE_1_OVERRIDDEN = '(skipped because the default Layout/LineLength:Max is overridden)'
18
19
  PHASE_1_DISABLED = '(skipped because Layout/LineLength is disabled)'
19
- PHASE_1_SKIPPED = '(skipped because a list of cops is passed to the `--only` flag)'
20
+ PHASE_1_SKIPPED_ONLY_COPS =
21
+ '(skipped because a list of cops is passed to the `--only` flag)'
22
+ PHASE_1_SKIPPED_ONLY_EXCLUDE =
23
+ '(skipped because only excludes will be generated due to `--auto-gen-only-exclude` flag)'
20
24
 
21
25
  def run
22
26
  add_formatter
@@ -28,12 +32,14 @@ module RuboCop
28
32
  private
29
33
 
30
34
  def maybe_run_line_length_cop
31
- if !line_length_enabled?(@config_store.for_pwd)
35
+ if only_exclude?
36
+ skip_line_length_cop(PHASE_1_SKIPPED_ONLY_EXCLUDE)
37
+ elsif !line_length_enabled?(@config_store.for_pwd)
32
38
  skip_line_length_cop(PHASE_1_DISABLED)
33
39
  elsif !same_max_line_length?(@config_store.for_pwd, ConfigLoader.default_configuration)
34
40
  skip_line_length_cop(PHASE_1_OVERRIDDEN)
35
41
  elsif options_has_only_flag?
36
- skip_line_length_cop(PHASE_1_SKIPPED)
42
+ skip_line_length_cop(PHASE_1_SKIPPED_ONLY_COPS)
37
43
  else
38
44
  run_line_length_cop
39
45
  end
@@ -64,6 +70,10 @@ module RuboCop
64
70
  @options[:only]
65
71
  end
66
72
 
73
+ def only_exclude?
74
+ @options[:auto_gen_only_exclude]
75
+ end
76
+
67
77
  # Do an initial run with only Layout/LineLength so that cops that
68
78
  # depend on Layout/LineLength:Max get the correct value for that
69
79
  # parameter.
@@ -125,15 +135,19 @@ module RuboCop
125
135
 
126
136
  def existing_configuration(config_file)
127
137
  File.read(config_file, encoding: Encoding::UTF_8)
128
- .sub(/^inherit_from: *[^\n]+/, '')
129
- .sub(/^inherit_from: *(\n *- *[^\n]+)+/, '')
138
+ .sub(/^inherit_from: *[^\n]+/, PLACEHOLDER)
139
+ .sub(/^inherit_from: *(\n *- *[^\n]+)+/, PLACEHOLDER)
130
140
  end
131
141
 
132
142
  def write_config_file(file_name, file_string, rubocop_yml_contents)
133
143
  lines = /\S/.match?(rubocop_yml_contents) ? rubocop_yml_contents.split("\n", -1) : []
134
- doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1
135
- lines.insert(doc_start_index + 1, "inherit_from:#{file_string}\n")
136
- File.write(file_name, lines.join("\n"))
144
+ unless rubocop_yml_contents&.include?(PLACEHOLDER)
145
+ doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1
146
+ lines.insert(doc_start_index + 1, PLACEHOLDER)
147
+ end
148
+ File.write(file_name, lines.join("\n")
149
+ .sub(/#{PLACEHOLDER}\n*/o, "inherit_from:#{file_string}\n\n")
150
+ .sub(/\n\n+\Z/, "\n"))
137
151
  end
138
152
 
139
153
  def relative_path_to_todo_from_options_config
@@ -76,13 +76,18 @@ module RuboCop
76
76
  warn <<~WARNING
77
77
  Errors are usually caused by RuboCop bugs.
78
78
  Please, report your problems to RuboCop's issue tracker.
79
- #{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}
80
-
79
+ #{bug_tracker_uri}
81
80
  Mention the following information in the issue report:
82
81
  #{RuboCop::Version.version(debug: true)}
83
82
  WARNING
84
83
  end
85
84
 
85
+ def bug_tracker_uri
86
+ return unless Gem.loaded_specs.key?('rubocop')
87
+
88
+ "#{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}\n"
89
+ end
90
+
86
91
  def maybe_print_corrected_source
87
92
  # Integration tools (like RubyMine) expect to have only the JSON result
88
93
  # when specifying JSON format. Similar HTML and JUnit are targeted as well.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../lsp/server'
4
+
5
+ module RuboCop
6
+ class CLI
7
+ module Command
8
+ # Start Language Server Protocol of RuboCop.
9
+ # @api private
10
+ class LSP < Base
11
+ self.command_name = :lsp
12
+
13
+ def run
14
+ RuboCop::LSP::Server.new(@config_store).start
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/rubocop/cli.rb CHANGED
@@ -11,8 +11,8 @@ module RuboCop
11
11
  STATUS_ERROR = 2
12
12
  STATUS_INTERRUPTED = Signal.list['INT'] + 128
13
13
  DEFAULT_PARALLEL_OPTIONS = %i[
14
- color debug display_style_guide display_time display_only_fail_level_offenses
15
- display_only_failed except extra_details fail_level fix_layout format
14
+ color config debug display_style_guide display_time display_only_fail_level_offenses
15
+ display_only_failed editor_mode except extra_details fail_level fix_layout format
16
16
  ignore_disable_comments lint only only_guide_cops require safe
17
17
  autocorrect safe_autocorrect autocorrect_all
18
18
  ].freeze
@@ -87,20 +87,20 @@ module RuboCop
87
87
 
88
88
  tmp_dir = File.join(ConfigFinder.project_root, 'tmp')
89
89
  FileUtils.mkdir_p(tmp_dir)
90
+ cpu_profile_file = File.join(tmp_dir, 'rubocop-stackprof.dump')
90
91
  status = nil
91
92
 
92
- StackProf.run(out: File.join(tmp_dir, 'rubocop-stackprof.dump')) do
93
+ StackProf.run(out: cpu_profile_file) do
93
94
  status = yield
94
95
  end
95
- puts 'Profile report generated'
96
+ puts "Profile report generated at #{cpu_profile_file}"
96
97
 
97
98
  if with_memory
98
99
  puts 'Building memory report...'
99
100
  report = MemoryProfiler.stop
100
- report.pretty_print(
101
- to_file: File.join(tmp_dir, 'rubocop-memory_profiler.txt'),
102
- scale_bytes: true
103
- )
101
+ memory_profile_file = File.join(tmp_dir, 'rubocop-memory_profiler.txt')
102
+ report.pretty_print(to_file: memory_profile_file, scale_bytes: true)
103
+ puts "Memory report generated at #{memory_profile_file}"
104
104
  end
105
105
  status
106
106
  end
@@ -151,6 +151,7 @@ module RuboCop
151
151
 
152
152
  def act_on_options
153
153
  set_options_to_config_loader
154
+ handle_editor_mode
154
155
 
155
156
  @config_store.options_config = @options[:config] if @options[:config]
156
157
  @config_store.force_default_config! if @options[:force_default_config]
@@ -174,14 +175,21 @@ module RuboCop
174
175
  ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops]
175
176
  end
176
177
 
178
+ def handle_editor_mode
179
+ RuboCop::LSP.enable if @options[:editor_mode]
180
+ end
181
+
182
+ # rubocop:disable Metrics/CyclomaticComplexity
177
183
  def handle_exiting_options
178
184
  return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o }
179
185
 
180
186
  run_command(:version) if @options[:version] || @options[:verbose_version]
181
187
  run_command(:show_cops) if @options[:show_cops]
182
188
  run_command(:show_docs_url) if @options[:show_docs_url]
189
+ run_command(:lsp) if @options[:lsp]
183
190
  raise Finished
184
191
  end
192
+ # rubocop:enable Metrics/CyclomaticComplexity
185
193
 
186
194
  def apply_default_formatter
187
195
  # This must be done after the options have already been processed,
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
-
5
3
  # FIXME: Moving Rails department code to RuboCop Rails will remove
6
4
  # the following rubocop:disable comment.
7
5
  # rubocop:disable Metrics/ClassLength
@@ -29,7 +27,7 @@ module RuboCop
29
27
  end
30
28
 
31
29
  # rubocop:disable Metrics/AbcSize
32
- def initialize(hash = {}, loaded_path = nil)
30
+ def initialize(hash = RuboCop::ConfigLoader.default_configuration, loaded_path = nil)
33
31
  @loaded_path = loaded_path
34
32
  @for_cop = Hash.new do |h, cop|
35
33
  cop_name = cop.respond_to?(:cop_name) ? cop.cop_name : cop
@@ -246,6 +244,10 @@ module RuboCop
246
244
  end
247
245
  end
248
246
 
247
+ def parser_engine
248
+ @parser_engine ||= for_all_cops.fetch('ParserEngine', :parser_whitequark).to_sym
249
+ end
250
+
249
251
  def target_rails_version
250
252
  @target_rails_version ||=
251
253
  if for_all_cops['TargetRailsVersion']
@@ -284,6 +286,10 @@ module RuboCop
284
286
  end
285
287
  end
286
288
 
289
+ def inspect # :nodoc:
290
+ "#<#{self.class.name}:#{object_id} @loaded_path=#{loaded_path}>"
291
+ end
292
+
287
293
  private
288
294
 
289
295
  def target_rails_version_from_bundler_lock_file
@@ -17,8 +17,8 @@ module RuboCop
17
17
  attr_writer :project_root
18
18
 
19
19
  def find_config_path(target_dir)
20
- find_project_dotfile(target_dir) || find_user_dotfile || find_user_xdg_config ||
21
- DEFAULT_FILE
20
+ find_project_dotfile(target_dir) || find_project_root_dot_config ||
21
+ find_user_dotfile || find_user_xdg_config || DEFAULT_FILE
22
22
  end
23
23
 
24
24
  # Returns the path RuboCop inferred as the root of the project. No file
@@ -41,19 +41,29 @@ module RuboCop
41
41
  find_file_upwards(DOTFILE, target_dir, project_root)
42
42
  end
43
43
 
44
+ def find_project_root_dot_config
45
+ return unless project_root
46
+
47
+ dotfile = File.join(project_root, '.config', DOTFILE)
48
+ return dotfile if File.exist?(dotfile)
49
+
50
+ xdg_config = File.join(project_root, '.config', 'rubocop', XDG_CONFIG)
51
+ xdg_config if File.exist?(xdg_config)
52
+ end
53
+
44
54
  def find_user_dotfile
45
55
  return unless ENV.key?('HOME')
46
56
 
47
57
  file = File.join(Dir.home, DOTFILE)
48
58
 
49
- return file if File.exist?(file)
59
+ file if File.exist?(file)
50
60
  end
51
61
 
52
62
  def find_user_xdg_config
53
63
  xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config'))
54
64
  xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG)
55
65
 
56
- return xdg_config if File.exist?(xdg_config)
66
+ xdg_config if File.exist?(xdg_config)
57
67
  end
58
68
 
59
69
  def expand_path(path)
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'erb'
4
- require 'pathname'
5
4
  require 'yaml'
6
5
  require_relative 'config_finder'
7
6
 
@@ -23,6 +22,14 @@ module RuboCop
23
22
  class << self
24
23
  include FileFinder
25
24
 
25
+ PENDING_BANNER = <<~BANNER
26
+ The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
27
+
28
+ Please also note that you can opt-in to new cops by default by adding this to your config:
29
+ AllCops:
30
+ NewCops: enable
31
+ BANNER
32
+
26
33
  attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops,
27
34
  :ignore_unrecognized_cops
28
35
  attr_writer :default_configuration
@@ -165,14 +172,6 @@ module RuboCop
165
172
  ConfigFinder.project_root
166
173
  end
167
174
 
168
- PENDING_BANNER = <<~BANNER
169
- The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file.
170
-
171
- Please also note that you can opt-in to new cops by default by adding this to your config:
172
- AllCops:
173
- NewCops: enable
174
- BANNER
175
-
176
175
  def warn_on_pending_cops(pending_cops)
177
176
  warn Rainbow(PENDING_BANNER).yellow
178
177
 
@@ -33,7 +33,7 @@ module RuboCop
33
33
  inherit_mode: determine_inherit_mode(hash, k))
34
34
  end
35
35
  hash[k] = v
36
- fix_include_paths(base_config.loaded_path, hash, k, v) if v.key?('Include')
36
+ fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include')
37
37
  end
38
38
  end
39
39
  end
@@ -42,12 +42,13 @@ module RuboCop
42
42
  # base configuration are relative to the directory where the base configuration file is. For the
43
43
  # derived configuration, we need to make those paths relative to where the derived configuration
44
44
  # file is.
45
- def fix_include_paths(base_config_path, hash, key, value)
45
+ def fix_include_paths(base_config_path, hash, path, key, value)
46
46
  return unless File.basename(base_config_path).start_with?('.rubocop')
47
47
 
48
48
  base_dir = File.dirname(base_config_path)
49
+ derived_dir = File.dirname(path)
49
50
  hash[key]['Include'] = value['Include'].map do |include_path|
50
- PathUtil.relative_path(File.join(base_dir, include_path), Dir.pwd)
51
+ PathUtil.relative_path(File.join(base_dir, include_path), derived_dir)
51
52
  end
52
53
  end
53
54
 
@@ -19,7 +19,7 @@ module RuboCop
19
19
  end
20
20
 
21
21
  def violated?
22
- config[cop]&.key?(parameter)
22
+ applies_to_current_ruby_version? && config[cop]&.key?(parameter)
23
23
  end
24
24
 
25
25
  def warning?
@@ -28,6 +28,14 @@ module RuboCop
28
28
 
29
29
  private
30
30
 
31
+ def applies_to_current_ruby_version?
32
+ minimum_ruby_version = metadata['minimum_ruby_version']
33
+
34
+ return true unless minimum_ruby_version
35
+
36
+ config.target_ruby_version >= minimum_ruby_version
37
+ end
38
+
31
39
  def alternative
32
40
  metadata['alternative']
33
41
  end
@@ -15,6 +15,8 @@ module RuboCop
15
15
  'changed_parameters' => ChangedParameter,
16
16
  'changed_enforced_styles' => ChangedEnforcedStyles
17
17
  }.freeze
18
+ LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant
19
+ private_constant :LOAD_RULES_CACHE
18
20
 
19
21
  attr_reader :rules, :warnings
20
22
 
@@ -48,16 +50,17 @@ module RuboCop
48
50
  # Default rules for obsoletions are in config/obsoletion.yml
49
51
  # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename`
50
52
  def load_rules # rubocop:disable Metrics/AbcSize
51
- rules = self.class.files.each_with_object({}) do |filename, hash|
52
- hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
53
- case first
54
- when Hash
55
- first.merge(second)
56
- when Array
57
- first.concat(second)
53
+ rules = LOAD_RULES_CACHE[self.class.files] ||=
54
+ self.class.files.each_with_object({}) do |filename, hash|
55
+ hash.merge!(YAML.safe_load(File.read(filename))) do |_key, first, second|
56
+ case first
57
+ when Hash
58
+ first.merge(second)
59
+ when Array
60
+ first.concat(second)
61
+ end
58
62
  end
59
63
  end
60
- end
61
64
 
62
65
  cop_rules = rules.slice(*COP_RULE_CLASSES.keys)
63
66
  parameter_rules = rules.slice(*PARAMETER_RULE_CLASSES.keys)
@@ -68,11 +71,11 @@ module RuboCop
68
71
  # Cop rules are keyed by the name of the original cop
69
72
  def load_cop_rules(rules)
70
73
  rules.flat_map do |rule_type, data|
71
- data.map do |cop_name, configuration|
74
+ data.filter_map do |cop_name, configuration|
72
75
  next unless configuration # allow configurations to be disabled with `CopName: ~`
73
76
 
74
77
  COP_RULE_CLASSES[rule_type].new(@config, cop_name, configuration)
75
- end.compact
78
+ end
76
79
  end
77
80
  end
78
81
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
-
5
3
  module RuboCop
6
4
  # Handles validation of configuration, for example cop names, parameter
7
5
  # names, and Ruby versions.
@@ -20,6 +18,7 @@ module RuboCop
20
18
  # @api private
21
19
  CONFIG_CHECK_KEYS = %w[Enabled Safe SafeAutoCorrect AutoCorrect].to_set.freeze
22
20
  CONFIG_CHECK_DEPARTMENTS = %w[pending override_department].freeze
21
+ CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze
23
22
  private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS
24
23
 
25
24
  def_delegators :@config, :smart_loaded_path, :for_all_cops
@@ -250,23 +249,31 @@ module RuboCop
250
249
  end
251
250
  end
252
251
 
252
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
253
253
  def check_cop_config_value(hash, parent = nil)
254
254
  hash.each do |key, value|
255
255
  check_cop_config_value(value, key) if value.is_a?(Hash)
256
256
 
257
257
  next unless CONFIG_CHECK_KEYS.include?(key) && value.is_a?(String)
258
258
 
259
- next if key == 'Enabled' && CONFIG_CHECK_DEPARTMENTS.include?(value)
259
+ if key == 'Enabled' && !CONFIG_CHECK_DEPARTMENTS.include?(value)
260
+ supposed_values = 'a boolean'
261
+ elsif key == 'AutoCorrect' && !CONFIG_CHECK_AUTOCORRECTS.include?(value)
262
+ supposed_values = '`always`, `contextual`, `disabled`, or a boolean'
263
+ else
264
+ next
265
+ end
260
266
 
261
- raise ValidationError, msg_not_boolean(parent, key, value)
267
+ raise ValidationError, param_error_message(parent, key, value, supposed_values)
262
268
  end
263
269
  end
270
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
264
271
 
265
272
  # FIXME: Handling colors in exception messages like this is ugly.
266
- def msg_not_boolean(parent, key, value)
273
+ def param_error_message(parent, key, value, supposed_values)
267
274
  "#{Rainbow('').reset}" \
268
- "Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow} " \
269
- "is supposed to be a boolean and #{Rainbow(value).yellow} is not."
275
+ "Property #{Rainbow(key).yellow} of #{Rainbow(parent).yellow} cop " \
276
+ "is supposed to be #{supposed_values} and #{Rainbow(value).yellow} is not."
270
277
  end
271
278
  end
272
279
  end
@@ -32,10 +32,15 @@ module RuboCop
32
32
  # allow turning off autocorrect on a cop by cop basis
33
33
  return true unless cop_config
34
34
 
35
- return false if cop_config['AutoCorrect'] == false
35
+ # `false` is the same as `disabled` for backward compatibility.
36
+ return false if ['disabled', false].include?(cop_config['AutoCorrect'])
37
+
38
+ # When LSP is enabled, it is considered as editing source code,
39
+ # and autocorrection with `AutoCorrect: contextual` will not be performed.
40
+ return false if contextual_autocorrect? && LSP.enabled?
36
41
 
37
42
  # :safe_autocorrect is a derived option based on several command-line
38
- # arguments - see Rubocop::Options#add_autocorrection_options
43
+ # arguments - see RuboCop::Options#add_autocorrection_options
39
44
  return safe_autocorrect? if @options.fetch(:safe_autocorrect, false)
40
45
 
41
46
  true
@@ -43,18 +48,24 @@ module RuboCop
43
48
 
44
49
  private
45
50
 
46
- def disable_offense(range)
47
- heredoc_range = surrounding_heredoc(range)
48
- if heredoc_range
49
- disable_offense_before_and_after(range_by_lines(heredoc_range))
51
+ def disable_offense(offense_range)
52
+ range = surrounding_heredoc(offense_range) || surrounding_percent_array(offense_range)
53
+
54
+ if range
55
+ disable_offense_before_and_after(range_by_lines(range))
56
+ else
57
+ disable_offense_with_eol_or_surround_comment(offense_range)
58
+ end
59
+ end
60
+
61
+ def disable_offense_with_eol_or_surround_comment(range)
62
+ eol_comment = " # rubocop:todo #{cop_name}"
63
+ needed_line_length = (range.source_line + eol_comment).length
64
+
65
+ if needed_line_length <= max_line_length
66
+ disable_offense_at_end_of_line(range_of_first_line(range), eol_comment)
50
67
  else
51
- eol_comment = " # rubocop:todo #{cop_name}"
52
- needed_line_length = (range.source_line + eol_comment).length
53
- if needed_line_length <= max_line_length
54
- disable_offense_at_end_of_line(range_of_first_line(range), eol_comment)
55
- else
56
- disable_offense_before_and_after(range_by_lines(range))
57
- end
68
+ disable_offense_before_and_after(range_by_lines(range))
58
69
  end
59
70
  end
60
71
 
@@ -69,6 +80,18 @@ module RuboCop
69
80
  .find { |range| range.contains?(offense_range) }
70
81
  end
71
82
 
83
+ def surrounding_percent_array(offense_range)
84
+ return nil if offense_range.empty?
85
+
86
+ percent_array = processed_source.ast.each_descendant.select do |node|
87
+ node.array_type? && node.percent_literal?
88
+ end
89
+
90
+ percent_array.map(&:source_range).find do |range|
91
+ offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
92
+ end
93
+ end
94
+
72
95
  def range_of_first_line(range)
73
96
  begin_of_first_line = range.begin_pos - range.column
74
97
  end_of_first_line = begin_of_first_line + range.source_line.length
@@ -53,7 +53,7 @@ module RuboCop
53
53
  # List of cops that should not try to autocorrect at the same
54
54
  # time as this cop
55
55
  #
56
- # @return [Array<RuboCop::Cop::Cop>]
56
+ # @return [Array<RuboCop::Cop::Base>]
57
57
  #
58
58
  # @api public
59
59
  def self.autocorrect_incompatible_with
@@ -232,6 +232,10 @@ module RuboCop
232
232
  @config.target_ruby_version
233
233
  end
234
234
 
235
+ def parser_engine
236
+ @config.parser_engine
237
+ end
238
+
235
239
  def target_rails_version
236
240
  @config.target_rails_version
237
241
  end
@@ -254,7 +258,7 @@ module RuboCop
254
258
 
255
259
  # There should be very limited reasons for a Cop to do it's own parsing
256
260
  def parse(source, path = nil)
257
- ProcessedSource.new(source, target_ruby_version, path)
261
+ ProcessedSource.new(source, target_ruby_version, path, parser_engine: parser_engine)
258
262
  end
259
263
 
260
264
  # @api private
@@ -284,7 +288,7 @@ module RuboCop
284
288
  # @api private
285
289
  def self.callbacks_needed
286
290
  @callbacks_needed ||= public_instance_methods.select do |m|
287
- m.match?(/^on_|^after_/) &&
291
+ m.start_with?(/on_|after_/) &&
288
292
  !Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
289
293
  end
290
294
  end
@@ -305,6 +309,21 @@ module RuboCop
305
309
  @current_original = original
306
310
  end
307
311
 
312
+ # @api private
313
+ def always_autocorrect?
314
+ # `true` is the same as `'always'` for backward compatibility.
315
+ ['always', true].include?(cop_config.fetch('AutoCorrect', 'always'))
316
+ end
317
+
318
+ # @api private
319
+ def contextual_autocorrect?
320
+ cop_config.fetch('AutoCorrect', 'always') == 'contextual'
321
+ end
322
+
323
+ def inspect # :nodoc:
324
+ "#<#{self.class.name}:#{object_id} @config=#{@config} @options=#{@options}>"
325
+ end
326
+
308
327
  private
309
328
 
310
329
  ### Reserved for Cop::Cop
@@ -385,7 +404,7 @@ module RuboCop
385
404
  def use_corrector(range, corrector)
386
405
  if autocorrect?
387
406
  attempt_correction(range, corrector)
388
- elsif corrector && cop_config.fetch('AutoCorrect', true)
407
+ elsif corrector && (always_autocorrect? || (contextual_autocorrect? && !LSP.enabled?))
389
408
  :uncorrected
390
409
  else
391
410
  :unsupported
@@ -4,6 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Bundler
6
6
  # A Gem's requirements should be listed only once in a Gemfile.
7
+ #
7
8
  # @example
8
9
  # # bad
9
10
  # gem 'rubocop'