rubocop 1.67.0 → 1.81.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 (526) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +384 -72
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +19 -4
  15. data/lib/rubocop/comment_config.rb +2 -2
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +56 -48
  18. data/lib/rubocop/config_loader_resolver.rb +36 -10
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +53 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -16
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/generator.rb +6 -0
  42. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  43. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  44. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  47. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  48. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  49. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  52. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  55. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  56. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  57. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  58. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  59. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  60. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  61. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  62. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  63. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  64. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  66. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  67. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  68. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  70. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  72. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  73. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  74. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  76. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  77. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  78. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  79. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  81. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  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_class_body.rb +1 -1
  85. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  86. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  87. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  88. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  89. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  90. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  91. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  93. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -11
  95. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  97. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  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 +158 -10
  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 +11 -8
  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 +14 -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 +8 -2
  119. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  121. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  122. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  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 +18 -3
  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 +6 -4
  130. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  131. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  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/binary_operator_with_identical_operands.rb +10 -12
  135. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  136. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  137. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  138. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  140. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -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 +7 -3
  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 +111 -23
  147. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  148. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  149. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  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/empty_interpolation.rb +14 -1
  154. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  155. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  156. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  157. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  158. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  159. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  160. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  161. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  162. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  163. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  164. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  165. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  166. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  167. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
  168. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  169. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  170. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  171. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  172. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  173. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  174. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  175. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  176. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  177. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  178. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  179. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  180. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  181. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  182. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  183. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  184. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  185. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  186. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  187. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  188. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  189. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  190. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  191. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  192. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  193. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  194. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  195. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  196. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  197. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  198. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  199. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  200. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  201. data/lib/rubocop/cop/lint/self_assignment.rb +39 -15
  202. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  203. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  204. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  205. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  206. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  207. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  208. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  209. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  210. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  211. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  212. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  213. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  214. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  215. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  216. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  217. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  218. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  219. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  220. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  221. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  222. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  223. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  224. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  225. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  226. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  227. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  228. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  229. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  230. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  231. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  232. data/lib/rubocop/cop/lint/void.rb +23 -12
  233. data/lib/rubocop/cop/message_annotator.rb +7 -3
  234. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  235. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  236. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  237. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  238. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  239. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  240. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  241. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  242. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  243. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  244. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  245. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  246. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  247. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  248. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  249. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  250. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  251. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  252. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  253. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  254. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  255. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  256. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  257. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  258. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  259. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  260. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  261. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  262. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  263. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  264. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  265. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  266. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  267. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  268. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  269. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  270. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  271. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  272. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  273. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  274. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  275. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  276. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  277. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  278. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  279. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  280. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  281. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  282. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  283. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  284. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  285. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  286. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  287. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  288. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  289. data/lib/rubocop/cop/offense.rb +2 -3
  290. data/lib/rubocop/cop/registry.rb +9 -6
  291. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  292. data/lib/rubocop/cop/security/eval.rb +2 -1
  293. data/lib/rubocop/cop/security/json_load.rb +33 -11
  294. data/lib/rubocop/cop/security/open.rb +1 -0
  295. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  296. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  297. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  298. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  299. data/lib/rubocop/cop/style/and_or.rb +1 -1
  300. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  301. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  302. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  303. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  304. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  305. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  306. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  307. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  308. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  309. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  310. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  311. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  312. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  313. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  314. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  315. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  316. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  317. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -31
  318. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  319. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  320. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  321. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  322. data/lib/rubocop/cop/style/documentation.rb +1 -1
  323. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  324. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  325. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  326. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  327. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  328. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  329. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  330. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  331. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  332. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  333. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  334. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  335. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  336. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  337. data/lib/rubocop/cop/style/file_null.rb +89 -0
  338. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  339. data/lib/rubocop/cop/style/float_division.rb +8 -4
  340. data/lib/rubocop/cop/style/for.rb +1 -1
  341. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  342. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  343. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  344. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  345. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  346. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  347. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  348. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  349. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  350. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  351. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  352. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  353. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  354. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  355. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  356. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  357. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  358. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  359. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  360. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  361. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  362. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  363. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  364. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  365. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  366. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  367. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  368. data/lib/rubocop/cop/style/lambda.rb +1 -0
  369. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  370. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  371. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  372. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  373. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  374. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  379. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  380. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  381. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  382. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  383. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  384. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  385. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  386. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  387. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  388. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  389. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  390. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  391. data/lib/rubocop/cop/style/next.rb +44 -0
  392. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  393. data/lib/rubocop/cop/style/not.rb +1 -1
  394. data/lib/rubocop/cop/style/object_then.rb +15 -15
  395. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  396. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  397. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  398. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  399. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  400. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  401. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  402. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  403. data/lib/rubocop/cop/style/proc.rb +2 -2
  404. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  405. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  406. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  407. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  408. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  409. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  410. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  411. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  412. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  413. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  414. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  415. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  416. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  417. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  418. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  419. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  420. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  421. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  422. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  423. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
  424. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  425. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  426. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  427. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  428. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  429. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  430. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  431. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  432. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  433. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  434. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  435. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  436. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  437. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  438. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  439. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  440. data/lib/rubocop/cop/style/semicolon.rb +21 -6
  441. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  442. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  443. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  444. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  445. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  446. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  447. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  448. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  449. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  450. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  451. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  452. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  453. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  454. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  455. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  456. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  457. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  458. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  459. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  460. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  461. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  462. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  463. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  464. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  465. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  466. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  467. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  468. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  469. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  470. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  471. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  472. data/lib/rubocop/cop/team.rb +1 -1
  473. data/lib/rubocop/cop/util.rb +12 -5
  474. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  475. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  476. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  477. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  478. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  479. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  480. data/lib/rubocop/cop/variable_force.rb +30 -19
  481. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  482. data/lib/rubocop/directive_comment.rb +45 -11
  483. data/lib/rubocop/ext/regexp_node.rb +0 -1
  484. data/lib/rubocop/formatter/disabled_config_formatter.rb +20 -6
  485. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  486. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  487. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  488. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  489. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  490. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  491. data/lib/rubocop/lsp/diagnostic.rb +190 -0
  492. data/lib/rubocop/lsp/logger.rb +2 -2
  493. data/lib/rubocop/lsp/routes.rb +66 -26
  494. data/lib/rubocop/lsp/runtime.rb +18 -50
  495. data/lib/rubocop/lsp/server.rb +2 -4
  496. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  497. data/lib/rubocop/magic_comment.rb +11 -3
  498. data/lib/rubocop/options.rb +28 -12
  499. data/lib/rubocop/path_util.rb +15 -8
  500. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  501. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  502. data/lib/rubocop/plugin/load_error.rb +26 -0
  503. data/lib/rubocop/plugin/loader.rb +100 -0
  504. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  505. data/lib/rubocop/plugin.rb +46 -0
  506. data/lib/rubocop/rake_task.rb +4 -1
  507. data/lib/rubocop/result_cache.rb +27 -25
  508. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  509. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  510. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  511. data/lib/rubocop/rspec/support.rb +4 -2
  512. data/lib/rubocop/runner.rb +31 -18
  513. data/lib/rubocop/server/cache.rb +51 -13
  514. data/lib/rubocop/server/cli.rb +2 -2
  515. data/lib/rubocop/server/client_command/base.rb +10 -0
  516. data/lib/rubocop/server/client_command/exec.rb +2 -1
  517. data/lib/rubocop/server/client_command/start.rb +11 -1
  518. data/lib/rubocop/target_finder.rb +14 -9
  519. data/lib/rubocop/target_ruby.rb +27 -3
  520. data/lib/rubocop/version.rb +53 -12
  521. data/lib/rubocop.rb +44 -2
  522. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  523. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  524. metadata +91 -21
  525. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  526. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -33,6 +33,7 @@ module RuboCop
33
33
 
34
34
  MSG = 'Use `%<constant>s.%<method>s(%<replacement_args>s)` instead of `%<original>s`.'
35
35
 
36
+ RESTRICT_ON_SEND = %i[new digest].freeze
36
37
  NO_ARG_ALGORITHM = %w[BF DES IDEA RC4].freeze
37
38
 
38
39
  # @!method algorithm_const(node)
@@ -51,7 +52,7 @@ module RuboCop
51
52
  PATTERN
52
53
 
53
54
  def on_send(node)
54
- return if node.arguments.any? { |arg| arg.variable? || arg.send_type? || arg.const_type? }
55
+ return if node.arguments.any? { |arg| arg.variable? || arg.call_type? || arg.const_type? }
55
56
  return if digest_const?(node.receiver)
56
57
  return unless algorithm_const(node)
57
58
 
@@ -117,8 +118,11 @@ module RuboCop
117
118
 
118
119
  def replacement_args(node)
119
120
  algorithm_constant, = algorithm_const(node)
120
- algorithm_name = algorithm_name(algorithm_constant)
121
+ if algorithm_constant.source == 'OpenSSL::Cipher::Cipher'
122
+ return node.first_argument.source
123
+ end
121
124
 
125
+ algorithm_name = algorithm_name(algorithm_constant)
122
126
  if openssl_class(algorithm_constant) == 'OpenSSL::Cipher'
123
127
  build_cipher_arguments(node, algorithm_name, node.arguments.empty?)
124
128
  else
@@ -133,7 +137,7 @@ module RuboCop
133
137
  if NO_ARG_ALGORITHM.include?(algorithm_parts.first.upcase) && no_arguments
134
138
  "'#{algorithm_parts.first}'"
135
139
  else
136
- mode = 'cbc' unless size_and_mode == ['cbc']
140
+ mode = 'cbc' if size_and_mode.empty?
137
141
 
138
142
  "'#{(algorithm_parts + size_and_mode + [mode]).compact.take(3).join('-')}'"
139
143
  end
@@ -15,6 +15,9 @@ module RuboCop
15
15
  # With `IgnoreConstantBranches: true`, branches are not registered
16
16
  # as offenses if they return a constant value.
17
17
  #
18
+ # With `IgnoreDuplicateElseBranch: true`, in conditionals with multiple branches,
19
+ # duplicate 'else' branches are not registered as offenses.
20
+ #
18
21
  # @example
19
22
  # # bad
20
23
  # if foo
@@ -83,21 +86,37 @@ module RuboCop
83
86
  # else MEDIUM_SIZE
84
87
  # end
85
88
  #
89
+ # @example IgnoreDuplicateElseBranch: true
90
+ # # good
91
+ # if foo
92
+ # do_foo
93
+ # elsif bar
94
+ # do_bar
95
+ # else
96
+ # do_foo
97
+ # end
98
+ #
86
99
  class DuplicateBranch < Base
87
100
  MSG = 'Duplicate branch body detected.'
88
101
 
89
102
  def on_branching_statement(node)
90
- branches(node).each_with_object(Set.new) do |branch, previous|
91
- next unless consider_branch?(branch)
103
+ branches = branches(node)
104
+ branches.each_with_object(Set.new) do |branch, previous|
105
+ next unless consider_branch?(branches, branch)
92
106
 
93
107
  add_offense(offense_range(branch)) unless previous.add?(branch)
94
108
  end
95
109
  end
96
- alias on_if on_branching_statement
97
110
  alias on_case on_branching_statement
98
111
  alias on_case_match on_branching_statement
99
112
  alias on_rescue on_branching_statement
100
113
 
114
+ def on_if(node)
115
+ # Ignore 'elsif' nodes, because we don't want to check them separately whether
116
+ # the 'else' branch is duplicated. We want to check only on the outermost conditional.
117
+ on_branching_statement(node) unless node.elsif?
118
+ end
119
+
101
120
  private
102
121
 
103
122
  def offense_range(duplicate_branch)
@@ -118,10 +137,14 @@ module RuboCop
118
137
  node.branches.compact
119
138
  end
120
139
 
121
- def consider_branch?(branch)
140
+ def consider_branch?(branches, branch)
122
141
  return false if ignore_literal_branches? && literal_branch?(branch)
123
142
  return false if ignore_constant_branches? && const_branch?(branch)
124
143
 
144
+ if ignore_duplicate_else_branches? && duplicate_else_branch?(branches, branch)
145
+ return false
146
+ end
147
+
125
148
  true
126
149
  end
127
150
 
@@ -133,6 +156,10 @@ module RuboCop
133
156
  cop_config.fetch('IgnoreConstantBranches', false)
134
157
  end
135
158
 
159
+ def ignore_duplicate_else_branches?
160
+ cop_config.fetch('IgnoreDuplicateElseBranch', false)
161
+ end
162
+
136
163
  def literal_branch?(branch) # rubocop:disable Metrics/CyclomaticComplexity
137
164
  return false if !branch.literal? || branch.xstr_type?
138
165
  return true if branch.basic_literal?
@@ -147,6 +174,14 @@ module RuboCop
147
174
  def const_branch?(branch)
148
175
  branch.const_type?
149
176
  end
177
+
178
+ def duplicate_else_branch?(branches, branch)
179
+ return false unless (parent = branch.parent)
180
+
181
+ branches.size > 2 &&
182
+ branch.equal?(branches.last) &&
183
+ parent.respond_to?(:else?) && parent.else?
184
+ end
150
185
  end
151
186
  end
152
187
  end
@@ -106,7 +106,7 @@ module RuboCop
106
106
  private
107
107
 
108
108
  def pattern_identity(pattern)
109
- pattern_source = if pattern.hash_pattern_type? || pattern.match_alt_type?
109
+ pattern_source = if pattern.type?(:hash_pattern, :match_alt)
110
110
  pattern.children.map(&:source).sort.to_s
111
111
  else
112
112
  pattern.source
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # Checks for duplicated instance (or singleton) method
7
7
  # definitions.
8
8
  #
9
+ # NOTE: Aliasing a method to itself is allowed, as it indicates that
10
+ # the developer intends to suppress Ruby's method redefinition warnings.
11
+ # See https://bugs.ruby-lang.org/issues/13574.
12
+ #
9
13
  # @example
10
14
  #
11
15
  # # bad
@@ -39,10 +43,64 @@ module RuboCop
39
43
  # end
40
44
  #
41
45
  # alias bar foo
46
+ #
47
+ # # good
48
+ # alias foo foo
49
+ # def foo
50
+ # 1
51
+ # end
52
+ #
53
+ # # good
54
+ # alias_method :foo, :foo
55
+ # def foo
56
+ # 1
57
+ # end
58
+ #
59
+ # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
60
+ #
61
+ # # good
62
+ # def foo
63
+ # 1
64
+ # end
65
+ #
66
+ # delegate :foo, to: :bar
67
+ #
68
+ # @example AllCops:ActiveSupportExtensionsEnabled: true
69
+ #
70
+ # # bad
71
+ # def foo
72
+ # 1
73
+ # end
74
+ #
75
+ # delegate :foo, to: :bar
76
+ #
77
+ # # good
78
+ # def foo
79
+ # 1
80
+ # end
81
+ #
82
+ # delegate :baz, to: :bar
83
+ #
84
+ # # good - delegate with splat arguments is ignored
85
+ # def foo
86
+ # 1
87
+ # end
88
+ #
89
+ # delegate :foo, **options
90
+ #
91
+ # # good - delegate inside a condition is ignored
92
+ # def foo
93
+ # 1
94
+ # end
95
+ #
96
+ # if cond
97
+ # delegate :foo, to: :bar
98
+ # end
99
+ #
42
100
  class DuplicateMethods < Base
43
101
  MSG = 'Method `%<method>s` is defined at both %<defined>s and %<current>s.'
44
- RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr].freeze
45
- DEF_TYPES = %i[def defs].freeze
102
+ RESTRICT_ON_SEND = %i[alias_method attr_reader attr_writer attr_accessor attr
103
+ delegate].freeze
46
104
 
47
105
  def initialize(config = nil, options = nil)
48
106
  super
@@ -54,14 +112,12 @@ module RuboCop
54
112
  # if a method definition is inside an if, it is very likely
55
113
  # that a different definition is used depending on platform, etc.
56
114
  return if node.each_ancestor.any?(&:if_type?)
57
- return if possible_dsl?(node)
58
115
 
59
116
  found_instance_method(node, node.method_name)
60
117
  end
61
118
 
62
119
  def on_defs(node)
63
120
  return if node.each_ancestor.any?(&:if_type?)
64
- return if possible_dsl?(node)
65
121
 
66
122
  if node.receiver.const_type?
67
123
  _, const_name = *node.receiver
@@ -73,32 +129,48 @@ module RuboCop
73
129
 
74
130
  # @!method method_alias?(node)
75
131
  def_node_matcher :method_alias?, <<~PATTERN
76
- (alias (sym $_name) sym)
132
+ (alias (sym $_name) (sym $_original_name))
77
133
  PATTERN
78
134
 
79
135
  def on_alias(node)
80
- return unless (name = method_alias?(node))
136
+ name, original_name = method_alias?(node)
137
+ return unless name && original_name
138
+ return if name == original_name
81
139
  return if node.ancestors.any?(&:if_type?)
82
- return if possible_dsl?(node)
83
140
 
84
141
  found_instance_method(node, name)
85
142
  end
86
143
 
87
144
  # @!method alias_method?(node)
88
145
  def_node_matcher :alias_method?, <<~PATTERN
89
- (send nil? :alias_method (sym $_name) _)
146
+ (send nil? :alias_method (sym $_name) (sym $_original_name))
147
+ PATTERN
148
+
149
+ # @!method delegate_method?(node)
150
+ def_node_matcher :delegate_method?, <<~PATTERN
151
+ (send nil? :delegate
152
+ ({sym str} $_)+
153
+ (hash <(pair (sym :to) {sym str}) ...>)
154
+ )
90
155
  PATTERN
91
156
 
92
157
  # @!method sym_name(node)
93
158
  def_node_matcher :sym_name, '(sym $_name)'
94
- def on_send(node)
95
- if (name = alias_method?(node))
159
+
160
+ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
161
+ name, original_name = alias_method?(node)
162
+
163
+ if name && original_name
164
+ return if name == original_name
96
165
  return if node.ancestors.any?(&:if_type?)
97
- return if possible_dsl?(node)
98
166
 
99
167
  found_instance_method(node, name)
100
168
  elsif (attr = node.attribute_accessor?)
101
169
  on_attr(node, *attr)
170
+ elsif active_support_extensions_enabled? && (names = delegate_method?(node))
171
+ return if node.ancestors.any?(&:if_type?)
172
+
173
+ on_delegate(node, names)
102
174
  end
103
175
  end
104
176
 
@@ -123,6 +195,32 @@ module RuboCop
123
195
  current: source_location(node))
124
196
  end
125
197
 
198
+ def on_delegate(node, method_names)
199
+ name_prefix = delegate_prefix(node)
200
+
201
+ method_names.each do |name|
202
+ name = "#{name_prefix}_#{name}" if name_prefix
203
+
204
+ found_instance_method(node, name)
205
+ end
206
+ end
207
+
208
+ def delegate_prefix(node)
209
+ kwargs_node = node.last_argument
210
+
211
+ return unless (prefix = hash_value(kwargs_node, :prefix))
212
+
213
+ if prefix.true_type?
214
+ hash_value(kwargs_node, :to).value
215
+ elsif prefix.type?(:sym, :str)
216
+ prefix.value
217
+ end
218
+ end
219
+
220
+ def hash_value(node, key)
221
+ node.pairs.find { |pair| pair.key.value == key }&.value
222
+ end
223
+
126
224
  def found_instance_method(node, name)
127
225
  return found_sclass_method(node, name) unless (scope = node.parent_module_name)
128
226
 
@@ -166,7 +264,7 @@ module RuboCop
166
264
  end
167
265
 
168
266
  def method_key(node, method_name)
169
- if (ancestor_def = node.each_ancestor(*DEF_TYPES).first)
267
+ if (ancestor_def = node.each_ancestor(:any_def).first)
170
268
  "#{ancestor_def.method_name}.#{method_name}"
171
269
  else
172
270
  method_name
@@ -174,7 +272,7 @@ module RuboCop
174
272
  end
175
273
 
176
274
  def location(node)
177
- if DEF_TYPES.include?(node.type)
275
+ if node.any_def_type?
178
276
  node.loc.keyword.join(node.loc.name)
179
277
  else
180
278
  node.source_range
@@ -237,16 +335,6 @@ module RuboCop
237
335
  end
238
336
  end
239
337
 
240
- def possible_dsl?(node)
241
- # DSL methods may evaluate a block in the context of a newly created
242
- # class or module
243
- # Assume that if a method definition is inside any block call which
244
- # we can't identify, it could be a DSL
245
- node.each_ancestor(:block).any? do |ancestor|
246
- !ancestor.method?(:class_eval) && !ancestor.class_constructor?
247
- end
248
- end
249
-
250
338
  def source_location(node)
251
339
  range = node.source_range
252
340
  path = smart_path(range.source_buffer.name)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for duplicate elements in Regexp character classes.
6
+ # Checks for duplicate elements in `Regexp` character classes.
7
7
  #
8
8
  # @example
9
9
  #
@@ -24,8 +24,6 @@ module RuboCop
24
24
 
25
25
  MSG_REPEATED_ELEMENT = 'Duplicate element inside regexp character class'
26
26
 
27
- OCTAL_DIGITS_AFTER_ESCAPE = 2
28
-
29
27
  def on_regexp(node)
30
28
  each_repeated_character_class_element_loc(node) do |loc|
31
29
  add_offense(loc, message: MSG_REPEATED_ELEMENT) do |corrector|
@@ -40,9 +38,9 @@ module RuboCop
40
38
 
41
39
  seen = Set.new
42
40
  group_expressions(node, expr.expressions) do |group|
43
- group_source = group.map(&:to_s).join
41
+ group_source = group.to_s
44
42
 
45
- yield source_range(group) if seen.include?(group_source)
43
+ yield group.expression if seen.include?(group_source)
46
44
 
47
45
  seen << group_source
48
46
  end
@@ -52,40 +50,13 @@ module RuboCop
52
50
  private
53
51
 
54
52
  def group_expressions(node, expressions)
55
- # Create a mutable list to simplify state tracking while we iterate.
56
- expressions = expressions.to_a
57
-
58
- until expressions.empty?
59
- # With we may need to compose a group of multiple expressions.
60
- group = [expressions.shift]
61
- next if within_interpolation?(node, group.first)
62
-
63
- # With regexp_parser < 2.7 escaped octal sequences may be up to 3
64
- # separate expressions ("\\0", "0", "1").
65
- pop_octal_digits(group, expressions) if escaped_octal?(group.first.to_s)
66
-
67
- yield(group)
68
- end
69
- end
70
-
71
- def pop_octal_digits(current_child, expressions)
72
- OCTAL_DIGITS_AFTER_ESCAPE.times do
73
- next_child = expressions.first
74
- break unless octal?(next_child.to_s)
53
+ expressions.each do |expression|
54
+ next if within_interpolation?(node, expression)
75
55
 
76
- current_child << expressions.shift
56
+ yield(expression)
77
57
  end
78
58
  end
79
59
 
80
- def source_range(children)
81
- return children.first.expression if children.size == 1
82
-
83
- range_between(
84
- children.first.expression.begin_pos,
85
- children.last.expression.begin_pos + children.last.to_s.length
86
- )
87
- end
88
-
89
60
  def skip_expression?(expr)
90
61
  expr.type != :set || expr.token == :intersection
91
62
  end
@@ -99,14 +70,6 @@ module RuboCop
99
70
  interpolation_locs(node).any? { |il| il.overlaps?(parse_tree_child_loc) }
100
71
  end
101
72
 
102
- def escaped_octal?(string)
103
- string.length == 2 && string[0] == '\\' && octal?(string[1])
104
- end
105
-
106
- def octal?(char)
107
- ('0'..'7').cover?(char)
108
- end
109
-
110
73
  def interpolation_locs(node)
111
74
  @interpolation_locs ||= {}
112
75
 
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for duplicate literal, constant, or variable elements in Set.
6
+ # Checks for duplicate literal, constant, or variable elements in `Set` and `SortedSet`.
7
7
  #
8
8
  # @example
9
9
  #
@@ -25,17 +25,28 @@ module RuboCop
25
25
  # # good
26
26
  # [:foo, :bar].to_set
27
27
  #
28
+ # # bad
29
+ # SortedSet[:foo, :bar, :foo]
30
+ #
31
+ # # good
32
+ # SortedSet[:foo, :bar]
33
+ #
34
+ # # bad
35
+ # SortedSet.new([:foo, :bar, :foo])
36
+ #
37
+ # # good
38
+ # SortedSet.new([:foo, :bar])
28
39
  class DuplicateSetElement < Base
29
40
  extend AutoCorrector
30
41
 
31
- MSG = 'Remove the duplicate element in Set.'
42
+ MSG = 'Remove the duplicate element in %<class_name>s.'
32
43
  RESTRICT_ON_SEND = %i[\[\] new to_set].freeze
33
44
 
34
45
  # @!method set_init_elements(node)
35
46
  def_node_matcher :set_init_elements, <<~PATTERN
36
47
  {
37
- (send (const {nil? cbase} :Set) :[] $...)
38
- (send (const {nil? cbase} :Set) :new (array $...))
48
+ (send (const {nil? cbase} {:Set :SortedSet}) :[] $...)
49
+ (send (const {nil? cbase} {:Set :SortedSet}) :new (array $...))
39
50
  (call (array $...) :to_set)
40
51
  }
41
52
  PATTERN
@@ -51,7 +62,7 @@ module RuboCop
51
62
  next if !set_element.literal? && !set_element.const_type? && !set_element.variable?
52
63
 
53
64
  if seen_elements.include?(set_element)
54
- register_offense(set_element, set_elements[index - 1])
65
+ register_offense(set_element, set_elements[index - 1], node)
55
66
  else
56
67
  seen_elements << set_element
57
68
  end
@@ -61,8 +72,10 @@ module RuboCop
61
72
 
62
73
  private
63
74
 
64
- def register_offense(current_element, prev_element)
65
- add_offense(current_element) do |corrector|
75
+ def register_offense(current_element, prev_element, node)
76
+ class_name = node.receiver.const_type? ? node.receiver.const_name : 'Set'
77
+
78
+ add_offense(current_element, message: format(MSG, class_name: class_name)) do |corrector|
66
79
  range = prev_element.source_range.end.join(current_element.source_range.end)
67
80
 
68
81
  corrector.remove(range)
@@ -7,11 +7,6 @@ module RuboCop
7
7
  #
8
8
  # NOTE: empty `else` branches are handled by `Style/EmptyElse`.
9
9
  #
10
- # @safety
11
- # Autocorrection for this cop is not safe. The conditions for empty branches that
12
- # the autocorrection removes may have side effects, or the logic in subsequent
13
- # branches may change due to the removal of a previous condition.
14
- #
15
10
  # @example
16
11
  # # bad
17
12
  # if condition
@@ -41,6 +36,13 @@ module RuboCop
41
36
  # if condition
42
37
  # do_something
43
38
  # elsif other_condition
39
+ # nil
40
+ # end
41
+ #
42
+ # # good
43
+ # if condition
44
+ # do_something
45
+ # elsif other_condition
44
46
  # do_something_else
45
47
  # end
46
48
  #
@@ -63,11 +65,9 @@ module RuboCop
63
65
  class EmptyConditionalBody < Base
64
66
  extend AutoCorrector
65
67
  include CommentsHelp
66
- include RangeHelp
67
68
 
68
69
  MSG = 'Avoid `%<keyword>s` branches without a body.'
69
70
 
70
- # rubocop:disable Metrics/AbcSize
71
71
  def on_if(node)
72
72
  return if node.body || same_line?(node.loc.begin, node.loc.end)
73
73
  return if cop_config['AllowComments'] && contains_comments?(node)
@@ -75,12 +75,11 @@ module RuboCop
75
75
  range = offense_range(node)
76
76
 
77
77
  add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
78
- next if node.parent&.call_type?
78
+ next unless can_simplify_conditional?(node)
79
79
 
80
- autocorrect(corrector, node)
80
+ flip_orphaned_else(corrector, node)
81
81
  end
82
82
  end
83
- # rubocop:enable Metrics/AbcSize
84
83
 
85
84
  private
86
85
 
@@ -92,53 +91,23 @@ module RuboCop
92
91
  end
93
92
  end
94
93
 
95
- def autocorrect(corrector, node)
96
- remove_comments(corrector, node)
97
- remove_empty_branch(corrector, node)
98
- correct_other_branches(corrector, node)
99
- end
100
-
101
- def remove_comments(corrector, node)
102
- comments_in_range(node).each do |comment|
103
- range = range_by_whole_lines(comment.source_range, include_final_newline: true)
104
- corrector.remove(range)
105
- end
94
+ def can_simplify_conditional?(node)
95
+ node.else_branch && node.loc.else.source == 'else'
106
96
  end
107
97
 
108
- # rubocop:disable Metrics/AbcSize
109
98
  def remove_empty_branch(corrector, node)
110
99
  range = if empty_if_branch?(node) && else_branch?(node)
111
100
  branch_range(node)
112
- elsif same_line?(node, else_kw_loc = node.loc.else)
113
- node.source_range.begin.join(else_kw_loc.begin)
114
- elsif node.parent&.loc.respond_to?(:end) &&
115
- same_line?(node, end_loc = node.parent.loc.end)
116
- node.source_range.begin.join(end_loc.begin)
117
101
  else
118
102
  deletion_range(branch_range(node))
119
103
  end
120
104
 
121
105
  corrector.remove(range)
122
106
  end
123
- # rubocop:enable Metrics/AbcSize
124
-
125
- def correct_other_branches(corrector, node)
126
- return unless require_other_branches_correction?(node)
127
-
128
- if node.else_branch&.if_type? && !node.else_branch.modifier_form?
129
- # Replace an orphaned `elsif` with `if`
130
- corrector.replace(node.else_branch.loc.keyword, 'if')
131
- else
132
- # Flip orphaned `else`
133
- corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
134
- end
135
- end
136
-
137
- def require_other_branches_correction?(node)
138
- return false unless node.if_type? && node.else?
139
- return false if !empty_if_branch?(node) && node.elsif?
140
107
 
141
- !empty_elsif_branch?(node)
108
+ def flip_orphaned_else(corrector, node)
109
+ corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
110
+ remove_empty_branch(corrector, node)
142
111
  end
143
112
 
144
113
  def empty_if_branch?(node)
@@ -149,36 +118,17 @@ module RuboCop
149
118
  if_branch.if_type? && !if_branch.body
150
119
  end
151
120
 
152
- def empty_elsif_branch?(node)
153
- return false unless (else_branch = node.else_branch)
154
-
155
- else_branch.if_type? && !else_branch.body
156
- end
157
-
158
121
  def else_branch?(node)
159
122
  node.else_branch && !node.else_branch.if_type?
160
123
  end
161
124
 
162
- # rubocop:disable Metrics/AbcSize
163
125
  def branch_range(node)
164
126
  if empty_if_branch?(node) && else_branch?(node)
165
127
  node.source_range.with(end_pos: node.loc.else.begin_pos)
166
128
  elsif node.loc.else
167
129
  node.source_range.with(end_pos: node.condition.source_range.end_pos)
168
- elsif all_branches_body_missing?(node)
169
- if_node = node.ancestors.detect(&:if?)
170
- node.source_range.join(if_node.loc.end.end)
171
- else
172
- node.source_range
173
130
  end
174
131
  end
175
- # rubocop:enable Metrics/AbcSize
176
-
177
- def all_branches_body_missing?(node)
178
- return false unless node.parent&.if_type?
179
-
180
- node.parent.branches.compact.empty?
181
- end
182
132
 
183
133
  def deletion_range(range)
184
134
  # Collect a range between the start of the `if` node and the next relevant node,
@@ -38,7 +38,7 @@ module RuboCop
38
38
  MSG = 'Empty `ensure` block detected.'
39
39
 
40
40
  def on_ensure(node)
41
- return if node.body
41
+ return if node.branch
42
42
 
43
43
  add_offense(node.loc.keyword) { |corrector| corrector.remove(node.loc.keyword) }
44
44
  end
@@ -14,8 +14,6 @@ module RuboCop
14
14
  # bar
15
15
  # end
16
16
  #
17
- # @example
18
- #
19
17
  # # good
20
18
  #
21
19
  # foo = (some_expression)
@@ -21,8 +21,6 @@ module RuboCop
21
21
  # # File consisting only of comments
22
22
  #
23
23
  class EmptyFile < Base
24
- include RangeHelp
25
-
26
24
  MSG = 'Empty file detected.'
27
25
 
28
26
  def on_new_investigation