rubocop 1.90.0 → 1.92.0

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 (303) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +241 -11
  4. data/config/obsoletion.yml +9 -0
  5. data/lib/rubocop/cached_data.rb +47 -7
  6. data/lib/rubocop/changed_files.rb +134 -0
  7. data/lib/rubocop/cli/command/cop_names.rb +57 -0
  8. data/lib/rubocop/cli/command/execute_runner.rb +23 -3
  9. data/lib/rubocop/cli/command/explain.rb +34 -0
  10. data/lib/rubocop/cli/command/show_cops.rb +6 -0
  11. data/lib/rubocop/cli/command/show_docs_url.rb +6 -4
  12. data/lib/rubocop/cli.rb +11 -4
  13. data/lib/rubocop/comment_config/directive_range.rb +3 -1
  14. data/lib/rubocop/comment_config/disable_next.rb +49 -3
  15. data/lib/rubocop/comment_config/push_pop.rb +55 -0
  16. data/lib/rubocop/comment_config.rb +32 -53
  17. data/lib/rubocop/config.rb +10 -0
  18. data/lib/rubocop/config_loader.rb +18 -7
  19. data/lib/rubocop/config_loader_resolver.rb +79 -12
  20. data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
  21. data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
  22. data/lib/rubocop/config_obsoletion.rb +1 -1
  23. data/lib/rubocop/config_validator.rb +29 -3
  24. data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
  25. data/lib/rubocop/cop/badge.rb +1 -1
  26. data/lib/rubocop/cop/base.rb +57 -24
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +0 -1
  28. data/lib/rubocop/cop/bundler/ordered_gems.rb +0 -8
  29. data/lib/rubocop/cop/cop_documentation.rb +81 -0
  30. data/lib/rubocop/cop/cop_explanation.rb +140 -0
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -1
  32. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
  33. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
  34. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +23 -2
  35. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
  36. data/lib/rubocop/cop/correctors.rb +2 -2
  37. data/lib/rubocop/cop/documentation.rb +1 -1
  38. data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
  39. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +0 -6
  40. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  41. data/lib/rubocop/cop/generator.rb +1 -1
  42. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -5
  43. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
  44. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
  45. data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
  46. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
  47. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -0
  48. data/lib/rubocop/cop/layout/block_alignment.rb +27 -0
  49. data/lib/rubocop/cop/layout/case_indentation.rb +25 -9
  50. data/lib/rubocop/cop/layout/class_structure.rb +9 -1
  51. data/lib/rubocop/cop/layout/comment_indentation.rb +8 -5
  52. data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
  54. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
  55. data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
  56. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
  57. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
  58. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
  59. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
  60. data/lib/rubocop/cop/layout/end_alignment.rb +16 -10
  61. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
  62. data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -0
  63. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -4
  64. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -3
  65. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
  66. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
  67. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
  68. data/lib/rubocop/cop/layout/hash_alignment.rb +15 -10
  69. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -0
  70. data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
  71. data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
  72. data/lib/rubocop/cop/layout/indentation_width.rb +4 -4
  73. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -1
  74. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
  75. data/lib/rubocop/cop/layout/line_length.rb +71 -19
  76. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +12 -0
  77. data/lib/rubocop/cop/layout/multiline_block_layout.rb +8 -1
  78. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +7 -0
  79. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
  80. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +14 -0
  81. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
  82. data/lib/rubocop/cop/layout/redundant_line_break.rb +22 -1
  83. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -2
  84. data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
  85. data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
  86. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
  87. data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
  88. data/lib/rubocop/cop/layout/space_around_operators.rb +5 -1
  89. data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
  90. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
  91. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
  92. data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
  93. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
  94. data/lib/rubocop/cop/lint/argument_mismatch.rb +14 -4
  95. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -0
  96. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +88 -14
  97. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
  98. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  99. data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
  100. data/lib/rubocop/cop/lint/literal_as_condition.rb +23 -2
  101. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +63 -19
  102. data/lib/rubocop/cop/lint/loop.rb +24 -2
  103. data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
  104. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -4
  105. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  106. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  107. data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
  108. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +17 -1
  109. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +42 -17
  110. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
  111. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +18 -1
  112. data/lib/rubocop/cop/lint/useless_assignment.rb +14 -7
  113. data/lib/rubocop/cop/lint/void.rb +8 -1
  114. data/lib/rubocop/cop/lint.rb +1 -0
  115. data/lib/rubocop/cop/metrics/class_length.rb +4 -2
  116. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
  117. data/lib/rubocop/cop/metrics/module_length.rb +4 -2
  118. data/lib/rubocop/cop/migration/department_name.rb +1 -1
  119. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  120. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  121. data/lib/rubocop/cop/mixin/check_line_breakable.rb +17 -14
  122. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -1
  123. data/lib/rubocop/cop/mixin/code_length.rb +10 -2
  124. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
  125. data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
  126. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
  127. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +26 -2
  128. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +31 -3
  129. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  130. data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
  131. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
  132. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -0
  133. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  134. data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
  135. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +29 -3
  136. data/lib/rubocop/cop/mixin/project_index_help.rb +15 -0
  137. data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +13 -3
  138. data/lib/rubocop/cop/mixin/statement_modifier.rb +22 -2
  139. data/lib/rubocop/cop/mixin.rb +4 -2
  140. data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
  141. data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
  142. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  143. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
  144. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
  145. data/lib/rubocop/cop/naming/predicate_prefix.rb +7 -22
  146. data/lib/rubocop/cop/offense.rb +59 -3
  147. data/lib/rubocop/cop/registry.rb +10 -2
  148. data/lib/rubocop/cop/security/json_load.rb +16 -4
  149. data/lib/rubocop/cop/severity.rb +12 -0
  150. data/lib/rubocop/cop/style/access_modifier_declarations.rb +10 -2
  151. data/lib/rubocop/cop/style/alias.rb +18 -5
  152. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
  153. data/lib/rubocop/cop/style/and_or.rb +4 -0
  154. data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -3
  155. data/lib/rubocop/cop/style/attr.rb +3 -4
  156. data/lib/rubocop/cop/style/bitwise_predicate.rb +6 -4
  157. data/lib/rubocop/cop/style/block_delimiters.rb +29 -3
  158. data/lib/rubocop/cop/style/case_like_if.rb +9 -6
  159. data/lib/rubocop/cop/style/class_and_module_children.rb +54 -16
  160. data/lib/rubocop/cop/style/class_methods_definitions.rb +8 -0
  161. data/lib/rubocop/cop/style/combinable_loops.rb +85 -11
  162. data/lib/rubocop/cop/style/concat_array_literals.rb +46 -7
  163. data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
  164. data/lib/rubocop/cop/style/constant_visibility.rb +6 -2
  165. data/lib/rubocop/cop/style/data_inheritance.rb +14 -0
  166. data/lib/rubocop/cop/style/directive_scope.rb +154 -21
  167. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +118 -18
  168. data/lib/rubocop/cop/style/documentation_method.rb +1 -9
  169. data/lib/rubocop/cop/style/double_negation.rb +11 -0
  170. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  171. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  172. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  173. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  174. data/lib/rubocop/cop/style/empty_method.rb +15 -3
  175. data/lib/rubocop/cop/style/endless_method.rb +91 -11
  176. data/lib/rubocop/cop/style/exact_regexp_match.rb +45 -8
  177. data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
  178. data/lib/rubocop/cop/style/file_null.rb +2 -2
  179. data/lib/rubocop/cop/style/float_division.rb +28 -14
  180. data/lib/rubocop/cop/style/for.rb +44 -1
  181. data/lib/rubocop/cop/style/format_string.rb +28 -6
  182. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  183. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  184. data/lib/rubocop/cop/style/guard_clause.rb +13 -1
  185. data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
  186. data/lib/rubocop/cop/style/hash_lookup_method.rb +35 -9
  187. data/lib/rubocop/cop/style/hash_syntax.rb +16 -3
  188. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  189. data/lib/rubocop/cop/style/if_inside_else.rb +21 -1
  190. data/lib/rubocop/cop/style/if_unless_modifier.rb +19 -20
  191. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -0
  192. data/lib/rubocop/cop/style/if_with_semicolon.rb +47 -4
  193. data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
  194. data/lib/rubocop/cop/style/it_block_parameter.rb +32 -3
  195. data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
  196. data/lib/rubocop/cop/style/lambda.rb +18 -0
  197. data/lib/rubocop/cop/style/lambda_call.rb +7 -2
  198. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  199. data/lib/rubocop/cop/style/map_into_array.rb +1 -2
  200. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +45 -10
  201. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -2
  202. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
  203. data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -3
  204. data/lib/rubocop/cop/style/missing_else.rb +7 -1
  205. data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
  206. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
  207. data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -5
  208. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
  209. data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
  210. data/lib/rubocop/cop/style/mutable_constant.rb +28 -1
  211. data/lib/rubocop/cop/style/negated_if_else_condition.rb +2 -1
  212. data/lib/rubocop/cop/style/negative_array_index.rb +9 -1
  213. data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
  214. data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
  215. data/lib/rubocop/cop/style/next.rb +24 -10
  216. data/lib/rubocop/cop/style/nil_comparison.rb +48 -8
  217. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  218. data/lib/rubocop/cop/style/non_nil_check.rb +18 -2
  219. data/lib/rubocop/cop/style/not.rb +10 -3
  220. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
  221. data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
  222. data/lib/rubocop/cop/style/one_line_conditional.rb +14 -3
  223. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
  224. data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
  225. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
  226. data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
  227. data/lib/rubocop/cop/style/redundant_begin.rb +20 -3
  228. data/lib/rubocop/cop/style/redundant_condition.rb +34 -17
  229. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +16 -1
  230. data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
  231. data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
  232. data/lib/rubocop/cop/style/redundant_freeze.rb +10 -1
  233. data/lib/rubocop/cop/style/redundant_parentheses.rb +23 -2
  234. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
  235. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
  236. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +25 -5
  237. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
  238. data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
  239. data/lib/rubocop/cop/style/require_order.rb +9 -0
  240. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -9
  241. data/lib/rubocop/cop/style/return_nil.rb +17 -2
  242. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
  243. data/lib/rubocop/cop/style/sample.rb +9 -8
  244. data/lib/rubocop/cop/style/self_assignment.rb +12 -15
  245. data/lib/rubocop/cop/style/semicolon.rb +16 -5
  246. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  247. data/lib/rubocop/cop/style/single_line_methods.rb +16 -4
  248. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  249. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
  250. data/lib/rubocop/cop/style/string_concatenation.rb +9 -3
  251. data/lib/rubocop/cop/style/struct_inheritance.rb +14 -0
  252. data/lib/rubocop/cop/style/super_arguments.rb +3 -0
  253. data/lib/rubocop/cop/style/symbol_proc.rb +23 -5
  254. data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
  255. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  256. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -19
  257. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  258. data/lib/rubocop/cop/style/yoda_condition.rb +24 -9
  259. data/lib/rubocop/cop/style/yoda_expression.rb +10 -1
  260. data/lib/rubocop/cop/style.rb +0 -1
  261. data/lib/rubocop/cop/team.rb +10 -5
  262. data/lib/rubocop/cop/util.rb +1 -1
  263. data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
  264. data/lib/rubocop/cop/variable_force/variable.rb +14 -1
  265. data/lib/rubocop/cops_documentation_generator.rb +23 -2
  266. data/lib/rubocop/directive_comment.rb +37 -8
  267. data/lib/rubocop/formatter/base_formatter.rb +22 -0
  268. data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -1
  269. data/lib/rubocop/formatter/formatter_set.rb +6 -1
  270. data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
  271. data/lib/rubocop/formatter/html_formatter.rb +2 -2
  272. data/lib/rubocop/formatter/json_formatter.rb +71 -1
  273. data/lib/rubocop/formatter/junit_formatter.rb +1 -1
  274. data/lib/rubocop/formatter/offense_count_formatter.rb +3 -1
  275. data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
  276. data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
  277. data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
  278. data/lib/rubocop/formatter.rb +1 -0
  279. data/lib/rubocop/lsp/runtime.rb +47 -11
  280. data/lib/rubocop/lsp/stdin_runner.rb +11 -5
  281. data/lib/rubocop/lsp.rb +5 -2
  282. data/lib/rubocop/magic_comment.rb +27 -0
  283. data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
  284. data/lib/rubocop/mcp/explain_tool.rb +68 -0
  285. data/lib/rubocop/mcp/scope.rb +65 -0
  286. data/lib/rubocop/mcp/server.rb +184 -76
  287. data/lib/rubocop/mcp/source_files.rb +35 -0
  288. data/lib/rubocop/offense_limit.rb +30 -0
  289. data/lib/rubocop/options.rb +97 -4
  290. data/lib/rubocop/path_util.rb +1 -1
  291. data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
  292. data/lib/rubocop/plugin/loader.rb +1 -1
  293. data/lib/rubocop/rake_task.rb +1 -1
  294. data/lib/rubocop/remote_config.rb +8 -5
  295. data/lib/rubocop/result_cache.rb +36 -18
  296. data/lib/rubocop/runner.rb +160 -49
  297. data/lib/rubocop/server/cache.rb +2 -2
  298. data/lib/rubocop/unified_diff.rb +257 -0
  299. data/lib/rubocop/util.rb +69 -0
  300. data/lib/rubocop/version.rb +1 -1
  301. data/lib/rubocop.rb +9 -1
  302. metadata +21 -6
  303. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
@@ -0,0 +1,257 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # Renders a unified diff between two versions of a file's source.
5
+ #
6
+ # RuboCop has no diffing dependency and this output is meant to be read by
7
+ # people (and occasionally piped into `git apply`), so the goal is a diff
8
+ # that is correct and readable, not one that matches `diff -u` byte for byte.
9
+ #
10
+ # @api private
11
+ class UnifiedDiff
12
+ CONTEXT_LINES = 3
13
+ NO_NEWLINE_MARKER = "\\n"
14
+
15
+ # Finding a minimal diff costs time and memory proportional to the square
16
+ # of the number of edits. Past this many edits the file was rewritten
17
+ # rather than corrected, so the changed region is reported as a single
18
+ # replacement instead.
19
+ MAX_EDIT_DISTANCE = 400
20
+
21
+ def initialize(path, old_source, new_source)
22
+ @path = path
23
+ @old_lines = old_source.lines
24
+ @new_lines = new_source.lines
25
+ end
26
+
27
+ # @return [String] the diff, or an empty string when the sources are identical
28
+ def to_s
29
+ return '' if @old_lines == @new_lines
30
+
31
+ hunks = hunks_for(edit_script)
32
+ return '' if hunks.empty?
33
+
34
+ ["--- a/#{@path}\n", "+++ b/#{@path}\n", *hunks].join
35
+ end
36
+
37
+ private
38
+
39
+ def edit_script
40
+ prefix = common_prefix_length
41
+ suffix = common_suffix_length(prefix)
42
+ old_last = @old_lines.length - suffix
43
+ new_last = @new_lines.length - suffix
44
+
45
+ [
46
+ *@old_lines[0...prefix].map { |line| [:equal, line] },
47
+ *middle_script(@old_lines[prefix...old_last], @new_lines[prefix...new_last]),
48
+ *@old_lines[old_last..].map { |line| [:equal, line] }
49
+ ]
50
+ end
51
+
52
+ def common_prefix_length
53
+ length = 0
54
+ length += 1 while length < @old_lines.length && @old_lines[length] == @new_lines[length]
55
+ length
56
+ end
57
+
58
+ def common_suffix_length(prefix)
59
+ length = 0
60
+ max = [@old_lines.length, @new_lines.length].min - prefix
61
+ while length < max &&
62
+ @old_lines[@old_lines.length - 1 - length] == @new_lines[@new_lines.length - 1 - length]
63
+ length += 1
64
+ end
65
+ length
66
+ end
67
+
68
+ def middle_script(old_lines, new_lines)
69
+ # The region that actually differs is diffed on its own, so the rest of
70
+ # the algorithm works on these two slices rather than the whole file.
71
+ @from_lines = old_lines
72
+ @to_lines = new_lines
73
+
74
+ myers_script ||
75
+ [*old_lines.map { |line| [:delete, line] }, *new_lines.map { |line| [:insert, line] }]
76
+ end
77
+
78
+ # Myers' diff algorithm. Each round `d` extends the furthest reaching path
79
+ # for every diagonal `k`; the first path to reach the end of both sources
80
+ # is a shortest edit script, which is then reconstructed from the saved
81
+ # rounds. Returns `nil` when the sources are too different to bother.
82
+ def myers_script
83
+ trace = []
84
+ furthest = Hash.new(0)
85
+ max_distance = [@from_lines.length + @to_lines.length, MAX_EDIT_DISTANCE].min
86
+
87
+ 0.upto(max_distance) do |distance|
88
+ trace << furthest.dup
89
+
90
+ (-distance).step(distance, 2) do |diagonal|
91
+ furthest[diagonal] = advance(furthest, diagonal, distance)
92
+
93
+ return backtrack(trace) if reached_end?(furthest[diagonal], diagonal)
94
+ end
95
+ end
96
+
97
+ nil
98
+ end
99
+
100
+ def reached_end?(old_index, diagonal)
101
+ old_index >= @from_lines.length && old_index - diagonal >= @to_lines.length
102
+ end
103
+
104
+ # Picks the better of the two paths reaching this diagonal, then follows
105
+ # the diagonal as far as the lines match.
106
+ def advance(furthest, diagonal, distance)
107
+ old_index = start_of_path(furthest, diagonal, distance)
108
+
109
+ follow_diagonal(old_index, old_index - diagonal)
110
+ end
111
+
112
+ # A path arrives at this diagonal either from the one above it (having
113
+ # inserted a line) or the one below it (having deleted one); whichever
114
+ # reached further wins.
115
+ def previous_diagonal(furthest, diagonal, distance)
116
+ if diagonal == -distance ||
117
+ (diagonal != distance && furthest[diagonal - 1] < furthest[diagonal + 1])
118
+ diagonal + 1
119
+ else
120
+ diagonal - 1
121
+ end
122
+ end
123
+
124
+ def start_of_path(furthest, diagonal, distance)
125
+ previous = previous_diagonal(furthest, diagonal, distance)
126
+
127
+ previous > diagonal ? furthest[previous] : furthest[previous] + 1
128
+ end
129
+
130
+ # Matching lines cost nothing, so the path slides along them for free.
131
+ def follow_diagonal(old_index, new_index)
132
+ while old_index < @from_lines.length && new_index < @to_lines.length &&
133
+ @from_lines[old_index] == @to_lines[new_index]
134
+ old_index += 1
135
+ new_index += 1
136
+ end
137
+
138
+ old_index
139
+ end
140
+
141
+ def backtrack(trace)
142
+ script = []
143
+ position = [@from_lines.length, @to_lines.length]
144
+
145
+ trace.each_with_index.reverse_each do |furthest, distance|
146
+ previous = previous_position(furthest, distance, *position)
147
+ position = walk_diagonal(script, position, previous)
148
+ next if distance.zero?
149
+
150
+ position = record_edit(script, position, previous)
151
+ end
152
+
153
+ script
154
+ end
155
+
156
+ # Both sides step back together for as long as their lines match.
157
+ def walk_diagonal(script, position, previous)
158
+ old_index, new_index = position
159
+
160
+ while old_index > previous[0] && new_index > previous[1]
161
+ old_index -= 1
162
+ new_index -= 1
163
+ script.unshift([:equal, @from_lines[old_index]])
164
+ end
165
+
166
+ [old_index, new_index]
167
+ end
168
+
169
+ def record_edit(script, position, previous)
170
+ old_index, new_index = position
171
+
172
+ if old_index == previous[0]
173
+ new_index -= 1
174
+ script.unshift([:insert, @to_lines[new_index]])
175
+ else
176
+ old_index -= 1
177
+ script.unshift([:delete, @from_lines[old_index]])
178
+ end
179
+
180
+ [old_index, new_index]
181
+ end
182
+
183
+ def previous_position(furthest, distance, old_index, new_index)
184
+ previous = previous_diagonal(furthest, old_index - new_index, distance)
185
+ previous_old = furthest[previous]
186
+
187
+ [previous_old, previous_old - previous]
188
+ end
189
+
190
+ def hunks_for(script)
191
+ changed = script.each_index.reject { |index| script[index].first == :equal }
192
+ return [] if changed.empty?
193
+
194
+ ranges_for(changed, script.length).map { |range| hunk(script, range) }
195
+ end
196
+
197
+ # Every change is shown with a few lines of context around it, and changes
198
+ # whose context would overlap are shown as a single hunk.
199
+ def ranges_for(changed, script_length)
200
+ ranges = []
201
+
202
+ changed.each do |index|
203
+ first = [index - CONTEXT_LINES, 0].max
204
+ last = [index + CONTEXT_LINES, script_length - 1].min
205
+
206
+ if ranges.last && first <= ranges.last.last + 1
207
+ ranges[-1] = (ranges.last.first..last)
208
+ else
209
+ ranges << (first..last)
210
+ end
211
+ end
212
+
213
+ ranges
214
+ end
215
+
216
+ def hunk(script, range)
217
+ old_start, new_start = start_positions(script, range.first)
218
+ old_count = script[range].count { |kind, _| kind != :insert }
219
+ new_count = script[range].count { |kind, _| kind != :delete }
220
+ body = script[range].map { |kind, line| formatted_line(kind, line) }
221
+
222
+ [
223
+ "@@ -#{position(old_start, old_count)} +#{position(new_start, new_count)} @@\n",
224
+ *body
225
+ ].join
226
+ end
227
+
228
+ def start_positions(script, index)
229
+ old_line = 1
230
+ new_line = 1
231
+
232
+ script[0...index].each do |entry|
233
+ old_line += 1 unless entry.first == :insert
234
+ new_line += 1 unless entry.first == :delete
235
+ end
236
+
237
+ [old_line, new_line]
238
+ end
239
+
240
+ # An empty side is anchored to the line it follows, which is how `diff`
241
+ # reports a pure insertion or deletion, and a single line drops the count.
242
+ def position(start, count)
243
+ case count
244
+ when 0 then "#{start - 1},0"
245
+ when 1 then start.to_s
246
+ else "#{start},#{count}"
247
+ end
248
+ end
249
+
250
+ def formatted_line(kind, line)
251
+ marker = { equal: ' ', delete: '-', insert: '+' }.fetch(kind)
252
+ return "#{marker}#{line}" if line.end_with?("\n")
253
+
254
+ "#{marker}#{line}\n#{NO_NEWLINE_MARKER}"
255
+ end
256
+ end
257
+ end
data/lib/rubocop/util.rb CHANGED
@@ -12,5 +12,74 @@ module RuboCop
12
12
  ensure
13
13
  $VERBOSE = old_verbose
14
14
  end
15
+
16
+ # The source as it reads back after `File.write`, which in text mode turns
17
+ # each LF into CRLF on Windows. Cops like `Layout/EndOfLine` have to see
18
+ # corrected code that way between correction passes, and so does anything
19
+ # that compares it with what a write leaves on disk. The final `File.write`
20
+ # still performs the conversion for the file itself.
21
+ def self.emulate_write_read_cycle(source)
22
+ return source unless Platform.windows?
23
+
24
+ source.encode(source.encoding, crlf_newline: true)
25
+ end
26
+
27
+ # Replaces the contents of `path` without a window in which the file is truncated
28
+ # but not yet rewritten, so that an interrupted run or a full disk cannot lose
29
+ # the original: the new contents are written next to the file and renamed over it,
30
+ # like `ResultCache#save`. `File.write` is used for the temporary file so text-mode
31
+ # semantics (the CRLF conversion on Windows) stay identical to a direct write.
32
+ # Where the temporary file cannot be created or renamed for lack of permission,
33
+ # a direct write is used as before.
34
+ def self.replace_file_contents(path, contents)
35
+ # Write through symlinks so that the rename replaces the real file and
36
+ # the symlink survives.
37
+ path = File.realpath(path)
38
+
39
+ # Opening a read-only file fails without truncating it, keeping the behavior
40
+ # a direct write always had.
41
+ return File.write(path, contents) unless File.writable?(path)
42
+
43
+ temp_path = "#{path}.#{Process.pid}.#{rand(1_000_000_000)}.rubocop.tmp"
44
+ begin
45
+ replace_via_temporary_file(path, temp_path, contents)
46
+ ensure
47
+ FileUtils.rm_f(temp_path)
48
+ end
49
+ rescue Errno::ENOENT
50
+ # The file vanished mid-run or is a dangling symlink: recreate it the way
51
+ # a direct write always has.
52
+ File.write(path, contents)
53
+ end
54
+
55
+ def self.replace_via_temporary_file(path, temp_path, contents)
56
+ # The directory refuses new files even though the file itself is writable,
57
+ # so a direct write is the only option left.
58
+ return File.write(path, contents) unless write_temporary_file(temp_path, contents)
59
+
60
+ begin
61
+ # A fresh file would get umask-default permissions on rename;
62
+ # keep the original's.
63
+ File.chmod(File.stat(path).mode, temp_path)
64
+ File.rename(temp_path, path)
65
+ rescue SystemCallError
66
+ # The replacement was refused, e.g. the file is open in another process on Windows.
67
+ # The contents already fit on disk, so a direct write is safe once the temporary copy
68
+ # no longer takes up that space.
69
+ FileUtils.rm_f(temp_path)
70
+ File.write(path, contents)
71
+ end
72
+ end
73
+ private_class_method :replace_via_temporary_file
74
+
75
+ # Space errors such as `ENOSPC` must propagate: a direct write would then
76
+ # truncate the file and fail, which is exactly the loss being avoided.
77
+ def self.write_temporary_file(temp_path, contents)
78
+ File.write(temp_path, contents)
79
+ true
80
+ rescue Errno::EACCES, Errno::EPERM
81
+ false
82
+ end
83
+ private_class_method :write_temporary_file
15
84
  end
16
85
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.90.0'
6
+ STRING = '1.92.0'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
data/lib/rubocop.rb CHANGED
@@ -27,6 +27,7 @@ require_relative 'rubocop/ext/regexp_parser'
27
27
  require_relative 'rubocop/core_ext/string'
28
28
  require_relative 'rubocop/ext/processed_source'
29
29
 
30
+ require_relative 'rubocop/changed_files'
30
31
  require_relative 'rubocop/error'
31
32
  require_relative 'rubocop/file_finder'
32
33
  require_relative 'rubocop/file_patterns'
@@ -34,10 +35,11 @@ require_relative 'rubocop/name_similarity'
34
35
  require_relative 'rubocop/path_util'
35
36
  require_relative 'rubocop/platform'
36
37
  require_relative 'rubocop/string_interpreter'
38
+ require_relative 'rubocop/unified_diff'
37
39
  require_relative 'rubocop/util'
38
40
  require_relative 'rubocop/warning'
39
41
 
40
- # rubocop:disable Style/RequireOrder
42
+ # rubocop:disable Style/RequireOrder -- ordered by load dependency, not alphabetically
41
43
 
42
44
  require_relative 'rubocop/project_index_loader'
43
45
  require_relative 'rubocop/cop/util'
@@ -53,6 +55,8 @@ require_relative 'rubocop/cop/base'
53
55
  require_relative 'rubocop/cop/cop'
54
56
  require_relative 'rubocop/cop/commissioner'
55
57
  require_relative 'rubocop/cop/documentation'
58
+ require_relative 'rubocop/cop/cop_documentation'
59
+ require_relative 'rubocop/cop/cop_explanation'
56
60
  require_relative 'rubocop/cop/corrector'
57
61
  require_relative 'rubocop/cop/correctors'
58
62
  require_relative 'rubocop/cop/force'
@@ -112,14 +116,18 @@ require_relative 'rubocop/target_finder'
112
116
  require_relative 'rubocop/directive_comment'
113
117
  require_relative 'rubocop/comment_config/directive_range'
114
118
  require_relative 'rubocop/comment_config/disable_next'
119
+ require_relative 'rubocop/comment_config/push_pop'
115
120
  require_relative 'rubocop/comment_config'
116
121
  require_relative 'rubocop/result_cache'
122
+ require_relative 'rubocop/offense_limit'
117
123
  require_relative 'rubocop/runner'
118
124
  require_relative 'rubocop/cli'
119
125
  require_relative 'rubocop/cli/command'
120
126
  require_relative 'rubocop/cli/environment'
121
127
  require_relative 'rubocop/cli/command/base'
122
128
  require_relative 'rubocop/cli/command/auto_generate_config'
129
+ require_relative 'rubocop/cli/command/cop_names'
130
+ require_relative 'rubocop/cli/command/explain'
123
131
  require_relative 'rubocop/cli/command/execute_runner'
124
132
  require_relative 'rubocop/cli/command/init_dotfile'
125
133
  require_relative 'rubocop/cli/command/lsp'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.90.0
4
+ version: 1.92.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -107,7 +107,7 @@ dependencies:
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 2.9.3
110
+ version: 2.11.3
111
111
  - - "<"
112
112
  - !ruby/object:Gem::Version
113
113
  version: '3.0'
@@ -117,7 +117,7 @@ dependencies:
117
117
  requirements:
118
118
  - - ">="
119
119
  - !ruby/object:Gem::Version
120
- version: 2.9.3
120
+ version: 2.11.3
121
121
  - - "<"
122
122
  - !ruby/object:Gem::Version
123
123
  version: '3.0'
@@ -201,11 +201,14 @@ files:
201
201
  - lib/rubocop/ast_aliases.rb
202
202
  - lib/rubocop/cache_config.rb
203
203
  - lib/rubocop/cached_data.rb
204
+ - lib/rubocop/changed_files.rb
204
205
  - lib/rubocop/cli.rb
205
206
  - lib/rubocop/cli/command.rb
206
207
  - lib/rubocop/cli/command/auto_generate_config.rb
207
208
  - lib/rubocop/cli/command/base.rb
209
+ - lib/rubocop/cli/command/cop_names.rb
208
210
  - lib/rubocop/cli/command/execute_runner.rb
211
+ - lib/rubocop/cli/command/explain.rb
209
212
  - lib/rubocop/cli/command/init_dotfile.rb
210
213
  - lib/rubocop/cli/command/list_enabled_cops_for.rb
211
214
  - lib/rubocop/cli/command/lsp.rb
@@ -218,6 +221,7 @@ files:
218
221
  - lib/rubocop/comment_config.rb
219
222
  - lib/rubocop/comment_config/directive_range.rb
220
223
  - lib/rubocop/comment_config/disable_next.rb
224
+ - lib/rubocop/comment_config/push_pop.rb
221
225
  - lib/rubocop/config.rb
222
226
  - lib/rubocop/config_finder.rb
223
227
  - lib/rubocop/config_loader.rb
@@ -248,6 +252,8 @@ files:
248
252
  - lib/rubocop/cop/bundler/ordered_gems.rb
249
253
  - lib/rubocop/cop/commissioner.rb
250
254
  - lib/rubocop/cop/cop.rb
255
+ - lib/rubocop/cop/cop_documentation.rb
256
+ - lib/rubocop/cop/cop_explanation.rb
251
257
  - lib/rubocop/cop/corrector.rb
252
258
  - lib/rubocop/cop/correctors.rb
253
259
  - lib/rubocop/cop/correctors/alignment_corrector.rb
@@ -502,6 +508,7 @@ files:
502
508
  - lib/rubocop/cop/lint/literal_assignment_in_condition.rb
503
509
  - lib/rubocop/cop/lint/literal_in_interpolation.rb
504
510
  - lib/rubocop/cop/lint/loop.rb
511
+ - lib/rubocop/cop/lint/misplaced_magic_comment.rb
505
512
  - lib/rubocop/cop/lint/missing_cop_enable_directive.rb
506
513
  - lib/rubocop/cop/lint/missing_super.rb
507
514
  - lib/rubocop/cop/lint/mixed_case_range.rb
@@ -640,6 +647,7 @@ files:
640
647
  - lib/rubocop/cop/mixin/empty_lines_around_body.rb
641
648
  - lib/rubocop/cop/mixin/empty_parameter.rb
642
649
  - lib/rubocop/cop/mixin/end_keyword_alignment.rb
650
+ - lib/rubocop/cop/mixin/endless_method_body_help.rb
643
651
  - lib/rubocop/cop/mixin/endless_method_rewriter.rb
644
652
  - lib/rubocop/cop/mixin/enforce_superclass.rb
645
653
  - lib/rubocop/cop/mixin/first_element_line_break.rb
@@ -672,6 +680,7 @@ files:
672
680
  - lib/rubocop/cop/mixin/on_normal_if_unless.rb
673
681
  - lib/rubocop/cop/mixin/ordered_gem_node.rb
674
682
  - lib/rubocop/cop/mixin/parentheses.rb
683
+ - lib/rubocop/cop/mixin/pattern_matching_help.rb
675
684
  - lib/rubocop/cop/mixin/percent_array.rb
676
685
  - lib/rubocop/cop/mixin/percent_literal.rb
677
686
  - lib/rubocop/cop/mixin/preceding_following_alignment.rb
@@ -785,7 +794,6 @@ files:
785
794
  - lib/rubocop/cop/style/document_dynamic_eval_definition.rb
786
795
  - lib/rubocop/cop/style/documentation.rb
787
796
  - lib/rubocop/cop/style/documentation_method.rb
788
- - lib/rubocop/cop/style/double_cop_disable_directive.rb
789
797
  - lib/rubocop/cop/style/double_negation.rb
790
798
  - lib/rubocop/cop/style/each_for_simple_loop.rb
791
799
  - lib/rubocop/cop/style/each_with_object.rb
@@ -1073,6 +1081,7 @@ files:
1073
1081
  - lib/rubocop/formatter/pacman_formatter.rb
1074
1082
  - lib/rubocop/formatter/progress_formatter.rb
1075
1083
  - lib/rubocop/formatter/quiet_formatter.rb
1084
+ - lib/rubocop/formatter/sarif_formatter.rb
1076
1085
  - lib/rubocop/formatter/simple_text_formatter.rb
1077
1086
  - lib/rubocop/formatter/tap_formatter.rb
1078
1087
  - lib/rubocop/formatter/text_util.rb
@@ -1088,8 +1097,13 @@ files:
1088
1097
  - lib/rubocop/lsp/severity.rb
1089
1098
  - lib/rubocop/lsp/stdin_runner.rb
1090
1099
  - lib/rubocop/magic_comment.rb
1100
+ - lib/rubocop/mcp/autocorrection_request.rb
1101
+ - lib/rubocop/mcp/explain_tool.rb
1102
+ - lib/rubocop/mcp/scope.rb
1091
1103
  - lib/rubocop/mcp/server.rb
1104
+ - lib/rubocop/mcp/source_files.rb
1092
1105
  - lib/rubocop/name_similarity.rb
1106
+ - lib/rubocop/offense_limit.rb
1093
1107
  - lib/rubocop/options.rb
1094
1108
  - lib/rubocop/path_util.rb
1095
1109
  - lib/rubocop/pending_cops_reporter.rb
@@ -1131,6 +1145,7 @@ files:
1131
1145
  - lib/rubocop/target_finder.rb
1132
1146
  - lib/rubocop/target_ruby.rb
1133
1147
  - lib/rubocop/todo_audit.rb
1148
+ - lib/rubocop/unified_diff.rb
1134
1149
  - lib/rubocop/util.rb
1135
1150
  - lib/rubocop/version.rb
1136
1151
  - lib/rubocop/warning.rb
@@ -1142,9 +1157,9 @@ licenses:
1142
1157
  - MIT
1143
1158
  metadata:
1144
1159
  homepage_uri: https://rubocop.org/
1145
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.90.0
1160
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.92.0
1146
1161
  source_code_uri: https://github.com/rubocop/rubocop/
1147
- documentation_uri: https://docs.rubocop.org/rubocop/1.90/
1162
+ documentation_uri: https://docs.rubocop.org/rubocop/1.92/
1148
1163
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1149
1164
  rubygems_mfa_required: 'true'
1150
1165
  rdoc_options: []
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # rubocop:disable Lint/RedundantCopDisableDirective
4
- # rubocop:disable Style/DoubleCopDisableDirective
5
-
6
- module RuboCop
7
- module Cop
8
- module Style
9
- # Detects double disable comments on one line. This is mostly to catch
10
- # automatically generated comments that need to be regenerated.
11
- #
12
- # @example
13
- # # bad
14
- # def f # rubocop:disable Style/For # rubocop:disable Metrics/AbcSize
15
- # end
16
- #
17
- # # good
18
- # # rubocop:disable Metrics/AbcSize
19
- # def f # rubocop:disable Style/For
20
- # end
21
- # # rubocop:enable Metrics/AbcSize
22
- #
23
- # # if both fit on one line
24
- # def f # rubocop:disable Style/For, Metrics/AbcSize
25
- # end
26
- #
27
- class DoubleCopDisableDirective < Base
28
- extend AutoCorrector
29
-
30
- # rubocop:enable Style/For, Style/DoubleCopDisableDirective
31
- # rubocop:enable Lint/RedundantCopDisableDirective, Metrics/AbcSize
32
- MSG = 'More than one disable comment on one line.'
33
-
34
- def on_new_investigation
35
- processed_source.comments.each do |comment|
36
- next unless comment.text.scan(/# rubocop:(?:disable|todo)/).size > 1
37
-
38
- add_offense(comment) do |corrector|
39
- corrector.replace(comment, comment.text.gsub(%r{ # rubocop:(disable|todo)}, ','))
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end