rubocop 1.69.2 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +122 -17
  5. data/config/internal_affairs.yml +20 -0
  6. data/lib/rubocop/cli/command/execute_runner.rb +3 -3
  7. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  9. data/lib/rubocop/comment_config.rb +2 -2
  10. data/lib/rubocop/config.rb +17 -4
  11. data/lib/rubocop/config_loader.rb +48 -9
  12. data/lib/rubocop/config_loader_resolver.rb +36 -10
  13. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  14. data/lib/rubocop/config_obsoletion.rb +1 -1
  15. data/lib/rubocop/config_validator.rb +19 -9
  16. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  17. data/lib/rubocop/cop/base.rb +6 -0
  18. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  19. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  20. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  21. data/lib/rubocop/cop/internal_affairs/example_description.rb +7 -3
  22. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  23. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  24. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  25. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  26. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  27. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  28. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  29. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  30. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  31. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  32. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  33. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  34. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  35. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  36. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  37. data/lib/rubocop/cop/internal_affairs.rb +6 -16
  38. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  39. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
  40. data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
  41. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  42. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  43. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  44. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  45. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +1 -1
  46. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  47. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +27 -1
  48. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
  49. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
  50. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  51. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  52. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  53. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  54. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  55. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  56. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  57. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  58. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  59. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  60. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  61. data/lib/rubocop/cop/layout/line_length.rb +4 -3
  62. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  63. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  64. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
  65. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  66. data/lib/rubocop/cop/layout/redundant_line_break.rb +7 -6
  67. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  68. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  69. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  70. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  71. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  72. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  73. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
  74. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  75. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
  76. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  77. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  78. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  79. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  80. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  81. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  82. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
  83. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  84. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  85. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  86. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  87. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  88. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
  89. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  90. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  91. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  92. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  93. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  94. data/lib/rubocop/cop/lint/float_comparison.rb +6 -8
  95. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  96. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  97. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  98. data/lib/rubocop/cop/lint/literal_as_condition.rb +103 -9
  99. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  100. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  101. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
  102. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  103. data/lib/rubocop/cop/lint/nested_method_definition.rb +8 -4
  104. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  105. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -3
  106. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  107. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +18 -31
  108. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
  109. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  110. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  111. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  112. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  113. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +258 -0
  114. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  115. data/lib/rubocop/cop/lint/return_in_void_context.rb +4 -11
  116. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
  117. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  118. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  119. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  120. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  121. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  122. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
  123. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  124. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  125. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  126. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  127. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  128. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  129. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  130. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  131. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  132. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  133. data/lib/rubocop/cop/lint/void.rb +11 -9
  134. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  135. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  136. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  137. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  138. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  139. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  140. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  141. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  142. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  143. data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -11
  144. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
  145. data/lib/rubocop/cop/mixin/comments_help.rb +4 -2
  146. data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
  147. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  148. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  149. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  150. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  151. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  152. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  153. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
  154. data/lib/rubocop/cop/mixin/range_help.rb +15 -3
  155. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  156. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  157. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  158. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  159. data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
  160. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  161. data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
  162. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  163. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
  164. data/lib/rubocop/cop/naming/variable_name.rb +64 -6
  165. data/lib/rubocop/cop/security/compound_hash.rb +1 -0
  166. data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
  167. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  168. data/lib/rubocop/cop/style/and_or.rb +1 -1
  169. data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
  170. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  171. data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
  172. data/lib/rubocop/cop/style/class_and_module_children.rb +35 -10
  173. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  174. data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
  175. data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
  176. data/lib/rubocop/cop/style/commented_keyword.rb +10 -3
  177. data/lib/rubocop/cop/style/comparable_between.rb +75 -0
  178. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  179. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
  180. data/lib/rubocop/cop/style/documentation.rb +1 -1
  181. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  182. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  183. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  184. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  185. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  186. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  187. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  188. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  189. data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
  190. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  191. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  192. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  193. data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
  194. data/lib/rubocop/cop/style/float_division.rb +8 -4
  195. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  196. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  197. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
  198. data/lib/rubocop/cop/style/hash_except.rb +24 -148
  199. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  200. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  201. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  202. data/lib/rubocop/cop/style/if_unless_modifier.rb +5 -5
  203. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
  204. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  205. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  206. data/lib/rubocop/cop/style/inverse_methods.rb +14 -11
  207. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  208. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  209. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  210. data/lib/rubocop/cop/style/map_into_array.rb +1 -1
  211. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  212. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  213. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -15
  214. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  215. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
  216. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  217. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  218. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  219. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  220. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  221. data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
  222. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  223. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
  224. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  225. data/lib/rubocop/cop/style/object_then.rb +13 -15
  226. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  227. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
  228. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  229. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  230. data/lib/rubocop/cop/style/proc.rb +1 -2
  231. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  232. data/lib/rubocop/cop/style/raise_args.rb +6 -4
  233. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  234. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  235. data/lib/rubocop/cop/style/redundant_condition.rb +47 -2
  236. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  237. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  238. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  239. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  240. data/lib/rubocop/cop/style/redundant_format.rb +250 -0
  241. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  242. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  243. data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -13
  244. data/lib/rubocop/cop/style/redundant_parentheses.rb +28 -14
  245. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
  246. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  247. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  248. data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
  249. data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
  250. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  251. data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
  252. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  253. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  254. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  255. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  256. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  257. data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
  258. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  259. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  260. data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -8
  261. data/lib/rubocop/cop/style/string_concatenation.rb +2 -2
  262. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  263. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  264. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  265. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  266. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  267. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  268. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  269. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  270. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  271. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  272. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  273. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  274. data/lib/rubocop/cop/util.rb +12 -5
  275. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  276. data/lib/rubocop/cop/variable_force/variable.rb +14 -2
  277. data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
  278. data/lib/rubocop/cops_documentation_generator.rb +25 -14
  279. data/lib/rubocop/directive_comment.rb +45 -11
  280. data/lib/rubocop/ext/regexp_node.rb +0 -1
  281. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  282. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  283. data/lib/rubocop/lsp/logger.rb +2 -2
  284. data/lib/rubocop/lsp/routes.rb +7 -23
  285. data/lib/rubocop/lsp/runtime.rb +17 -49
  286. data/lib/rubocop/lsp/server.rb +0 -2
  287. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  288. data/lib/rubocop/options.rb +28 -12
  289. data/lib/rubocop/path_util.rb +15 -8
  290. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  291. data/lib/rubocop/plugin/load_error.rb +26 -0
  292. data/lib/rubocop/plugin/loader.rb +100 -0
  293. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  294. data/lib/rubocop/plugin.rb +46 -0
  295. data/lib/rubocop/rake_task.rb +4 -1
  296. data/lib/rubocop/result_cache.rb +13 -13
  297. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  298. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  299. data/lib/rubocop/rspec/shared_contexts.rb +19 -1
  300. data/lib/rubocop/rspec/support.rb +2 -2
  301. data/lib/rubocop/runner.rb +5 -6
  302. data/lib/rubocop/server/cache.rb +35 -2
  303. data/lib/rubocop/server/cli.rb +2 -2
  304. data/lib/rubocop/target_finder.rb +1 -0
  305. data/lib/rubocop/target_ruby.rb +15 -0
  306. data/lib/rubocop/version.rb +17 -2
  307. data/lib/rubocop.rb +12 -1
  308. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  309. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  310. metadata +55 -16
  311. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  312. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -108,18 +108,16 @@ module RuboCop
108
108
  end
109
109
 
110
110
  def call_in_literals?(node)
111
- parent = node.parent&.block_type? ? node.parent.parent : node.parent
111
+ parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
112
112
  return false unless parent
113
113
 
114
- parent.pair_type? ||
115
- parent.array_type? ||
116
- parent.range_type? ||
114
+ parent.type?(:pair, :array, :range) ||
117
115
  splat?(parent) ||
118
116
  ternary_if?(parent)
119
117
  end
120
118
 
121
119
  def call_in_logical_operators?(node)
122
- parent = node.parent&.block_type? ? node.parent.parent : node.parent
120
+ parent = node.parent&.any_block_type? ? node.parent.parent : node.parent
123
121
  return false unless parent
124
122
 
125
123
  logical_operator?(parent) ||
@@ -128,46 +126,48 @@ module RuboCop
128
126
  end
129
127
 
130
128
  def call_in_optional_arguments?(node)
131
- node.parent && (node.parent.optarg_type? || node.parent.kwoptarg_type?)
129
+ node.parent&.type?(:optarg, :kwoptarg)
132
130
  end
133
131
 
134
132
  def call_in_single_line_inheritance?(node)
135
133
  node.parent&.class_type? && node.parent.single_line?
136
134
  end
137
135
 
138
- def call_with_ambiguous_arguments?(node) # rubocop:disable Metrics/PerceivedComplexity
136
+ # rubocop:disable Metrics/PerceivedComplexity
137
+ def call_with_ambiguous_arguments?(node)
139
138
  call_with_braced_block?(node) ||
140
139
  call_in_argument_with_block?(node) ||
141
140
  call_as_argument_or_chain?(node) ||
142
141
  call_in_match_pattern?(node) ||
143
142
  hash_literal_in_arguments?(node) ||
143
+ ambiguous_range_argument?(node) ||
144
144
  node.descendants.any? do |n|
145
- n.forwarded_args_type? || n.block_type? || n.numblock_type? ||
145
+ n.type?(:forwarded_args, :any_block) ||
146
146
  ambiguous_literal?(n) || logical_operator?(n)
147
147
  end
148
148
  end
149
+ # rubocop:enable Metrics/PerceivedComplexity
149
150
 
150
151
  def call_with_braced_block?(node)
151
- (node.call_type? || node.super_type?) && node.block_node&.braces?
152
+ node.type?(:call, :super) && node.block_node&.braces?
152
153
  end
153
154
 
154
155
  def call_in_argument_with_block?(node)
155
- parent = node.parent&.block_type? && node.parent.parent
156
+ parent = node.parent&.any_block_type? && node.parent.parent
156
157
  return false unless parent
157
158
 
158
- parent.call_type? || parent.super_type? || parent.yield_type?
159
+ parent.type?(:call, :super, :yield)
159
160
  end
160
161
 
161
162
  def call_as_argument_or_chain?(node)
162
- node.parent &&
163
- (node.parent.call_type? || node.parent.super_type? || node.parent.yield_type?) &&
163
+ node.parent&.type?(:call, :super, :yield) &&
164
164
  !assigned_before?(node.parent, node)
165
165
  end
166
166
 
167
167
  def call_in_match_pattern?(node)
168
168
  return false unless (parent = node.parent)
169
169
 
170
- parent.match_pattern_type? || parent.match_pattern_p_type?
170
+ parent.type?(:match_pattern, :match_pattern_p)
171
171
  end
172
172
 
173
173
  def hash_literal_in_arguments?(node)
@@ -177,6 +177,13 @@ module RuboCop
177
177
  end
178
178
  end
179
179
 
180
+ def ambiguous_range_argument?(node)
181
+ return true if (first_arg = node.first_argument)&.range_type? && first_arg.begin.nil?
182
+ return true if (last_arg = node.last_argument)&.range_type? && last_arg.end.nil?
183
+
184
+ false
185
+ end
186
+
180
187
  def allowed_multiline_call_with_parentheses?(node)
181
188
  cop_config['AllowParenthesesInMultilineCall'] && node.multiline?
182
189
  end
@@ -195,7 +202,7 @@ module RuboCop
195
202
  end
196
203
 
197
204
  def splat?(node)
198
- node.splat_type? || node.kwsplat_type? || node.block_pass_type?
205
+ node.type?(:splat, :kwsplat, :block_pass)
199
206
  end
200
207
 
201
208
  def ternary_if?(node)
@@ -61,6 +61,8 @@ module RuboCop
61
61
  # https://bugs.ruby-lang.org/issues/18396.
62
62
  # - Parentheses are required in anonymous arguments, keyword arguments
63
63
  # and block passing in Ruby 3.2.
64
+ # - Parentheses are required when the first argument is a beginless range or
65
+ # the last argument is an endless range.
64
66
  #
65
67
  # @example EnforcedStyle: require_parentheses (default)
66
68
  #
@@ -45,6 +45,7 @@ module RuboCop
45
45
  register_offense(node)
46
46
  end
47
47
  # rubocop:enable Metrics/CyclomaticComplexity
48
+ alias on_csend on_send
48
49
 
49
50
  private
50
51
 
@@ -100,7 +101,7 @@ module RuboCop
100
101
  # `obj.method ||= value` parses as (or-asgn (send ...) ...)
101
102
  # which IS an `asgn_node`. Similarly, `obj.method += value` parses
102
103
  # as (op-asgn (send ...) ...), which is also an `asgn_node`.
103
- next if asgn_node.shorthand_asgn? && asgn_node.lhs.send_type?
104
+ next if asgn_node.shorthand_asgn? && asgn_node.lhs.call_type?
104
105
 
105
106
  yield asgn_node
106
107
  end
@@ -40,10 +40,8 @@ module RuboCop
40
40
  def on_send(node)
41
41
  return if ignored_node?(node)
42
42
 
43
- receiver = node.receiver
44
-
45
- return unless (receiver&.block_type? || receiver&.numblock_type?) &&
46
- receiver.loc.end.is?('end')
43
+ return unless (receiver = node.receiver)
44
+ return unless receiver.any_block_type? && receiver.keywords?
47
45
 
48
46
  range = range_between(receiver.loc.end.begin_pos, node.source_range.end_pos)
49
47
 
@@ -168,7 +168,7 @@ module RuboCop
168
168
 
169
169
  def anonymous_arguments?(node)
170
170
  return true if node.arguments.any? do |arg|
171
- arg.forward_arg_type? || arg.restarg_type? || arg.kwrestarg_type?
171
+ arg.type?(:forward_arg, :restarg, :kwrestarg)
172
172
  end
173
173
  return false unless (last_argument = node.last_argument)
174
174
 
@@ -144,6 +144,8 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def autocorrect(corrector, node)
147
+ node = node.ancestors.find { |ancestor| ancestor.loc.end } unless node.loc.end
148
+
147
149
  case empty_else_style
148
150
  when :empty
149
151
  corrector.insert_before(node.loc.end, 'else; nil; ')
@@ -28,10 +28,10 @@ module RuboCop
28
28
  MSG = 'Avoid multi-line chains of blocks.'
29
29
 
30
30
  def on_block(node)
31
- node.send_node.each_node(:send, :csend) do |send_node|
31
+ node.send_node.each_node(:call) do |send_node|
32
32
  receiver = send_node.receiver
33
33
 
34
- next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline?
34
+ next unless receiver&.any_block_type? && receiver.multiline?
35
35
 
36
36
  range = range_between(receiver.loc.end.begin_pos, node.send_node.source_range.end_pos)
37
37
 
@@ -50,7 +50,7 @@ module RuboCop
50
50
  corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
51
51
  end
52
52
 
53
- arguments_range = arguments_range(node)
53
+ arguments_range = range_with_surrounding_space(arguments_range(node), side: :left)
54
54
  # If the method name isn't on the same line as def, move it directly after def
55
55
  if arguments_range.first_line != opening_line(node)
56
56
  corrector.remove(node.loc.name)
@@ -66,14 +66,6 @@ module RuboCop
66
66
  processed_source[arguments.last_line - 1].strip
67
67
  end
68
68
 
69
- def arguments_range(node)
70
- range = range_between(
71
- node.first_argument.source_range.begin_pos, node.last_argument.source_range.end_pos
72
- )
73
-
74
- range_with_surrounding_space(range, side: :left)
75
- end
76
-
77
69
  def opening_line(node)
78
70
  node.first_line
79
71
  end
@@ -55,6 +55,22 @@ module RuboCop
55
55
  MSG = 'Avoid comparing a variable with multiple items ' \
56
56
  'in a conditional, use `Array#include?` instead.'
57
57
 
58
+ # @!method simple_double_comparison?(node)
59
+ def_node_matcher :simple_double_comparison?, <<~PATTERN
60
+ (send lvar :== lvar)
61
+ PATTERN
62
+
63
+ # @!method simple_comparison_lhs(node)
64
+ def_node_matcher :simple_comparison_lhs, <<~PATTERN
65
+ (send ${lvar call} :== $_)
66
+ PATTERN
67
+
68
+ # @!method simple_comparison_rhs(node)
69
+ def_node_matcher :simple_comparison_rhs, <<~PATTERN
70
+ (send $_ :== ${lvar call})
71
+ PATTERN
72
+
73
+ # rubocop:disable Metrics/AbcSize
58
74
  def on_or(node)
59
75
  root_of_or_node = root_of_or_node(node)
60
76
  return unless node == root_of_or_node
@@ -67,27 +83,16 @@ module RuboCop
67
83
 
68
84
  add_offense(range) do |corrector|
69
85
  elements = values.map(&:source).join(', ')
70
- prefer_method = "[#{elements}].include?(#{variable_name(variable)})"
86
+ argument = variable.lvar_type? ? variable_name(variable) : variable.source
87
+ prefer_method = "[#{elements}].include?(#{argument})"
71
88
 
72
89
  corrector.replace(range, prefer_method)
73
90
  end
74
91
  end
92
+ # rubocop:enable Metrics/AbcSize
75
93
 
76
94
  private
77
95
 
78
- # @!method simple_double_comparison?(node)
79
- def_node_matcher :simple_double_comparison?, '(send $lvar :== $lvar)'
80
-
81
- # @!method simple_comparison_lhs?(node)
82
- def_node_matcher :simple_comparison_lhs?, <<~PATTERN
83
- (send $lvar :== $_)
84
- PATTERN
85
-
86
- # @!method simple_comparison_rhs?(node)
87
- def_node_matcher :simple_comparison_rhs?, <<~PATTERN
88
- (send $_ :== $lvar)
89
- PATTERN
90
-
91
96
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
92
97
  def find_offending_var(node, variables = Set.new, values = [])
93
98
  if node.or_type?
@@ -95,8 +100,8 @@ module RuboCop
95
100
  find_offending_var(node.rhs, variables, values)
96
101
  elsif simple_double_comparison?(node)
97
102
  return
98
- elsif (var, obj = simple_comparison?(node))
99
- return if allow_method_comparison? && obj.send_type?
103
+ elsif (var, obj = simple_comparison(node))
104
+ return if allow_method_comparison? && obj.call_type?
100
105
 
101
106
  variables << var
102
107
  return if variables.size > 1
@@ -125,12 +130,13 @@ module RuboCop
125
130
  end
126
131
 
127
132
  def comparison?(node)
128
- simple_comparison?(node) || nested_comparison?(node)
133
+ !!simple_comparison(node) || nested_comparison?(node)
129
134
  end
130
135
 
131
- def simple_comparison?(node)
132
- if (var, obj = simple_comparison_lhs?(node)) ||
133
- (obj, var = simple_comparison_rhs?(node))
136
+ def simple_comparison(node)
137
+ if (var, obj = simple_comparison_lhs(node)) || (obj, var = simple_comparison_rhs(node))
138
+ return if var.call_type? && !allow_method_comparison?
139
+
134
140
  [var, obj]
135
141
  end
136
142
  end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # acceptable value other than none, it will suppress the offenses
20
20
  # raised by this cop. It enforces frozen state.
21
21
  #
22
- # NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
22
+ # NOTE: `Regexp` and `Range` literals are frozen objects since Ruby 3.0.
23
23
  #
24
24
  # NOTE: From Ruby 3.0, interpolated strings are not frozen when
25
25
  # `# frozen-string-literal: true` is used, so this cop enforces explicit
@@ -197,7 +197,7 @@ module RuboCop
197
197
  end
198
198
 
199
199
  def frozen_regexp_or_range_literals?(node)
200
- target_ruby_version >= 3.0 && (node.regexp_type? || node.range_type?)
200
+ target_ruby_version >= 3.0 && node.type?(:regexp, :range)
201
201
  end
202
202
 
203
203
  def requires_parentheses?(node)
@@ -238,7 +238,7 @@ module RuboCop
238
238
 
239
239
  # @!method range_enclosed_in_parentheses?(node)
240
240
  def_node_matcher :range_enclosed_in_parentheses?, <<~PATTERN
241
- (begin ({irange erange} _ _))
241
+ (begin (range _ _))
242
242
  PATTERN
243
243
  end
244
244
  end
@@ -74,7 +74,7 @@ module RuboCop
74
74
  end
75
75
 
76
76
  def unwrap_begin_nodes(node)
77
- node = node.children.first while node && (node.begin_type? || node.kwbegin_type?)
77
+ node = node.children.first while node&.type?(:begin, :kwbegin)
78
78
 
79
79
  node
80
80
  end
@@ -35,7 +35,7 @@ module RuboCop
35
35
  def on_send(node)
36
36
  return unless node.parenthesized?
37
37
 
38
- node.each_child_node(:send, :csend) do |nested|
38
+ node.each_child_node(:call) do |nested|
39
39
  next if allowed_omission?(nested)
40
40
 
41
41
  message = format(MSG, source: nested.source)
@@ -33,9 +33,10 @@ module RuboCop
33
33
  RESTRICT_ON_SEND = %i[then yield_self].freeze
34
34
 
35
35
  def on_block(node)
36
+ return unless RESTRICT_ON_SEND.include?(node.method_name)
37
+
36
38
  check_method_node(node.send_node)
37
39
  end
38
-
39
40
  alias on_numblock on_block
40
41
 
41
42
  def on_send(node)
@@ -43,29 +44,26 @@ module RuboCop
43
44
 
44
45
  check_method_node(node)
45
46
  end
47
+ alias on_csend on_send
46
48
 
47
49
  private
48
50
 
49
51
  def check_method_node(node)
50
- return unless preferred_method?(node)
51
-
52
- message = message(node)
53
- add_offense(node.loc.selector, message: message) do |corrector|
54
- prefer = style == :then && node.receiver.nil? ? 'self.then' : style
52
+ if preferred_method?(node)
53
+ correct_style_detected
54
+ else
55
+ opposite_style_detected
56
+ message = message(node)
57
+ add_offense(node.loc.selector, message: message) do |corrector|
58
+ prefer = style == :then && node.receiver.nil? ? 'self.then' : style
55
59
 
56
- corrector.replace(node.loc.selector, prefer)
60
+ corrector.replace(node.loc.selector, prefer)
61
+ end
57
62
  end
58
63
  end
59
64
 
60
65
  def preferred_method?(node)
61
- case style
62
- when :then
63
- node.method?(:yield_self)
64
- when :yield_self
65
- node.method?(:then)
66
- else
67
- false
68
- end
66
+ node.method?(style)
69
67
  end
70
68
 
71
69
  def message(node)
@@ -3,15 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Flags uses of OpenStruct, as it is now officially discouraged
6
+ # Flags uses of `OpenStruct`, as it is now officially discouraged
7
7
  # to be used for performance, version compatibility, and potential security issues.
8
8
  #
9
9
  # @safety
10
- #
11
10
  # Note that this cop may flag false positives; for instance, the following legal
12
11
  # use of a hand-rolled `OpenStruct` type would be considered an offense:
13
12
  #
14
- # ```
13
+ # [source,ruby]
14
+ # -----
15
15
  # module MyNamespace
16
16
  # class OpenStruct # not the OpenStruct we're looking for
17
17
  # end
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # OpenStruct.new # resolves to MyNamespace::OpenStruct
21
21
  # end
22
22
  # end
23
- # ```
23
+ # -----
24
24
  #
25
25
  # @example
26
26
  #
@@ -61,7 +61,7 @@ module RuboCop
61
61
  def custom_class_or_module_definition?(node)
62
62
  parent = node.parent
63
63
 
64
- (parent.class_type? || parent.module_type?) && node.left_siblings.empty?
64
+ parent.type?(:class, :module) && node.left_siblings.empty?
65
65
  end
66
66
  end
67
67
  end
@@ -69,11 +69,7 @@ module RuboCop
69
69
  elements = Array(node).compact
70
70
 
71
71
  # Account for edge case of `Constant::CONSTANT`
72
- !node.array_type? || return_of_method_call?(node) || elements.any?(&:splat_type?)
73
- end
74
-
75
- def return_of_method_call?(node)
76
- node.block_type? || node.send_type?
72
+ !node.array_type? || elements.any?(&:splat_type?)
77
73
  end
78
74
 
79
75
  def assignment_corrector(node, rhs, order)
@@ -94,8 +94,8 @@ module RuboCop
94
94
  end
95
95
 
96
96
  def require_parentheses?(node, condition_body)
97
- return false if !node.while_type? && !node.until_type?
98
- return false if !condition_body.block_type? && !condition_body.numblock_type?
97
+ return false unless node.type?(:while, :until)
98
+ return false unless condition_body.any_block_type?
99
99
 
100
100
  condition_body.send_node.block_literal? && condition_body.keywords?
101
101
  end
@@ -99,7 +99,7 @@ module RuboCop
99
99
  def string_source(node)
100
100
  if node.is_a?(String)
101
101
  node.scrub
102
- elsif node.respond_to?(:type) && (node.str_type? || node.sym_type?)
102
+ elsif node.respond_to?(:type) && node.type?(:str, :sym)
103
103
  node.source
104
104
  end
105
105
  end
@@ -19,8 +19,7 @@ module RuboCop
19
19
  MSG = 'Use `proc` instead of `Proc.new`.'
20
20
 
21
21
  # @!method proc_new?(node)
22
- def_node_matcher :proc_new?,
23
- '({block numblock} $(send (const {nil? cbase} :Proc) :new) ...)'
22
+ def_node_matcher :proc_new?, '(any_block $(send (const {nil? cbase} :Proc) :new) ...)'
24
23
 
25
24
  def on_block(node)
26
25
  proc_new?(node) do |block_method|
@@ -98,7 +98,7 @@ module RuboCop
98
98
 
99
99
  def style
100
100
  return super unless super == :same_as_string_literals
101
- return :single_quotes unless string_literals_config['Enabled']
101
+ return :single_quotes unless config.cop_enabled?('Style/StringLiterals')
102
102
 
103
103
  string_literals_config['EnforcedStyle'].to_sym
104
104
  end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  # passed multiple arguments.
15
15
  #
16
16
  # The exploded style has an `AllowedCompactTypes` configuration
17
- # option that takes an Array of exception name Strings.
17
+ # option that takes an `Array` of exception name Strings.
18
18
  #
19
19
  # @safety
20
20
  # This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
@@ -50,6 +50,9 @@ module RuboCop
50
50
 
51
51
  EXPLODED_MSG = 'Provide an exception class and message as arguments to `%<method>s`.'
52
52
  COMPACT_MSG = 'Provide an exception object as an argument to `%<method>s`.'
53
+ ACCEPTABLE_ARG_TYPES = %i[
54
+ hash forwarded_restarg splat forwarded_restarg forwarded_args
55
+ ].freeze
53
56
 
54
57
  RESTRICT_ON_SEND = %i[raise fail].freeze
55
58
 
@@ -138,9 +141,8 @@ module RuboCop
138
141
 
139
142
  arg = args.first
140
143
 
141
- # Allow code like `raise Ex.new(kw: arg)`.
142
- # Allow code like `raise Ex.new(*args)`.
143
- arg.hash_type? || arg.splat_type?
144
+ # Allow nodes that may forward more than one argument
145
+ ACCEPTABLE_ARG_TYPES.include?(arg.type)
144
146
  end
145
147
 
146
148
  def allowed_non_exploded_type?(arg)
@@ -36,7 +36,7 @@ module RuboCop
36
36
  (send
37
37
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
38
38
  :rand
39
- {int (irange int int) (erange int int)}))
39
+ {int (range int int)}))
40
40
  PATTERN
41
41
 
42
42
  # @!method rand_op_integer?(node)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  (send
46
46
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
47
47
  :rand
48
- {int (irange int int) (erange int int)})
48
+ {int (range int int)})
49
49
  {:+ :-}
50
50
  int)
51
51
  PATTERN
@@ -56,7 +56,7 @@ module RuboCop
56
56
  (send
57
57
  {nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
58
58
  :rand
59
- {int (irange int int) (erange int int)})
59
+ {int (range int int)})
60
60
  {:succ :pred :next})
61
61
  PATTERN
62
62
 
@@ -185,7 +185,7 @@ module RuboCop
185
185
  def contain_rescue_or_ensure?(node)
186
186
  first_child = node.children.first
187
187
 
188
- first_child.rescue_type? || first_child.ensure_type?
188
+ first_child.type?(:rescue, :ensure)
189
189
  end
190
190
 
191
191
  def valid_context_using_only_begin?(node)
@@ -42,7 +42,28 @@ module RuboCop
42
42
  # c
43
43
  # end
44
44
  #
45
+ # # bad
46
+ # a.nil? ? true : a
47
+ #
48
+ # # good
49
+ # a.nil? || a
50
+ #
51
+ # # bad
52
+ # if a.nil?
53
+ # true
54
+ # else
55
+ # a
56
+ # end
57
+ #
58
+ # # good
59
+ # a.nil? || a
60
+ #
61
+ # @example AllowedMethods: ['nonzero?'] (default)
62
+ # # good
63
+ # num.nonzero? ? true : false
64
+ #
45
65
  class RedundantCondition < Base
66
+ include AllowedMethods
46
67
  include CommentsHelp
47
68
  include RangeHelp
48
69
  extend AutoCorrector
@@ -128,6 +149,16 @@ module RuboCop
128
149
  # end
129
150
  return true if condition == if_branch
130
151
 
152
+ # e.g.
153
+ # a.nil? ? true : a
154
+ # or
155
+ # if a.nil?
156
+ # true
157
+ # else
158
+ # a
159
+ # end
160
+ return true if if_branch_is_true_type_and_else_is_not?(node)
161
+
131
162
  # e.g.
132
163
  # if foo
133
164
  # @value = foo
@@ -146,6 +177,18 @@ module RuboCop
146
177
  !use_hash_key_access?(if_branch)
147
178
  end
148
179
 
180
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
181
+ def if_branch_is_true_type_and_else_is_not?(node)
182
+ return false unless node.ternary? || node.if?
183
+
184
+ cond = node.condition
185
+ return false unless cond.call_type?
186
+ return false if !cond.predicate_method? || allowed_method?(cond.method_name)
187
+
188
+ node.if_branch&.true_type? && node.else_branch && !node.else_branch.true_type?
189
+ end
190
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
191
+
149
192
  def branches_have_assignment?(node)
150
193
  _condition, if_branch, else_branch = *node # rubocop:disable InternalAffairs/NodeDestructuring
151
194
 
@@ -157,7 +200,7 @@ module RuboCop
157
200
  end
158
201
 
159
202
  def asgn_type?(node)
160
- node.lvasgn_type? || node.ivasgn_type? || node.cvasgn_type? || node.gvasgn_type?
203
+ node.type?(:lvasgn, :ivasgn, :cvasgn, :gvasgn)
161
204
  end
162
205
 
163
206
  def branches_have_method?(node)
@@ -184,7 +227,7 @@ module RuboCop
184
227
  return false unless argument.hash_type?
185
228
  return false unless (node = argument.children.first)
186
229
 
187
- node.kwsplat_type? || node.forwarded_kwrestarg_type?
230
+ node.type?(:kwsplat, :forwarded_kwrestarg)
188
231
  end
189
232
 
190
233
  def if_source(if_branch, arithmetic_operation)
@@ -194,6 +237,8 @@ module RuboCop
194
237
  argument_source = if_branch.first_argument.source
195
238
 
196
239
  "#{if_branch.receiver.source} #{if_branch.method_name} (#{argument_source}"
240
+ elsif if_branch.true_type?
241
+ if_branch.parent.condition.source
197
242
  else
198
243
  if_branch.source
199
244
  end