rubocop 1.59.0 → 1.68.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (352) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +69 -70
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +165 -24
  7. data/config/internal_affairs.yml +11 -0
  8. data/exe/rubocop +4 -3
  9. data/lib/rubocop/cached_data.rb +21 -5
  10. data/lib/rubocop/cli/command/auto_generate_config.rb +18 -10
  11. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  12. data/lib/rubocop/cli/command/lsp.rb +4 -4
  13. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  14. data/lib/rubocop/cli/command/version.rb +2 -2
  15. data/lib/rubocop/cli.rb +10 -1
  16. data/lib/rubocop/comment_config.rb +1 -1
  17. data/lib/rubocop/config.rb +41 -13
  18. data/lib/rubocop/config_finder.rb +12 -2
  19. data/lib/rubocop/config_loader.rb +15 -10
  20. data/lib/rubocop/config_loader_resolver.rb +13 -8
  21. data/lib/rubocop/config_obsoletion.rb +1 -1
  22. data/lib/rubocop/config_validator.rb +17 -9
  23. data/lib/rubocop/cop/autocorrect_logic.rb +28 -3
  24. data/lib/rubocop/cop/base.rb +73 -18
  25. data/lib/rubocop/cop/bundler/gem_version.rb +4 -5
  26. data/lib/rubocop/cop/cop.rb +30 -4
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  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/line_break_corrector.rb +2 -0
  31. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  32. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  33. data/lib/rubocop/cop/documentation.rb +32 -5
  34. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  35. data/lib/rubocop/cop/force.rb +12 -0
  36. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  37. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  38. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  39. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  40. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  41. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  42. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  43. data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
  44. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
  46. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  47. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  48. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  49. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  50. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  51. data/lib/rubocop/cop/internal_affairs.rb +17 -0
  52. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  53. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  54. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  55. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  56. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  57. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  58. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  59. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  60. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  61. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  62. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  63. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  64. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
  65. data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
  66. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  67. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -4
  68. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  69. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  70. data/lib/rubocop/cop/layout/indentation_width.rb +5 -6
  71. data/lib/rubocop/cop/layout/leading_comment_space.rb +56 -1
  72. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
  73. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  74. data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
  75. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
  76. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  77. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  78. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  79. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  80. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  81. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  82. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
  83. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  84. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  85. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  86. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  87. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  88. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -3
  89. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  90. data/lib/rubocop/cop/lint/debugger.rb +27 -6
  91. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  92. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  93. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  94. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  95. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
  96. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
  97. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  98. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  99. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  100. data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -8
  101. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  102. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  103. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  104. data/lib/rubocop/cop/lint/ensure_return.rb +1 -9
  105. data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
  106. data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
  107. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  108. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  109. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +23 -12
  110. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  111. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  112. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +5 -14
  113. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  114. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
  115. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -6
  116. data/lib/rubocop/cop/lint/loop.rb +6 -12
  117. data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
  118. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  119. data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
  120. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  121. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +7 -0
  122. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  123. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  124. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  125. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  126. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  127. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  128. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
  129. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  130. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
  131. data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
  132. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  133. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  134. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  135. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  136. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +9 -4
  137. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +107 -41
  138. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  139. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  140. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
  141. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  142. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  143. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
  144. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  145. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  146. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  147. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  148. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  149. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  150. data/lib/rubocop/cop/lint/useless_assignment.rb +19 -16
  151. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  152. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  153. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  154. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  155. data/lib/rubocop/cop/lint/void.rb +41 -9
  156. data/lib/rubocop/cop/metrics/block_length.rb +6 -5
  157. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  158. data/lib/rubocop/cop/metrics/class_length.rb +6 -5
  159. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
  160. data/lib/rubocop/cop/metrics/method_length.rb +6 -5
  161. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  162. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
  163. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  164. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  165. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  166. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  167. data/lib/rubocop/cop/mixin/check_line_breakable.rb +10 -0
  168. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  169. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  170. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  171. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  172. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -10
  173. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
  174. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  175. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  176. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  177. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  178. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  179. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  180. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  181. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  182. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  183. data/lib/rubocop/cop/naming/block_forwarding.rb +33 -6
  184. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  185. data/lib/rubocop/cop/naming/inclusive_language.rb +13 -5
  186. data/lib/rubocop/cop/naming/predicate_name.rb +55 -29
  187. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
  188. data/lib/rubocop/cop/offense.rb +4 -5
  189. data/lib/rubocop/cop/registry.rb +1 -1
  190. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  191. data/lib/rubocop/cop/security/open.rb +2 -2
  192. data/lib/rubocop/cop/style/access_modifier_declarations.rb +62 -2
  193. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  194. data/lib/rubocop/cop/style/alias.rb +2 -1
  195. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  196. data/lib/rubocop/cop/style/arguments_forwarding.rb +141 -24
  197. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  198. data/lib/rubocop/cop/style/block_delimiters.rb +31 -3
  199. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  200. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  201. data/lib/rubocop/cop/style/collection_compact.rb +19 -10
  202. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  203. data/lib/rubocop/cop/style/combinable_loops.rb +7 -0
  204. data/lib/rubocop/cop/style/commented_keyword.rb +12 -3
  205. data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
  206. data/lib/rubocop/cop/style/copyright.rb +31 -21
  207. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  208. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  209. data/lib/rubocop/cop/style/documentation.rb +24 -24
  210. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  211. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  212. data/lib/rubocop/cop/style/empty_else.rb +6 -5
  213. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  214. data/lib/rubocop/cop/style/empty_literal.rb +31 -22
  215. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  216. data/lib/rubocop/cop/style/eval_with_location.rb +16 -24
  217. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
  218. data/lib/rubocop/cop/style/file_read.rb +2 -5
  219. data/lib/rubocop/cop/style/file_write.rb +2 -5
  220. data/lib/rubocop/cop/style/for.rb +2 -0
  221. data/lib/rubocop/cop/style/format_string.rb +9 -9
  222. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  223. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  224. data/lib/rubocop/cop/style/guard_clause.rb +17 -2
  225. data/lib/rubocop/cop/style/hash_each_methods.rb +35 -8
  226. data/lib/rubocop/cop/style/hash_except.rb +8 -5
  227. data/lib/rubocop/cop/style/hash_syntax.rb +26 -4
  228. data/lib/rubocop/cop/style/identical_conditional_branches.rb +5 -2
  229. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  230. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  231. data/lib/rubocop/cop/style/if_with_semicolon.rb +49 -6
  232. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  233. data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
  234. data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
  235. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  236. data/lib/rubocop/cop/style/lambda.rb +1 -1
  237. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  238. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
  239. data/lib/rubocop/cop/style/map_into_array.rb +233 -0
  240. data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
  241. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  242. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +29 -11
  243. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  244. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
  245. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  246. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  247. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  248. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
  249. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  250. data/lib/rubocop/cop/style/multiple_comparison.rb +28 -47
  251. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  252. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  253. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  254. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  255. data/lib/rubocop/cop/style/numeric_predicate.rb +12 -4
  256. data/lib/rubocop/cop/style/object_then.rb +5 -3
  257. data/lib/rubocop/cop/style/one_line_conditional.rb +6 -2
  258. data/lib/rubocop/cop/style/operator_method_call.rb +25 -6
  259. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -9
  260. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  261. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
  262. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  263. data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
  264. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  265. data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
  266. data/lib/rubocop/cop/style/redundant_condition.rb +4 -4
  267. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
  268. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  269. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  270. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  271. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  272. data/lib/rubocop/cop/style/redundant_line_continuation.rb +40 -7
  273. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -13
  274. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  275. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
  276. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
  277. data/lib/rubocop/cop/style/redundant_return.rb +6 -0
  278. data/lib/rubocop/cop/style/require_order.rb +2 -2
  279. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -1
  280. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  281. data/lib/rubocop/cop/style/safe_navigation.rb +106 -52
  282. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  283. data/lib/rubocop/cop/style/sample.rb +1 -3
  284. data/lib/rubocop/cop/style/select_by_regexp.rb +9 -6
  285. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  286. data/lib/rubocop/cop/style/send.rb +4 -4
  287. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
  288. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  289. data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
  290. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  291. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  292. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  293. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  294. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  295. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  296. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  297. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  298. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  299. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  300. data/lib/rubocop/cop/team.rb +27 -3
  301. data/lib/rubocop/cop/util.rb +8 -2
  302. data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
  303. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  304. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  305. data/lib/rubocop/cop/variable_force/variable.rb +5 -1
  306. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
  307. data/lib/rubocop/cop/variable_force.rb +13 -1
  308. data/lib/rubocop/cops_documentation_generator.rb +96 -43
  309. data/lib/rubocop/core_ext/string.rb +2 -6
  310. data/lib/rubocop/directive_comment.rb +10 -8
  311. data/lib/rubocop/ext/regexp_node.rb +18 -35
  312. data/lib/rubocop/ext/regexp_parser.rb +4 -21
  313. data/lib/rubocop/file_finder.rb +9 -4
  314. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  315. data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -9
  316. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  317. data/lib/rubocop/formatter/html_formatter.rb +32 -10
  318. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  319. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  320. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  321. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  322. data/lib/rubocop/formatter.rb +1 -1
  323. data/lib/rubocop/lockfile.rb +58 -7
  324. data/lib/rubocop/lsp/logger.rb +1 -1
  325. data/lib/rubocop/lsp/routes.rb +12 -15
  326. data/lib/rubocop/lsp/runtime.rb +3 -1
  327. data/lib/rubocop/lsp/server.rb +6 -2
  328. data/lib/rubocop/lsp/severity.rb +1 -1
  329. data/lib/rubocop/lsp.rb +36 -0
  330. data/lib/rubocop/magic_comment.rb +1 -1
  331. data/lib/rubocop/options.rb +17 -12
  332. data/lib/rubocop/path_util.rb +6 -2
  333. data/lib/rubocop/rake_task.rb +1 -1
  334. data/lib/rubocop/remote_config.rb +5 -1
  335. data/lib/rubocop/result_cache.rb +2 -8
  336. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  337. data/lib/rubocop/rspec/expect_offense.rb +17 -8
  338. data/lib/rubocop/rspec/shared_contexts.rb +75 -18
  339. data/lib/rubocop/rspec/support.rb +3 -0
  340. data/lib/rubocop/runner.rb +31 -9
  341. data/lib/rubocop/server/cache.rb +16 -2
  342. data/lib/rubocop/server/client_command/exec.rb +2 -3
  343. data/lib/rubocop/server/client_command/start.rb +1 -1
  344. data/lib/rubocop/server/core.rb +5 -0
  345. data/lib/rubocop/server/server_command/exec.rb +0 -1
  346. data/lib/rubocop/target_finder.rb +84 -78
  347. data/lib/rubocop/target_ruby.rb +87 -81
  348. data/lib/rubocop/version.rb +45 -9
  349. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  350. data/lib/rubocop.rb +21 -1
  351. metadata +33 -35
  352. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -9,6 +9,7 @@ module RuboCop
9
9
  class HTMLFormatter < BaseFormatter
10
10
  ELLIPSES = '<span class="extra-code">...</span>'
11
11
  TEMPLATE_PATH = File.expand_path('../../../assets/output.html.erb', __dir__)
12
+ CSS_PATH = File.expand_path('../../../assets/output.css.erb', __dir__)
12
13
 
13
14
  Color = Struct.new(:red, :green, :blue, :alpha) do
14
15
  def to_s
@@ -50,8 +51,10 @@ module RuboCop
50
51
  context = ERBContext.new(files, summary)
51
52
 
52
53
  template = File.read(TEMPLATE_PATH, encoding: Encoding::UTF_8)
53
- erb = ERB.new(template, trim_mode: '-')
54
- html = erb.result(context.binding)
54
+ erb = ERB.new(template)
55
+ html = erb.result(context.binding).lines.map do |line|
56
+ line.match?(/\A\s*\z/) ? "\n" : line
57
+ end.join
55
58
 
56
59
  output.write html
57
60
  end
@@ -61,14 +64,6 @@ module RuboCop
61
64
  include PathUtil
62
65
  include TextUtil
63
66
 
64
- SEVERITY_COLORS = {
65
- refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
66
- convention: Color.new(0xED, 0x9C, 0x28, 1.0),
67
- warning: Color.new(0x96, 0x28, 0xEF, 1.0),
68
- error: Color.new(0xD2, 0x32, 0x2D, 1.0),
69
- fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
70
- }.freeze
71
-
72
67
  LOGO_IMAGE_PATH = File.expand_path('../../../assets/logo.png', __dir__)
73
68
 
74
69
  attr_reader :files, :summary
@@ -127,6 +122,33 @@ module RuboCop
127
122
  # https://github.com/ruby/base64/blob/v0.1.1/lib/base64.rb#L27-L40
128
123
  [image].pack('m')
129
124
  end
125
+
126
+ def render_css
127
+ context = CSSContext.new
128
+ template = File.read(CSS_PATH, encoding: Encoding::UTF_8)
129
+ erb = ERB.new(template, trim_mode: '-')
130
+ erb.result(context.binding).lines.map do |line|
131
+ line == "\n" ? line : " #{line}"
132
+ end.join
133
+ end
134
+ end
135
+
136
+ # This class provides helper methods used in the ERB CSS template.
137
+ class CSSContext
138
+ SEVERITY_COLORS = {
139
+ refactor: Color.new(0xED, 0x9C, 0x28, 1.0),
140
+ convention: Color.new(0xED, 0x9C, 0x28, 1.0),
141
+ warning: Color.new(0x96, 0x28, 0xEF, 1.0),
142
+ error: Color.new(0xD2, 0x32, 0x2D, 1.0),
143
+ fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
144
+ }.freeze
145
+
146
+ # Make Kernel#binding public.
147
+ # rubocop:disable Lint/UselessMethodDefinition
148
+ def binding
149
+ super
150
+ end
151
+ # rubocop:enable Lint/UselessMethodDefinition
130
152
  end
131
153
  end
132
154
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require 'pathname'
5
4
 
6
5
  module RuboCop
7
6
  module Formatter
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rexml/document'
4
-
5
3
  #
6
4
  # This code is based on https://github.com/mikian/rubocop-junit-formatter.
7
5
  #
@@ -15,13 +13,18 @@ module RuboCop
15
13
  module Formatter
16
14
  # This formatter formats the report data in JUnit format.
17
15
  class JUnitFormatter < BaseFormatter
16
+ ESCAPE_MAP = {
17
+ '"' => '&quot;',
18
+ "'" => '&apos;',
19
+ '<' => '&lt;',
20
+ '>' => '&gt;',
21
+ '&' => '&amp;'
22
+ }.freeze
23
+
18
24
  def initialize(output, options = {})
19
25
  super
20
26
 
21
- @document = REXML::Document.new.tap { |document| document << REXML::XMLDecl.new }
22
- testsuites = REXML::Element.new('testsuites', @document)
23
- testsuite = REXML::Element.new('testsuite', testsuites)
24
- @testsuite = testsuite.tap { |element| element.add_attributes('name' => 'rubocop') }
27
+ @test_case_elements = []
25
28
 
26
29
  reset_count
27
30
  end
@@ -44,6 +47,33 @@ module RuboCop
44
47
  end
45
48
  end
46
49
 
50
+ # rubocop:disable Layout/LineLength,Metrics/AbcSize,Metrics/MethodLength
51
+ def finished(_inspected_files)
52
+ output.puts %(<?xml version='1.0'?>)
53
+ output.puts %(<testsuites>)
54
+ output.puts %( <testsuite name='rubocop' tests='#{@inspected_file_count}' failures='#{@offense_count}'>)
55
+
56
+ @test_case_elements.each do |test_case_element|
57
+ if test_case_element.failures.empty?
58
+ output.puts %( <testcase classname='#{xml_escape test_case_element.classname}' name='#{test_case_element.name}'/>)
59
+ else
60
+ output.puts %( <testcase classname='#{xml_escape test_case_element.classname}' name='#{test_case_element.name}'>)
61
+ test_case_element.failures.each do |failure_element|
62
+ output.puts %( <failure type='#{failure_element.type}' message='#{xml_escape failure_element.message}'>)
63
+ output.puts %( #{xml_escape failure_element.text})
64
+ output.puts %( </failure>)
65
+ end
66
+ output.puts %( </testcase>)
67
+ end
68
+ end
69
+
70
+ output.puts %( </testsuite>)
71
+ output.puts %(</testsuites>)
72
+ end
73
+ # rubocop:enable Layout/LineLength,Metrics/AbcSize,Metrics/MethodLength
74
+
75
+ private
76
+
47
77
  def relevant_for_output?(options, target_offenses)
48
78
  !options[:display_only_failed] || target_offenses.any?
49
79
  end
@@ -53,11 +83,11 @@ module RuboCop
53
83
  end
54
84
 
55
85
  def add_testcase_element_to_testsuite_element(file, target_offenses, cop)
56
- REXML::Element.new('testcase', @testsuite).tap do |testcase|
57
- testcase.attributes['classname'] = classname_attribute_value(file)
58
- testcase.attributes['name'] = cop.cop_name
59
-
60
- add_failure_to(testcase, target_offenses, cop.cop_name)
86
+ @test_case_elements << TestCaseElement.new(
87
+ classname: classname_attribute_value(file),
88
+ name: cop.cop_name
89
+ ).tap do |test_case_element|
90
+ add_failure_to(test_case_element, target_offenses, cop.cop_name)
61
91
  end
62
92
  end
63
93
 
@@ -68,13 +98,6 @@ module RuboCop
68
98
  @classname_attribute_value_cache[file]
69
99
  end
70
100
 
71
- def finished(_inspected_files)
72
- @testsuite.add_attributes('tests' => @inspected_file_count, 'failures' => @offense_count)
73
- @document.write(output, 2)
74
- end
75
-
76
- private
77
-
78
101
  def reset_count
79
102
  @inspected_file_count = 0
80
103
  @offense_count = 0
@@ -84,11 +107,35 @@ module RuboCop
84
107
  # One failure per offense. Zero failures is a passing test case,
85
108
  # for most surefire/nUnit parsers.
86
109
  offenses.each do |offense|
87
- REXML::Element.new('failure', testcase).tap do |failure|
88
- failure.attributes['type'] = cop_name
89
- failure.attributes['message'] = offense.message
90
- failure.add_text(offense.location.to_s)
91
- end
110
+ testcase.failures << FailureElement.new(
111
+ type: cop_name,
112
+ message: offense.message,
113
+ text: offense.location.to_s
114
+ )
115
+ end
116
+ end
117
+
118
+ def xml_escape(string)
119
+ string.gsub(Regexp.union(ESCAPE_MAP.keys), ESCAPE_MAP)
120
+ end
121
+
122
+ class TestCaseElement # :nodoc:
123
+ attr_reader :classname, :name, :failures
124
+
125
+ def initialize(classname:, name:)
126
+ @classname = classname
127
+ @name = name
128
+ @failures = []
129
+ end
130
+ end
131
+
132
+ class FailureElement # :nodoc:
133
+ attr_reader :type, :message, :text
134
+
135
+ def initialize(type:, message:, text:)
136
+ @type = type
137
+ @message = message
138
+ @text = text
92
139
  end
93
140
  end
94
141
  end
@@ -61,8 +61,7 @@ module RuboCop
61
61
 
62
62
  column_width = total_count.to_s.length + 2
63
63
  per_cop_counts.each do |cop_name, count|
64
- output.puts "#{count.to_s.ljust(column_width)}#{cop_name}" \
65
- "#{@style_guide_links[cop_name]}\n"
64
+ output.puts "#{count.to_s.ljust(column_width)}#{cop_information(cop_name)}"
66
65
  end
67
66
  output.puts '--'
68
67
  output.puts "#{total_count} Total in #{offending_files_count} files"
@@ -78,6 +77,17 @@ module RuboCop
78
77
  def total_offense_count(offense_counts)
79
78
  offense_counts.values.sum
80
79
  end
80
+
81
+ def cop_information(cop_name)
82
+ cop = RuboCop::Cop::Registry.global.find_by_cop_name(cop_name).new
83
+
84
+ if cop.correctable?
85
+ safety = cop.safe_autocorrect? ? 'Safe' : 'Unsafe'
86
+ correctable = Rainbow(" [#{safety} Correctable]").yellow
87
+ end
88
+
89
+ "#{cop_name}#{correctable}#{@style_guide_links[cop_name]}"
90
+ end
81
91
  end
82
92
  end
83
93
  end
@@ -53,14 +53,10 @@ module RuboCop
53
53
  message: message(offense)
54
54
  )
55
55
 
56
- begin
57
- return unless valid_line?(offense)
56
+ return unless valid_line?(offense)
58
57
 
59
- report_line(offense.location)
60
- report_highlighted_area(offense.highlighted_area)
61
- rescue IndexError
62
- # range is not on a valid line; perhaps the source file is empty
63
- end
58
+ report_line(offense.location)
59
+ report_highlighted_area(offense.highlighted_area)
64
60
  end
65
61
 
66
62
  def annotate_message(msg)
@@ -14,7 +14,7 @@ module RuboCop
14
14
  require_relative 'formatter/emacs_style_formatter'
15
15
  require_relative 'formatter/file_list_formatter'
16
16
  require_relative 'formatter/fuubar_style_formatter'
17
- require_relative 'formatter/git_hub_actions_formatter'
17
+ require_relative 'formatter/github_actions_formatter'
18
18
  require_relative 'formatter/html_formatter'
19
19
  require_relative 'formatter/json_formatter'
20
20
  require_relative 'formatter/junit_formatter'
@@ -1,18 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ begin
4
+ # We might not be running with `bundle exec`, so we need to pull in Bundler ourselves,
5
+ # in order to use `Bundler::LockfileParser`.
6
+ require 'bundler'
7
+ rescue LoadError
8
+ nil
9
+ end
10
+
3
11
  module RuboCop
4
12
  # Encapsulation of a lockfile for use when checking for gems.
5
13
  # Does not actually resolve gems, just parses the lockfile.
6
14
  # @api private
7
15
  class Lockfile
8
- # Gems that the bundle depends on
16
+ # @param [String, Pathname, nil] lockfile_path
17
+ def initialize(lockfile_path = nil)
18
+ lockfile_path ||= begin
19
+ ::Bundler.default_lockfile if use_bundler_lock_parser?
20
+ rescue ::Bundler::GemfileNotFound
21
+ nil # We might not be a folder with a Gemfile, but that's okay.
22
+ end
23
+
24
+ @lockfile_path = lockfile_path
25
+ end
26
+
27
+ # Gems that the bundle directly depends on.
28
+ # @return [Array<Bundler::Dependency>, nil]
9
29
  def dependencies
10
30
  return [] unless parser
11
31
 
12
32
  parser.dependencies.values
13
33
  end
14
34
 
15
- # All activated gems, including transitive dependencies
35
+ # All activated gems, including transitive dependencies.
36
+ # @return [Array<Bundler::Dependency>, nil]
16
37
  def gems
17
38
  return [] unless parser
18
39
 
@@ -21,20 +42,50 @@ module RuboCop
21
42
  parser.dependencies.values.concat(parser.specs.flat_map(&:dependencies))
22
43
  end
23
44
 
45
+ # Returns the locked versions of gems from this lockfile.
46
+ # @param [Boolean] include_transitive_dependencies: When false, only direct dependencies
47
+ # are returned, i.e. those listed explicitly in the `Gemfile`.
48
+ # @returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems' names.
49
+ def gem_versions(include_transitive_dependencies: true)
50
+ return {} unless parser
51
+
52
+ all_gem_versions = parser.specs.to_h { |spec| [spec.name, spec.version] }
53
+
54
+ if include_transitive_dependencies
55
+ all_gem_versions
56
+ else
57
+ direct_dep_names = parser.dependencies.keys
58
+ all_gem_versions.slice(*direct_dep_names)
59
+ end
60
+ end
61
+
62
+ # Whether this lockfile includes the named gem, directly or indirectly.
63
+ # @param [String] name
64
+ # @return [Boolean]
24
65
  def includes_gem?(name)
25
66
  gems.any? { |gem| gem.name == name }
26
67
  end
27
68
 
28
69
  private
29
70
 
71
+ # @return [Bundler::LockfileParser, nil]
30
72
  def parser
31
- return unless defined?(Bundler) && Bundler.default_lockfile
32
73
  return @parser if defined?(@parser)
33
74
 
34
- lockfile = Bundler.read_file(Bundler.default_lockfile)
35
- @parser = lockfile ? Bundler::LockfileParser.new(lockfile) : nil
36
- rescue Bundler::BundlerError
37
- nil
75
+ @parser = if @lockfile_path && File.exist?(@lockfile_path) && use_bundler_lock_parser?
76
+ begin
77
+ lockfile = ::Bundler.read_file(@lockfile_path)
78
+ ::Bundler::LockfileParser.new(lockfile) if lockfile
79
+ rescue ::Bundler::BundlerError
80
+ nil
81
+ end
82
+ end
83
+ end
84
+
85
+ def use_bundler_lock_parser?
86
+ return false unless Object.const_defined?(:Bundler)
87
+
88
+ Bundler.const_defined?(:LockfileParser) && Bundler::VERSION >= '2.0'
38
89
  end
39
90
  end
40
91
  end
@@ -10,7 +10,7 @@
10
10
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
11
  #
12
12
  module RuboCop
13
- module Lsp
13
+ module LSP
14
14
  # Log for Language Server Protocol of RuboCop.
15
15
  # @api private
16
16
  class Logger
@@ -12,12 +12,12 @@ require_relative 'severity'
12
12
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
13
13
  #
14
14
  module RuboCop
15
- module Lsp
15
+ module LSP
16
16
  # Routes for Language Server Protocol of RuboCop.
17
17
  # @api private
18
18
  class Routes
19
19
  def self.handle(name, &block)
20
- define_method("handle_#{name}", &block)
20
+ define_method(:"handle_#{name}", &block)
21
21
  end
22
22
 
23
23
  private_class_method :handle
@@ -45,10 +45,6 @@ module RuboCop
45
45
  result: LanguageServer::Protocol::Interface::InitializeResult.new(
46
46
  capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
47
47
  document_formatting_provider: true,
48
- diagnostic_provider: LanguageServer::Protocol::Interface::DiagnosticOptions.new(
49
- inter_file_dependencies: false,
50
- workspace_diagnostics: false
51
- ),
52
48
  text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
53
49
  change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL,
54
50
  open_close: true
@@ -60,8 +56,9 @@ module RuboCop
60
56
 
61
57
  handle 'initialized' do |_request|
62
58
  version = RuboCop::Version::STRING
59
+ yjit = Object.const_defined?('RubyVM::YJIT') && RubyVM::YJIT.enabled? ? ' +YJIT' : ''
63
60
 
64
- Logger.log("RuboCop #{version} language server initialized, PID #{Process.pid}")
61
+ Logger.log("RuboCop #{version} language server#{yjit} initialized, PID #{Process.pid}")
65
62
  end
66
63
 
67
64
  handle 'shutdown' do |request|
@@ -72,12 +69,6 @@ module RuboCop
72
69
  end
73
70
  end
74
71
 
75
- handle 'textDocument/diagnostic' do |request|
76
- doc = request[:params][:textDocument]
77
- result = diagnostic(doc[:uri], doc[:text])
78
- @server.write(result)
79
- end
80
-
81
72
  handle 'textDocument/didChange' do |request|
82
73
  params = request[:params]
83
74
  result = diagnostic(params[:textDocument][:uri], params[:contentChanges][0][:text])
@@ -126,6 +117,12 @@ module RuboCop
126
117
  end
127
118
 
128
119
  uri = request[:params][:arguments][0][:uri]
120
+ formatted = nil
121
+
122
+ # The `workspace/executeCommand` is an LSP method triggered by intentional user actions,
123
+ # so the user's intention for autocorrection is respected.
124
+ LSP.disable { formatted = format_file(uri, command: command) }
125
+
129
126
  @server.write(
130
127
  id: request[:id],
131
128
  method: 'workspace/applyEdit',
@@ -133,7 +130,7 @@ module RuboCop
133
130
  label: label,
134
131
  edit: {
135
132
  changes: {
136
- uri => format_file(uri, command: command)
133
+ uri => formatted
137
134
  }
138
135
  }
139
136
  }
@@ -238,7 +235,7 @@ module RuboCop
238
235
  def to_range(location)
239
236
  {
240
237
  start: { character: location[:start_column] - 1, line: location[:start_line] - 1 },
241
- end: { character: location[:last_column] - 1, line: location[:last_line] - 1 }
238
+ end: { character: location[:last_column], line: location[:last_line] - 1 }
242
239
  }
243
240
  end
244
241
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
4
+
3
5
  #
4
6
  # This code is based on https://github.com/standardrb/standard.
5
7
  #
@@ -10,7 +12,7 @@
10
12
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
13
  #
12
14
  module RuboCop
13
- module Lsp
15
+ module LSP
14
16
  # Runtime for Language Server Protocol of RuboCop.
15
17
  # @api private
16
18
  class Runtime
@@ -15,14 +15,18 @@ require_relative 'runtime'
15
15
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
16
16
  #
17
17
  module RuboCop
18
- module Lsp
18
+ module LSP
19
19
  # Language Server Protocol of RuboCop.
20
20
  # @api private
21
21
  class Server
22
22
  def initialize(config_store)
23
+ $PROGRAM_NAME = "rubocop --lsp #{ConfigFinder.project_root}"
24
+
25
+ RuboCop::LSP.enable
26
+
23
27
  @reader = LanguageServer::Protocol::Transport::Io::Reader.new($stdin)
24
28
  @writer = LanguageServer::Protocol::Transport::Io::Writer.new($stdout)
25
- @runtime = RuboCop::Lsp::Runtime.new(config_store)
29
+ @runtime = RuboCop::LSP::Runtime.new(config_store)
26
30
  @routes = Routes.new(self)
27
31
  end
28
32
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuboCop
4
- module Lsp
4
+ module LSP
5
5
  # Severity for Language Server Protocol of RuboCop.
6
6
  # @api private
7
7
  class Severity
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # The RuboCop's built-in LSP module.
5
+ module LSP
6
+ module_function
7
+
8
+ # Returns true when LSP is enabled, false when disabled.
9
+ #
10
+ # @return [Boolean]
11
+ def enabled?
12
+ @enabled ||= false
13
+ end
14
+
15
+ # Enable LSP.
16
+ #
17
+ # @return [void]
18
+ def enable
19
+ @enabled = true
20
+ end
21
+
22
+ # Disable LSP.
23
+ #
24
+ # @return [void]
25
+ def disable(&block)
26
+ if block
27
+ original = @enabled
28
+ @enabled = false
29
+ yield
30
+ @enabled = original
31
+ else
32
+ @enabled = false
33
+ end
34
+ end
35
+ end
36
+ end
@@ -268,7 +268,7 @@ module RuboCop
268
268
 
269
269
  # Rewrite the comment without a given token type
270
270
  def without(type)
271
- if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/)
271
+ if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/io)
272
272
  ''
273
273
  else
274
274
  @comment
@@ -95,6 +95,7 @@ module RuboCop
95
95
  option(opts, '--ignore-unrecognized-cops')
96
96
  option(opts, '--force-default-config')
97
97
  option(opts, '-s', '--stdin FILE')
98
+ option(opts, '--editor-mode')
98
99
  option(opts, '-P', '--[no-]parallel')
99
100
  option(opts, '--raise-cop-error')
100
101
  add_severity_option(opts)
@@ -364,15 +365,12 @@ module RuboCop
364
365
  raise OptionArgumentError, '-C/--cache argument must be true or false'
365
366
  end
366
367
 
367
- if display_only_fail_level_offenses_with_autocorrect?
368
- raise OptionArgumentError, '--autocorrect cannot be used with ' \
369
- '--display-only-fail-level-offenses.'
370
- end
371
368
  validate_auto_gen_config
372
369
  validate_autocorrect
373
370
  validate_display_only_failed
374
371
  validate_display_only_failed_and_display_only_correctable
375
372
  validate_display_only_correctable_and_autocorrect
373
+ validate_lsp_and_editor_mode
376
374
  disable_parallel_when_invalid_option_combo
377
375
 
378
376
  return if incompatible_options.size <= 1
@@ -420,6 +418,13 @@ module RuboCop
420
418
  format('--display-only-failed cannot be used together with other display options.')
421
419
  end
422
420
 
421
+ def validate_lsp_and_editor_mode
422
+ return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
423
+
424
+ raise OptionArgumentError,
425
+ format('Do not specify `--editor-mode` as it is redundant in `--lsp`.')
426
+ end
427
+
423
428
  def validate_autocorrect
424
429
  if @options.key?(:safe_autocorrect) && @options.key?(:autocorrect_all)
425
430
  message = Rainbow(<<~MESSAGE).red
@@ -460,10 +465,6 @@ module RuboCop
460
465
  (@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
461
466
  end
462
467
 
463
- def display_only_fail_level_offenses_with_autocorrect?
464
- @options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
465
- end
466
-
467
468
  def except_syntax?
468
469
  @options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
469
470
  end
@@ -572,7 +573,7 @@ module RuboCop
572
573
  'cops. Only valid for --format junit.'],
573
574
  display_only_fail_level_offenses:
574
575
  ['Only output offense messages at',
575
- 'the specified --fail-level or above'],
576
+ 'the specified --fail-level or above.'],
576
577
  display_only_correctable: ['Only output correctable offense messages.'],
577
578
  display_only_safe_correctable: ['Only output safe-correctable offense messages',
578
579
  'when combined with --display-only-correctable.'],
@@ -614,9 +615,13 @@ module RuboCop
614
615
  version: 'Display version.',
615
616
  verbose_version: 'Display verbose version.',
616
617
  parallel: ['Use available CPUs to execute inspection in',
617
- 'parallel. Default is true.'],
618
+ 'parallel. Default is true.',
619
+ 'You can specify the number of parallel processes using',
620
+ 'the $PARALLEL_PROCESSOR_COUNT environment variable.'],
618
621
  stdin: ['Pipe source from STDIN, using FILE in offense',
619
622
  'reports. This is useful for editor integration.'],
623
+ editor_mode: ['Optimize real-time feedback in editors,',
624
+ 'adjusting behaviors for editing experience.'],
620
625
  init: 'Generate a .rubocop.yml file in the current directory.',
621
626
  server: ['If a server process has not been started yet, start',
622
627
  'the server process and execute inspection with server.',
@@ -633,8 +638,8 @@ module RuboCop
633
638
  raise_cop_error: ['Raise cop-related errors with cause and location.',
634
639
  'This is used to prevent cops from failing silently.',
635
640
  'Default is false.'],
636
- profile: 'Profile rubocop',
637
- memory: 'Profile rubocop memory usage'
641
+ profile: 'Profile rubocop.',
642
+ memory: 'Profile rubocop memory usage.'
638
643
  }.freeze
639
644
  end
640
645
  # rubocop:enable Metrics/ModuleLength
@@ -44,7 +44,7 @@ module RuboCop
44
44
  end
45
45
  end
46
46
 
47
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
47
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48
48
  def match_path?(pattern, path)
49
49
  case pattern
50
50
  when String
@@ -52,6 +52,10 @@ module RuboCop
52
52
  if pattern == path
53
53
  true
54
54
  elsif glob?(pattern)
55
+ # File name matching doesn't really work with relative patterns that start with "..". We
56
+ # get around that problem by converting the pattern to an absolute path.
57
+ pattern = File.expand_path(pattern) if pattern.start_with?('..')
58
+
55
59
  File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
56
60
  end
57
61
 
@@ -66,7 +70,7 @@ module RuboCop
66
70
  end
67
71
  end
68
72
  end
69
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
73
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
70
74
 
71
75
  # Returns true for an absolute Unix or Windows path.
72
76
  def absolute?(path)
@@ -44,7 +44,7 @@ module RuboCop
44
44
  def run_cli(verbose, options)
45
45
  # We lazy-load RuboCop so that the task doesn't dramatically impact the
46
46
  # load time of your Rakefile.
47
- require 'rubocop'
47
+ require_relative '../rubocop'
48
48
 
49
49
  cli = CLI.new
50
50
  puts 'Running RuboCop...' if verbose