rubocop 1.67.0 → 1.82.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +403 -75
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +12 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +21 -5
  15. data/lib/rubocop/comment_config.rb +64 -19
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +58 -49
  18. data/lib/rubocop/config_loader_resolver.rb +43 -16
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +57 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +2 -3
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +9 -19
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +2 -3
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
  42. data/lib/rubocop/cop/generator.rb +6 -0
  43. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  44. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  45. data/lib/rubocop/cop/internal_affairs/location_exists.rb +142 -0
  46. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  47. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  48. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  49. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  52. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  55. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  56. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  57. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  58. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  59. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  60. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  61. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  62. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  63. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  64. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  65. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  66. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  67. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  68. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  69. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  70. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  71. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  72. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  73. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  74. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  75. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  76. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  77. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  78. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +6 -3
  79. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  80. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  81. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  82. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  83. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  84. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  85. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  86. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  87. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  88. data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
  89. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  90. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  91. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  93. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  94. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  95. data/lib/rubocop/cop/layout/hash_alignment.rb +10 -11
  96. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -3
  97. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -4
  98. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  99. data/lib/rubocop/cop/layout/indentation_width.rb +20 -8
  100. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  101. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  102. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  103. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  104. data/lib/rubocop/cop/layout/line_length.rb +163 -11
  105. data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -0
  106. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  107. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  108. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  109. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +9 -5
  110. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  111. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  112. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  113. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  114. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  115. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +16 -7
  116. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  118. data/lib/rubocop/cop/layout/space_after_comma.rb +3 -11
  119. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_after_semicolon.rb +12 -2
  121. data/lib/rubocop/cop/layout/space_around_keyword.rb +9 -3
  122. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  123. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  124. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  125. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  126. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  127. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  128. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  129. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  130. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  131. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  132. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  133. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  134. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  135. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  136. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  137. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  138. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  139. data/lib/rubocop/cop/lint/circular_argument_reference.rb +51 -4
  140. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  141. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  142. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  143. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  144. data/lib/rubocop/cop/lint/debugger.rb +3 -5
  145. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  146. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
  147. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  148. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +5 -5
  149. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  150. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  151. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  152. data/lib/rubocop/cop/lint/else_layout.rb +19 -0
  153. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  154. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  155. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  156. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  157. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  158. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  159. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  160. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  161. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  162. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  163. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  164. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  165. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  166. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  167. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  168. data/lib/rubocop/cop/lint/literal_as_condition.rb +129 -10
  169. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  170. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +25 -7
  171. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +17 -8
  172. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  173. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  174. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  175. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  176. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  177. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +6 -2
  178. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  179. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  180. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  181. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  182. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  183. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  184. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  185. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  186. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  187. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  188. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
  189. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  190. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  191. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -23
  192. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  193. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +15 -8
  194. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  195. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  196. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  197. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  198. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  199. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  200. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  201. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  202. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  203. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  204. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  205. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  206. data/lib/rubocop/cop/lint/self_assignment.rb +47 -15
  207. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  208. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  209. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  210. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  211. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  212. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  213. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  214. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  215. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  216. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  217. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  218. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  219. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  220. data/lib/rubocop/cop/lint/unreachable_code.rb +54 -2
  221. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  222. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  223. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  224. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  225. data/lib/rubocop/cop/lint/useless_assignment.rb +47 -17
  226. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  227. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  228. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  229. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  230. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  231. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  232. data/lib/rubocop/cop/lint/useless_or.rb +111 -0
  233. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  234. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  235. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  236. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  237. data/lib/rubocop/cop/lint/void.rb +23 -12
  238. data/lib/rubocop/cop/message_annotator.rb +7 -3
  239. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  240. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  241. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  242. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  243. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  244. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  245. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  246. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  247. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  248. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +5 -4
  249. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  250. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  251. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  252. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  253. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  254. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  255. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +47 -0
  256. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  257. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  258. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  259. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  260. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  261. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  262. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  263. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  264. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  265. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  266. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  267. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  268. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  269. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  270. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  271. data/lib/rubocop/cop/mixin/line_length_help.rb +48 -12
  272. data/lib/rubocop/cop/mixin/method_complexity.rb +3 -2
  273. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +8 -10
  274. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  275. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  276. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  277. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  278. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  279. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
  280. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  281. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -8
  282. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  283. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  284. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  285. data/lib/rubocop/cop/mixin/trailing_comma.rb +28 -9
  286. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  287. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  288. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  289. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  290. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  291. data/lib/rubocop/cop/naming/method_name.rb +187 -15
  292. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  293. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  294. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  295. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  296. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  297. data/lib/rubocop/cop/offense.rb +2 -3
  298. data/lib/rubocop/cop/registry.rb +9 -6
  299. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  300. data/lib/rubocop/cop/security/eval.rb +2 -1
  301. data/lib/rubocop/cop/security/json_load.rb +33 -11
  302. data/lib/rubocop/cop/security/open.rb +1 -0
  303. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  304. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  305. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  306. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  307. data/lib/rubocop/cop/style/and_or.rb +1 -1
  308. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  309. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  310. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  311. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  312. data/lib/rubocop/cop/style/bare_percent_literals.rb +1 -2
  313. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  314. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  315. data/lib/rubocop/cop/style/case_equality.rb +11 -13
  316. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  317. data/lib/rubocop/cop/style/class_and_module_children.rb +53 -11
  318. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  319. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  320. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  321. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  322. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  323. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  324. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  325. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  326. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  327. data/lib/rubocop/cop/style/conditional_assignment.rb +50 -42
  328. data/lib/rubocop/cop/style/constant_visibility.rb +19 -23
  329. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  330. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  331. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  332. data/lib/rubocop/cop/style/documentation.rb +1 -1
  333. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  334. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  335. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  336. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  337. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  338. data/lib/rubocop/cop/style/empty_method.rb +0 -6
  339. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  340. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  341. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  342. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  343. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  344. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  345. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  346. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  347. data/lib/rubocop/cop/style/file_null.rb +89 -0
  348. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  349. data/lib/rubocop/cop/style/float_division.rb +23 -5
  350. data/lib/rubocop/cop/style/for.rb +1 -1
  351. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  352. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  353. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  354. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  355. data/lib/rubocop/cop/style/guard_clause.rb +17 -14
  356. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  357. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  358. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  359. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  360. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  361. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  362. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  363. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  364. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  365. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  366. data/lib/rubocop/cop/style/if_unless_modifier.rb +39 -12
  367. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  368. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  369. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  370. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  371. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  372. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  373. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  374. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  375. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  376. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  377. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  378. data/lib/rubocop/cop/style/lambda.rb +1 -0
  379. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  380. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  381. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  382. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  383. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  384. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  385. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +12 -1
  386. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +35 -4
  387. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  388. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  389. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  390. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  391. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  392. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  393. data/lib/rubocop/cop/style/module_member_existence_check.rb +74 -0
  394. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  395. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  396. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  397. data/lib/rubocop/cop/style/multiline_method_signature.rb +3 -13
  398. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  399. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  400. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  401. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  402. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  403. data/lib/rubocop/cop/style/next.rb +44 -0
  404. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  405. data/lib/rubocop/cop/style/not.rb +1 -1
  406. data/lib/rubocop/cop/style/object_then.rb +15 -15
  407. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  408. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  409. data/lib/rubocop/cop/style/operator_method_call.rb +16 -8
  410. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  411. data/lib/rubocop/cop/style/parallel_assignment.rb +43 -40
  412. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  413. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  414. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  415. data/lib/rubocop/cop/style/proc.rb +2 -2
  416. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  417. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  418. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  419. data/lib/rubocop/cop/style/redundant_argument.rb +5 -1
  420. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  421. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  422. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  423. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  424. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  425. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  426. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  427. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  428. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  429. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  430. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  431. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  432. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  433. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  434. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  435. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -2
  436. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +13 -0
  437. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  438. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  439. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  440. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  441. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  442. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  443. data/lib/rubocop/cop/style/redundant_sort.rb +10 -10
  444. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  445. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  446. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  447. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  448. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  449. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  450. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  451. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  452. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  453. data/lib/rubocop/cop/style/semicolon.rb +24 -8
  454. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  455. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  456. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  457. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  458. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  459. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  460. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  461. data/lib/rubocop/cop/style/sole_nested_conditional.rb +75 -102
  462. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  463. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  464. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  465. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  466. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  467. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  468. data/lib/rubocop/cop/style/super_arguments.rb +68 -21
  469. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  470. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  471. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  472. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  473. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  474. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  475. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  476. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  477. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  478. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +15 -15
  479. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  480. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  481. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  482. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  483. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  484. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  485. data/lib/rubocop/cop/team.rb +1 -1
  486. data/lib/rubocop/cop/util.rb +14 -8
  487. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  488. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  489. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  490. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  491. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  492. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  493. data/lib/rubocop/cop/variable_force.rb +30 -19
  494. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  495. data/lib/rubocop/directive_comment.rb +88 -11
  496. data/lib/rubocop/ext/regexp_node.rb +0 -1
  497. data/lib/rubocop/formatter/disabled_config_formatter.rb +21 -6
  498. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  499. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  500. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  501. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  502. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  503. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  504. data/lib/rubocop/lsp/diagnostic.rb +185 -0
  505. data/lib/rubocop/lsp/logger.rb +2 -2
  506. data/lib/rubocop/lsp/routes.rb +37 -24
  507. data/lib/rubocop/lsp/runtime.rb +18 -50
  508. data/lib/rubocop/lsp/server.rb +0 -2
  509. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  510. data/lib/rubocop/magic_comment.rb +31 -3
  511. data/lib/rubocop/options.rb +28 -12
  512. data/lib/rubocop/path_util.rb +15 -8
  513. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  514. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  515. data/lib/rubocop/plugin/load_error.rb +26 -0
  516. data/lib/rubocop/plugin/loader.rb +100 -0
  517. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  518. data/lib/rubocop/plugin.rb +46 -0
  519. data/lib/rubocop/rake_task.rb +5 -2
  520. data/lib/rubocop/remote_config.rb +7 -8
  521. data/lib/rubocop/result_cache.rb +61 -48
  522. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  523. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  524. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  525. data/lib/rubocop/rspec/support.rb +4 -2
  526. data/lib/rubocop/runner.rb +35 -18
  527. data/lib/rubocop/server/cache.rb +51 -13
  528. data/lib/rubocop/server/cli.rb +2 -2
  529. data/lib/rubocop/server/client_command/base.rb +10 -0
  530. data/lib/rubocop/server/client_command/exec.rb +2 -1
  531. data/lib/rubocop/server/client_command/start.rb +11 -1
  532. data/lib/rubocop/target_finder.rb +14 -9
  533. data/lib/rubocop/target_ruby.rb +27 -3
  534. data/lib/rubocop/version.rb +53 -12
  535. data/lib/rubocop.rb +45 -2
  536. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  537. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  538. metadata +92 -21
  539. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  540. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -35,8 +35,8 @@ module RuboCop
35
35
  # `false` is the same as `disabled` for backward compatibility.
36
36
  return false if ['disabled', false].include?(cop_config['AutoCorrect'])
37
37
 
38
- # When LSP is enabled, it is considered as editing source code,
39
- # and autocorrection with `AutoCorrect: contextual` will not be performed.
38
+ # When LSP is enabled or the `--editor-mode` option is on, it is considered as editing
39
+ # source code, and autocorrection with `AutoCorrect: contextual` will not be performed.
40
40
  return false if contextual_autocorrect? && LSP.enabled?
41
41
 
42
42
  # :safe_autocorrect is a derived option based on several command-line
@@ -49,47 +49,70 @@ module RuboCop
49
49
  private
50
50
 
51
51
  def disable_offense(offense_range)
52
- range = surrounding_heredoc(offense_range) || surrounding_percent_array(offense_range)
52
+ unbreakable_range = multiline_ranges(offense_range)&.find do |range|
53
+ eol_comment_would_be_inside_literal?(offense_range, range)
54
+ end
53
55
 
54
- if range
55
- disable_offense_before_and_after(range_by_lines(range))
56
+ if unbreakable_range
57
+ disable_offense_before_and_after(range_by_lines(unbreakable_range))
56
58
  else
57
59
  disable_offense_with_eol_or_surround_comment(offense_range)
58
60
  end
59
61
  end
60
62
 
61
- def disable_offense_with_eol_or_surround_comment(range)
62
- eol_comment = " # rubocop:todo #{cop_name}"
63
- needed_line_length = (range.source_line + eol_comment).length
63
+ def multiline_ranges(offense_range)
64
+ return if offense_range.empty?
64
65
 
65
- if needed_line_length <= max_line_length
66
- disable_offense_at_end_of_line(range_of_first_line(range), eol_comment)
67
- else
66
+ processed_source.ast.each_node.filter_map do |node|
67
+ if surrounding_heredoc?(node)
68
+ heredoc_range(node)
69
+ elsif string_continuation?(node)
70
+ range_by_lines(node.source_range)
71
+ elsif surrounding_percent_array?(node) || multiline_string?(node)
72
+ node.source_range
73
+ end
74
+ end
75
+ end
76
+
77
+ def disable_offense_with_eol_or_surround_comment(range)
78
+ if line_with_eol_comment_too_long?(range)
68
79
  disable_offense_before_and_after(range_by_lines(range))
80
+ else
81
+ disable_offense_at_end_of_line(range_of_first_line(range))
69
82
  end
70
83
  end
71
84
 
72
- def surrounding_heredoc(offense_range)
73
- # The empty offense range is an edge case that can be reached from the Lint/Syntax cop.
74
- return nil if offense_range.empty?
85
+ def eol_comment_would_be_inside_literal?(offense_range, literal_range)
86
+ return true if line_with_eol_comment_too_long?(offense_range)
75
87
 
76
- heredoc_nodes = processed_source.ast.each_descendant.select do |node|
77
- node.respond_to?(:heredoc?) && node.heredoc?
78
- end
79
- heredoc_nodes.map { |node| node.source_range.join(node.loc.heredoc_end) }
80
- .find { |range| range.contains?(offense_range) }
88
+ offense_line = offense_range.line
89
+ offense_line >= literal_range.first_line && offense_line < literal_range.last_line
81
90
  end
82
91
 
83
- def surrounding_percent_array(offense_range)
84
- return nil if offense_range.empty?
92
+ def line_with_eol_comment_too_long?(range)
93
+ return false unless max_line_length
85
94
 
86
- percent_array = processed_source.ast.each_descendant.select do |node|
87
- node.array_type? && node.percent_literal?
88
- end
95
+ (range.source_line + eol_comment).length > max_line_length
96
+ end
89
97
 
90
- percent_array.map(&:source_range).find do |range|
91
- offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
92
- end
98
+ def surrounding_heredoc?(node)
99
+ node.any_str_type? && node.heredoc?
100
+ end
101
+
102
+ def heredoc_range(node)
103
+ node.source_range.join(node.loc.heredoc_end)
104
+ end
105
+
106
+ def surrounding_percent_array?(node)
107
+ node.array_type? && node.percent_literal?
108
+ end
109
+
110
+ def string_continuation?(node)
111
+ node.any_str_type? && node.source.match?(/\\\s*$/)
112
+ end
113
+
114
+ def multiline_string?(node)
115
+ node.dstr_type? && node.multiline?
93
116
  end
94
117
 
95
118
  def range_of_first_line(range)
@@ -112,13 +135,19 @@ module RuboCop
112
135
  end
113
136
 
114
137
  def max_line_length
138
+ return unless config.cop_enabled?('Layout/LineLength')
139
+
115
140
  config.for_cop('Layout/LineLength')['Max'] || 120
116
141
  end
117
142
 
118
- def disable_offense_at_end_of_line(range, eol_comment)
143
+ def disable_offense_at_end_of_line(range)
119
144
  Corrector.new(range).insert_after(range, eol_comment)
120
145
  end
121
146
 
147
+ def eol_comment
148
+ " # rubocop:todo #{cop_name}"
149
+ end
150
+
122
151
  def disable_offense_before_and_after(range_by_lines)
123
152
  range_with_newline = range_by_lines.resize(range_by_lines.size + 1)
124
153
  leading_whitespace = range_by_lines.source_line[/^\s*/]
@@ -60,7 +60,7 @@ module RuboCop
60
60
  []
61
61
  end
62
62
 
63
- # Returns an url to view this cops documentation online.
63
+ # Returns a url to view this cops documentation online.
64
64
  # Requires 'DocumentationBaseURL' to be set for your department.
65
65
  # Will follow the convention of RuboCops own documentation structure,
66
66
  # overwrite this method to accommodate your custom layout.
@@ -261,6 +261,12 @@ module RuboCop
261
261
  @config.target_ruby_version
262
262
  end
263
263
 
264
+ # Returns a gems locked versions (i.e. from Gemfile.lock or gems.locked)
265
+ # @returns [Gem::Version | nil] The locked gem version, or nil if the gem is not present.
266
+ def target_gem_version(gem_name)
267
+ @config.gem_versions_in_target && @config.gem_versions_in_target[gem_name]
268
+ end
269
+
264
270
  def parser_engine
265
271
  @config.parser_engine
266
272
  end
@@ -66,14 +66,14 @@ module RuboCop
66
66
 
67
67
  def conditional_declaration?(nodes)
68
68
  parent = nodes[0].each_ancestor.find { |ancestor| !ancestor.begin_type? }
69
- return false unless parent&.if_type? || parent&.when_type?
69
+ return false unless parent&.type?(:if, :when)
70
70
 
71
71
  root_conditional_node = parent.if_type? ? parent : parent.parent
72
72
  nodes.all? { |node| within_conditional?(node, root_conditional_node) }
73
73
  end
74
74
 
75
75
  def within_conditional?(node, conditional_node)
76
- conditional_node.branches.any? do |branch|
76
+ conditional_node.branches.compact.any? do |branch|
77
77
  branch == node || branch.child_nodes.include?(node)
78
78
  end
79
79
  end
@@ -161,7 +161,7 @@ module RuboCop
161
161
  end
162
162
 
163
163
  def gem_options(node)
164
- return [] unless node.last_argument&.type == :hash
164
+ return [] unless node.last_argument&.hash_type?
165
165
 
166
166
  node.last_argument.keys.map(&:value)
167
167
  end
@@ -27,7 +27,6 @@ module RuboCop
27
27
  # Project contains gems.rb and gems.locked files
28
28
  class GemFilename < Base
29
29
  include ConfigurableEnforcedStyle
30
- include RangeHelp
31
30
 
32
31
  MSG_GEMFILE_REQUIRED = '`gems.rb` file was found but `Gemfile` is required ' \
33
32
  '(file path: %<file_path>s).'
@@ -39,7 +39,6 @@ module RuboCop
39
39
  # source 'http://rubygems.org'
40
40
  #
41
41
  class InsecureProtocolSource < Base
42
- include RangeHelp
43
42
  extend AutoCorrector
44
43
 
45
44
  MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
@@ -43,9 +43,8 @@ module RuboCop
43
43
  def on_new_investigation
44
44
  return if processed_source.blank?
45
45
 
46
- gem_declarations(processed_source.ast)
47
- .each_cons(2) do |previous, current|
48
- next unless consecutive_lines(previous, current)
46
+ gem_declarations(processed_source.ast).each_cons(2) do |previous, current|
47
+ next unless consecutive_lines?(previous, current)
49
48
  next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
50
49
 
51
50
  register_offense(previous, current)
@@ -29,10 +29,13 @@ module RuboCop
29
29
  def align_end(corrector, processed_source, node, align_to)
30
30
  @processed_source = processed_source
31
31
  whitespace = whitespace_range(node)
32
- return false unless whitespace.source.strip.empty?
33
-
34
32
  column = alignment_column(align_to)
35
- corrector.replace(whitespace, ' ' * column)
33
+
34
+ if whitespace.source.strip.empty?
35
+ corrector.replace(whitespace, ' ' * column)
36
+ else
37
+ corrector.insert_after(whitespace, "\n#{' ' * column}")
38
+ end
36
39
  end
37
40
 
38
41
  private
@@ -47,14 +50,14 @@ module RuboCop
47
50
  if column_delta.positive? && range.resize(1).source != "\n"
48
51
  corrector.insert_before(range, ' ' * column_delta)
49
52
  elsif /\A[ \t]+\z/.match?(range.source)
50
- remove(range, corrector)
53
+ corrector.remove(range)
51
54
  end
52
55
  end
53
56
 
54
57
  def inside_string_ranges(node)
55
58
  return [] unless node.is_a?(Parser::AST::Node)
56
59
 
57
- node.each_node(:str, :dstr, :xstr).filter_map { |n| inside_string_range(n) }
60
+ node.each_node(:any_str).filter_map { |n| inside_string_range(n) }
58
61
  end
59
62
 
60
63
  def inside_string_range(node)
@@ -73,9 +76,7 @@ module RuboCop
73
76
  # nil.
74
77
  # - The source map of `__FILE__` responds to neither :begin nor :end.
75
78
  def delimited_string_literal?(node)
76
- loc = node.location
77
-
78
- loc.respond_to?(:begin) && loc.begin && loc.respond_to?(:end) && loc.end
79
+ node.loc?(:begin) && node.loc?(:end)
79
80
  end
80
81
 
81
82
  def block_comment_within?(expr)
@@ -96,17 +97,6 @@ module RuboCop
96
97
  end
97
98
  end
98
99
 
99
- def remove(range, corrector)
100
- original_stderr = $stderr
101
- $stderr = StringIO.new # Avoid error messages on console
102
- corrector.remove(range)
103
- rescue RuntimeError
104
- range = range_between(range.begin_pos + 1, range.end_pos + 1)
105
- retry if /^ +$/.match?(range.source)
106
- ensure
107
- $stderr = original_stderr
108
- end
109
-
110
100
  def each_line(expr)
111
101
  line_begin_pos = expr.begin_pos
112
102
  expr.source.each_line do |line|
@@ -6,7 +6,7 @@ module RuboCop
6
6
  class ForToEachCorrector
7
7
  extend NodePattern::Macros
8
8
 
9
- CORRECTION = '%<collection>s.each do |%<argument>s|'
9
+ CORRECTION = '%<collection>s%<dot>seach do |%<argument>s|'
10
10
 
11
11
  def initialize(for_node)
12
12
  @for_node = for_node
@@ -25,7 +25,12 @@ module RuboCop
25
25
  attr_reader :for_node, :variable_node, :collection_node
26
26
 
27
27
  def correction
28
- format(CORRECTION, collection: collection_source, argument: variable_node.source)
28
+ format(
29
+ CORRECTION,
30
+ collection: collection_source,
31
+ dot: collection_node.csend_type? ? '&.' : '.',
32
+ argument: variable_node.source
33
+ )
29
34
  end
30
35
 
31
36
  def collection_source
@@ -39,7 +44,7 @@ module RuboCop
39
44
  def requires_parentheses?
40
45
  return true if collection_node.send_type? && collection_node.operator_method?
41
46
 
42
- collection_node.range_type? || collection_node.or_type? || collection_node.and_type?
47
+ collection_node.range_type? || collection_node.operator_keyword?
43
48
  end
44
49
 
45
50
  def end_range
@@ -10,8 +10,11 @@ module RuboCop
10
10
  COMMA_REGEXP = /(?<=\))\s*,/.freeze
11
11
 
12
12
  def correct(corrector, node)
13
- corrector.remove(node.loc.begin)
14
- corrector.remove(node.loc.end)
13
+ buffer = node.source_range.source_buffer
14
+ corrector.remove(range_with_surrounding_space(range: node.loc.begin, buffer: buffer,
15
+ side: :right, whitespace: true))
16
+ corrector.remove(range_with_surrounding_space(range: node.loc.end, buffer: buffer,
17
+ side: :left))
15
18
  handle_orphaned_comma(corrector, node)
16
19
 
17
20
  return unless ternary_condition?(node) && next_char_is_question_mark?(node)
@@ -94,6 +94,16 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def substitute_escaped_delimiters(content, delimiters)
97
+ if delimiters.first != delimiters.last
98
+ # With different delimiters (eg. `[]`, `()`), if there are the same
99
+ # number of each, escaping is not necessary
100
+ delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts|
101
+ counts[delimiter] = content.count(delimiter)
102
+ end
103
+
104
+ return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last]
105
+ end
106
+
97
107
  delimiters.each { |delim| content.gsub!(delim, "\\#{delim}") }
98
108
  end
99
109
 
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Gemspec
6
+ # Use consistent style for Gemspec attributes assignment.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # # This example uses two styles for assignment of metadata attribute.
12
+ # Gem::Specification.new do |spec|
13
+ # spec.metadata = { 'key' => 'value' }
14
+ # spec.metadata['another-key'] = 'another-value'
15
+ # end
16
+ #
17
+ # # good
18
+ # Gem::Specification.new do |spec|
19
+ # spec.metadata['key'] = 'value'
20
+ # spec.metadata['another-key'] = 'another-value'
21
+ # end
22
+ #
23
+ # # good
24
+ # Gem::Specification.new do |spec|
25
+ # spec.metadata = { 'key' => 'value', 'another-key' => 'another-value' }
26
+ # end
27
+ #
28
+ # # bad
29
+ # # This example uses two styles for assignment of authors attribute.
30
+ # Gem::Specification.new do |spec|
31
+ # spec.authors = %w[author-0 author-1]
32
+ # spec.authors[2] = 'author-2'
33
+ # end
34
+ #
35
+ # # good
36
+ # Gem::Specification.new do |spec|
37
+ # spec.authors = %w[author-0 author-1 author-2]
38
+ # end
39
+ #
40
+ # # good
41
+ # Gem::Specification.new do |spec|
42
+ # spec.authors[0] = 'author-0'
43
+ # spec.authors[1] = 'author-1'
44
+ # spec.authors[2] = 'author-2'
45
+ # end
46
+ #
47
+ # # good
48
+ # # This example uses consistent assignment per attribute,
49
+ # # even though two different styles are used overall.
50
+ # Gem::Specification.new do |spec|
51
+ # spec.metadata = { 'key' => 'value' }
52
+ # spec.authors[0] = 'author-0'
53
+ # spec.authors[1] = 'author-1'
54
+ # spec.authors[2] = 'author-2'
55
+ # end
56
+ #
57
+ class AttributeAssignment < Base
58
+ include GemspecHelp
59
+
60
+ MSG = 'Use consistent style for Gemspec attributes assignment.'
61
+
62
+ def on_new_investigation
63
+ return if processed_source.blank?
64
+
65
+ assignments = source_assignments(processed_source.ast)
66
+ indexed_assignments = source_indexed_assignments(processed_source.ast)
67
+
68
+ assignments.keys.intersection(indexed_assignments.keys).each do |attribute|
69
+ indexed_assignments[attribute].each do |node|
70
+ add_offense(node)
71
+ end
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def source_assignments(ast)
78
+ assignment_method_declarations(ast)
79
+ .select(&:assignment_method?)
80
+ .group_by(&:method_name)
81
+ .transform_keys { |method_name| method_name.to_s.delete_suffix('=').to_sym }
82
+ end
83
+
84
+ def source_indexed_assignments(ast)
85
+ indexed_assignment_method_declarations(ast)
86
+ .group_by { |node| node.children.first.method_name }
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -62,8 +62,7 @@ module RuboCop
62
62
 
63
63
  def node_and_method_name(node, attribute)
64
64
  if node.op_asgn_type?
65
- lhs, _op, _rhs = *node
66
- [lhs, attribute]
65
+ [node.lhs, attribute]
67
66
  else
68
67
  [node, :"#{attribute}="]
69
68
  end
@@ -6,10 +6,11 @@ module RuboCop
6
6
  # An attribute assignment method calls should be listed only once
7
7
  # in a gemspec.
8
8
  #
9
- # Assigning to an attribute with the same name using `spec.foo =` will be
10
- # an unintended usage. On the other hand, duplication of methods such
11
- # as `spec.requirements`, `spec.add_runtime_dependency`, and others are
12
- # permitted because it is the intended use of appending values.
9
+ # Assigning to an attribute with the same name using `spec.foo =` or
10
+ # `spec.attribute#[]=` will be an unintended usage. On the other hand,
11
+ # duplication of methods such # as `spec.requirements`,
12
+ # `spec.add_runtime_dependency`, and others are permitted because it is
13
+ # the intended use of appending values.
13
14
  #
14
15
  # @example
15
16
  # # bad
@@ -34,6 +35,18 @@ module RuboCop
34
35
  # spec.add_dependency('parallel', '~> 1.10')
35
36
  # spec.add_dependency('parser', '>= 2.3.3.1', '< 3.0')
36
37
  # end
38
+ #
39
+ # # bad
40
+ # Gem::Specification.new do |spec|
41
+ # spec.metadata["key"] = "value"
42
+ # spec.metadata["key"] = "value"
43
+ # end
44
+ #
45
+ # # good
46
+ # Gem::Specification.new do |spec|
47
+ # spec.metadata["key"] = "value"
48
+ # end
49
+ #
37
50
  class DuplicatedAssignment < Base
38
51
  include RangeHelp
39
52
  include GemspecHelp
@@ -41,15 +54,16 @@ module RuboCop
41
54
  MSG = '`%<assignment>s` method calls already given on line ' \
42
55
  '%<line_of_first_occurrence>d of the gemspec.'
43
56
 
44
- # @!method assignment_method_declarations(node)
45
- def_node_search :assignment_method_declarations, <<~PATTERN
46
- (send
47
- (lvar #match_block_variable_name?) _ ...)
48
- PATTERN
49
-
50
57
  def on_new_investigation
51
58
  return if processed_source.blank?
52
59
 
60
+ process_assignment_method_nodes
61
+ process_indexed_assignment_method_nodes
62
+ end
63
+
64
+ private
65
+
66
+ def process_assignment_method_nodes
53
67
  duplicated_assignment_method_nodes.each do |nodes|
54
68
  nodes[1..].each do |node|
55
69
  register_offense(node, node.method_name, nodes.first.first_line)
@@ -57,11 +71,12 @@ module RuboCop
57
71
  end
58
72
  end
59
73
 
60
- private
61
-
62
- def match_block_variable_name?(receiver_name)
63
- gem_specification(processed_source.ast) do |block_variable_name|
64
- return block_variable_name == receiver_name
74
+ def process_indexed_assignment_method_nodes
75
+ duplicated_indexed_assignment_method_nodes.each do |nodes|
76
+ nodes[1..].each do |node|
77
+ assignment = "#{node.children.first.method_name}[#{node.first_argument.source}]="
78
+ register_offense(node, assignment, nodes.first.first_line)
79
+ end
65
80
  end
66
81
  end
67
82
 
@@ -73,6 +88,13 @@ module RuboCop
73
88
  .select { |nodes| nodes.size > 1 }
74
89
  end
75
90
 
91
+ def duplicated_indexed_assignment_method_nodes
92
+ indexed_assignment_method_declarations(processed_source.ast)
93
+ .group_by { |node| [node.children.first.method_name, node.first_argument] }
94
+ .values
95
+ .select { |nodes| nodes.size > 1 }
96
+ end
97
+
76
98
  def register_offense(node, assignment, line_of_first_occurrence)
77
99
  line_range = node.loc.column...node.loc.last_column
78
100
  offense_location = source_range(processed_source.buffer, node.first_line, line_range)
@@ -69,9 +69,8 @@ module RuboCop
69
69
  def on_new_investigation
70
70
  return if processed_source.blank?
71
71
 
72
- dependency_declarations(processed_source.ast)
73
- .each_cons(2) do |previous, current|
74
- next unless consecutive_lines(previous, current)
72
+ dependency_declarations(processed_source.ast).each_cons(2) do |previous, current|
73
+ next unless consecutive_lines?(previous, current)
75
74
  next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous))
76
75
  next unless get_dependency_name(previous) == get_dependency_name(current)
77
76
 
@@ -74,6 +74,14 @@ module RuboCop
74
74
  }
75
75
  PATTERN
76
76
 
77
+ # @!method metadata_assignment(node)
78
+ def_node_search :metadata_assignment, <<~PATTERN
79
+ `{
80
+ (send _ :metadata= _)
81
+ (send (send _ :metadata) :[]= (str _) _)
82
+ }
83
+ PATTERN
84
+
77
85
  # @!method rubygems_mfa_required(node)
78
86
  def_node_search :rubygems_mfa_required, <<~PATTERN
79
87
  (pair (str "rubygems_mfa_required") $_)
@@ -131,9 +139,15 @@ module RuboCop
131
139
  end
132
140
 
133
141
  def insert_mfa_required(corrector, node, block_var)
134
- corrector.insert_before(node.loc.end, <<~RUBY)
142
+ require_mfa_directive = <<~RUBY.strip
135
143
  #{block_var}.metadata['rubygems_mfa_required'] = 'true'
136
144
  RUBY
145
+
146
+ if (last_assignment = metadata_assignment(processed_source.ast).to_a.last)
147
+ corrector.insert_after(last_assignment, "\n#{require_mfa_directive}")
148
+ else
149
+ corrector.insert_before(node.loc.end, "#{require_mfa_directive}\n")
150
+ end
137
151
  end
138
152
 
139
153
  def change_value(corrector, value)
@@ -53,8 +53,6 @@ module RuboCop
53
53
  # spec.required_ruby_version = '~> 2.5'
54
54
  # end
55
55
  class RequiredRubyVersion < Base
56
- include RangeHelp
57
-
58
56
  RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
59
57
  NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
60
58
  '(%<target_ruby_version>s, which may be specified in ' \
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
- # Checks that `RUBY_VERSION` constant is not used in gemspec.
7
- # Using `RUBY_VERSION` is dangerous because value of the
6
+ # Checks that `RUBY_VERSION` and `Ruby::VERSION` constants are not used in gemspec.
7
+ # Using `RUBY_VERSION` and `Ruby::VERSION` are dangerous because value of the
8
8
  # constant is determined by `rake release`.
9
9
  # It's possible to have dependency based on ruby version used
10
10
  # to execute `rake release` and not user's ruby version.
@@ -28,15 +28,20 @@ module RuboCop
28
28
  class RubyVersionGlobalsUsage < Base
29
29
  include GemspecHelp
30
30
 
31
- MSG = 'Do not use `RUBY_VERSION` in gemspec file.'
31
+ MSG = 'Do not use `%<ruby_version>s` in gemspec file.'
32
32
 
33
33
  # @!method ruby_version?(node)
34
- def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)'
34
+ def_node_matcher :ruby_version?, <<~PATTERN
35
+ {
36
+ (const {cbase nil?} :RUBY_VERSION)
37
+ (const (const {cbase nil?} :Ruby) :VERSION)
38
+ }
39
+ PATTERN
35
40
 
36
41
  def on_const(node)
37
42
  return unless gem_spec_with_ruby_version?(node)
38
43
 
39
- add_offense(node)
44
+ add_offense(node, message: format(MSG, ruby_version: node.source))
40
45
  end
41
46
 
42
47
  private
@@ -71,11 +71,17 @@ module RuboCop
71
71
  (send nil? :bad_method ...)
72
72
  PATTERN
73
73
 
74
+ # Called on every `send` node (method call) while walking the AST.
75
+ # TODO: remove this method if inspecting `send` nodes is unneeded for your cop.
76
+ # By default, this is aliased to `on_csend` as well to handle method calls
77
+ # with safe navigation, remove the alias if this is unnecessary.
78
+ # If kept, ensure your tests cover safe navigation as well!
74
79
  def on_send(node)
75
80
  return unless bad_method?(node)
76
81
 
77
82
  add_offense(node)
78
83
  end
84
+ alias on_csend on_send
79
85
  end
80
86
  end
81
87
  end