rubocop 1.67.0 → 1.81.6

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 (526) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +384 -72
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +19 -4
  15. data/lib/rubocop/comment_config.rb +2 -2
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +56 -48
  18. data/lib/rubocop/config_loader_resolver.rb +36 -10
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +53 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -16
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/generator.rb +6 -0
  42. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  43. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  44. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  47. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  48. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  49. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  52. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  55. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  56. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  57. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  58. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  59. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  60. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  61. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  62. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  63. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  64. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  66. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  67. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  68. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  70. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  72. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  73. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  74. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  76. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  77. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  78. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  79. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  81. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  82. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  83. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  84. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  85. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  86. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  87. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  88. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  89. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  90. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  91. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  93. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -11
  95. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  97. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  98. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  99. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  100. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  101. data/lib/rubocop/cop/layout/line_length.rb +158 -10
  102. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  105. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  106. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  107. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  108. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  109. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  110. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  111. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  112. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
  113. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  115. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  116. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  118. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  119. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  121. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  122. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  123. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  125. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  126. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  127. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  128. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  129. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  130. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  131. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  132. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  133. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  134. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  135. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  136. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  137. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  138. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  140. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  141. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  142. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  143. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
  144. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  145. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  146. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  147. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  148. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  149. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  150. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  151. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  152. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  153. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  154. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  155. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  156. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  157. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  158. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  159. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  160. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  161. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  162. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  163. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  164. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  165. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  166. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  167. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
  168. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  169. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  170. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  171. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  172. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  173. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  174. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  175. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  176. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  177. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  178. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  179. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  180. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  181. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  182. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  183. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  184. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  185. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  186. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  187. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  188. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  189. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  190. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  191. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  192. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  193. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  194. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  195. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  196. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  197. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  198. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  199. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  200. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  201. data/lib/rubocop/cop/lint/self_assignment.rb +39 -15
  202. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  203. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  204. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  205. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  206. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  207. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  208. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  209. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  210. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  211. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  212. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  213. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  214. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  215. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  216. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  217. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  218. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  219. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  220. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  221. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  222. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  223. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  224. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  225. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  226. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  227. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  228. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  229. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  230. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  231. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  232. data/lib/rubocop/cop/lint/void.rb +23 -12
  233. data/lib/rubocop/cop/message_annotator.rb +7 -3
  234. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  235. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  236. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  237. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  238. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  239. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  240. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  241. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  242. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  243. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  244. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  245. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  246. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  247. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  248. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  249. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  250. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  251. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  252. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  253. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  254. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  255. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  256. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  257. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  258. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  259. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  260. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  261. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  262. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  263. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  264. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  265. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  266. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  267. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  268. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  269. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  270. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  271. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  272. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  273. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  274. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  275. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  276. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  277. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  278. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  279. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  280. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  281. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  282. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  283. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  284. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  285. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  286. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  287. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  288. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  289. data/lib/rubocop/cop/offense.rb +2 -3
  290. data/lib/rubocop/cop/registry.rb +9 -6
  291. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  292. data/lib/rubocop/cop/security/eval.rb +2 -1
  293. data/lib/rubocop/cop/security/json_load.rb +33 -11
  294. data/lib/rubocop/cop/security/open.rb +1 -0
  295. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  296. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  297. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  298. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  299. data/lib/rubocop/cop/style/and_or.rb +1 -1
  300. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  301. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  302. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  303. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  304. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  305. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  306. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  307. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  308. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  309. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  310. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  311. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  312. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  313. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  314. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  315. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  316. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  317. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -31
  318. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  319. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  320. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  321. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  322. data/lib/rubocop/cop/style/documentation.rb +1 -1
  323. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  324. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  325. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  326. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  327. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  328. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  329. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  330. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  331. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  332. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  333. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  334. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  335. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  336. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  337. data/lib/rubocop/cop/style/file_null.rb +89 -0
  338. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  339. data/lib/rubocop/cop/style/float_division.rb +8 -4
  340. data/lib/rubocop/cop/style/for.rb +1 -1
  341. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  342. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  343. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  344. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  345. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  346. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  347. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  348. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  349. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  350. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  351. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  352. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  353. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  354. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  355. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  356. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  357. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  358. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  359. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  360. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  361. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  362. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  363. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  364. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  365. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  366. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  367. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  368. data/lib/rubocop/cop/style/lambda.rb +1 -0
  369. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  370. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  371. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  372. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  373. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  374. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  379. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  380. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  381. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  382. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  383. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  384. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  385. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  386. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  387. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  388. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  389. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  390. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  391. data/lib/rubocop/cop/style/next.rb +44 -0
  392. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  393. data/lib/rubocop/cop/style/not.rb +1 -1
  394. data/lib/rubocop/cop/style/object_then.rb +15 -15
  395. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  396. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  397. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  398. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  399. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  400. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  401. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  402. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  403. data/lib/rubocop/cop/style/proc.rb +2 -2
  404. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  405. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  406. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  407. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  408. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  409. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  410. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  411. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  412. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  413. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  414. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  415. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  416. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  417. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  418. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  419. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  420. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  421. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  422. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  423. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
  424. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  425. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  426. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  427. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  428. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  429. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  430. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  431. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  432. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  433. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  434. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  435. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  436. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  437. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  438. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  439. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  440. data/lib/rubocop/cop/style/semicolon.rb +21 -6
  441. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  442. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  443. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  444. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  445. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  446. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  447. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  448. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  449. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  450. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  451. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  452. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  453. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  454. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  455. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  456. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  457. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  458. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  459. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  460. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  461. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  462. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  463. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  464. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  465. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  466. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  467. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  468. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  469. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  470. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  471. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  472. data/lib/rubocop/cop/team.rb +1 -1
  473. data/lib/rubocop/cop/util.rb +12 -5
  474. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  475. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  476. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  477. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  478. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  479. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  480. data/lib/rubocop/cop/variable_force.rb +30 -19
  481. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  482. data/lib/rubocop/directive_comment.rb +45 -11
  483. data/lib/rubocop/ext/regexp_node.rb +0 -1
  484. data/lib/rubocop/formatter/disabled_config_formatter.rb +20 -6
  485. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  486. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  487. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  488. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  489. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  490. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  491. data/lib/rubocop/lsp/diagnostic.rb +190 -0
  492. data/lib/rubocop/lsp/logger.rb +2 -2
  493. data/lib/rubocop/lsp/routes.rb +66 -26
  494. data/lib/rubocop/lsp/runtime.rb +18 -50
  495. data/lib/rubocop/lsp/server.rb +2 -4
  496. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  497. data/lib/rubocop/magic_comment.rb +11 -3
  498. data/lib/rubocop/options.rb +28 -12
  499. data/lib/rubocop/path_util.rb +15 -8
  500. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  501. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  502. data/lib/rubocop/plugin/load_error.rb +26 -0
  503. data/lib/rubocop/plugin/loader.rb +100 -0
  504. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  505. data/lib/rubocop/plugin.rb +46 -0
  506. data/lib/rubocop/rake_task.rb +4 -1
  507. data/lib/rubocop/result_cache.rb +27 -25
  508. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  509. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  510. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  511. data/lib/rubocop/rspec/support.rb +4 -2
  512. data/lib/rubocop/runner.rb +31 -18
  513. data/lib/rubocop/server/cache.rb +51 -13
  514. data/lib/rubocop/server/cli.rb +2 -2
  515. data/lib/rubocop/server/client_command/base.rb +10 -0
  516. data/lib/rubocop/server/client_command/exec.rb +2 -1
  517. data/lib/rubocop/server/client_command/start.rb +11 -1
  518. data/lib/rubocop/target_finder.rb +14 -9
  519. data/lib/rubocop/target_ruby.rb +27 -3
  520. data/lib/rubocop/version.rb +53 -12
  521. data/lib/rubocop.rb +44 -2
  522. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  523. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  524. metadata +91 -21
  525. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  526. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -12,16 +12,30 @@ module RuboCop
12
12
  # @api private
13
13
  LINT_SYNTAX_COP = "#{LINT_DEPARTMENT}/Syntax"
14
14
  # @api private
15
- COP_NAME_PATTERN = '([A-Z]\w+/)*(?:[A-Z]\w+)'
15
+ COP_NAME_PATTERN = '([A-Za-z]\w+/)*(?:[A-Za-z]\w+)'
16
16
  # @api private
17
17
  COP_NAMES_PATTERN = "(?:#{COP_NAME_PATTERN} , )*#{COP_NAME_PATTERN}"
18
18
  # @api private
19
19
  COPS_PATTERN = "(all|#{COP_NAMES_PATTERN})"
20
20
  # @api private
21
+ AVAILABLE_MODES = %w[disable enable todo].freeze
22
+ # @api private
23
+ DIRECTIVE_MARKER_PATTERN = '# rubocop : '
24
+ # @api private
25
+ DIRECTIVE_MARKER_REGEXP = Regexp.new(DIRECTIVE_MARKER_PATTERN.gsub(' ', '\s*'))
26
+ # @api private
27
+ DIRECTIVE_HEADER_PATTERN = "#{DIRECTIVE_MARKER_PATTERN}((?:#{AVAILABLE_MODES.join('|')}))\\b"
28
+ # @api private
21
29
  DIRECTIVE_COMMENT_REGEXP = Regexp.new(
22
- "# rubocop : ((?:disable|enable|todo))\\b #{COPS_PATTERN}"
30
+ "#{DIRECTIVE_HEADER_PATTERN} #{COPS_PATTERN}"
23
31
  .gsub(' ', '\s*')
24
32
  )
33
+ # @api private
34
+ TRAILING_COMMENT_MARKER = '--'
35
+ # @api private
36
+ MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP = Regexp.new(
37
+ "\\A#{DIRECTIVE_HEADER_PATTERN}\\s*\\z".gsub(' ', '\s*')
38
+ )
25
39
 
26
40
  def self.before_comment(line)
27
41
  line.split(DIRECTIVE_COMMENT_REGEXP).first
@@ -32,9 +46,28 @@ module RuboCop
32
46
  def initialize(comment, cop_registry = Cop::Registry.global)
33
47
  @comment = comment
34
48
  @cop_registry = cop_registry
49
+ @match_data = comment.text.match(DIRECTIVE_COMMENT_REGEXP)
35
50
  @mode, @cops = match_captures
36
51
  end
37
52
 
53
+ # Checks if the comment starts with `# rubocop:` marker
54
+ def start_with_marker?
55
+ comment.text.start_with?(DIRECTIVE_MARKER_REGEXP)
56
+ end
57
+
58
+ # Checks if the comment is malformed as a `# rubocop:` directive
59
+ def malformed?
60
+ return true if !start_with_marker? || @match_data.nil?
61
+
62
+ tail = @match_data.post_match.lstrip
63
+ !(tail.empty? || tail.start_with?(TRAILING_COMMENT_MARKER))
64
+ end
65
+
66
+ # Checks if the directive comment is missing a cop name
67
+ def missing_cop_name?
68
+ MALFORMED_DIRECTIVE_WITHOUT_COP_NAME_REGEXP.match?(comment.text)
69
+ end
70
+
38
71
  # Checks if this directive relates to single line
39
72
  def single_line?
40
73
  !comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP)
@@ -55,7 +88,7 @@ module RuboCop
55
88
 
56
89
  # Returns match captures to directive comment pattern
57
90
  def match_captures
58
- @match_captures ||= comment.text.match(DIRECTIVE_COMMENT_REGEXP)&.captures
91
+ @match_captures ||= @match_data&.captures
59
92
  end
60
93
 
61
94
  # Checks if this directive disables cops
@@ -88,10 +121,15 @@ module RuboCop
88
121
  @cop_names ||= all_cops? ? all_cop_names : parsed_cop_names
89
122
  end
90
123
 
124
+ # Returns an array of cops for this directive comment, without resolving departments
125
+ def raw_cop_names
126
+ @raw_cop_names ||= (cops || '').split(/,\s*/)
127
+ end
128
+
91
129
  # Returns array of specified in this directive department names
92
130
  # when all department disabled
93
131
  def department_names
94
- splitted_cops_string.select { |cop| department?(cop) }
132
+ raw_cop_names.select { |cop| department?(cop) }
95
133
  end
96
134
 
97
135
  # Checks if directive departments include cop
@@ -101,11 +139,11 @@ module RuboCop
101
139
 
102
140
  # Checks if cop department has already used in directive comment
103
141
  def overridden_by_department?(cop)
104
- in_directive_department?(cop) && splitted_cops_string.include?(cop)
142
+ in_directive_department?(cop) && raw_cop_names.include?(cop)
105
143
  end
106
144
 
107
145
  def directive_count
108
- splitted_cops_string.count
146
+ raw_cop_names.count
109
147
  end
110
148
 
111
149
  # Returns line number for directive
@@ -115,12 +153,8 @@ module RuboCop
115
153
 
116
154
  private
117
155
 
118
- def splitted_cops_string
119
- (cops || '').split(/,\s*/)
120
- end
121
-
122
156
  def parsed_cop_names
123
- cops = splitted_cops_string.map do |name|
157
+ cops = raw_cop_names.map do |name|
124
158
  department?(name) ? cop_names_for_department(name) : name
125
159
  end.flatten
126
160
  cops - [LINT_SYNTAX_COP]
@@ -43,7 +43,6 @@ module RuboCop
43
43
  def named_capturing?(exp, event, named)
44
44
  event == :enter &&
45
45
  named == exp.respond_to?(:name) &&
46
- !exp.text.start_with?('(?<=') &&
47
46
  exp.respond_to?(:capturing?) &&
48
47
  exp.capturing?
49
48
  end
@@ -4,19 +4,35 @@ module RuboCop
4
4
  module Formatter
5
5
  # This formatter displays a YAML configuration file where all cops that
6
6
  # detected any offenses are configured to not detect the offense.
7
- class DisabledConfigFormatter < BaseFormatter
7
+ class DisabledConfigFormatter < BaseFormatter # rubocop:disable Metrics/ClassLength
8
8
  include PathUtil
9
9
 
10
10
  HEADING = <<~COMMENTS
11
11
  # This configuration was generated by
12
12
  # `%<command>s`
13
- # %<timestamp>susing RuboCop version #{Version.version}.
13
+ # %<timestamp>susing RuboCop version #{Version::STRING}.
14
14
  # The point is for the user to remove these configuration records
15
15
  # one by one as the offenses are removed from the code base.
16
16
  # Note that changes in the inspected code, or installation of new
17
17
  # versions of RuboCop, may require this file to be generated again.
18
18
  COMMENTS
19
19
 
20
+ EXCLUDED_CONFIG_KEYS = %w[
21
+ AutoCorrect
22
+ Description
23
+ Enabled
24
+ Exclude
25
+ Include
26
+ Reference
27
+ References
28
+ Safe
29
+ SafeAutoCorrect
30
+ StyleGuide
31
+ VersionAdded
32
+ VersionChanged
33
+ VersionRemoved
34
+ ].freeze
35
+
20
36
  @config_to_allow_offenses = {}
21
37
  @detected_styles = {}
22
38
 
@@ -163,10 +179,7 @@ module RuboCop
163
179
  end
164
180
 
165
181
  def cop_config_params(default_cfg, cfg)
166
- default_cfg.keys -
167
- %w[Description StyleGuide Reference Enabled Exclude Safe
168
- SafeAutoCorrect VersionAdded VersionChanged VersionRemoved] -
169
- cfg.keys
182
+ default_cfg.keys - EXCLUDED_CONFIG_KEYS - cfg.keys
170
183
  end
171
184
 
172
185
  def output_cop_param_comments(output_buffer, params, default_cfg)
@@ -178,6 +191,7 @@ module RuboCop
178
191
  next unless value.is_a?(Array)
179
192
  next if value.empty?
180
193
 
194
+ value.map! { |v| v.nil? ? '~' : v } # Change nil back to ~ as in the YAML file.
181
195
  output_buffer.puts "# #{param}: #{value.uniq.join(', ')}"
182
196
  end
183
197
  end
@@ -77,7 +77,7 @@ module RuboCop
77
77
  case formatter_type
78
78
  when Class
79
79
  formatter_type
80
- when /\A[A-Z]/
80
+ when /\A(::)?[A-Z]/
81
81
  custom_formatter_class(formatter_type)
82
82
  else
83
83
  builtin_formatter_class(formatter_type)
@@ -22,7 +22,7 @@ module RuboCop
22
22
 
23
23
  @severest_offense = nil
24
24
 
25
- file_phrase = target_files.count == 1 ? 'file' : 'files'
25
+ file_phrase = target_files.one? ? 'file' : 'files'
26
26
 
27
27
  # 185/407 files |====== 45 ======> | ETA: 00:00:04
28
28
  # %c / %C | %w > %i | %e
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require 'cgi/escape'
4
4
  require 'erb'
5
5
 
6
6
  module RuboCop
@@ -6,6 +6,7 @@ module RuboCop
6
6
  class MarkdownFormatter < BaseFormatter
7
7
  include TextUtil
8
8
  include PathUtil
9
+
9
10
  attr_reader :files, :summary
10
11
 
11
12
  def initialize(output, options = {})
@@ -24,7 +24,7 @@ module RuboCop
24
24
 
25
25
  return unless output.tty?
26
26
 
27
- file_phrase = target_files.count == 1 ? 'file' : 'files'
27
+ file_phrase = target_files.one? ? 'file' : 'files'
28
28
 
29
29
  # 185/407 files |====== 45 ======> | ETA: 00:00:04
30
30
  # %c / %C | %w > %i | %e
@@ -9,6 +9,7 @@ module RuboCop
9
9
  # https://github.com/go-labs/rspec_pacman_formatter
10
10
  class PacmanFormatter < ClangStyleFormatter
11
11
  include TextUtil
12
+
12
13
  attr_accessor :progress_line
13
14
 
14
15
  FALLBACK_TERMINAL_WIDTH = 80
@@ -58,7 +59,7 @@ module RuboCop
58
59
  return pacdots(@total_files) unless @total_files > cols
59
60
  return pacdots(cols) unless (@total_files / cols).eql?(@repetitions)
60
61
 
61
- pacdots((@total_files - (cols * @repetitions)))
62
+ pacdots(@total_files - (cols * @repetitions))
62
63
  end
63
64
 
64
65
  def pacdots(number)
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'severity'
4
+
5
+ #
6
+ # This code is based on https://github.com/standardrb/standard.
7
+ #
8
+ # Copyright (c) 2023 Test Double, Inc.
9
+ #
10
+ # The MIT License (MIT)
11
+ #
12
+ # https://github.com/standardrb/standard/blob/main/LICENSE.txt
13
+ #
14
+ module RuboCop
15
+ module LSP
16
+ # Diagnostic for Language Server Protocol of RuboCop.
17
+ # @api private
18
+ class Diagnostic
19
+ def initialize(position_encoding, offense, uri, cop_class)
20
+ @position_encoding = position_encoding
21
+ @offense = offense
22
+ @uri = uri
23
+ @cop_class = cop_class
24
+ end
25
+
26
+ def to_lsp_code_actions
27
+ code_actions = []
28
+
29
+ code_actions << autocorrect_action if correctable?
30
+ code_actions << disable_line_action
31
+
32
+ code_actions
33
+ end
34
+
35
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
36
+ def to_lsp_diagnostic(config)
37
+ highlighted = @offense.highlighted_area
38
+
39
+ LanguageServer::Protocol::Interface::Diagnostic.new(
40
+ message: message,
41
+ source: 'RuboCop',
42
+ code: @offense.cop_name,
43
+ code_description: code_description(config),
44
+ severity: severity,
45
+ range: LanguageServer::Protocol::Interface::Range.new(
46
+ start: LanguageServer::Protocol::Interface::Position.new(
47
+ line: @offense.line - 1,
48
+ character: to_position_character(highlighted.begin_pos)
49
+ ),
50
+ end: LanguageServer::Protocol::Interface::Position.new(
51
+ line: @offense.line - 1,
52
+ character: to_position_character(highlighted.end_pos)
53
+ )
54
+ ),
55
+ data: {
56
+ correctable: correctable?,
57
+ code_actions: to_lsp_code_actions
58
+ }
59
+ )
60
+ end
61
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
62
+
63
+ private
64
+
65
+ def message
66
+ message = @offense.message
67
+ message += "\n\nThis offense is not autocorrectable.\n" unless correctable?
68
+ message
69
+ end
70
+
71
+ def severity
72
+ Severity.find_by(@offense.severity.name)
73
+ end
74
+
75
+ def code_description(config)
76
+ return unless @cop_class
77
+ return unless (doc_url = @cop_class.documentation_url(config))
78
+
79
+ LanguageServer::Protocol::Interface::CodeDescription.new(href: doc_url)
80
+ end
81
+
82
+ # rubocop:disable Metrics/MethodLength
83
+ def autocorrect_action
84
+ LanguageServer::Protocol::Interface::CodeAction.new(
85
+ title: "Autocorrect #{@offense.cop_name}",
86
+ kind: LanguageServer::Protocol::Constant::CodeActionKind::QUICK_FIX,
87
+ edit: LanguageServer::Protocol::Interface::WorkspaceEdit.new(
88
+ document_changes: [
89
+ LanguageServer::Protocol::Interface::TextDocumentEdit.new(
90
+ text_document: LanguageServer::Protocol::Interface::OptionalVersionedTextDocumentIdentifier.new(
91
+ uri: ensure_uri_scheme(@uri.to_s).to_s,
92
+ version: nil
93
+ ),
94
+ edits: correctable? ? offense_replacements : []
95
+ )
96
+ ]
97
+ ),
98
+ is_preferred: true
99
+ )
100
+ end
101
+ # rubocop:enable Metrics/MethodLength
102
+
103
+ # rubocop:disable Metrics/MethodLength
104
+ def offense_replacements
105
+ @offense.corrector.as_replacements.map do |range, replacement|
106
+ LanguageServer::Protocol::Interface::TextEdit.new(
107
+ range: LanguageServer::Protocol::Interface::Range.new(
108
+ start: LanguageServer::Protocol::Interface::Position.new(
109
+ line: range.line - 1,
110
+ character: to_position_character(range.column)
111
+ ),
112
+ end: LanguageServer::Protocol::Interface::Position.new(
113
+ line: range.last_line - 1,
114
+ character: to_position_character(range.last_column)
115
+ )
116
+ ),
117
+ new_text: replacement
118
+ )
119
+ end
120
+ end
121
+ # rubocop:enable Metrics/MethodLength
122
+
123
+ # rubocop:disable Metrics/MethodLength
124
+ def disable_line_action
125
+ LanguageServer::Protocol::Interface::CodeAction.new(
126
+ title: "Disable #{@offense.cop_name} for this line",
127
+ kind: LanguageServer::Protocol::Constant::CodeActionKind::QUICK_FIX,
128
+ edit: LanguageServer::Protocol::Interface::WorkspaceEdit.new(
129
+ document_changes: [
130
+ LanguageServer::Protocol::Interface::TextDocumentEdit.new(
131
+ text_document: LanguageServer::Protocol::Interface::OptionalVersionedTextDocumentIdentifier.new(
132
+ uri: ensure_uri_scheme(@uri.to_s).to_s,
133
+ version: nil
134
+ ),
135
+ edits: line_disable_comment
136
+ )
137
+ ]
138
+ )
139
+ )
140
+ end
141
+ # rubocop:enable Metrics/MethodLength
142
+
143
+ def line_disable_comment
144
+ new_text = if @offense.source_line.include?(' # rubocop:disable ')
145
+ ",#{@offense.cop_name}"
146
+ else
147
+ " # rubocop:disable #{@offense.cop_name}"
148
+ end
149
+
150
+ eol = LanguageServer::Protocol::Interface::Position.new(
151
+ line: @offense.line - 1,
152
+ character: to_position_character
153
+ )
154
+
155
+ # TODO: fails for multiline strings - may be preferable to use block
156
+ # comments to disable some offenses
157
+ inline_comment = LanguageServer::Protocol::Interface::TextEdit.new(
158
+ range: LanguageServer::Protocol::Interface::Range.new(start: eol, end: eol),
159
+ new_text: new_text
160
+ )
161
+
162
+ [inline_comment]
163
+ end
164
+
165
+ def correctable?
166
+ !@offense.corrector.nil?
167
+ end
168
+
169
+ def ensure_uri_scheme(uri)
170
+ uri = URI.parse(uri)
171
+ uri.scheme = 'file' if uri.scheme.nil?
172
+ uri
173
+ end
174
+
175
+ def to_position_character(utf8_index = nil)
176
+ str = utf8_index ? @offense.source_line[0, utf8_index] : @offense.source_line
177
+ case @position_encoding
178
+ when 'utf-8', Encoding::UTF_8
179
+ str.bytesize
180
+ when 'utf-32', Encoding::UTF_32
181
+ str.size
182
+ else # 'utf-16'
183
+ # utf-16 is default position encoding on LSP
184
+ # https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
185
+ str.size + str.count("\u{10000}-\u{10FFFF}")
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -14,8 +14,8 @@ module RuboCop
14
14
  # Log for Language Server Protocol of RuboCop.
15
15
  # @api private
16
16
  class Logger
17
- def self.log(message)
18
- warn("[server] #{message}")
17
+ def self.log(message, prefix: '[server]')
18
+ warn("#{prefix} #{message}")
19
19
  end
20
20
  end
21
21
  end
@@ -15,7 +15,12 @@ module RuboCop
15
15
  module LSP
16
16
  # Routes for Language Server Protocol of RuboCop.
17
17
  # @api private
18
- class Routes
18
+ class Routes # rubocop:disable Metrics/ClassLength
19
+ CONFIGURATION_FILE_PATTERNS = [
20
+ RuboCop::ConfigFinder::DOTFILE,
21
+ RuboCop::CLI::Command::AutoGenerateConfig::AUTO_GENERATED_FILE
22
+ ].freeze
23
+
19
24
  def self.handle(name, &block)
20
25
  define_method(:"handle_#{name}", &block)
21
26
  end
@@ -37,6 +42,7 @@ module RuboCop
37
42
 
38
43
  handle 'initialize' do |request|
39
44
  initialization_options = extract_initialization_options_from(request)
45
+ @position_encoding = initialization_options[:position_encoding]
40
46
 
41
47
  @server.configure(initialization_options)
42
48
 
@@ -46,9 +52,10 @@ module RuboCop
46
52
  capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
47
53
  document_formatting_provider: true,
48
54
  text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
49
- change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL,
55
+ change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::INCREMENTAL,
50
56
  open_close: true
51
- )
57
+ ),
58
+ position_encoding: @position_encoding
52
59
  )
53
60
  )
54
61
  )
@@ -71,7 +78,12 @@ module RuboCop
71
78
 
72
79
  handle 'textDocument/didChange' do |request|
73
80
  params = request[:params]
74
- result = diagnostic(params[:textDocument][:uri], params[:contentChanges][0][:text])
81
+ file_uri = params[:textDocument][:uri]
82
+ text = @text_cache[file_uri]
83
+ params[:contentChanges].each do |content|
84
+ text = change_text(text, content[:text], content[:range])
85
+ end
86
+ result = diagnostic(file_uri, text)
75
87
  @server.write(result)
76
88
  end
77
89
 
@@ -96,7 +108,7 @@ module RuboCop
96
108
 
97
109
  handle 'workspace/didChangeWatchedFiles' do |request|
98
110
  changed = request[:params][:changes].any? do |change|
99
- change[:uri].end_with?(RuboCop::ConfigFinder::DOTFILE)
111
+ CONFIGURATION_FILE_PATTERNS.any? { |path| change[:uri].end_with?(path) }
100
112
  end
101
113
 
102
114
  if changed
@@ -174,14 +186,26 @@ module RuboCop
174
186
 
175
187
  def extract_initialization_options_from(request)
176
188
  safe_autocorrect = request.dig(:params, :initializationOptions, :safeAutocorrect)
189
+ position_encodings = request.dig(:params, :capabilities, :general, :positionEncodings)
177
190
 
178
191
  {
179
192
  safe_autocorrect: safe_autocorrect.nil? || safe_autocorrect == true,
180
193
  lint_mode: request.dig(:params, :initializationOptions, :lintMode) == true,
181
- layout_mode: request.dig(:params, :initializationOptions, :layoutMode) == true
194
+ layout_mode: request.dig(:params, :initializationOptions, :layoutMode) == true,
195
+ position_encoding: position_encoding(position_encodings)
182
196
  }
183
197
  end
184
198
 
199
+ def position_encoding(position_encodings)
200
+ if position_encodings&.include?('utf-8')
201
+ 'utf-8'
202
+ elsif position_encodings&.include?('utf-32')
203
+ 'utf-32'
204
+ else
205
+ 'utf-16'
206
+ end
207
+ end
208
+
185
209
  def format_file(file_uri, command: nil)
186
210
  unless (text = @text_cache[file_uri])
187
211
  Logger.log("Format request arrived before text synchronized; skipping: `#{file_uri}'")
@@ -189,7 +213,7 @@ module RuboCop
189
213
  return []
190
214
  end
191
215
 
192
- new_text = @server.format(remove_file_protocol_from(file_uri), text, command: command)
216
+ new_text = @server.format(convert_file_uri_to_path(file_uri), text, command: command)
193
217
 
194
218
  return [] if new_text == text
195
219
 
@@ -204,39 +228,55 @@ module RuboCop
204
228
 
205
229
  def diagnostic(file_uri, text)
206
230
  @text_cache[file_uri] = text
207
- offenses = @server.offenses(remove_file_protocol_from(file_uri), text)
208
- diagnostics = offenses.map { |offense| to_diagnostic(offense) }
209
231
 
210
232
  {
211
233
  method: 'textDocument/publishDiagnostics',
212
234
  params: {
213
235
  uri: file_uri,
214
- diagnostics: diagnostics
236
+ diagnostics: @server.offenses(convert_file_uri_to_path(file_uri),
237
+ text, @position_encoding)
215
238
  }
216
239
  }
217
240
  end
218
241
 
219
- def remove_file_protocol_from(uri)
220
- uri.delete_prefix('file://')
242
+ def change_text(orig_text, text, range)
243
+ return text unless range
244
+
245
+ start_pos = text_pos(orig_text, range[:start])
246
+ end_pos = text_pos(orig_text, range[:end])
247
+ orig_text[start_pos...end_pos] = text
248
+ orig_text
221
249
  end
222
250
 
223
- def to_diagnostic(offense)
224
- code = offense[:cop_name]
225
- message = offense[:message]
226
- loc = offense[:location]
227
- rubocop_severity = offense[:severity]
228
- severity = Severity.find_by(rubocop_severity)
251
+ def text_pos(text, range)
252
+ line = range[:line]
253
+ char = range[:character]
254
+ pos = 0
255
+ text.each_line.with_index do |l, i|
256
+ if i == line
257
+ pos += line_pos(l, char)
258
+ return pos
259
+ end
260
+ pos += l.size
261
+ end
262
+ pos
263
+ end
229
264
 
230
- {
231
- code: code, message: message, range: to_range(loc), severity: severity, source: 'rubocop'
232
- }
265
+ def line_pos(line, char)
266
+ case @position_encoding
267
+ when 'utf-8'
268
+ line.byteslice(0, char).size
269
+ when 'utf-32'
270
+ char
271
+ else # 'utf-16'
272
+ # utf-16 is default position encoding on LSP
273
+ # https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
274
+ line.encode('utf-16be').byteslice(0, char * 2).size
275
+ end
233
276
  end
234
277
 
235
- def to_range(location)
236
- {
237
- start: { character: location[:start_column] - 1, line: location[:start_line] - 1 },
238
- end: { character: location[:last_column], line: location[:last_line] - 1 }
239
- }
278
+ def convert_file_uri_to_path(uri)
279
+ URI.decode_www_form_component(uri.delete_prefix('file://'))
240
280
  end
241
281
  end
242
282
  end