rubocop 1.67.0 → 1.73.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 (412) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +168 -19
  5. data/config/internal_affairs.yml +16 -0
  6. data/lib/rubocop/cached_data.rb +12 -4
  7. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  8. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  9. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  10. data/lib/rubocop/cli/command/version.rb +2 -2
  11. data/lib/rubocop/comment_config.rb +2 -2
  12. data/lib/rubocop/config.rb +17 -4
  13. data/lib/rubocop/config_loader.rb +48 -8
  14. data/lib/rubocop/config_loader_resolver.rb +35 -10
  15. data/lib/rubocop/config_validator.rb +19 -9
  16. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  17. data/lib/rubocop/cop/base.rb +7 -1
  18. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  19. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  20. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  21. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  22. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  23. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  24. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  25. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  26. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  27. data/lib/rubocop/cop/generator.rb +6 -0
  28. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  29. data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
  30. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  31. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  32. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  33. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  34. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  36. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  37. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  38. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  39. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  40. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  42. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  43. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  45. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  46. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  47. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  48. data/lib/rubocop/cop/internal_affairs.rb +6 -16
  49. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  50. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  51. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  52. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  53. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  54. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  55. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  56. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  57. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  58. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  59. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +29 -4
  60. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  61. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  62. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  63. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  64. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  65. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  66. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  67. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  68. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  69. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  70. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  71. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  72. data/lib/rubocop/cop/layout/indentation_width.rb +7 -7
  73. data/lib/rubocop/cop/layout/leading_comment_space.rb +44 -1
  74. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  75. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  76. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  77. data/lib/rubocop/cop/layout/line_length.rb +119 -4
  78. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  79. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  80. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  81. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  82. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  83. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  84. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  85. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
  86. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
  87. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  88. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  89. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  90. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  91. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  92. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  93. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  94. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
  95. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  96. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  97. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  99. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  100. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  101. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  102. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  103. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  104. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  105. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  106. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  107. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  108. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  109. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  110. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  111. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  112. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  113. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  114. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  115. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
  116. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  117. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  118. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  119. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  120. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  121. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  122. data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
  123. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  124. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  125. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  126. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  127. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  128. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  129. data/lib/rubocop/cop/lint/literal_as_condition.rb +105 -7
  130. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  131. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  132. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  133. data/lib/rubocop/cop/lint/mixed_case_range.rb +4 -7
  134. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  135. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  136. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  137. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  138. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  139. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  140. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  141. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  142. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  143. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  144. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  145. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  146. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  147. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  148. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  149. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  150. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  151. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  152. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  153. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +252 -0
  154. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  155. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  156. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  157. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  158. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  159. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  160. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  161. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  162. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  163. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  164. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  165. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  166. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  167. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  168. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  169. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  170. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  171. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  172. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  173. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  174. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  175. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  176. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  177. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  178. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  179. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  180. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  181. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  182. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  183. data/lib/rubocop/cop/lint/void.rb +14 -11
  184. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  185. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  186. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  187. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  188. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  189. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  190. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  191. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  192. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  193. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  194. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  195. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  196. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  197. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
  198. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  199. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  200. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  201. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  202. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
  203. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  204. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  205. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  206. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  207. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  208. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  209. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  210. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  211. data/lib/rubocop/cop/mixin/range_help.rb +3 -4
  212. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  213. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  214. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  215. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  216. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  217. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  218. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  219. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  220. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  221. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  222. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  223. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  224. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  225. data/lib/rubocop/cop/naming/variable_name.rb +63 -6
  226. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  227. data/lib/rubocop/cop/offense.rb +2 -3
  228. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  229. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  230. data/lib/rubocop/cop/style/access_modifier_declarations.rb +86 -28
  231. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  232. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  233. data/lib/rubocop/cop/style/and_or.rb +1 -1
  234. data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
  235. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  236. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  237. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  238. data/lib/rubocop/cop/style/block_delimiters.rb +41 -24
  239. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  240. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  241. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  242. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  243. data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
  244. data/lib/rubocop/cop/style/commented_keyword.rb +11 -1
  245. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  246. data/lib/rubocop/cop/style/conditional_assignment.rb +25 -25
  247. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  248. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  249. data/lib/rubocop/cop/style/documentation.rb +1 -1
  250. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  251. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  252. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  253. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  254. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  255. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  256. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  257. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  258. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  259. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  260. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  261. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  262. data/lib/rubocop/cop/style/file_null.rb +89 -0
  263. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  264. data/lib/rubocop/cop/style/float_division.rb +8 -4
  265. data/lib/rubocop/cop/style/for.rb +0 -1
  266. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  267. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  268. data/lib/rubocop/cop/style/guard_clause.rb +15 -2
  269. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  270. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
  271. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  272. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  273. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  274. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  275. data/lib/rubocop/cop/style/if_inside_else.rb +0 -1
  276. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  277. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
  278. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  279. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  280. data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
  281. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  282. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  283. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  284. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  285. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  286. data/lib/rubocop/cop/style/map_into_array.rb +7 -2
  287. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  288. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  289. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +20 -13
  290. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  291. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  292. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  293. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  294. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  295. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  296. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  297. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  298. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  299. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  300. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  301. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  302. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  303. data/lib/rubocop/cop/style/not.rb +1 -1
  304. data/lib/rubocop/cop/style/object_then.rb +14 -15
  305. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  306. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  307. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  308. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  309. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  310. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  311. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  312. data/lib/rubocop/cop/style/proc.rb +1 -2
  313. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  314. data/lib/rubocop/cop/style/raise_args.rb +7 -5
  315. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  316. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  317. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  318. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  319. data/lib/rubocop/cop/style/redundant_condition.rb +72 -23
  320. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  321. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  322. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  323. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  324. data/lib/rubocop/cop/style/redundant_format.rb +250 -0
  325. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  326. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  327. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -15
  328. data/lib/rubocop/cop/style/redundant_parentheses.rb +36 -24
  329. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  330. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  331. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  332. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  333. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  334. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  335. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  336. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  337. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  338. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -3
  339. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  340. data/lib/rubocop/cop/style/safe_navigation.rb +14 -2
  341. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  342. data/lib/rubocop/cop/style/select_by_regexp.rb +1 -1
  343. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  344. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  345. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  346. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  347. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  348. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  349. data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -3
  350. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  351. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  352. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
  353. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  354. data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
  355. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  356. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  357. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  358. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  359. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  360. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  361. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  362. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  363. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  364. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  365. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  366. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  367. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  368. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  369. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  370. data/lib/rubocop/cop/util.rb +12 -5
  371. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  372. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  373. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  374. data/lib/rubocop/cop/variable_force/variable.rb +18 -2
  375. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  376. data/lib/rubocop/cop/variable_force.rb +4 -10
  377. data/lib/rubocop/cops_documentation_generator.rb +44 -23
  378. data/lib/rubocop/directive_comment.rb +44 -10
  379. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  380. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  381. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  382. data/lib/rubocop/lsp/logger.rb +2 -2
  383. data/lib/rubocop/lsp/routes.rb +7 -23
  384. data/lib/rubocop/lsp/runtime.rb +17 -49
  385. data/lib/rubocop/lsp/server.rb +0 -2
  386. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  387. data/lib/rubocop/magic_comment.rb +3 -3
  388. data/lib/rubocop/options.rb +28 -12
  389. data/lib/rubocop/path_util.rb +15 -8
  390. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  391. data/lib/rubocop/plugin/load_error.rb +26 -0
  392. data/lib/rubocop/plugin/loader.rb +100 -0
  393. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  394. data/lib/rubocop/plugin.rb +46 -0
  395. data/lib/rubocop/rake_task.rb +4 -1
  396. data/lib/rubocop/result_cache.rb +13 -13
  397. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  398. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  399. data/lib/rubocop/rspec/shared_contexts.rb +19 -1
  400. data/lib/rubocop/rspec/support.rb +2 -2
  401. data/lib/rubocop/runner.rb +21 -14
  402. data/lib/rubocop/server/cache.rb +35 -2
  403. data/lib/rubocop/server/cli.rb +2 -2
  404. data/lib/rubocop/target_finder.rb +1 -0
  405. data/lib/rubocop/target_ruby.rb +16 -1
  406. data/lib/rubocop/version.rb +41 -7
  407. data/lib/rubocop.rb +27 -1
  408. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  409. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  410. metadata +73 -20
  411. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  412. 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,8 +174,9 @@ 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
@@ -162,7 +200,7 @@ module RuboCop
162
200
 
163
201
  def find_node_for_line(last_line)
164
202
  processed_source.ast.each_node do |node|
165
- return node if node.respond_to?(:expression) && node.expression&.last_line == last_line
203
+ return node if same_line?(node, last_line)
166
204
  end
167
205
  end
168
206
 
@@ -191,8 +229,9 @@ module RuboCop
191
229
  node.call_type? && !node.arguments.empty?
192
230
  end
193
231
 
194
- def start_with_arithmetic_operator?(source_line)
195
- %r{\A\s*[+\-*/%]}.match?(source_line)
232
+ def start_with_arithmetic_operator?(range)
233
+ line_range = processed_source.buffer.line_range(range.line + 1)
234
+ ARITHMETIC_OPERATOR_TOKENS.include?(processed_source.first_token_of(line_range).type)
196
235
  end
197
236
  end
198
237
  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
20
  ALLOWED_NODE_TYPES = %i[and 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,6 +41,10 @@ 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) ||
@@ -53,13 +56,12 @@ module RuboCop
53
56
  def ignore_syntax?(node)
54
57
  return false unless (parent = node.parent)
55
58
 
56
- parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
59
+ parent.type?(:while_post, :until_post, :match_with_lvasgn) ||
57
60
  like_method_argument_parentheses?(parent) || multiline_control_flow_statements?(node)
58
61
  end
59
62
 
60
63
  def allowed_expression?(node)
61
64
  allowed_ancestor?(node) ||
62
- allowed_method_call?(node) ||
63
65
  allowed_multiple_expression?(node) ||
64
66
  allowed_ternary?(node) ||
65
67
  node.parent&.range_type?
@@ -70,18 +72,13 @@ module RuboCop
70
72
  keyword_ancestor?(node) && parens_required?(node)
71
73
  end
72
74
 
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
75
  def allowed_multiple_expression?(node)
79
76
  return false if node.children.one?
80
77
 
81
78
  ancestor = node.ancestors.first
82
79
  return false unless ancestor
83
80
 
84
- !ancestor.begin_type? && !ancestor.def_type? && !ancestor.block_type?
81
+ !ancestor.type?(:begin, :def, :any_block)
85
82
  end
86
83
 
87
84
  def allowed_ternary?(node)
@@ -98,7 +95,7 @@ module RuboCop
98
95
  end
99
96
 
100
97
  def like_method_argument_parentheses?(node)
101
- return false if !node.send_type? && !node.super_type? && !node.yield_type?
98
+ return false unless node.type?(:send, :super, :yield)
102
99
 
103
100
  node.arguments.one? && !node.parenthesized? &&
104
101
  !node.arithmetic_operation? && node.first_argument.begin_type?
@@ -108,7 +105,7 @@ module RuboCop
108
105
  return false unless (parent = node.parent)
109
106
  return false if parent.single_line?
110
107
 
111
- parent.return_type? || parent.next_type? || parent.break_type?
108
+ parent.type?(:return, :next, :break)
112
109
  end
113
110
 
114
111
  def empty_parentheses?(node)
@@ -137,6 +134,8 @@ module RuboCop
137
134
  node = begin_node.children.first
138
135
 
139
136
  if (message = find_offense_message(begin_node, node))
137
+ begin_node = begin_node.parent if node.range_type?
138
+
140
139
  return offense(begin_node, message)
141
140
  end
142
141
 
@@ -146,9 +145,12 @@ module RuboCop
146
145
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
147
146
  def find_offense_message(begin_node, node)
148
147
  return 'a keyword' if keyword_with_redundant_parentheses?(node)
149
- return 'a literal' if disallowed_literal?(begin_node, node)
148
+ return 'a literal' if node.literal? && disallowed_literal?(begin_node, node)
150
149
  return 'a variable' if node.variable?
151
150
  return 'a constant' if node.const_type?
151
+ if node.assignment? && (begin_node.parent.nil? || begin_node.parent.begin_type?)
152
+ return 'an assignment'
153
+ end
152
154
  if node.lambda_or_proc? && (node.braces? || node.send_node.lambda_literal?)
153
155
  return 'an expression'
154
156
  end
@@ -156,7 +158,7 @@ module RuboCop
156
158
 
157
159
  return if begin_node.chained?
158
160
 
159
- if node.and_type? || node.or_type?
161
+ if node.operator_keyword?
160
162
  return if node.semantic_operator? && begin_node.parent
161
163
  return if node.multiline? && allow_in_multiline_conditions?
162
164
  return if ALLOWED_NODE_TYPES.include?(begin_node.parent&.type)
@@ -175,17 +177,15 @@ module RuboCop
175
177
  def_node_matcher :interpolation?, '[^begin ^^dstr]'
176
178
 
177
179
  def allow_in_multiline_conditions?
178
- parentheses_around_condition_config = config.for_cop('Style/ParenthesesAroundCondition')
179
- return false unless parentheses_around_condition_config['Enabled']
180
-
181
- !!parentheses_around_condition_config['AllowInMultilineConditions']
180
+ !!config.for_enabled_cop('Style/ParenthesesAroundCondition')['AllowInMultilineConditions']
182
181
  end
183
182
 
184
183
  def check_send(begin_node, node)
185
184
  return check_unary(begin_node, node) if node.unary_operation?
186
185
 
187
186
  return unless method_call_with_redundant_parentheses?(node)
188
- return if call_chain_starts_with_int?(begin_node, node)
187
+ return if call_chain_starts_with_int?(begin_node, node) ||
188
+ do_end_block_in_method_chain?(begin_node, node)
189
189
 
190
190
  offense(begin_node, 'a method call')
191
191
  end
@@ -215,7 +215,13 @@ module RuboCop
215
215
  end
216
216
 
217
217
  def disallowed_literal?(begin_node, node)
218
- node.literal? && !node.range_type? && !raised_to_power_negative_numeric?(begin_node, node)
218
+ if node.range_type?
219
+ return false unless (parent = begin_node.parent)
220
+
221
+ parent.begin_type? && parent.children.one?
222
+ else
223
+ !raised_to_power_negative_numeric?(begin_node, node)
224
+ end
219
225
  end
220
226
 
221
227
  def raised_to_power_negative_numeric?(begin_node, node)
@@ -252,7 +258,7 @@ module RuboCop
252
258
  end
253
259
 
254
260
  def only_begin_arg?(args)
255
- args.one? && args.first.begin_type?
261
+ args.one? && args.first&.begin_type?
256
262
  end
257
263
 
258
264
  def first_argument?(node)
@@ -285,6 +291,12 @@ module RuboCop
285
291
  recv&.int_type? && (parent = begin_node.parent) &&
286
292
  parent.send_type? && (parent.method?(:-@) || parent.method?(:+@))
287
293
  end
294
+
295
+ def do_end_block_in_method_chain?(begin_node, node)
296
+ return false unless (block = node.each_descendant(:any_block).first)
297
+
298
+ block.keywords? && begin_node.each_ancestor(:call).any?
299
+ end
288
300
  end
289
301
  end
290
302
  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,12 @@ 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)
71
70
  end
72
71
  alias on_and_asgn on_or_asgn
73
72
 
74
73
  def on_op_asgn(node)
75
- lhs, _op, _rhs = *node
76
- allow_self(lhs)
74
+ allow_self(node.lhs)
77
75
  end
78
76
 
79
77
  # Using self.x to distinguish from local variable x
@@ -92,13 +90,11 @@ module RuboCop
92
90
  end
93
91
 
94
92
  def on_masgn(node)
95
- lhs, rhs = *node
96
- add_masgn_lhs_variables(rhs, lhs)
93
+ add_masgn_lhs_variables(node.rhs, node.lhs)
97
94
  end
98
95
 
99
96
  def on_lvasgn(node)
100
- lhs, rhs = *node
101
- add_lhs_to_local_variables_scopes(rhs, lhs)
97
+ add_lhs_to_local_variables_scopes(node.rhs, node.lhs)
102
98
  end
103
99
 
104
100
  def on_in_pattern(node)
@@ -127,12 +123,10 @@ module RuboCop
127
123
  # Allow conditional nodes to use `self` in the condition if that variable
128
124
  # name is used in an `lvasgn` or `masgn` within the `if`.
129
125
  node.child_nodes.each do |child_node|
130
- lhs, _rhs = *child_node
131
-
132
126
  if child_node.lvasgn_type?
133
- add_lhs_to_local_variables_scopes(node.condition, lhs)
127
+ add_lhs_to_local_variables_scopes(node.condition, child_node.lhs)
134
128
  elsif child_node.masgn_type?
135
- add_masgn_lhs_variables(node.condition, lhs)
129
+ add_masgn_lhs_variables(node.condition, child_node.lhs)
136
130
  end
137
131
  end
138
132
  end
@@ -181,9 +175,8 @@ module RuboCop
181
175
  def on_argument(node)
182
176
  if node.mlhs_type?
183
177
  on_args(node)
184
- else
185
- name, = *node
186
- @local_variables_scopes[node] << name
178
+ elsif node.respond_to?(:name)
179
+ @local_variables_scopes[node] << node.name
187
180
  end
188
181
  end
189
182
 
@@ -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
@@ -41,7 +41,7 @@ module RuboCop
41
41
  MSG = 'Redundant escape of %<char>s inside string literal.'
42
42
 
43
43
  def on_str(node)
44
- return if node.parent&.regexp_type? || node.parent&.xstr_type? || node.character_literal?
44
+ return if node.parent&.type?(:regexp, :xstr) || node.character_literal?
45
45
 
46
46
  str_contents_range = str_contents_range(node)
47
47
 
@@ -147,7 +147,7 @@ module RuboCop
147
147
  end
148
148
 
149
149
  def heredoc?(node)
150
- (node.str_type? || node.dstr_type?) && node.heredoc?
150
+ node.type?(:str, :dstr) && node.heredoc?
151
151
  end
152
152
 
153
153
  def delimiter?(node, char)
@@ -68,8 +68,7 @@ module RuboCop
68
68
  end
69
69
 
70
70
  def correct_rescue_block(corrector, node, parenthesized)
71
- operation, rescue_modifier, = *node
72
- *_, rescue_args = *rescue_modifier
71
+ operation = node.body
73
72
 
74
73
  node_indentation, node_offset = indentation_and_offset(node, parenthesized)
75
74
 
@@ -78,7 +77,7 @@ module RuboCop
78
77
  corrector.insert_after(heredoc_end(operation) || operation, <<~RESCUE_CLAUSE.chop)
79
78
 
80
79
  #{node_offset}rescue
81
- #{node_indentation}#{rescue_args.source}
80
+ #{node_indentation}#{node.resbody_branches.first.body.source}
82
81
  #{node_offset}end
83
82
  RESCUE_CLAUSE
84
83
  end
@@ -83,7 +83,7 @@ module RuboCop
83
83
  end
84
84
 
85
85
  def scoped_node?(node)
86
- node.def_type? || node.defs_type? || node.lambda?
86
+ node.type?(:def, :defs) || node.lambda?
87
87
  end
88
88
 
89
89
  # @!method chained_send?(node)
@@ -21,6 +21,11 @@ module RuboCop
21
21
  # We have limited the cop to not register an offense for method chains
22
22
  # that exceed this option's value.
23
23
  #
24
+ # NOTE: This cop will recognize offenses but not autocorrect code when the
25
+ # right hand side (RHS) of the `&&` statement is an `||` statement
26
+ # (eg. `foo && (foo.bar? || foo.baz?)`). It can be corrected
27
+ # manually by removing the `foo &&` and adding `&.` to each `foo` on the RHS.
28
+ #
24
29
  # @safety
25
30
  # Autocorrection is unsafe because if a value is `false`, the resulting
26
31
  # code will have different behavior or raise an error.
@@ -121,6 +126,9 @@ module RuboCop
121
126
  }
122
127
  PATTERN
123
128
 
129
+ # @!method and_with_rhs_or?(node)
130
+ def_node_matcher :and_with_rhs_or?, '(and _ {or (begin or)})'
131
+
124
132
  # @!method not_nil_check?(node)
125
133
  def_node_matcher :not_nil_check?, '(send (send $_ :nil?) :!)'
126
134
 
@@ -172,6 +180,10 @@ module RuboCop
172
180
 
173
181
  def report_offense(node, rhs, rhs_receiver, *removal_ranges, offense_range: node)
174
182
  add_offense(offense_range) do |corrector|
183
+ # If the RHS is an `or` we cannot safely autocorrect because in order to remove
184
+ # the non-nil check we need to add safe-navs to all clauses where the receiver is used
185
+ next if and_with_rhs_or?(node)
186
+
175
187
  removal_ranges.each { |range| corrector.remove(range) }
176
188
  yield corrector if block_given?
177
189
 
@@ -300,7 +312,7 @@ module RuboCop
300
312
  end
301
313
 
302
314
  def chain_length(method_chain, method)
303
- method.each_ancestor(:send).inject(0) do |total, ancestor|
315
+ method.each_ancestor(:call).inject(0) do |total, ancestor|
304
316
  break total + 1 if ancestor == method_chain
305
317
 
306
318
  total + 1
@@ -311,7 +323,7 @@ module RuboCop
311
323
  return true if unsafe_method?(method)
312
324
 
313
325
  method.each_ancestor(:send).any? do |ancestor|
314
- break true unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
326
+ break true unless config.cop_enabled?('Lint/SafeNavigationChain')
315
327
 
316
328
  break true if unsafe_method?(ancestor)
317
329
  break true if nil_methods.include?(ancestor.method_name)