rubocop 1.65.1 → 1.75.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +72 -72
  4. data/config/default.yml +299 -55
  5. data/config/internal_affairs.yml +31 -0
  6. data/config/obsoletion.yml +3 -1
  7. data/exe/rubocop +4 -3
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/lsp.rb +2 -2
  12. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  13. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  14. data/lib/rubocop/cli/command/version.rb +2 -2
  15. data/lib/rubocop/cli.rb +1 -1
  16. data/lib/rubocop/comment_config.rb +3 -3
  17. data/lib/rubocop/config.rb +57 -11
  18. data/lib/rubocop/config_loader.rb +66 -17
  19. data/lib/rubocop/config_loader_resolver.rb +39 -14
  20. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  21. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  22. data/lib/rubocop/config_obsoletion.rb +46 -2
  23. data/lib/rubocop/config_validator.rb +27 -15
  24. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  25. data/lib/rubocop/cop/base.rb +17 -3
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  30. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  31. data/lib/rubocop/cop/cop.rb +8 -0
  32. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  33. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  34. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  35. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  36. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  37. data/lib/rubocop/cop/documentation.rb +18 -1
  38. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  39. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  40. data/lib/rubocop/cop/generator.rb +6 -0
  41. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  42. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  43. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  44. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  45. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  46. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  47. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  48. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  49. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  52. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  55. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  56. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  57. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  58. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  59. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  60. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  61. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  62. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  63. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  64. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  65. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +23 -2
  66. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  67. data/lib/rubocop/cop/internal_affairs.rb +7 -0
  68. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  69. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  70. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  72. data/lib/rubocop/cop/layout/block_alignment.rb +32 -13
  73. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  74. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  75. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  76. data/lib/rubocop/cop/layout/def_end_alignment.rb +2 -2
  77. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  78. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  79. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +4 -4
  80. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +9 -12
  81. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
  82. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  83. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  84. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +12 -8
  85. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  86. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  87. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  88. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  89. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -10
  90. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  91. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  92. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  93. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  95. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +12 -12
  97. data/lib/rubocop/cop/layout/leading_comment_space.rb +83 -1
  98. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  99. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  100. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  101. data/lib/rubocop/cop/layout/line_length.rb +135 -16
  102. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  105. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  106. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  107. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  108. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  109. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  110. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  111. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  112. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  113. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  115. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  116. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  118. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  119. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  121. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  122. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  123. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  125. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  126. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  127. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  128. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  129. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  130. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  131. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  132. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  133. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  134. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  135. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  136. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  137. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  138. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  140. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  141. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  142. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  143. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  144. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  145. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  146. data/lib/rubocop/cop/lint/duplicate_methods.rb +46 -19
  147. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  148. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  149. data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -58
  150. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  151. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  152. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  153. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  154. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -7
  155. data/lib/rubocop/cop/lint/float_comparison.rb +21 -17
  156. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  157. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  158. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  159. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +13 -5
  160. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  161. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  162. data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
  163. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  164. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
  165. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  166. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  167. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  168. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  169. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  170. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  171. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  172. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  173. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  174. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  175. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  176. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  177. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  178. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  179. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  180. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  181. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  182. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  183. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  184. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  185. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  186. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  187. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  188. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  189. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  190. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  191. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  192. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  193. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  194. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  195. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  196. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  197. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  198. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  199. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  200. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  201. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  202. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  203. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  204. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
  205. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  206. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  207. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  208. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  209. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  210. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  211. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  212. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  213. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  214. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  215. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  216. data/lib/rubocop/cop/lint/useless_assignment.rb +20 -11
  217. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  218. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  219. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  220. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  221. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +78 -0
  222. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  223. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  224. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  225. data/lib/rubocop/cop/lint/void.rb +40 -14
  226. data/lib/rubocop/cop/message_annotator.rb +7 -3
  227. data/lib/rubocop/cop/metrics/block_length.rb +7 -5
  228. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  229. data/lib/rubocop/cop/metrics/class_length.rb +15 -14
  230. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  231. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  232. data/lib/rubocop/cop/metrics/method_length.rb +15 -6
  233. data/lib/rubocop/cop/metrics/module_length.rb +7 -6
  234. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  235. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  236. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  237. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  238. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  239. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  240. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  241. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  242. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  243. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  244. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  245. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  246. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  247. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  248. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  249. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  250. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  251. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -11
  252. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  253. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  254. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  255. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  256. data/lib/rubocop/cop/mixin/line_length_help.rb +12 -6
  257. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  258. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  259. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  260. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  261. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  262. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  263. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  264. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  265. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  266. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  267. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  268. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  269. data/lib/rubocop/cop/naming/accessor_method_name.rb +11 -6
  270. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  271. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  272. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  273. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  274. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  275. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  276. data/lib/rubocop/cop/naming/predicate_name.rb +46 -2
  277. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  278. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  279. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  280. data/lib/rubocop/cop/offense.rb +4 -5
  281. data/lib/rubocop/cop/registry.rb +9 -6
  282. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  283. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  284. data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
  285. data/lib/rubocop/cop/style/accessor_grouping.rb +29 -7
  286. data/lib/rubocop/cop/style/alias.rb +1 -1
  287. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  288. data/lib/rubocop/cop/style/and_or.rb +1 -1
  289. data/lib/rubocop/cop/style/arguments_forwarding.rb +94 -30
  290. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  291. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  292. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  293. data/lib/rubocop/cop/style/block_delimiters.rb +51 -20
  294. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  295. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  296. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  297. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  298. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  299. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  300. data/lib/rubocop/cop/style/combinable_loops.rb +10 -2
  301. data/lib/rubocop/cop/style/commented_keyword.rb +25 -2
  302. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  303. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  304. data/lib/rubocop/cop/style/conditional_assignment.rb +40 -28
  305. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  306. data/lib/rubocop/cop/style/data_inheritance.rb +8 -1
  307. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  308. data/lib/rubocop/cop/style/documentation.rb +1 -1
  309. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  310. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  311. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  312. data/lib/rubocop/cop/style/empty_else.rb +10 -7
  313. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  314. data/lib/rubocop/cop/style/empty_literal.rb +35 -22
  315. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  316. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  317. data/lib/rubocop/cop/style/eval_with_location.rb +5 -5
  318. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  319. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  320. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  321. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  322. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  323. data/lib/rubocop/cop/style/file_null.rb +89 -0
  324. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  325. data/lib/rubocop/cop/style/float_division.rb +8 -4
  326. data/lib/rubocop/cop/style/for.rb +1 -1
  327. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  328. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  329. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  330. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  331. data/lib/rubocop/cop/style/guard_clause.rb +20 -4
  332. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  333. data/lib/rubocop/cop/style/hash_each_methods.rb +12 -8
  334. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  335. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  336. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  337. data/lib/rubocop/cop/style/hash_syntax.rb +11 -5
  338. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  339. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  340. data/lib/rubocop/cop/style/identical_conditional_branches.rb +26 -7
  341. data/lib/rubocop/cop/style/if_inside_else.rb +11 -15
  342. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -5
  343. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  344. data/lib/rubocop/cop/style/if_with_semicolon.rb +60 -6
  345. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  346. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  347. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  348. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  349. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  350. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  351. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  352. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  353. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  354. data/lib/rubocop/cop/style/lambda.rb +2 -1
  355. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  356. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  357. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  358. data/lib/rubocop/cop/style/map_into_array.rb +75 -14
  359. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  360. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  361. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +38 -23
  362. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  363. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +10 -13
  364. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  365. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  366. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  367. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  368. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  369. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  370. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  371. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  372. data/lib/rubocop/cop/style/multiple_comparison.rb +53 -60
  373. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  374. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  375. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  376. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  377. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  378. data/lib/rubocop/cop/style/next.rb +44 -0
  379. data/lib/rubocop/cop/style/not.rb +1 -1
  380. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
  381. data/lib/rubocop/cop/style/object_then.rb +15 -15
  382. data/lib/rubocop/cop/style/one_line_conditional.rb +30 -5
  383. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  384. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  385. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  386. data/lib/rubocop/cop/style/parallel_assignment.rb +14 -22
  387. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  388. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  389. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  390. data/lib/rubocop/cop/style/proc.rb +2 -2
  391. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
  392. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  393. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  394. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  395. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  396. data/lib/rubocop/cop/style/redundant_begin.rb +6 -1
  397. data/lib/rubocop/cop/style/redundant_condition.rb +97 -24
  398. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  399. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  400. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  401. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  402. data/lib/rubocop/cop/style/redundant_format.rb +257 -0
  403. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  404. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  405. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  406. data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -20
  407. data/lib/rubocop/cop/style/redundant_parentheses.rb +57 -27
  408. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -1
  409. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  410. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  411. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  412. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  413. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  414. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  415. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  416. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  417. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  418. data/lib/rubocop/cop/style/require_order.rb +1 -1
  419. data/lib/rubocop/cop/style/rescue_modifier.rb +18 -4
  420. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  421. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  422. data/lib/rubocop/cop/style/safe_navigation.rb +123 -54
  423. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  424. data/lib/rubocop/cop/style/select_by_regexp.rb +14 -8
  425. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  426. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  427. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  428. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  429. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  430. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  431. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  432. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  433. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  434. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  435. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  436. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  437. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  438. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  439. data/lib/rubocop/cop/style/struct_inheritance.rb +9 -2
  440. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  441. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  442. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  443. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  444. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  445. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  446. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  447. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  448. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  449. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  450. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  451. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  452. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  453. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  454. data/lib/rubocop/cop/team.rb +14 -3
  455. data/lib/rubocop/cop/util.rb +12 -5
  456. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  457. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  458. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  459. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  460. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  461. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  462. data/lib/rubocop/cop/variable_force.rb +5 -11
  463. data/lib/rubocop/cops_documentation_generator.rb +117 -53
  464. data/lib/rubocop/directive_comment.rb +45 -11
  465. data/lib/rubocop/ext/regexp_node.rb +0 -1
  466. data/lib/rubocop/file_finder.rb +9 -4
  467. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  468. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  469. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  470. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  471. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  472. data/lib/rubocop/lockfile.rb +6 -4
  473. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  474. data/lib/rubocop/lsp/logger.rb +2 -2
  475. data/lib/rubocop/lsp/routes.rb +7 -23
  476. data/lib/rubocop/lsp/runtime.rb +19 -49
  477. data/lib/rubocop/lsp/server.rb +0 -3
  478. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  479. data/lib/rubocop/magic_comment.rb +11 -3
  480. data/lib/rubocop/options.rb +28 -12
  481. data/lib/rubocop/path_util.rb +15 -8
  482. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  483. data/lib/rubocop/plugin/load_error.rb +26 -0
  484. data/lib/rubocop/plugin/loader.rb +100 -0
  485. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  486. data/lib/rubocop/plugin.rb +46 -0
  487. data/lib/rubocop/rake_task.rb +4 -1
  488. data/lib/rubocop/remote_config.rb +5 -1
  489. data/lib/rubocop/result_cache.rb +15 -21
  490. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  491. data/lib/rubocop/rspec/expect_offense.rb +7 -2
  492. data/lib/rubocop/rspec/shared_contexts.rb +40 -3
  493. data/lib/rubocop/rspec/support.rb +4 -2
  494. data/lib/rubocop/runner.rb +27 -13
  495. data/lib/rubocop/server/cache.rb +52 -11
  496. data/lib/rubocop/server/cli.rb +2 -2
  497. data/lib/rubocop/server/core.rb +1 -0
  498. data/lib/rubocop/target_finder.rb +7 -2
  499. data/lib/rubocop/target_ruby.rb +36 -17
  500. data/lib/rubocop/version.rb +54 -11
  501. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  502. data/lib/rubocop.rb +36 -2
  503. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  504. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  505. metadata +83 -40
  506. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  507. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -42,22 +42,28 @@ module RuboCop
42
42
  return if kwarg_nodes.empty?
43
43
 
44
44
  add_offense(node) do |corrector|
45
- if node.parent.find(&:kwoptarg_type?) == node
46
- corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
45
+ defining_node = node.each_ancestor(:any_def, :block).first
46
+ next if processed_source.contains_comment?(arguments_range(defining_node))
47
+ next unless node.parent.find(&:kwoptarg_type?) == node
47
48
 
48
- arguments = node.each_ancestor(:def, :defs, :block).first.arguments
49
- append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
50
-
51
- remove_kwargs(kwarg_nodes, corrector)
52
- end
49
+ autocorrect(corrector, node, defining_node, kwarg_nodes)
53
50
  end
54
51
  end
55
52
 
56
53
  private
57
54
 
55
+ def autocorrect(corrector, node, defining_node, kwarg_nodes)
56
+ corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
57
+
58
+ arguments = defining_node.arguments
59
+ append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
60
+
61
+ remove_kwargs(kwarg_nodes, corrector)
62
+ end
63
+
58
64
  def append_newline_to_last_kwoptarg(arguments, corrector)
59
65
  last_argument = arguments.last
60
- return if last_argument.kwrestarg_type? || last_argument.blockarg_type?
66
+ return if last_argument.type?(:kwrestarg, :blockarg)
61
67
 
62
68
  last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
63
69
  corrector.insert_after(last_kwoptarg, "\n") unless arguments.parent.block_type?
@@ -68,7 +68,7 @@ module RuboCop
68
68
 
69
69
  return unless offending_selector?(node, selector)
70
70
 
71
- add_offense(node.send_node.source_range, message: message(node, selector)) do |corrector|
71
+ add_offense(node.send_node, message: message(node, selector)) do |corrector|
72
72
  if node.send_node.lambda_literal?
73
73
  LambdaLiteralToMethodCorrector.new(node).call(corrector)
74
74
  else
@@ -77,6 +77,7 @@ module RuboCop
77
77
  end
78
78
  end
79
79
  alias on_numblock on_block
80
+ alias on_itblock on_block
80
81
 
81
82
  private
82
83
 
@@ -20,7 +20,6 @@ module RuboCop
20
20
  # lambda.(x, y)
21
21
  class LambdaCall < Base
22
22
  include ConfigurableEnforcedStyle
23
- include IgnoredNode
24
23
  extend AutoCorrector
25
24
 
26
25
  MSG = 'Prefer the use of `%<prefer>s` over `%<current>s`.'
@@ -45,6 +44,7 @@ module RuboCop
45
44
  correct_style_detected
46
45
  end
47
46
  end
47
+ alias on_csend on_send
48
48
 
49
49
  private
50
50
 
@@ -54,10 +54,16 @@ module RuboCop
54
54
 
55
55
  def prefer(node)
56
56
  receiver = node.receiver.source
57
- arguments = node.arguments.map(&:source).join(', ')
58
- method = explicit_style? ? "call(#{arguments})" : "(#{arguments})"
57
+ dot = node.loc.dot.source
58
+ call_arguments = if node.arguments.empty?
59
+ ''
60
+ else
61
+ arguments = node.arguments.map(&:source).join(', ')
62
+ "(#{arguments})"
63
+ end
64
+ method = explicit_style? ? "call#{call_arguments}" : "(#{arguments})"
59
65
 
60
- "#{receiver}.#{method}"
66
+ "#{receiver}#{dot}#{method}"
61
67
  end
62
68
 
63
69
  def implicit_style?
@@ -36,7 +36,7 @@ module RuboCop
36
36
  include RangeHelp
37
37
  extend AutoCorrector
38
38
 
39
- MSG = 'Use `\\` instead of `+` or `<<` to concatenate those strings.'
39
+ MSG = 'Use `\\` instead of `%<operator>s` to concatenate multiline strings.'
40
40
  CONCAT_TOKEN_TYPES = %i[tPLUS tLSHFT].freeze
41
41
  SIMPLE_STRING_TOKEN_TYPE = :tSTRING
42
42
  COMPLEX_STRING_BEGIN_TOKEN = :tSTRING_BEG
@@ -61,14 +61,20 @@ module RuboCop
61
61
  successor = tokens[index + 2]
62
62
 
63
63
  return unless eligible_token_set?(predecessor, operator, successor)
64
-
65
64
  return if same_line?(operator, successor)
66
65
 
67
66
  next_successor = token_after_last_string(successor, index)
68
-
69
67
  return unless eligible_next_successor?(next_successor)
70
68
 
71
- add_offense(operator.pos) { |corrector| autocorrect(corrector, operator.pos) }
69
+ register_offense(operator)
70
+ end
71
+
72
+ def register_offense(operator)
73
+ message = format(MSG, operator: operator.text)
74
+
75
+ add_offense(operator.pos, message: message) do |corrector|
76
+ autocorrect(corrector, operator.pos)
77
+ end
72
78
  end
73
79
 
74
80
  def autocorrect(corrector, operator_range)
@@ -105,7 +105,7 @@ module RuboCop
105
105
 
106
106
  # Value object to extract source ranges for the different parts of a magic comment
107
107
  class CommentRange
108
- extend Forwardable
108
+ extend SimpleForwardable
109
109
 
110
110
  DIRECTIVE_REGEXP = Regexp.union(MagicComment::KEYWORDS.map do |_, v|
111
111
  Regexp.new(v, Regexp::IGNORECASE)
@@ -13,8 +13,10 @@ module RuboCop
13
13
  # return value of `Enumerable#map` is an `Array`. They are not autocorrected
14
14
  # when a return value could be used because these types differ.
15
15
  #
16
- # NOTE: It only detects when the mapping destination is a local variable
17
- # initialized as an empty array and referred to only by the pushing operation.
16
+ # NOTE: It only detects when the mapping destination is either:
17
+ # * a local variable initialized as an empty array and referred to only by the
18
+ # pushing operation;
19
+ # * or, if it is the single block argument to a `[].tap` block.
18
20
  # This is because, if not, it's challenging to statically guarantee that the
19
21
  # mapping destination variable remains an empty array:
20
22
  #
@@ -42,6 +44,14 @@ module RuboCop
42
44
  # # good
43
45
  # dest = src.map { |e| e * 2 }
44
46
  #
47
+ # # bad
48
+ # [].tap do |dest|
49
+ # src.each { |e| dest << e * 2 }
50
+ # end
51
+ #
52
+ # # good
53
+ # dest = src.map { |e| e * 2 }
54
+ #
45
55
  # # good - contains another operation
46
56
  # dest = []
47
57
  # src.each { |e| dest << e * 2; puts e }
@@ -53,17 +63,41 @@ module RuboCop
53
63
 
54
64
  MSG = 'Use `%<new_method_name>s` instead of `each` to map elements into an array.'
55
65
 
66
+ # @!method suitable_argument_node?(node)
67
+ def_node_matcher :suitable_argument_node?, <<-PATTERN
68
+ !{splat forwarded-restarg forwarded-args (hash (forwarded-kwrestarg)) (block-pass nil?)}
69
+ PATTERN
70
+
56
71
  # @!method each_block_with_push?(node)
57
72
  def_node_matcher :each_block_with_push?, <<-PATTERN
58
73
  [
59
- ^({begin kwbegin} ...)
60
- ({block numblock} (send !{nil? self} :each) _
61
- (send (lvar _) {:<< :push :append} _))
74
+ ^({begin kwbegin block} ...)
75
+ (any_block (send !{nil? self} :each) _
76
+ (send (lvar _) {:<< :push :append} #suitable_argument_node?))
62
77
  ]
63
78
  PATTERN
64
79
 
65
80
  # @!method empty_array_asgn?(node)
66
- def_node_matcher :empty_array_asgn?, '(lvasgn _ (array))'
81
+ def_node_matcher :empty_array_asgn?, <<~PATTERN
82
+ (
83
+ lvasgn _ {
84
+ (array)
85
+ (send (const {nil? cbase} :Array) :[])
86
+ (send (const {nil? cbase} :Array) :new (array)?)
87
+ (send nil? :Array (array))
88
+ }
89
+ )
90
+ PATTERN
91
+
92
+ # @!method empty_array_tap(node)
93
+ def_node_matcher :empty_array_tap, <<~PATTERN
94
+ ^^$(
95
+ block
96
+ (send (array) :tap)
97
+ (args (arg _))
98
+ ...
99
+ )
100
+ PATTERN
67
101
 
68
102
  # @!method lvar_ref?(node, name)
69
103
  def_node_matcher :lvar_ref?, '(lvar %1)'
@@ -80,14 +114,20 @@ module RuboCop
80
114
  return unless each_block_with_push?(node)
81
115
 
82
116
  dest_var = find_dest_var(node)
83
- return unless (asgn = find_closest_assignment(node, dest_var))
84
- return unless empty_array_asgn?(asgn)
85
- return unless dest_used_only_for_mapping?(node, dest_var, asgn)
117
+
118
+ if offending_empty_array_tap?(node, dest_var)
119
+ asgn = dest_var.declaration_node
120
+ else
121
+ return unless (asgn = find_closest_assignment(node, dest_var))
122
+ return unless empty_array_asgn?(asgn)
123
+ return unless dest_used_only_for_mapping?(node, dest_var, asgn)
124
+ end
86
125
 
87
126
  register_offense(node, dest_var, asgn)
88
127
  end
89
128
 
90
129
  alias on_numblock on_block
130
+ alias on_itblock on_block
91
131
 
92
132
  private
93
133
 
@@ -99,6 +139,15 @@ module RuboCop
99
139
  candidates.find { |v| v.references.any? { |n| n.node.equal?(node) } }
100
140
  end
101
141
 
142
+ def offending_empty_array_tap?(node, dest_var)
143
+ return false unless (tap_block_node = empty_array_tap(dest_var.declaration_node))
144
+
145
+ # A `tap` block only offends if the array push is the only thing in it;
146
+ # otherwise we cannot guarantee that the block variable is still an empty
147
+ # array when pushed to.
148
+ tap_block_node.body == node
149
+ end
150
+
102
151
  def find_closest_assignment(block, dest_var)
103
152
  dest_var.assignments.reverse_each.lazy.map(&:node).find do |node|
104
153
  node.source_range.end_pos < block.source_range.begin_pos
@@ -118,7 +167,13 @@ module RuboCop
118
167
  next if return_value_used?(block)
119
168
 
120
169
  corrector.replace(block.send_node.selector, new_method_name)
121
- remove_assignment(corrector, asgn)
170
+
171
+ if (tap_block_node = empty_array_tap(dest_var.declaration_node))
172
+ remove_tap(corrector, block, tap_block_node)
173
+ else
174
+ remove_assignment(corrector, asgn)
175
+ end
176
+
122
177
  correct_push_node(corrector, block.body)
123
178
  correct_return_value_handling(corrector, block, dest_var)
124
179
  end
@@ -138,10 +193,8 @@ module RuboCop
138
193
  false
139
194
  when :begin, :kwbegin
140
195
  !node.right_sibling && return_value_used?(parent)
141
- when :block, :numblock
142
- !parent.void_context?
143
196
  else
144
- true
197
+ !parent.respond_to?(:void_context?) || !parent.void_context?
145
198
  end
146
199
  end
147
200
 
@@ -152,10 +205,18 @@ module RuboCop
152
205
  corrector.remove(range)
153
206
  end
154
207
 
208
+ def remove_tap(corrector, node, block_node)
209
+ range = range_between(block_node.source_range.begin_pos, node.source_range.begin_pos)
210
+ corrector.remove(range)
211
+ corrector.remove(range_with_surrounding_space(block_node.loc.end, side: :left))
212
+ end
213
+
155
214
  def correct_push_node(corrector, push_node)
215
+ arg_node = push_node.first_argument
156
216
  range = push_node.source_range
157
- arg_range = push_node.first_argument.source_range
217
+ arg_range = arg_node.source_range
158
218
 
219
+ corrector.wrap(arg_node, '{ ', ' }') if arg_node.hash_type? && !arg_node.braces?
159
220
  corrector.remove(range_between(range.begin_pos, arg_range.begin_pos))
160
221
  corrector.remove(range_between(arg_range.end_pos, range.end_pos))
161
222
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # @!method map_to_h(node)
41
41
  def_node_matcher :map_to_h, <<~PATTERN
42
42
  {
43
- $(call ({block numblock} $(call _ {:map :collect}) ...) :to_h)
43
+ $(call (any_block $(call _ {:map :collect}) ...) :to_h)
44
44
  $(call $(call _ {:map :collect} (block_pass sym)) :to_h)
45
45
  }
46
46
  PATTERN
@@ -33,8 +33,8 @@ module RuboCop
33
33
  # @!method map_to_set?(node)
34
34
  def_node_matcher :map_to_set?, <<~PATTERN
35
35
  {
36
- $(send ({block numblock} $(send _ {:map :collect}) ...) :to_set)
37
- $(send $(send _ {:map :collect} (block_pass sym)) :to_set)
36
+ $(call (any_block $(call _ {:map :collect}) ...) :to_set)
37
+ $(call $(call _ {:map :collect} (block_pass sym)) :to_set)
38
38
  }
39
39
  PATTERN
40
40
 
@@ -49,6 +49,7 @@ module RuboCop
49
49
  autocorrect(corrector, to_set_node, map_node)
50
50
  end
51
51
  end
52
+ alias on_csend on_send
52
53
 
53
54
  private
54
55
 
@@ -7,6 +7,8 @@ module RuboCop
7
7
  # Style omit_parentheses
8
8
  # rubocop:disable Metrics/ModuleLength, Metrics/CyclomaticComplexity
9
9
  module OmitParentheses
10
+ include RangeHelp
11
+
10
12
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
11
13
  OMIT_MSG = 'Omit parentheses for method calls with arguments.'
12
14
  private_constant :OMIT_MSG
@@ -30,10 +32,13 @@ module RuboCop
30
32
  end
31
33
 
32
34
  def autocorrect(corrector, node)
35
+ range = args_begin(node)
33
36
  if parentheses_at_the_end_of_multiline_call?(node)
34
- corrector.replace(args_begin(node), ' \\')
37
+ # Whitespace after line continuation (`\ `) is a syntax error
38
+ with_whitespace = range_with_surrounding_space(range, side: :right, newlines: false)
39
+ corrector.replace(with_whitespace, ' \\')
35
40
  else
36
- corrector.replace(args_begin(node), ' ')
41
+ corrector.replace(range, ' ')
37
42
  end
38
43
  corrector.remove(node.loc.end)
39
44
  end
@@ -44,14 +49,14 @@ module RuboCop
44
49
 
45
50
  def inside_endless_method_def?(node)
46
51
  # parens are required around arguments inside an endless method
47
- node.each_ancestor(:def, :defs).any?(&:endless?) && node.arguments.any?
52
+ node.each_ancestor(:any_def).any?(&:endless?) && node.arguments.any?
48
53
  end
49
54
 
50
- def require_parentheses_for_hash_value_omission?(node)
55
+ def require_parentheses_for_hash_value_omission?(node) # rubocop:disable Metrics/PerceivedComplexity
51
56
  return false unless (last_argument = node.last_argument)
52
57
  return false if !last_argument.hash_type? || !last_argument.pairs.last&.value_omission?
53
58
 
54
- node.parent&.conditional? || !last_expression?(node)
59
+ node.parent&.conditional? || node.parent&.single_line? || !last_expression?(node)
55
60
  end
56
61
 
57
62
  # Require hash value omission be enclosed in parentheses to prevent the following issue:
@@ -103,18 +108,16 @@ module RuboCop
103
108
  end
104
109
 
105
110
  def call_in_literals?(node)
106
- parent = node.parent&.block_type? ? node.parent.parent : node.parent
111
+ parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
107
112
  return false unless parent
108
113
 
109
- parent.pair_type? ||
110
- parent.array_type? ||
111
- parent.range_type? ||
114
+ parent.type?(:pair, :array, :range) ||
112
115
  splat?(parent) ||
113
116
  ternary_if?(parent)
114
117
  end
115
118
 
116
119
  def call_in_logical_operators?(node)
117
- parent = node.parent&.block_type? ? node.parent.parent : node.parent
120
+ parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
118
121
  return false unless parent
119
122
 
120
123
  logical_operator?(parent) ||
@@ -123,46 +126,48 @@ module RuboCop
123
126
  end
124
127
 
125
128
  def call_in_optional_arguments?(node)
126
- node.parent && (node.parent.optarg_type? || node.parent.kwoptarg_type?)
129
+ node.parent&.type?(:optarg, :kwoptarg)
127
130
  end
128
131
 
129
132
  def call_in_single_line_inheritance?(node)
130
- node.parent&.class_type? && node.parent&.single_line?
133
+ node.parent&.class_type? && node.parent.single_line?
131
134
  end
132
135
 
133
- def call_with_ambiguous_arguments?(node) # rubocop:disable Metrics/PerceivedComplexity
136
+ # rubocop:disable Metrics/PerceivedComplexity
137
+ def call_with_ambiguous_arguments?(node)
134
138
  call_with_braced_block?(node) ||
135
139
  call_in_argument_with_block?(node) ||
136
140
  call_as_argument_or_chain?(node) ||
137
141
  call_in_match_pattern?(node) ||
138
142
  hash_literal_in_arguments?(node) ||
143
+ ambiguous_range_argument?(node) ||
139
144
  node.descendants.any? do |n|
140
- n.forwarded_args_type? || n.block_type? || n.numblock_type? ||
145
+ n.type?(:forwarded_args, :any_block) ||
141
146
  ambiguous_literal?(n) || logical_operator?(n)
142
147
  end
143
148
  end
149
+ # rubocop:enable Metrics/PerceivedComplexity
144
150
 
145
151
  def call_with_braced_block?(node)
146
- (node.call_type? || node.super_type?) && node.block_node&.braces?
152
+ node.type?(:call, :super) && node.block_node&.braces?
147
153
  end
148
154
 
149
155
  def call_in_argument_with_block?(node)
150
- parent = node.parent&.block_type? && node.parent&.parent
156
+ parent = node.parent&.any_block_type? && node.parent.parent
151
157
  return false unless parent
152
158
 
153
- parent.call_type? || parent.super_type? || parent.yield_type?
159
+ parent.type?(:call, :super, :yield)
154
160
  end
155
161
 
156
162
  def call_as_argument_or_chain?(node)
157
- node.parent &&
158
- (node.parent.call_type? || node.parent.super_type? || node.parent.yield_type?) &&
163
+ node.parent&.type?(:call, :super, :yield) &&
159
164
  !assigned_before?(node.parent, node)
160
165
  end
161
166
 
162
167
  def call_in_match_pattern?(node)
163
168
  return false unless (parent = node.parent)
164
169
 
165
- parent.match_pattern_type? || parent.match_pattern_p_type?
170
+ parent.type?(:match_pattern, :match_pattern_p)
166
171
  end
167
172
 
168
173
  def hash_literal_in_arguments?(node)
@@ -172,6 +177,13 @@ module RuboCop
172
177
  end
173
178
  end
174
179
 
180
+ def ambiguous_range_argument?(node)
181
+ return true if (first_arg = node.first_argument)&.range_type? && first_arg.begin.nil?
182
+ return true if (last_arg = node.last_argument)&.range_type? && last_arg.end.nil?
183
+
184
+ false
185
+ end
186
+
175
187
  def allowed_multiline_call_with_parentheses?(node)
176
188
  cop_config['AllowParenthesesInMultilineCall'] && node.multiline?
177
189
  end
@@ -190,7 +202,7 @@ module RuboCop
190
202
  end
191
203
 
192
204
  def splat?(node)
193
- node.splat_type? || node.kwsplat_type? || node.block_pass_type?
205
+ node.type?(:splat, :kwsplat, :block_pass)
194
206
  end
195
207
 
196
208
  def ternary_if?(node)
@@ -198,7 +210,7 @@ module RuboCop
198
210
  end
199
211
 
200
212
  def logical_operator?(node)
201
- (node.and_type? || node.or_type?) && node.logical_operator?
213
+ node.operator_keyword? && node.logical_operator?
202
214
  end
203
215
 
204
216
  def hash_literal?(node)
@@ -210,8 +222,11 @@ module RuboCop
210
222
  end
211
223
 
212
224
  def unary_literal?(node)
225
+ # NOTE: should be removed after releasing https://github.com/rubocop/rubocop-ast/pull/379
226
+ return node.source.match?(/\A[+-]/) if node.complex_type?
227
+
213
228
  (node.numeric_type? && node.sign?) ||
214
- (node.parent&.send_type? && node.parent&.unary_operation?)
229
+ (node.parent&.send_type? && node.parent.unary_operation?)
215
230
  end
216
231
 
217
232
  def assigned_before?(node, target)
@@ -61,6 +61,8 @@ module RuboCop
61
61
  # https://bugs.ruby-lang.org/issues/18396.
62
62
  # - Parentheses are required in anonymous arguments, keyword arguments
63
63
  # and block passing in Ruby 3.2.
64
+ # - Parentheses are required when the first argument is a beginless range or
65
+ # the last argument is an endless range.
64
66
  #
65
67
  # @example EnforcedStyle: require_parentheses (default)
66
68
  #
@@ -5,8 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unwanted parentheses in parameterless method calls.
7
7
  #
8
- # This cop can be customized allowed methods with `AllowedMethods`.
9
- # By default, there are no methods to allowed.
8
+ # This cop's allowed methods can be customized with `AllowedMethods`.
9
+ # By default, there are no allowed methods.
10
10
  #
11
11
  # NOTE: This cop allows the use of `it()` without arguments in blocks,
12
12
  # as in `0.times { it() }`, following `Lint/ItWithoutArgumentsInBlock` cop.
@@ -45,6 +45,7 @@ module RuboCop
45
45
  register_offense(node)
46
46
  end
47
47
  # rubocop:enable Metrics/CyclomaticComplexity
48
+ alias on_csend on_send
48
49
 
49
50
  private
50
51
 
@@ -71,9 +72,11 @@ module RuboCop
71
72
  return false if node.receiver
72
73
 
73
74
  any_assignment?(node) do |asgn_node|
74
- next variable_in_mass_assignment?(node.method_name, asgn_node) if asgn_node.masgn_type?
75
-
76
- asgn_node.loc.name.source == node.method_name.to_s
75
+ if asgn_node.masgn_type?
76
+ variable_in_mass_assignment?(node.method_name, asgn_node)
77
+ else
78
+ asgn_node.loc.name.source == node.method_name.to_s
79
+ end
77
80
  end
78
81
  end
79
82
 
@@ -98,20 +101,14 @@ module RuboCop
98
101
  # `obj.method ||= value` parses as (or-asgn (send ...) ...)
99
102
  # which IS an `asgn_node`. Similarly, `obj.method += value` parses
100
103
  # as (op-asgn (send ...) ...), which is also an `asgn_node`.
101
- if asgn_node.shorthand_asgn?
102
- asgn_node, _value = *asgn_node
103
- next if asgn_node.send_type?
104
- end
104
+ next if asgn_node.shorthand_asgn? && asgn_node.lhs.call_type?
105
105
 
106
106
  yield asgn_node
107
107
  end
108
108
  end
109
109
 
110
110
  def variable_in_mass_assignment?(variable_name, node)
111
- mlhs_node, _mrhs_node = *node
112
- var_nodes = *mlhs_node
113
-
114
- var_nodes.any? { |n| n.to_a.first == variable_name }
111
+ node.assignments.reject(&:send_type?).any? { |n| n.name == variable_name }
115
112
  end
116
113
 
117
114
  def offense_range(node)
@@ -36,14 +36,13 @@ module RuboCop
36
36
  end
37
37
 
38
38
  alias on_numblock on_block
39
+ alias on_itblock on_block
39
40
 
40
41
  def on_send(node)
41
42
  return if ignored_node?(node)
42
43
 
43
- receiver = node.receiver
44
-
45
- return unless (receiver&.block_type? || receiver&.numblock_type?) &&
46
- receiver.loc.end.is?('end')
44
+ return unless (receiver = node.receiver)
45
+ return unless receiver.any_block_type? && receiver.keywords?
47
46
 
48
47
  range = range_between(receiver.loc.end.begin_pos, node.source_range.end_pos)
49
48
 
@@ -168,7 +168,7 @@ module RuboCop
168
168
 
169
169
  def anonymous_arguments?(node)
170
170
  return true if node.arguments.any? do |arg|
171
- arg.forward_arg_type? || arg.restarg_type? || arg.kwrestarg_type?
171
+ arg.type?(:forward_arg, :restarg, :kwrestarg)
172
172
  end
173
173
  return false unless (last_argument = node.last_argument)
174
174
 
@@ -144,6 +144,8 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def autocorrect(corrector, node)
147
+ node = node.ancestors.find { |ancestor| ancestor.loc.end } unless node.loc.end
148
+
147
149
  case empty_else_style
148
150
  when :empty
149
151
  corrector.insert_before(node.loc.end, 'else; nil; ')
@@ -6,19 +6,49 @@ module RuboCop
6
6
  # Checks for the presence of `method_missing` without also
7
7
  # defining `respond_to_missing?`.
8
8
  #
9
+ # Not defining `respond_to_missing?` will cause metaprogramming
10
+ # methods like `respond_to?` to behave unexpectedly:
11
+ #
12
+ # [source,ruby]
13
+ # ----
14
+ # class StringDelegator
15
+ # def initialize(string)
16
+ # @string = string
17
+ # end
18
+ #
19
+ # def method_missing(name, *args)
20
+ # @string.send(name, *args)
21
+ # end
22
+ # end
23
+ #
24
+ # delegator = StringDelegator.new("foo")
25
+ # # Claims to not respond to `upcase`.
26
+ # delegator.respond_to?(:upcase) # => false
27
+ # # But you can call it.
28
+ # delegator.upcase # => FOO
29
+ # ----
30
+ #
9
31
  # @example
10
32
  # # bad
11
33
  # def method_missing(name, *args)
12
- # # ...
34
+ # if @delegate.respond_to?(name)
35
+ # @delegate.send(name, *args)
36
+ # else
37
+ # super
38
+ # end
13
39
  # end
14
40
  #
15
41
  # # good
16
42
  # def respond_to_missing?(name, include_private)
17
- # # ...
43
+ # @delegate.respond_to?(name) || super
18
44
  # end
19
45
  #
20
46
  # def method_missing(name, *args)
21
- # # ...
47
+ # if @delegate.respond_to?(name)
48
+ # @delegate.send(name, *args)
49
+ # else
50
+ # super
51
+ # end
22
52
  # end
23
53
  #
24
54
  class MissingRespondToMissing < Base
@@ -28,10 +28,10 @@ module RuboCop
28
28
  MSG = 'Avoid multi-line chains of blocks.'
29
29
 
30
30
  def on_block(node)
31
- node.send_node.each_node(:send, :csend) do |send_node|
31
+ node.send_node.each_node(:call) do |send_node|
32
32
  receiver = send_node.receiver
33
33
 
34
- next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
34
+ next unless receiver&.any_block_type? && receiver.multiline?
35
35
 
36
36
  range = range_between(receiver.loc.end.begin_pos, node.send_node.source_range.end_pos)
37
37
 
@@ -44,6 +44,7 @@ module RuboCop
44
44
  end
45
45
 
46
46
  alias on_numblock on_block
47
+ alias on_itblock on_block
47
48
  end
48
49
  end
49
50
  end