rubocop 1.67.0 → 1.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -17
  4. data/config/default.yml +337 -53
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +51 -26
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  31. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  32. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  33. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  34. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  35. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  36. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  37. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  38. data/lib/rubocop/cop/generator.rb +6 -0
  39. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  40. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  41. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  42. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  43. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  44. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  46. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  48. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  49. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  50. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  51. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  52. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  54. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  55. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  56. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  57. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  58. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  59. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  60. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  61. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  62. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  63. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  64. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  66. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  67. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  68. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  69. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  70. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  72. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  73. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  74. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  75. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  76. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  77. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  78. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  79. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  80. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  81. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  82. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  83. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  84. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  85. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  86. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  88. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  89. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  90. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  91. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  92. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  93. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/line_length.rb +149 -9
  95. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  96. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  97. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  98. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  99. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  100. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  101. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  102. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  103. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  104. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  105. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  106. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  108. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  109. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  110. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  111. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  112. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  114. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  115. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  116. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  118. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  119. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  120. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  121. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  122. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  123. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  124. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  125. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  126. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  127. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  128. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  129. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  130. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  131. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  132. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  133. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  134. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  135. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  136. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  137. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  138. data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
  139. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  140. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  141. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  142. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  143. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  144. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  145. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  146. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  147. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  148. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  149. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  150. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  151. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  152. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  153. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  154. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  156. data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
  157. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  158. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  159. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  160. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  161. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  162. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  163. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  164. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  165. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  166. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  167. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  168. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  169. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  170. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  171. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  172. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  173. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  174. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  175. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  176. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  177. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  178. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  179. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  180. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  181. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  182. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  183. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  184. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  185. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  186. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  187. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  188. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  189. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  190. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  191. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  192. data/lib/rubocop/cop/lint/self_assignment.rb +33 -10
  193. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  194. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  195. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  196. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  197. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  198. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  199. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  200. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  201. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  202. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  203. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  204. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  205. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  206. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  207. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  208. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  209. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  210. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  211. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  212. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  213. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  214. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  215. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  216. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  217. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  218. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  219. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  220. data/lib/rubocop/cop/lint/void.rb +16 -12
  221. data/lib/rubocop/cop/message_annotator.rb +7 -3
  222. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  223. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  224. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  225. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  226. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  227. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  228. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  229. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  230. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  231. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  232. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  233. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  234. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  235. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  236. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  237. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  238. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  239. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  240. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  241. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  242. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  243. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  244. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  245. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  246. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  247. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  248. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  249. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  250. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  251. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  252. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  253. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  254. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  255. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  256. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  257. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  258. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  259. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  260. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  261. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  262. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  263. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  264. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  265. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  266. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  267. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  268. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  269. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  270. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  271. data/lib/rubocop/cop/naming/predicate_method.rb +281 -0
  272. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  273. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  274. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  275. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  276. data/lib/rubocop/cop/offense.rb +2 -3
  277. data/lib/rubocop/cop/registry.rb +9 -6
  278. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  279. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  280. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  281. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  282. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  283. data/lib/rubocop/cop/style/and_or.rb +1 -1
  284. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  285. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  286. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  287. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  288. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  289. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  290. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  291. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  292. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  293. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  294. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  295. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  296. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  297. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  298. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  299. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  300. data/lib/rubocop/cop/style/conditional_assignment.rb +41 -27
  301. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  302. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  303. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  304. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  305. data/lib/rubocop/cop/style/documentation.rb +1 -1
  306. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  307. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  308. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  309. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  310. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  311. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  312. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  313. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  314. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  315. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  316. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  317. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  318. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  319. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  320. data/lib/rubocop/cop/style/file_null.rb +89 -0
  321. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  322. data/lib/rubocop/cop/style/float_division.rb +8 -4
  323. data/lib/rubocop/cop/style/for.rb +1 -1
  324. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  325. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  326. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  327. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  328. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  329. data/lib/rubocop/cop/style/hash_conversion.rb +12 -4
  330. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  331. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  332. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  333. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  334. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  335. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  336. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  337. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  338. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  339. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  340. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  341. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  342. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  343. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  344. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  345. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  346. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  347. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  348. data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
  349. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  350. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  351. data/lib/rubocop/cop/style/lambda.rb +1 -0
  352. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  353. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  354. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  355. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  356. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  357. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -18
  358. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  359. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  360. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  361. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  362. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  363. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  364. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  365. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  366. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  367. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  368. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  369. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  370. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  371. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  372. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  373. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  374. data/lib/rubocop/cop/style/next.rb +44 -0
  375. data/lib/rubocop/cop/style/not.rb +1 -1
  376. data/lib/rubocop/cop/style/object_then.rb +15 -15
  377. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  378. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  379. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  380. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  381. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  382. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  383. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  384. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  385. data/lib/rubocop/cop/style/proc.rb +2 -2
  386. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  387. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  388. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  389. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  390. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  391. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  392. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  393. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  394. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  395. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  396. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  397. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  398. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  399. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  400. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  401. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  402. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  403. data/lib/rubocop/cop/style/redundant_parentheses.rb +77 -26
  404. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  405. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  406. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  407. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  408. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  409. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  410. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  411. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  412. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  413. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  414. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  415. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  416. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  417. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  418. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  419. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  420. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  421. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  422. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  423. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  424. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  425. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  426. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  427. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  428. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  429. data/lib/rubocop/cop/style/sole_nested_conditional.rb +43 -106
  430. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  431. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  432. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  433. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  434. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  435. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  436. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  437. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  438. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  439. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  440. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  441. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  442. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  443. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  444. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  445. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  446. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  447. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  448. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  449. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  450. data/lib/rubocop/cop/team.rb +1 -1
  451. data/lib/rubocop/cop/util.rb +12 -5
  452. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  453. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  454. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  455. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  456. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  457. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  458. data/lib/rubocop/cop/variable_force.rb +5 -11
  459. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  460. data/lib/rubocop/directive_comment.rb +45 -11
  461. data/lib/rubocop/ext/regexp_node.rb +0 -1
  462. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  463. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  464. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  465. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  466. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  467. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  468. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  469. data/lib/rubocop/lsp/logger.rb +2 -2
  470. data/lib/rubocop/lsp/routes.rb +7 -23
  471. data/lib/rubocop/lsp/runtime.rb +18 -50
  472. data/lib/rubocop/lsp/server.rb +0 -2
  473. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  474. data/lib/rubocop/magic_comment.rb +11 -3
  475. data/lib/rubocop/options.rb +28 -12
  476. data/lib/rubocop/path_util.rb +15 -8
  477. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  478. data/lib/rubocop/plugin/load_error.rb +26 -0
  479. data/lib/rubocop/plugin/loader.rb +100 -0
  480. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  481. data/lib/rubocop/plugin.rb +46 -0
  482. data/lib/rubocop/rake_task.rb +4 -1
  483. data/lib/rubocop/result_cache.rb +13 -13
  484. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  485. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  486. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  487. data/lib/rubocop/rspec/support.rb +4 -2
  488. data/lib/rubocop/runner.rb +26 -15
  489. data/lib/rubocop/server/cache.rb +47 -11
  490. data/lib/rubocop/server/cli.rb +2 -2
  491. data/lib/rubocop/target_finder.rb +7 -2
  492. data/lib/rubocop/target_ruby.rb +17 -2
  493. data/lib/rubocop/version.rb +53 -12
  494. data/lib/rubocop.rb +40 -2
  495. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  496. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  497. metadata +87 -21
  498. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  499. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -69,17 +69,24 @@ module RuboCop
69
69
  extend AutoCorrector
70
70
 
71
71
  MSG = 'Redundant line continuation.'
72
+ LINE_CONTINUATION = '\\'
73
+ LINE_CONTINUATION_PATTERN = /(\\\n)/.freeze
72
74
  ALLOWED_STRING_TOKENS = %i[tSTRING tSTRING_CONTENT].freeze
73
75
  ARGUMENT_TYPES = %i[
74
- kFALSE kNIL kSELF kTRUE tCONSTANT tCVAR tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR
75
- tLBRACK tLCURLY tLPAREN_ARG tSTRING tSTRING_BEG tSYMBOL tXSTRING_BEG
76
+ kDEF kDEFINED kFALSE kNIL kSELF kTRUE tAMPER tBANG tCARET tCHARACTER tCOLON3 tCONSTANT
77
+ tCVAR tDOT2 tDOT3 tFLOAT tGVAR tIDENTIFIER tINTEGER tIVAR tLAMBDA tLBRACK tLCURLY
78
+ tLPAREN_ARG tPIPE tQSYMBOLS_BEG tQWORDS_BEG tREGEXP_BEG tSTAR tSTRING tSTRING_BEG tSYMBEG
79
+ tSYMBOL tSYMBOLS_BEG tTILDE tUMINUS tUNARY_NUM tUPLUS tWORDS_BEG tXSTRING_BEG
76
80
  ].freeze
77
- ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[tIDENTIFIER kRETURN kBREAK kNEXT kYIELD].freeze
81
+ ARGUMENT_TAKING_FLOW_TOKEN_TYPES = %i[
82
+ tIDENTIFIER kBREAK kNEXT kRETURN kSUPER kYIELD
83
+ ].freeze
84
+ ARITHMETIC_OPERATOR_TOKENS = %i[tDIVIDE tDSTAR tMINUS tPERCENT tPLUS tSTAR2].freeze
78
85
 
79
86
  def on_new_investigation
80
87
  return unless processed_source.ast
81
88
 
82
- each_match_range(processed_source.ast.source_range, /(\\\n)/) do |range|
89
+ each_match_range(processed_source.ast.source_range, LINE_CONTINUATION_PATTERN) do |range|
83
90
  next if require_line_continuation?(range)
84
91
  next unless redundant_line_continuation?(range)
85
92
 
@@ -87,20 +94,27 @@ module RuboCop
87
94
  corrector.remove_leading(range, 1)
88
95
  end
89
96
  end
97
+
98
+ inspect_end_of_ruby_code_line_continuation
90
99
  end
91
100
 
92
101
  private
93
102
 
94
103
  def require_line_continuation?(range)
95
- !ends_with_backslash_without_comment?(range.source_line) ||
104
+ !ends_with_uncommented_backslash?(range) ||
96
105
  string_concatenation?(range.source_line) ||
97
- start_with_arithmetic_operator?(processed_source[range.line]) ||
106
+ start_with_arithmetic_operator?(range) ||
98
107
  inside_string_literal_or_method_with_argument?(range) ||
99
108
  leading_dot_method_chain_with_blank_line?(range)
100
109
  end
101
110
 
102
- def ends_with_backslash_without_comment?(source_line)
103
- source_line.gsub(/#.+/, '').end_with?('\\')
111
+ def ends_with_uncommented_backslash?(range)
112
+ # A line continuation always needs to be the last character on the line, which
113
+ # means that it is impossible to have a comment following a continuation.
114
+ # Therefore, if the line contains a comment, it cannot end with a continuation.
115
+ return false if processed_source.line_with_comment?(range.line)
116
+
117
+ range.source_line.end_with?(LINE_CONTINUATION)
104
118
  end
105
119
 
106
120
  def string_concatenation?(source_line)
@@ -108,10 +122,13 @@ module RuboCop
108
122
  end
109
123
 
110
124
  def inside_string_literal_or_method_with_argument?(range)
125
+ line_range = range_by_whole_lines(range)
126
+
111
127
  processed_source.tokens.each_cons(2).any? do |token, next_token|
112
128
  next if token.line == next_token.line
113
129
 
114
- inside_string_literal?(range, token) || method_with_argument?(token, next_token)
130
+ inside_string_literal?(range, token) ||
131
+ method_with_argument?(line_range, token, next_token)
115
132
  end
116
133
  end
117
134
 
@@ -125,8 +142,28 @@ module RuboCop
125
142
  return true unless (node = find_node_for_line(range.last_line))
126
143
  return false if argument_newline?(node)
127
144
 
128
- source = node.parent ? node.parent.source : node.source
129
- parse(source.gsub("\\\n", "\n")).valid_syntax?
145
+ # Check if source is still valid without the continuation
146
+ source = processed_source.raw_source.dup
147
+ source[range.begin_pos, range.length] = "\n"
148
+ parse(source).valid_syntax?
149
+ end
150
+
151
+ def inspect_end_of_ruby_code_line_continuation
152
+ last_line = processed_source.lines[processed_source.ast.last_line - 1]
153
+ return unless code_ends_with_continuation?(last_line)
154
+
155
+ last_column = last_line.length
156
+ line_continuation_range = range_between(last_column - 1, last_column)
157
+
158
+ add_offense(line_continuation_range) do |corrector|
159
+ corrector.remove_trailing(line_continuation_range, 1)
160
+ end
161
+ end
162
+
163
+ def code_ends_with_continuation?(last_line)
164
+ return false if processed_source.line_with_comment?(processed_source.ast.last_line)
165
+
166
+ last_line.end_with?(LINE_CONTINUATION)
130
167
  end
131
168
 
132
169
  def inside_string_literal?(range, token)
@@ -137,15 +174,14 @@ module RuboCop
137
174
  #
138
175
  # do_something \
139
176
  # argument
140
- def method_with_argument?(current_token, next_token)
177
+ def method_with_argument?(line_range, current_token, next_token)
141
178
  return false unless ARGUMENT_TAKING_FLOW_TOKEN_TYPES.include?(current_token.type)
179
+ return false unless current_token.pos.overlaps?(line_range)
142
180
 
143
181
  ARGUMENT_TYPES.include?(next_token.type)
144
182
  end
145
183
 
146
- # rubocop:disable Metrics/AbcSize
147
184
  def argument_newline?(node)
148
- node = node.to_a.last if node.assignment?
149
185
  return false if node.parenthesized_call?
150
186
 
151
187
  node = node.children.first if node.root? && node.begin_type?
@@ -158,11 +194,10 @@ module RuboCop
158
194
  node.loc.selector.line != node.first_argument.loc.line
159
195
  end
160
196
  end
161
- # rubocop:enable Metrics/AbcSize
162
197
 
163
198
  def find_node_for_line(last_line)
164
199
  processed_source.ast.each_node do |node|
165
- return node if node.respond_to?(:expression) && node.expression&.last_line == last_line
200
+ return node if same_line?(node, last_line)
166
201
  end
167
202
  end
168
203
 
@@ -191,8 +226,9 @@ module RuboCop
191
226
  node.call_type? && !node.arguments.empty?
192
227
  end
193
228
 
194
- def start_with_arithmetic_operator?(source_line)
195
- %r{\A\s*[+\-*/%]}.match?(source_line)
229
+ def start_with_arithmetic_operator?(range)
230
+ line_range = processed_source.buffer.line_range(range.line + 1)
231
+ ARITHMETIC_OPERATOR_TOKENS.include?(processed_source.first_token_of(line_range).type)
196
232
  end
197
233
  end
198
234
  end
@@ -13,14 +13,16 @@ module RuboCop
13
13
  # # good
14
14
  # x if y.z.nil?
15
15
  #
16
- class RedundantParentheses < Base
16
+ class RedundantParentheses < Base # rubocop:disable Metrics/ClassLength
17
17
  include Parentheses
18
18
  extend AutoCorrector
19
19
 
20
- ALLOWED_NODE_TYPES = %i[and or send splat kwsplat].freeze
20
+ ALLOWED_NODE_TYPES = %i[or send splat kwsplat].freeze
21
21
 
22
22
  # @!method square_brackets?(node)
23
- def_node_matcher :square_brackets?, '(send {(send _recv _msg) str array hash} :[] ...)'
23
+ def_node_matcher :square_brackets?, <<~PATTERN
24
+ (send `{(send _recv _msg) str array hash const #variable?} :[] ...)
25
+ PATTERN
24
26
 
25
27
  # @!method method_node_and_args(node)
26
28
  def_node_matcher :method_node_and_args, '$(call _recv _msg $...)'
@@ -31,9 +33,6 @@ module RuboCop
31
33
  # @!method allowed_pin_operator?(node)
32
34
  def_node_matcher :allowed_pin_operator?, '^(pin (begin !{lvar ivar cvar gvar}))'
33
35
 
34
- # @!method arg_in_call_with_block?(node)
35
- def_node_matcher :arg_in_call_with_block?, '^^(block (send _ _ equal?(%0) ...) ...)'
36
-
37
36
  def on_begin(node)
38
37
  return if !parentheses?(node) || parens_allowed?(node) || ignore_syntax?(node)
39
38
 
@@ -42,10 +41,15 @@ module RuboCop
42
41
 
43
42
  private
44
43
 
44
+ def variable?(node)
45
+ node.respond_to?(:variable?) && node.variable?
46
+ end
47
+
45
48
  def parens_allowed?(node)
46
49
  empty_parentheses?(node) ||
47
50
  first_arg_begins_with_hash_literal?(node) ||
48
51
  rescue?(node) ||
52
+ in_pattern_matching_in_method_argument?(node) ||
49
53
  allowed_pin_operator?(node) ||
50
54
  allowed_expression?(node)
51
55
  end
@@ -53,13 +57,12 @@ module RuboCop
53
57
  def ignore_syntax?(node)
54
58
  return false unless (parent = node.parent)
55
59
 
56
- parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
60
+ parent.type?(:while_post, :until_post, :match_with_lvasgn) ||
57
61
  like_method_argument_parentheses?(parent) || multiline_control_flow_statements?(node)
58
62
  end
59
63
 
60
64
  def allowed_expression?(node)
61
65
  allowed_ancestor?(node) ||
62
- allowed_method_call?(node) ||
63
66
  allowed_multiple_expression?(node) ||
64
67
  allowed_ternary?(node) ||
65
68
  node.parent&.range_type?
@@ -70,18 +73,13 @@ module RuboCop
70
73
  keyword_ancestor?(node) && parens_required?(node)
71
74
  end
72
75
 
73
- def allowed_method_call?(node)
74
- # Don't flag `method (arg) { }`
75
- arg_in_call_with_block?(node) && !parentheses?(node.parent)
76
- end
77
-
78
76
  def allowed_multiple_expression?(node)
79
77
  return false if node.children.one?
80
78
 
81
79
  ancestor = node.ancestors.first
82
80
  return false unless ancestor
83
81
 
84
- !ancestor.begin_type? && !ancestor.def_type? && !ancestor.block_type?
82
+ !ancestor.type?(:begin, :any_def, :any_block)
85
83
  end
86
84
 
87
85
  def allowed_ternary?(node)
@@ -98,17 +96,17 @@ module RuboCop
98
96
  end
99
97
 
100
98
  def like_method_argument_parentheses?(node)
101
- return false if !node.send_type? && !node.super_type? && !node.yield_type?
99
+ return false unless node.type?(:send, :super, :yield)
102
100
 
103
101
  node.arguments.one? && !node.parenthesized? &&
104
- !node.arithmetic_operation? && node.first_argument.begin_type?
102
+ !node.operator_method? && node.first_argument.begin_type?
105
103
  end
106
104
 
107
105
  def multiline_control_flow_statements?(node)
108
106
  return false unless (parent = node.parent)
109
107
  return false if parent.single_line?
110
108
 
111
- parent.return_type? || parent.next_type? || parent.break_type?
109
+ parent.type?(:return, :next, :break)
112
110
  end
113
111
 
114
112
  def empty_parentheses?(node)
@@ -125,6 +123,13 @@ module RuboCop
125
123
  hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized
126
124
  end
127
125
 
126
+ def in_pattern_matching_in_method_argument?(begin_node)
127
+ return false unless begin_node.parent&.call_type?
128
+ return false unless (node = begin_node.children.first)
129
+
130
+ target_ruby_version <= 2.7 ? node.match_pattern_type? : node.match_pattern_p_type?
131
+ end
132
+
128
133
  def method_chain_begins_with_hash_literal(node)
129
134
  return if node.nil?
130
135
  return node if node.hash_type?
@@ -137,6 +142,10 @@ module RuboCop
137
142
  node = begin_node.children.first
138
143
 
139
144
  if (message = find_offense_message(begin_node, node))
145
+ if node.range_type? && !argument_of_parenthesized_method_call?(begin_node, node)
146
+ begin_node = begin_node.parent
147
+ end
148
+
140
149
  return offense(begin_node, message)
141
150
  end
142
151
 
@@ -146,20 +155,28 @@ module RuboCop
146
155
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
147
156
  def find_offense_message(begin_node, node)
148
157
  return 'a keyword' if keyword_with_redundant_parentheses?(node)
149
- return 'a literal' if disallowed_literal?(begin_node, node)
158
+ return 'a literal' if node.literal? && disallowed_literal?(begin_node, node)
150
159
  return 'a variable' if node.variable?
151
160
  return 'a constant' if node.const_type?
161
+ if node.assignment? && (begin_node.parent.nil? || begin_node.parent.begin_type?)
162
+ return 'an assignment'
163
+ end
152
164
  if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
153
165
  return 'an expression'
154
166
  end
167
+ if disallowed_one_line_pattern_matching?(begin_node, node)
168
+ return 'a one-line pattern matching'
169
+ end
155
170
  return 'an interpolated expression' if interpolation?(begin_node)
171
+ return 'a method argument' if argument_of_parenthesized_method_call?(begin_node, node)
156
172
 
157
173
  return if begin_node.chained?
158
174
 
159
- if node.and_type? || node.or_type?
175
+ if node.operator_keyword?
160
176
  return if node.semantic_operator? && begin_node.parent
161
177
  return if node.multiline? && allow_in_multiline_conditions?
162
178
  return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
179
+ return if !node.and_type? && begin_node.parent&.and_type?
163
180
  return if begin_node.parent&.if_type? && begin_node.parent.ternary?
164
181
 
165
182
  'a logical expression'
@@ -174,18 +191,31 @@ module RuboCop
174
191
  # @!method interpolation?(node)
175
192
  def_node_matcher :interpolation?, '[^begin ^^dstr]'
176
193
 
177
- def allow_in_multiline_conditions?
178
- parentheses_around_condition_config = config.for_cop('Style/ParenthesesAroundCondition')
179
- return false unless parentheses_around_condition_config['Enabled']
194
+ def argument_of_parenthesized_method_call?(begin_node, node)
195
+ if node.basic_conditional? || node.rescue_type? || method_call_parentheses_required?(node)
196
+ return false
197
+ end
198
+ return false unless (parent = begin_node.parent)
180
199
 
181
- !!parentheses_around_condition_config['AllowInMultilineConditions']
200
+ parent.call_type? && parent.parenthesized? && parent.receiver != begin_node
201
+ end
202
+
203
+ def method_call_parentheses_required?(node)
204
+ return false unless node.call_type?
205
+
206
+ (node.receiver.nil? || node.loc.dot) && node.arguments.any?
207
+ end
208
+
209
+ def allow_in_multiline_conditions?
210
+ !!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
182
211
  end
183
212
 
184
213
  def check_send(begin_node, node)
185
214
  return check_unary(begin_node, node) if node.unary_operation?
186
215
 
187
216
  return unless method_call_with_redundant_parentheses?(node)
188
- return if call_chain_starts_with_int?(begin_node, node)
217
+ return if call_chain_starts_with_int?(begin_node, node) ||
218
+ do_end_block_in_method_chain?(begin_node, node)
189
219
 
190
220
  offense(begin_node, 'a method call')
191
221
  end
@@ -215,7 +245,22 @@ module RuboCop
215
245
  end
216
246
 
217
247
  def disallowed_literal?(begin_node, node)
218
- node.literal? && !node.range_type? && !raised_to_power_negative_numeric?(begin_node, node)
248
+ if node.range_type?
249
+ return false unless (parent = begin_node.parent)
250
+
251
+ parent.begin_type? && parent.children.one?
252
+ else
253
+ !raised_to_power_negative_numeric?(begin_node, node)
254
+ end
255
+ end
256
+
257
+ def disallowed_one_line_pattern_matching?(begin_node, node)
258
+ if (parent = begin_node.parent)
259
+ return false if parent.any_def_type? && parent.endless?
260
+ return false if parent.assignment?
261
+ end
262
+
263
+ node.any_match_pattern_type? && node.each_ancestor.none?(&:operator_keyword?)
219
264
  end
220
265
 
221
266
  def raised_to_power_negative_numeric?(begin_node, node)
@@ -252,7 +297,7 @@ module RuboCop
252
297
  end
253
298
 
254
299
  def only_begin_arg?(args)
255
- args.one? && args.first.begin_type?
300
+ args.one? && args.first&.begin_type?
256
301
  end
257
302
 
258
303
  def first_argument?(node)
@@ -285,6 +330,12 @@ module RuboCop
285
330
  recv&.int_type? && (parent = begin_node.parent) &&
286
331
  parent.send_type? && (parent.method?(:-@) || parent.method?(:+@))
287
332
  end
333
+
334
+ def do_end_block_in_method_chain?(begin_node, node)
335
+ return false unless (block = node.each_descendant(:any_block).first)
336
+
337
+ block.keywords? && begin_node.each_ancestor(:call).any?
338
+ end
288
339
  end
289
340
  end
290
341
  end
@@ -70,6 +70,10 @@ module RuboCop
70
70
  new_argument = replacement(regexp_node)
71
71
 
72
72
  if new_argument.include?('"')
73
+ new_argument.gsub!("'", "\\\\'")
74
+ new_argument.gsub!('\"', '"')
75
+ quote = "'"
76
+ elsif new_argument.include?('\'')
73
77
  new_argument.gsub!("'", "\\\\'")
74
78
  quote = "'"
75
79
  elsif new_argument.include?('\\')
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for unnecessary single-element Regexp character classes.
6
+ # Checks for unnecessary single-element `Regexp` character classes.
7
7
  #
8
8
  # @example
9
9
  #
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for redundant escapes inside Regexp literals.
6
+ # Checks for redundant escapes inside `Regexp` literals.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -61,9 +61,9 @@ module RuboCop
61
61
  RESTRICT_ON_SEND = %i[define_method define_singleton_method lambda].freeze
62
62
 
63
63
  def on_send(node)
64
- return unless (parent = node.parent) && parent.block_type?
64
+ return unless node.block_literal?
65
65
 
66
- check_branch(parent.body)
66
+ check_branch(node.parent.body)
67
67
  end
68
68
 
69
69
  def on_def(node)
@@ -66,14 +66,15 @@ module RuboCop
66
66
  # Assignment of self.x
67
67
 
68
68
  def on_or_asgn(node)
69
- lhs, _rhs = *node
70
- allow_self(lhs)
69
+ allow_self(node.lhs)
70
+
71
+ lhs_name = node.lhs.lvasgn_type? ? node.lhs.name : node.lhs
72
+ add_lhs_to_local_variables_scopes(node.rhs, lhs_name)
71
73
  end
72
74
  alias on_and_asgn on_or_asgn
73
75
 
74
76
  def on_op_asgn(node)
75
- lhs, _op, _rhs = *node
76
- allow_self(lhs)
77
+ allow_self(node.lhs)
77
78
  end
78
79
 
79
80
  # Using self.x to distinguish from local variable x
@@ -92,13 +93,11 @@ module RuboCop
92
93
  end
93
94
 
94
95
  def on_masgn(node)
95
- lhs, rhs = *node
96
- add_masgn_lhs_variables(rhs, lhs)
96
+ add_masgn_lhs_variables(node.rhs, node.lhs)
97
97
  end
98
98
 
99
99
  def on_lvasgn(node)
100
- lhs, rhs = *node
101
- add_lhs_to_local_variables_scopes(rhs, lhs)
100
+ add_lhs_to_local_variables_scopes(node.rhs, node.lhs)
102
101
  end
103
102
 
104
103
  def on_in_pattern(node)
@@ -122,17 +121,16 @@ module RuboCop
122
121
  end
123
122
 
124
123
  alias on_numblock on_block
124
+ alias on_itblock on_block
125
125
 
126
126
  def on_if(node)
127
127
  # Allow conditional nodes to use `self` in the condition if that variable
128
128
  # name is used in an `lvasgn` or `masgn` within the `if`.
129
- node.child_nodes.each do |child_node|
130
- lhs, _rhs = *child_node
131
-
132
- if child_node.lvasgn_type?
133
- add_lhs_to_local_variables_scopes(node.condition, lhs)
134
- elsif child_node.masgn_type?
135
- add_masgn_lhs_variables(node.condition, lhs)
129
+ node.each_descendant(:lvasgn, :masgn) do |descendant_node|
130
+ if descendant_node.lvasgn_type?
131
+ add_lhs_to_local_variables_scopes(node.condition, descendant_node.lhs)
132
+ else
133
+ add_masgn_lhs_variables(node.condition, descendant_node.lhs)
136
134
  end
137
135
  end
138
136
  end
@@ -181,9 +179,8 @@ module RuboCop
181
179
  def on_argument(node)
182
180
  if node.mlhs_type?
183
181
  on_args(node)
184
- else
185
- name, = *node
186
- @local_variables_scopes[node] << name
182
+ elsif node.respond_to?(:name)
183
+ @local_variables_scopes[node] << node.name
187
184
  end
188
185
  end
189
186
 
@@ -21,12 +21,8 @@ module RuboCop
21
21
  # args += foo
22
22
  # hash.merge!(other)
23
23
  #
24
- # # bad
25
- # self.foo = foo.concat(ary)
26
- #
27
24
  # # good
28
25
  # foo.concat(ary)
29
- # self.foo += ary
30
26
  #
31
27
  class RedundantSelfAssignment < Base
32
28
  include RangeHelp
@@ -49,19 +45,31 @@ module RuboCop
49
45
  gvasgn: :gvar
50
46
  }.freeze
51
47
 
48
+ # @!method redundant_self_assignment?
49
+ def_node_matcher :redundant_self_assignment?, <<~PATTERN
50
+ (call
51
+ %1 _
52
+ (call
53
+ (call
54
+ %1 %2) #method_returning_self?
55
+ ...))
56
+ PATTERN
57
+
58
+ # rubocop:disable Metrics/AbcSize
52
59
  def on_lvasgn(node)
53
- lhs, rhs = *node
54
- receiver, method_name, = *rhs
55
- return unless receiver && method_returning_self?(method_name)
60
+ return unless (rhs = node.rhs)
61
+ return unless rhs.type?(:any_block, :call) && method_returning_self?(rhs.method_name)
62
+ return unless (receiver = rhs.receiver)
56
63
 
57
64
  receiver_type = ASSIGNMENT_TYPE_TO_RECEIVER_TYPE[node.type]
58
- return unless receiver.type == receiver_type && receiver.children.first == lhs
65
+ return unless receiver.type == receiver_type && receiver.children.first == node.lhs
59
66
 
60
- message = format(MSG, method_name: method_name)
67
+ message = format(MSG, method_name: rhs.method_name)
61
68
  add_offense(node.loc.operator, message: message) do |corrector|
62
69
  corrector.replace(node, rhs.source)
63
70
  end
64
71
  end
72
+ # rubocop:enable Metrics/AbcSize
65
73
  alias on_ivasgn on_lvasgn
66
74
  alias on_cvasgn on_lvasgn
67
75
  alias on_gvasgn on_lvasgn
@@ -75,6 +83,7 @@ module RuboCop
75
83
  corrector.remove(correction_range(node))
76
84
  end
77
85
  end
86
+ alias on_csend on_send
78
87
 
79
88
  private
80
89
 
@@ -82,31 +91,10 @@ module RuboCop
82
91
  METHODS_RETURNING_SELF.include?(method_name)
83
92
  end
84
93
 
85
- # @!method redundant_self_assignment?(node, method_name)
86
- def_node_matcher :redundant_self_assignment?, <<~PATTERN
87
- (send
88
- (self) _
89
- (send
90
- (send
91
- {(self) nil?} %1) #method_returning_self?
92
- ...))
93
- PATTERN
94
-
95
- # @!method redundant_nonself_assignment?(node, receiver, method_name)
96
- def_node_matcher :redundant_nonself_assignment?, <<~PATTERN
97
- (send
98
- %1 _
99
- (send
100
- (send
101
- %1 %2) #method_returning_self?
102
- ...))
103
- PATTERN
104
-
105
94
  def redundant_assignment?(node)
106
- receiver_name = node.method_name.to_s[0...-1].to_sym
95
+ receiver_name = node.method_name.to_s.delete_suffix('=').to_sym
107
96
 
108
- redundant_self_assignment?(node, receiver_name) ||
109
- redundant_nonself_assignment?(node, node.receiver, receiver_name)
97
+ redundant_self_assignment?(node, node.receiver, receiver_name)
110
98
  end
111
99
 
112
100
  def correction_range(node)
@@ -23,7 +23,6 @@ module RuboCop
23
23
  # foo = bar unless condition
24
24
  #
25
25
  class RedundantSelfAssignmentBranch < Base
26
- include RangeHelp
27
26
  extend AutoCorrector
28
27
 
29
28
  MSG = 'Remove the self-assignment branch.'
@@ -34,16 +33,17 @@ module RuboCop
34
33
  PATTERN
35
34
 
36
35
  def on_lvasgn(node)
37
- variable, expression = *node
36
+ expression = node.expression
37
+
38
38
  return unless use_if_and_else_branch?(expression)
39
39
 
40
40
  if_branch = expression.if_branch
41
41
  else_branch = expression.else_branch
42
42
  return if inconvertible_to_modifier?(if_branch, else_branch)
43
43
 
44
- if self_assign?(variable, if_branch)
44
+ if self_assign?(node.name, if_branch)
45
45
  register_offense(expression, if_branch, else_branch, 'unless')
46
- elsif self_assign?(variable, else_branch)
46
+ elsif self_assign?(node.name, else_branch)
47
47
  register_offense(expression, else_branch, if_branch, 'if')
48
48
  end
49
49
  end
@@ -93,9 +93,9 @@ module RuboCop
93
93
  (call $(call _ $:sort_by _) ${:last :first})
94
94
  (send $(send _ $:sort_by _) ${:[] :at :slice} {(int 0) (int -1)})
95
95
 
96
- (call ({block numblock} $(call _ ${:sort_by :sort}) ...) ${:last :first})
96
+ (call (any_block $(call _ ${:sort_by :sort}) ...) ${:last :first})
97
97
  (call
98
- ({block numblock} $(call _ ${:sort_by :sort}) ...)
98
+ (any_block $(call _ ${:sort_by :sort}) ...)
99
99
  ${:[] :at :slice} {(int 0) (int -1)}
100
100
  )
101
101
  }
@@ -201,7 +201,7 @@ module RuboCop
201
201
  def with_logical_operator?(node)
202
202
  return false unless (parent = node.parent)
203
203
 
204
- parent.or_type? || parent.and_type?
204
+ parent.operator_keyword?
205
205
  end
206
206
  end
207
207
  end