rubocop 1.66.1 → 1.72.2

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 (434) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +162 -14
  5. data/config/internal_affairs.yml +11 -0
  6. data/lib/rubocop/cached_data.rb +12 -4
  7. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  12. data/lib/rubocop/cli/command/version.rb +2 -2
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +17 -4
  15. data/lib/rubocop/config_loader.rb +48 -8
  16. data/lib/rubocop/config_loader_resolver.rb +36 -11
  17. data/lib/rubocop/config_validator.rb +20 -9
  18. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  19. data/lib/rubocop/cop/base.rb +13 -3
  20. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  21. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  22. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  23. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  24. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  25. data/lib/rubocop/cop/cop.rb +8 -0
  26. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  27. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  28. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  34. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  35. data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -2
  36. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  37. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  38. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  39. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  40. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  43. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  55. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  56. data/lib/rubocop/cop/internal_affairs.rb +6 -0
  57. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  58. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  59. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  60. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  61. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  62. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  64. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  65. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  66. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  67. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  68. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
  69. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  70. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  71. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  72. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  73. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  74. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  75. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  76. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  77. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  78. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  79. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  80. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  81. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  82. data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
  83. data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
  84. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  85. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  86. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/line_length.rb +119 -4
  88. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  89. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  90. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  91. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  92. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  93. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  94. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  95. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
  96. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
  97. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  99. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  103. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
  105. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  106. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  108. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  111. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  112. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  113. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  114. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  115. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  116. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  117. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  118. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  119. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  120. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  121. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  122. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  123. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  124. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  125. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  126. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  127. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  128. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  129. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  130. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  131. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  132. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  133. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  134. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  135. data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
  136. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  137. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  138. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  139. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +11 -5
  140. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  141. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  142. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  143. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  144. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
  145. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  146. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
  147. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  148. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  149. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  150. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  151. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  152. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  153. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  154. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  155. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  156. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  157. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  158. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  159. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  160. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  161. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  162. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  163. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  164. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  165. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
  166. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  167. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  168. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  169. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  170. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  171. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  172. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  173. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  174. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  175. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  176. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  177. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
  178. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  179. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  180. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  181. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  182. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  183. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  184. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  185. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  186. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  187. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  188. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  189. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  190. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  191. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  192. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  193. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  194. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  195. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  196. data/lib/rubocop/cop/lint/void.rb +8 -11
  197. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  198. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  199. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  200. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  201. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  202. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  203. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  204. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  205. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  206. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  207. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  208. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  209. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  210. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
  211. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  212. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  213. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  214. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  215. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
  216. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  217. data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
  218. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  219. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  220. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  221. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  222. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  223. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  224. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  225. data/lib/rubocop/cop/mixin/range_help.rb +3 -4
  226. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  227. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  228. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  229. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  230. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  231. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  232. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  233. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  234. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  235. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  236. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  237. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  238. data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
  239. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  240. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  241. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  242. data/lib/rubocop/cop/offense.rb +4 -5
  243. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  244. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  245. data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
  246. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  247. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  248. data/lib/rubocop/cop/style/and_or.rb +1 -1
  249. data/lib/rubocop/cop/style/arguments_forwarding.rb +78 -22
  250. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  251. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  252. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  253. data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
  254. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  255. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  256. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  257. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  258. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  259. data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
  260. data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
  261. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  262. data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
  263. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  264. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  265. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  266. data/lib/rubocop/cop/style/documentation.rb +1 -1
  267. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  268. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  269. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  270. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  271. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  272. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  273. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  274. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  275. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  276. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  277. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  278. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  279. data/lib/rubocop/cop/style/file_null.rb +89 -0
  280. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  281. data/lib/rubocop/cop/style/float_division.rb +8 -4
  282. data/lib/rubocop/cop/style/for.rb +0 -1
  283. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  284. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  285. data/lib/rubocop/cop/style/guard_clause.rb +16 -3
  286. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  287. data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
  288. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  289. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  290. data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
  291. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  292. data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
  293. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  294. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
  295. data/lib/rubocop/cop/style/if_with_semicolon.rb +26 -11
  296. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  297. data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
  298. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  299. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  300. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  301. data/lib/rubocop/cop/style/lambda.rb +1 -1
  302. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  303. data/lib/rubocop/cop/style/map_into_array.rb +60 -9
  304. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  305. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  306. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +32 -20
  307. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  308. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  309. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  310. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  311. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  312. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  313. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  314. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  315. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  316. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  317. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  318. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  319. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  320. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  321. data/lib/rubocop/cop/style/not.rb +1 -1
  322. data/lib/rubocop/cop/style/object_then.rb +14 -15
  323. data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
  324. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  325. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  326. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  327. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  328. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  329. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  330. data/lib/rubocop/cop/style/proc.rb +1 -2
  331. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  332. data/lib/rubocop/cop/style/raise_args.rb +7 -5
  333. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  334. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  335. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  336. data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
  337. data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
  338. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  339. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  340. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  341. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  342. data/lib/rubocop/cop/style/redundant_format.rb +238 -0
  343. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  344. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  345. data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
  346. data/lib/rubocop/cop/style/redundant_parentheses.rb +37 -25
  347. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  348. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  349. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  350. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  351. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  352. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  353. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  354. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  355. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  356. data/lib/rubocop/cop/style/require_order.rb +1 -1
  357. data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
  358. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  359. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  360. data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
  361. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  362. data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
  363. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  364. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  365. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  366. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  367. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  368. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  369. data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -3
  370. data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
  371. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  372. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
  373. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  374. data/lib/rubocop/cop/style/string_concatenation.rb +14 -13
  375. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  376. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  377. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  378. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  379. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  380. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  381. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  382. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  383. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  384. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  385. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  386. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  387. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  388. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  389. data/lib/rubocop/cop/team.rb +8 -1
  390. data/lib/rubocop/cop/util.rb +12 -5
  391. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  392. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  393. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  394. data/lib/rubocop/cop/variable_force/variable.rb +18 -2
  395. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  396. data/lib/rubocop/cop/variable_force.rb +4 -10
  397. data/lib/rubocop/cops_documentation_generator.rb +100 -51
  398. data/lib/rubocop/directive_comment.rb +44 -10
  399. data/lib/rubocop/file_finder.rb +9 -4
  400. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  401. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  402. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  403. data/lib/rubocop/lsp/logger.rb +2 -2
  404. data/lib/rubocop/lsp/routes.rb +7 -23
  405. data/lib/rubocop/lsp/runtime.rb +18 -48
  406. data/lib/rubocop/lsp/server.rb +0 -3
  407. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  408. data/lib/rubocop/magic_comment.rb +3 -3
  409. data/lib/rubocop/options.rb +28 -12
  410. data/lib/rubocop/path_util.rb +15 -8
  411. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  412. data/lib/rubocop/plugin/load_error.rb +26 -0
  413. data/lib/rubocop/plugin/loader.rb +100 -0
  414. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  415. data/lib/rubocop/plugin.rb +39 -0
  416. data/lib/rubocop/rake_task.rb +4 -1
  417. data/lib/rubocop/result_cache.rb +13 -13
  418. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  419. data/lib/rubocop/rspec/expect_offense.rb +7 -2
  420. data/lib/rubocop/rspec/shared_contexts.rb +4 -1
  421. data/lib/rubocop/rspec/support.rb +1 -2
  422. data/lib/rubocop/runner.rb +22 -12
  423. data/lib/rubocop/server/cache.rb +39 -1
  424. data/lib/rubocop/server/cli.rb +2 -2
  425. data/lib/rubocop/server/core.rb +1 -0
  426. data/lib/rubocop/target_finder.rb +1 -0
  427. data/lib/rubocop/target_ruby.rb +28 -13
  428. data/lib/rubocop/version.rb +42 -6
  429. data/lib/rubocop/yaml_duplication_checker.rb +20 -27
  430. data/lib/rubocop.rb +29 -0
  431. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  432. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  433. metadata +75 -19
  434. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Looks for places where an subset of an Enumerable (array,
6
+ # Looks for places where a subset of an Enumerable (array,
7
7
  # range, set, etc.; see note below) is calculated based on a `Regexp`
8
8
  # match, and suggests `grep` or `grep_v` instead.
9
9
  #
@@ -27,7 +27,7 @@ module RuboCop
27
27
  # so the correction may not be actually equivalent.
28
28
  #
29
29
  # @example
30
- # # bad (select or find_all)
30
+ # # bad (select, filter, or find_all)
31
31
  # array.select { |x| x.match? /regexp/ }
32
32
  # array.select { |x| /regexp/.match?(x) }
33
33
  # array.select { |x| x =~ /regexp/ }
@@ -47,9 +47,11 @@ module RuboCop
47
47
  include RangeHelp
48
48
 
49
49
  MSG = 'Prefer `%<replacement>s` to `%<original_method>s` with a regexp match.'
50
- RESTRICT_ON_SEND = %i[select find_all reject].freeze
51
- REPLACEMENTS = { select: 'grep', find_all: 'grep', reject: 'grep_v' }.freeze
52
- OPPOSITE_REPLACEMENTS = { select: 'grep_v', find_all: 'grep_v', reject: 'grep' }.freeze
50
+ RESTRICT_ON_SEND = %i[select filter find_all reject].freeze
51
+ REPLACEMENTS = { select: 'grep', filter: 'grep', find_all: 'grep', reject: 'grep_v' }.freeze
52
+ OPPOSITE_REPLACEMENTS = {
53
+ select: 'grep_v', filter: 'grep_v', find_all: 'grep_v', reject: 'grep'
54
+ }.freeze
53
55
  REGEXP_METHODS = %i[match? =~ !~].to_set.freeze
54
56
 
55
57
  # @!method regexp_match?(node)
@@ -84,8 +86,9 @@ module RuboCop
84
86
  }
85
87
  PATTERN
86
88
 
87
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
89
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
88
90
  def on_send(node)
91
+ return if target_ruby_version < 2.6 && node.method?(:filter)
89
92
  return unless (block_node = node.block_node)
90
93
  return if block_node.body&.begin_type?
91
94
  return if receiver_allowed?(block_node.receiver)
@@ -99,7 +102,7 @@ module RuboCop
99
102
 
100
103
  register_offense(node, block_node, regexp, replacement)
101
104
  end
102
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
105
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
103
106
  alias on_csend on_send
104
107
 
105
108
  private
@@ -37,33 +37,29 @@ module RuboCop
37
37
  private
38
38
 
39
39
  def check(node, var_type)
40
- var_name, rhs = *node
41
- return unless rhs
40
+ return unless (rhs = node.expression)
42
41
 
43
- if rhs.send_type?
44
- check_send_node(node, rhs, var_name, var_type)
42
+ if rhs.send_type? && rhs.arguments.one?
43
+ check_send_node(node, rhs, node.name, var_type)
45
44
  elsif rhs.operator_keyword?
46
- check_boolean_node(node, rhs, var_name, var_type)
45
+ check_boolean_node(node, rhs, node.name, var_type)
47
46
  end
48
47
  end
49
48
 
50
49
  def check_send_node(node, rhs, var_name, var_type)
51
- receiver, method_name, *_args = *rhs
52
- return unless OPS.include?(method_name)
50
+ return unless OPS.include?(rhs.method_name)
53
51
 
54
52
  target_node = s(var_type, var_name)
55
- return unless receiver == target_node
53
+ return unless rhs.receiver == target_node
56
54
 
57
- add_offense(node, message: format(MSG, method: method_name)) do |corrector|
55
+ add_offense(node, message: format(MSG, method: rhs.method_name)) do |corrector|
58
56
  autocorrect(corrector, node)
59
57
  end
60
58
  end
61
59
 
62
60
  def check_boolean_node(node, rhs, var_name, var_type)
63
- first_operand, _second_operand = *rhs
64
-
65
61
  target_node = s(var_type, var_name)
66
- return unless first_operand == target_node
62
+ return unless rhs.lhs == target_node
67
63
 
68
64
  operator = rhs.loc.operator.source
69
65
  add_offense(node, message: format(MSG, method: operator)) do |corrector|
@@ -72,7 +68,7 @@ module RuboCop
72
68
  end
73
69
 
74
70
  def autocorrect(corrector, node)
75
- _var_name, rhs = *node
71
+ rhs = node.expression
76
72
 
77
73
  if rhs.send_type?
78
74
  autocorrect_send_node(corrector, node, rhs)
@@ -82,13 +78,11 @@ module RuboCop
82
78
  end
83
79
 
84
80
  def autocorrect_send_node(corrector, node, rhs)
85
- _receiver, method_name, args = *rhs
86
- apply_autocorrect(corrector, node, rhs, method_name.to_s, args)
81
+ apply_autocorrect(corrector, node, rhs, rhs.method_name, rhs.first_argument)
87
82
  end
88
83
 
89
84
  def autocorrect_boolean_node(corrector, node, rhs)
90
- _first_operand, second_operand = *rhs
91
- apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, second_operand)
85
+ apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, rhs.rhs)
92
86
  end
93
87
 
94
88
  def apply_autocorrect(corrector, node, rhs, operator, new_rhs)
@@ -141,7 +141,7 @@ module RuboCop
141
141
 
142
142
  def expressions_per_line(exprs)
143
143
  # create a map matching lines to the number of expressions on them
144
- exprs_lines = exprs.map(&:first_line)
144
+ exprs_lines = exprs.map(&:last_line)
145
145
  exprs_lines.group_by(&:itself)
146
146
  end
147
147
 
@@ -164,7 +164,7 @@ module RuboCop
164
164
 
165
165
  ast = processed_source.ast
166
166
  @range_nodes = ast.range_type? ? [ast] : []
167
- @range_nodes.concat(ast.each_descendant(:irange, :erange).to_a)
167
+ @range_nodes.concat(ast.each_descendant(:range).to_a)
168
168
  end
169
169
  end
170
170
  end
@@ -68,7 +68,7 @@ module RuboCop
68
68
  def on_send(node)
69
69
  return if allow_send? && !node.method?(:public_send)
70
70
  return unless (first_argument = node.first_argument)
71
- return unless STATIC_METHOD_NAME_NODE_TYPES.include?(first_argument.type)
71
+ return unless first_argument.type?(*STATIC_METHOD_NAME_NODE_TYPES)
72
72
 
73
73
  offense_range = offense_range(node)
74
74
  method_name = first_argument.value
@@ -83,6 +83,7 @@ module RuboCop
83
83
  end
84
84
  end
85
85
  end
86
+ alias on_csend on_send
86
87
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
87
88
 
88
89
  private
@@ -122,10 +122,9 @@ module RuboCop
122
122
  def on_rescue(node)
123
123
  return unless style == :semantic
124
124
 
125
- begin_node, *rescue_nodes, _else_node = *node
126
- check_scope(:raise, begin_node)
125
+ check_scope(:raise, node.body)
127
126
 
128
- rescue_nodes.each do |rescue_node|
127
+ node.resbody_branches.each do |rescue_node|
129
128
  check_scope(:fail, rescue_node)
130
129
  allow(:raise, rescue_node)
131
130
  end
@@ -33,22 +33,19 @@ module RuboCop
33
33
  #
34
34
  class SingleArgumentDig < Base
35
35
  extend AutoCorrector
36
+ include DigHelp
36
37
 
37
38
  MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
38
39
  RESTRICT_ON_SEND = %i[dig].freeze
39
40
  IGNORED_ARGUMENT_TYPES = %i[block_pass forwarded_restarg forwarded_args hash].freeze
40
41
 
41
- # @!method single_argument_dig?(node)
42
- def_node_matcher :single_argument_dig?, <<~PATTERN
43
- (send _ :dig $!splat)
44
- PATTERN
45
-
46
42
  def on_send(node)
47
43
  return unless node.receiver
48
44
 
49
45
  expression = single_argument_dig?(node)
50
46
  return unless expression
51
47
  return if IGNORED_ARGUMENT_TYPES.include?(expression.type)
48
+ return if ignore_dig_chain?(node)
52
49
 
53
50
  receiver = node.receiver.source
54
51
  argument = expression.source
@@ -63,6 +60,13 @@ module RuboCop
63
60
 
64
61
  ignore_node(node)
65
62
  end
63
+
64
+ private
65
+
66
+ def ignore_dig_chain?(node)
67
+ dig_chain_enabled? &&
68
+ (dig?(node.receiver) || dig?(node.parent))
69
+ end
66
70
  end
67
71
  end
68
72
  end
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # parameters.
11
11
  #
12
12
  # Configuration option: Methods
13
- # Should be set to use this cop. Array of hashes, where each key is the
13
+ # Should be set to use this cop. `Array` of hashes, where each key is the
14
14
  # method name and value - array of argument names.
15
15
  #
16
16
  # @example Methods: [{reduce: %w[a b]}]
@@ -6,8 +6,13 @@ module RuboCop
6
6
  # Checks for single-line `do`...`end` block.
7
7
  #
8
8
  # In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic`
9
- # in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to
10
- # preserve semantics and does not change it to `{`...`}` block.
9
+ # is configured for `Style/BlockDelimiters`. The autocorrection maintains the
10
+ # `do` ... `end` syntax to preserve semantics and does not change it to `{`...`}` block.
11
+ #
12
+ # NOTE: If `InspectBlocks` is set to `true` for `Layout/RedundantLineBreak`, blocks will
13
+ # be autocorrected to be on a single line if possible. This cop respects that configuration
14
+ # by not registering an offense if it would subsequently cause a
15
+ # `Layout/RedundantLineBreak` offense.
11
16
  #
12
17
  # @example
13
18
  #
@@ -27,12 +32,14 @@ module RuboCop
27
32
  #
28
33
  class SingleLineDoEndBlock < Base
29
34
  extend AutoCorrector
35
+ include CheckSingleLineSuitability
30
36
 
31
37
  MSG = 'Prefer multiline `do`...`end` block.'
32
38
 
33
39
  # rubocop:disable Metrics/AbcSize
34
40
  def on_block(node)
35
41
  return if !node.single_line? || node.braces?
42
+ return if single_line_blocks_preferred? && suitable_as_single_line?(node)
36
43
 
37
44
  add_offense(node) do |corrector|
38
45
  corrector.insert_after(do_line(node), "\n")
@@ -60,7 +67,9 @@ module RuboCop
60
67
  end
61
68
  end
62
69
 
63
- def x(corrector, node); end
70
+ def single_line_blocks_preferred?
71
+ @config.for_enabled_cop('Layout/RedundantLineBreak')['InspectBlocks']
72
+ end
64
73
  end
65
74
  end
66
75
  end
@@ -68,7 +68,7 @@ module RuboCop
68
68
  return false if body_node.parent.assignment_method? ||
69
69
  NOT_SUPPORTED_ENDLESS_METHOD_BODY_TYPES.include?(body_node.type)
70
70
 
71
- !(body_node.begin_type? || body_node.kwbegin_type?)
71
+ !body_node.type?(:begin, :kwbegin)
72
72
  end
73
73
 
74
74
  def correct_to_multiline(corrector, node)
@@ -134,10 +134,9 @@ module RuboCop
134
134
  end
135
135
 
136
136
  def disallow_endless_method_style?
137
- endless_method_config = config.for_cop('Style/EndlessMethod')
138
- return true unless endless_method_config['Enabled']
137
+ return true unless config.cop_enabled?('Style/EndlessMethod')
139
138
 
140
- endless_method_config['EnforcedStyle'] == 'disallow'
139
+ config.for_cop('Style/EndlessMethod')['EnforcedStyle'] == 'disallow'
141
140
  end
142
141
  end
143
142
  end
@@ -78,38 +78,67 @@ module RuboCop
78
78
  return unless node.arguments.one?
79
79
 
80
80
  range_node = node.first_argument
81
- selector = node.loc.selector
82
- unless (message, removal_range = offense_message_with_removal_range(range_node, selector))
83
- return
84
- end
81
+ offense_range = find_offense_range(node)
82
+ return unless (message, removal_range =
83
+ offense_message_with_removal_range(node, range_node, offense_range))
84
+
85
+ # Changing the range to beginningless or endless when unparenthesized
86
+ # changes the semantics of the code, and thus will not be considered
87
+ # an offense.
88
+ return if removal_range != offense_range && unparenthesized_call?(node)
85
89
 
86
- add_offense(selector, message: message) do |corrector|
90
+ add_offense(offense_range, message: message) do |corrector|
87
91
  corrector.remove(removal_range)
88
92
  end
89
93
  end
94
+ alias on_csend on_send
90
95
 
91
96
  private
92
97
 
93
- def offense_message_with_removal_range(range_node, selector)
98
+ def unparenthesized_call?(node)
99
+ node.loc.dot && !node.parenthesized?
100
+ end
101
+
102
+ def find_offense_range(node)
103
+ if node.loc.dot
104
+ node.loc.dot.join(node.source_range.end)
105
+ else
106
+ node.loc.selector
107
+ end
108
+ end
109
+
110
+ def offense_message_with_removal_range(node, range_node, offense_range)
94
111
  if range_from_zero_till_minus_one?(range_node)
95
- [format(MSG_USELESS_RANGE, prefer: selector.source), selector]
112
+ [format(MSG_USELESS_RANGE, prefer: offense_range.source), offense_range]
96
113
  elsif range_till_minus_one?(range_node)
97
114
  [
98
- format(MSG, prefer: endless(range_node), current: selector.source), range_node.end
115
+ offense_message_for_partial_range(node, endless(range_node), offense_range),
116
+ range_node.end
99
117
  ]
100
118
  elsif range_from_zero?(range_node) && target_ruby_version >= 2.7
101
119
  [
102
- format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin
120
+ offense_message_for_partial_range(node, beginless(range_node), offense_range),
121
+ range_node.begin
103
122
  ]
104
123
  end
105
124
  end
106
125
 
126
+ def offense_message_for_partial_range(node, prefer, offense_range)
127
+ current = node.loc.dot ? arguments_source(node) : offense_range.source
128
+ prefer = "[#{prefer}]" unless node.loc.dot
129
+ format(MSG, prefer: prefer, current: current)
130
+ end
131
+
107
132
  def endless(range_node)
108
- "[#{range_node.begin.source}#{range_node.loc.operator.source}]"
133
+ "#{range_node.begin.source}#{range_node.loc.operator.source}"
109
134
  end
110
135
 
111
136
  def beginless(range_node)
112
- "[#{range_node.loc.operator.source}#{range_node.end.source}]"
137
+ "#{range_node.loc.operator.source}#{range_node.end.source}"
138
+ end
139
+
140
+ def arguments_source(node)
141
+ node.first_argument.source_range.join(node.last_argument.source_range.end).source
113
142
  end
114
143
  end
115
144
  end
@@ -156,7 +156,7 @@ module RuboCop
156
156
  # Handle `send` and `block` nodes that need to be wrapped in parens
157
157
  # FIXME: autocorrection prevents syntax errors by wrapping the entire node in parens,
158
158
  # but wrapping the argument list would be a more ergonomic correction.
159
- node_to_check = condition&.block_type? ? condition.send_node : condition
159
+ node_to_check = condition&.any_block_type? ? condition.send_node : condition
160
160
  return unless wrap_condition?(node_to_check)
161
161
 
162
162
  if condition.call_type?
@@ -214,7 +214,7 @@ module RuboCop
214
214
  end
215
215
 
216
216
  def insert_bang_for_and(corrector, node)
217
- lhs, rhs = *node
217
+ lhs, rhs = *node # rubocop:disable InternalAffairs/NodeDestructuring
218
218
 
219
219
  if lhs.and_type?
220
220
  insert_bang_for_and(corrector, lhs)
@@ -237,14 +237,13 @@ module RuboCop
237
237
  end
238
238
 
239
239
  def wrap_condition?(node)
240
- node.and_type? || node.or_type? ||
241
- (node.call_type? && node.arguments.any? && !node.parenthesized?)
240
+ node.operator_keyword? || (node.call_type? && node.arguments.any? && !node.parenthesized?)
242
241
  end
243
242
 
244
243
  def replace_condition(condition)
245
244
  return condition.source unless wrap_condition?(condition)
246
245
 
247
- if condition.call_type?
246
+ if condition.call_type? && !condition.comparison_method?
248
247
  parenthesized_method_arguments(condition)
249
248
  else
250
249
  "(#{condition.source})"
@@ -149,7 +149,7 @@ module RuboCop
149
149
  end
150
150
 
151
151
  def on_gvar(node)
152
- global_var, = *node
152
+ global_var = node.name
153
153
 
154
154
  return unless (preferred = preferred_names(global_var))
155
155
 
@@ -51,7 +51,6 @@ module RuboCop
51
51
  # Pathname.new('/') + 'test'
52
52
  #
53
53
  class StringConcatenation < Base
54
- include Util
55
54
  include RangeHelp
56
55
  extend AutoCorrector
57
56
 
@@ -133,7 +132,7 @@ module RuboCop
133
132
  end
134
133
 
135
134
  def heredoc?(node)
136
- return false unless node.str_type? || node.dstr_type?
135
+ return false unless node.type?(:str, :dstr)
137
136
 
138
137
  node.heredoc?
139
138
  end
@@ -143,22 +142,24 @@ module RuboCop
143
142
  end
144
143
 
145
144
  def replacement(parts)
146
- interpolated_parts =
147
- parts.map do |part|
148
- case part.type
149
- when :str
150
- value = part.value
151
- single_quoted?(part) ? value.gsub(/(\\|")/, '\\\\\&') : value.inspect[1..-2]
152
- when :dstr
153
- contents_range(part).source
154
- else
155
- "\#{#{part.source}}"
156
- end
145
+ interpolated_parts = parts.map do |part|
146
+ case part.type
147
+ when :str
148
+ adjust_str(part)
149
+ when :dstr
150
+ part.children.all?(&:str_type?) ? adjust_str(part) : contents_range(part).source
151
+ else
152
+ "\#{#{part.source}}"
157
153
  end
154
+ end
158
155
 
159
156
  "\"#{handle_quotes(interpolated_parts).join}\""
160
157
  end
161
158
 
159
+ def adjust_str(node)
160
+ single_quoted?(node) ? node.value.gsub(/(\\|")/, '\\\\\&') : node.value.inspect[1..-2]
161
+ end
162
+
162
163
  def handle_quotes(parts)
163
164
  parts.map do |part|
164
165
  part == '"' ? '\"' : part
@@ -69,7 +69,7 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def all_string_literals?(nodes)
72
- nodes.all? { |n| n.str_type? || n.dstr_type? }
72
+ nodes.all? { |n| n.type?(:str, :dstr) }
73
73
  end
74
74
 
75
75
  def detect_quote_styles(node)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Enforces the use of consistent method names
7
- # from the String class.
7
+ # from the `String` class.
8
8
  #
9
9
  # @example
10
10
  # # bad
@@ -33,7 +33,7 @@ module RuboCop
33
33
  def on_class(node)
34
34
  return unless struct_constructor?(node.parent_class)
35
35
 
36
- add_offense(node.parent_class.source_range) do |corrector|
36
+ add_offense(node.parent_class) do |corrector|
37
37
  corrector.remove(range_with_surrounding_space(node.loc.keyword, newlines: false))
38
38
  corrector.replace(node.loc.operator, '=')
39
39
 
@@ -23,6 +23,10 @@ module RuboCop
23
23
  # `define_method`, therefore, `super` used within these blocks will be allowed.
24
24
  # This approach might result in false negatives, yet ensuring safe detection takes precedence.
25
25
  #
26
+ # NOTE: When forwarding the same arguments but replacing the block argument with a new inline
27
+ # block, it is not necessary to explicitly list the non-block arguments. As such, an offense
28
+ # will be registered in this case.
29
+ #
26
30
  # @example
27
31
  # # bad
28
32
  # def method(*args, **kwargs)
@@ -44,6 +48,16 @@ module RuboCop
44
48
  # super()
45
49
  # end
46
50
  #
51
+ # # bad - forwarding with overridden block
52
+ # def method(*args, **kwargs, &block)
53
+ # super(*args, **kwargs) { do_something }
54
+ # end
55
+ #
56
+ # # good - implicitly passing all non-block arguments
57
+ # def method(*args, **kwargs, &block)
58
+ # super { do_something }
59
+ # end
60
+ #
47
61
  # # good - assigning to the block variable before calling super
48
62
  # def method(&block)
49
63
  # # Assigning to the block variable would pass the old value to super,
@@ -58,46 +72,77 @@ module RuboCop
58
72
  ASSIGN_TYPES = %i[or_asgn lvasgn].freeze
59
73
 
60
74
  MSG = 'Call `super` without arguments and parentheses when the signature is identical.'
75
+ MSG_INLINE_BLOCK = 'Call `super` without arguments and parentheses when all positional ' \
76
+ 'and keyword arguments are forwarded.'
61
77
 
62
78
  def on_super(super_node)
63
- def_node = super_node.ancestors.find do |node|
79
+ return unless (def_node = find_def_node(super_node))
80
+
81
+ def_node_args = def_node.arguments.argument_list
82
+ super_args = preprocess_super_args(super_node.arguments)
83
+
84
+ return unless arguments_identical?(def_node, super_node, def_node_args, super_args)
85
+
86
+ # If the number of arguments to the def node and super node are different here,
87
+ # it's because the block argument is not forwarded.
88
+ message = def_node_args.size == super_args.size ? MSG : MSG_INLINE_BLOCK
89
+ add_offense(super_node, message: message) do |corrector|
90
+ corrector.replace(super_node, 'super')
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def find_def_node(super_node)
97
+ super_node.ancestors.find do |node|
64
98
  # When defining dynamic methods, implicitly calling `super` is not possible.
65
99
  # Since there is a possibility of delegation to `define_method`,
66
100
  # `super` used within the block is always allowed.
67
- break if node.block_type?
101
+ break if node.any_block_type? && !block_sends_to_super?(super_node, node)
68
102
 
69
103
  break node if DEF_TYPES.include?(node.type)
70
104
  end
71
- return unless def_node
72
- return unless arguments_identical?(def_node, def_node.arguments.argument_list,
73
- super_node.arguments)
74
-
75
- add_offense(super_node) { |corrector| corrector.replace(super_node, 'super') }
76
105
  end
77
106
 
78
- private
79
-
80
107
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
81
- def arguments_identical?(def_node, def_args, super_args)
82
- super_args = preprocess_super_args(super_args)
83
- return false if def_args.size != super_args.size
108
+ def arguments_identical?(def_node, super_node, def_args, super_args)
109
+ return false if argument_list_size_differs?(def_args, super_args, super_node)
84
110
 
85
111
  def_args.zip(super_args).each do |def_arg, super_arg|
86
112
  next if positional_arg_same?(def_arg, super_arg)
87
113
  next if positional_rest_arg_same(def_arg, super_arg)
88
114
  next if keyword_arg_same?(def_arg, super_arg)
89
115
  next if keyword_rest_arg_same?(def_arg, super_arg)
90
- next if block_arg_same?(def_node, def_arg, super_arg)
116
+ next if block_arg_same?(def_node, super_node, def_arg, super_arg)
91
117
  next if forward_arg_same?(def_arg, super_arg)
92
118
 
93
119
  return false
94
120
  end
121
+
95
122
  true
96
123
  end
97
124
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
98
125
 
126
+ def argument_list_size_differs?(def_args, super_args, super_node)
127
+ # If the def node has a block argument and the super node has an explicit block,
128
+ # the number of arguments is the same, so ignore the def node block arg.
129
+ def_args_size = def_args.size
130
+ def_args_size -= 1 if def_args.any?(&:blockarg_type?) && block_sends_to_super?(super_node)
131
+
132
+ def_args_size != super_args.size
133
+ end
134
+
135
+ def block_sends_to_super?(super_node, parent_node = super_node.parent)
136
+ # Checks if the send node of a block is the given super node,
137
+ # or a method chain containing it.
138
+ return false unless parent_node
139
+ return false unless parent_node.any_block_type?
140
+
141
+ parent_node.send_node.each_node(:super).any?(super_node)
142
+ end
143
+
99
144
  def positional_arg_same?(def_arg, super_arg)
100
- return false unless def_arg.arg_type? || def_arg.optarg_type?
145
+ return false unless def_arg.type?(:arg, :optarg)
101
146
  return false unless super_arg.lvar_type?
102
147
 
103
148
  def_arg.name == super_arg.children.first
@@ -114,7 +159,7 @@ module RuboCop
114
159
  end
115
160
 
116
161
  def keyword_arg_same?(def_arg, super_arg)
117
- return false unless def_arg.kwarg_type? || def_arg.kwoptarg_type?
162
+ return false unless def_arg.type?(:kwarg, :kwoptarg)
118
163
  return false unless (pair_node = super_arg).pair_type?
119
164
  return false unless (sym_node = pair_node.key).sym_type?
120
165
  return false unless (lvar_node = pair_node.value).lvar_type?
@@ -133,8 +178,11 @@ module RuboCop
133
178
  def_arg.name == lvar_node.children.first
134
179
  end
135
180
 
136
- def block_arg_same?(def_node, def_arg, super_arg)
137
- return false unless def_arg.blockarg_type? && super_arg.block_pass_type?
181
+ def block_arg_same?(def_node, super_node, def_arg, super_arg)
182
+ return false unless def_arg.blockarg_type?
183
+ return true if block_sends_to_super?(super_node)
184
+ return false unless super_arg.block_pass_type?
185
+
138
186
  # anonymous forwarding
139
187
  return true if (block_pass_child = super_arg.children.first).nil? && def_arg.name.nil?
140
188
 
@@ -79,26 +79,15 @@ module RuboCop
79
79
  end
80
80
 
81
81
  def lhs(node)
82
- case node.type
83
- when :casgn
84
- namespace, name, = *node
85
- if namespace
86
- "#{namespace.const_name}::#{name}"
87
- else
88
- name.to_s
89
- end
82
+ if node.casgn_type?
83
+ "#{'::' if node.absolute?}#{node.const_name}"
90
84
  else
91
- node.children[0].to_s
85
+ node.name.to_s
92
86
  end
93
87
  end
94
88
 
95
89
  def rhs(node)
96
- case node.type
97
- when :casgn
98
- node.children[2].source
99
- else
100
- node.children[1].source
101
- end
90
+ node.expression.source
102
91
  end
103
92
 
104
93
  def correction_range(tmp_assign, y_assign)