rubocop 1.67.0 → 1.75.5

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 (465) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +264 -47
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +3 -1
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  28. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  34. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  35. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  36. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  37. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  38. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  39. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +230 -0
  43. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  55. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  56. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  57. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  58. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  59. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  60. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  61. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  62. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  64. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  65. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  66. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  67. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  68. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  69. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +30 -4
  70. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  71. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  72. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  73. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  74. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  76. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  77. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  78. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  79. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  80. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  81. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  82. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  83. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  84. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  85. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  86. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  87. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  88. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  89. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  90. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  91. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  92. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  93. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  94. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  95. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  96. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  97. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  98. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  99. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  100. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  102. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  103. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  105. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  106. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  108. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  109. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  110. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +10 -1
  113. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  114. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  115. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  116. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  117. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  118. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  119. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  120. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  121. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  122. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  123. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  124. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  125. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  126. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  127. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  128. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  129. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  130. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -17
  131. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  132. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  133. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  134. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  135. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  136. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  137. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  138. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  139. data/lib/rubocop/cop/lint/float_comparison.rb +20 -14
  140. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  141. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  142. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  143. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  144. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  145. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  146. data/lib/rubocop/cop/lint/literal_as_condition.rb +118 -9
  147. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  148. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  149. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  150. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  151. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  152. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  153. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  154. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  155. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  156. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  157. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  158. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  159. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  160. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  161. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  162. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  163. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  164. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  165. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  166. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  167. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  168. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  169. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  170. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  171. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  172. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  173. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  174. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  175. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  176. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  177. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  178. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  179. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  180. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  181. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  182. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  183. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  184. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +8 -1
  185. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  186. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  187. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  188. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  189. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  190. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  191. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  192. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  193. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  194. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  195. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  196. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  197. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  198. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  199. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  200. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  201. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  202. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  203. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  204. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  205. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  206. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  207. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  208. data/lib/rubocop/cop/lint/void.rb +16 -12
  209. data/lib/rubocop/cop/message_annotator.rb +7 -3
  210. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  211. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  212. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  213. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  214. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  215. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  216. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  217. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  218. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  219. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  220. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  221. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  222. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  223. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  224. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  225. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  226. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  227. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  228. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  229. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  230. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  231. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  232. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  233. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  234. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  235. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  236. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  237. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  238. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  239. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  240. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  241. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  242. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  243. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  244. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  245. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  246. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  247. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  248. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  249. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  250. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  251. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  252. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  253. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  254. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  255. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  256. data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
  257. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  258. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  259. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  260. data/lib/rubocop/cop/offense.rb +2 -3
  261. data/lib/rubocop/cop/registry.rb +9 -6
  262. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  263. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  264. data/lib/rubocop/cop/style/access_modifier_declarations.rb +86 -28
  265. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  266. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  267. data/lib/rubocop/cop/style/and_or.rb +1 -1
  268. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  269. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  270. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  271. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  272. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  273. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  274. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  275. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  276. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  277. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  278. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  279. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  280. data/lib/rubocop/cop/style/comparable_between.rb +75 -0
  281. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  282. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  283. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  284. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  285. data/lib/rubocop/cop/style/documentation.rb +1 -1
  286. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  287. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  288. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  289. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  290. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  291. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  292. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  293. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  294. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  295. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  296. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  297. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  298. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  299. data/lib/rubocop/cop/style/file_null.rb +89 -0
  300. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  301. data/lib/rubocop/cop/style/float_division.rb +8 -4
  302. data/lib/rubocop/cop/style/for.rb +1 -1
  303. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  304. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  305. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  306. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  307. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  308. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  309. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  310. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  311. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  312. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  313. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  314. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  315. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  316. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  317. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  318. data/lib/rubocop/cop/style/if_unless_modifier.rb +5 -5
  319. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  320. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  321. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  322. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  323. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  324. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  325. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  326. data/lib/rubocop/cop/style/it_block_parameter.rb +100 -0
  327. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  328. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  329. data/lib/rubocop/cop/style/lambda.rb +1 -0
  330. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  331. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  332. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  333. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  334. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  335. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  336. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  337. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  338. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  339. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  340. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  341. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  342. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  343. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  344. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  345. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  346. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  347. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  348. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  349. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  350. data/lib/rubocop/cop/style/next.rb +44 -0
  351. data/lib/rubocop/cop/style/not.rb +1 -1
  352. data/lib/rubocop/cop/style/object_then.rb +15 -15
  353. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  354. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  355. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  356. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  357. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  358. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  359. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  360. data/lib/rubocop/cop/style/proc.rb +2 -2
  361. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  362. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  363. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  364. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  365. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  366. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  367. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  368. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  369. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  370. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  371. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  372. data/lib/rubocop/cop/style/redundant_format.rb +257 -0
  373. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  374. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  375. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  376. data/lib/rubocop/cop/style/redundant_parentheses.rb +56 -26
  377. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  378. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  379. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  380. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  381. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  382. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  383. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  384. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  385. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  386. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  387. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  388. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  389. data/lib/rubocop/cop/style/safe_navigation.rb +32 -5
  390. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  391. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  392. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  393. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  394. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  395. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  396. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  397. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  398. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  399. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  400. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  401. data/lib/rubocop/cop/style/sole_nested_conditional.rb +40 -106
  402. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  403. data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
  404. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  405. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  406. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  407. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  408. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  409. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  410. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  411. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  412. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  413. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  414. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  415. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  416. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  417. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  418. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  419. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  420. data/lib/rubocop/cop/util.rb +12 -5
  421. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  422. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  423. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  424. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  425. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  426. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  427. data/lib/rubocop/cop/variable_force.rb +5 -11
  428. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  429. data/lib/rubocop/directive_comment.rb +45 -11
  430. data/lib/rubocop/ext/regexp_node.rb +0 -1
  431. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -2
  432. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  433. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  434. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  435. data/lib/rubocop/lsp/logger.rb +2 -2
  436. data/lib/rubocop/lsp/routes.rb +7 -23
  437. data/lib/rubocop/lsp/runtime.rb +18 -50
  438. data/lib/rubocop/lsp/server.rb +0 -2
  439. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  440. data/lib/rubocop/magic_comment.rb +11 -3
  441. data/lib/rubocop/options.rb +28 -12
  442. data/lib/rubocop/path_util.rb +15 -8
  443. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  444. data/lib/rubocop/plugin/load_error.rb +26 -0
  445. data/lib/rubocop/plugin/loader.rb +100 -0
  446. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  447. data/lib/rubocop/plugin.rb +46 -0
  448. data/lib/rubocop/rake_task.rb +4 -1
  449. data/lib/rubocop/result_cache.rb +13 -13
  450. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  451. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  452. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  453. data/lib/rubocop/rspec/support.rb +4 -2
  454. data/lib/rubocop/runner.rb +26 -15
  455. data/lib/rubocop/server/cache.rb +47 -11
  456. data/lib/rubocop/server/cli.rb +2 -2
  457. data/lib/rubocop/target_finder.rb +7 -2
  458. data/lib/rubocop/target_ruby.rb +17 -2
  459. data/lib/rubocop/version.rb +53 -12
  460. data/lib/rubocop.rb +32 -1
  461. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  462. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  463. metadata +78 -16
  464. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  465. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -59,7 +59,6 @@ module RuboCop
59
59
  # end
60
60
  #
61
61
  class IfInsideElse < Base
62
- include IgnoredNode
63
62
  include RangeHelp
64
63
  extend AutoCorrector
65
64
 
@@ -98,34 +97,31 @@ module RuboCop
98
97
  else
99
98
  correct_to_elsif_from_if_inside_else_form(corrector, node, node.condition)
100
99
  end
101
-
102
- corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
103
- return unless (if_branch = node.if_branch)
104
-
105
- range = range_by_whole_lines(if_branch.source_range, include_final_newline: true)
106
- corrector.remove(range)
107
100
  end
108
101
 
109
102
  def correct_to_elsif_from_modifier_form(corrector, node)
110
- corrector.replace(node.parent.loc.else, <<~RUBY.chop)
111
- elsif #{node.condition.source}
112
- #{indent(node.if_branch)}#{node.if_branch.source}
113
- end
114
- RUBY
103
+ corrector.replace(node.parent.loc.else, "elsif #{node.condition.source}")
104
+
105
+ condition_range = range_between(
106
+ node.if_branch.source_range.end_pos, node.condition.source_range.end_pos
107
+ )
108
+ corrector.remove(condition_range)
115
109
  end
116
110
 
117
- def correct_to_elsif_from_if_inside_else_form(corrector, node, condition)
111
+ def correct_to_elsif_from_if_inside_else_form(corrector, node, condition) # rubocop:disable Metrics/AbcSize
118
112
  corrector.replace(node.parent.loc.else, "elsif #{condition.source}")
119
113
 
120
114
  if_condition_range = if_condition_range(node, condition)
121
115
 
122
116
  if (if_branch = node.if_branch)
123
- corrector.replace(if_condition_range, if_branch.source)
117
+ corrector.replace(if_condition_range, range_with_comments(if_branch).source)
118
+ corrector.remove(range_with_comments_and_lines(if_branch))
124
119
  else
125
120
  corrector.remove(range_by_whole_lines(if_condition_range, include_final_newline: true))
126
121
  end
127
122
 
128
123
  corrector.remove(condition)
124
+ corrector.remove(range_by_whole_lines(find_end_range(node), include_final_newline: true))
129
125
  end
130
126
 
131
127
  def then?(node)
@@ -103,7 +103,7 @@ module RuboCop
103
103
 
104
104
  def defined_argument_is_undefined?(if_node, defined_node)
105
105
  defined_argument = defined_node.first_argument
106
- return false unless defined_argument.lvar_type? || defined_argument.send_type?
106
+ return false unless defined_argument.type?(:lvar, :send)
107
107
 
108
108
  if_node.left_siblings.none? do |sibling|
109
109
  sibling.respond_to?(:lvasgn_type?) && sibling.lvasgn_type? &&
@@ -112,11 +112,11 @@ module RuboCop
112
112
  end
113
113
 
114
114
  def pattern_matching_nodes(condition)
115
- if condition.match_pattern_type? || condition.match_pattern_p_type?
115
+ if condition.type?(:match_pattern, :match_pattern_p)
116
116
  [condition]
117
117
  else
118
118
  condition.each_descendant.select do |node|
119
- node.match_pattern_type? || node.match_pattern_p_type?
119
+ node.type?(:match_pattern, :match_pattern_p)
120
120
  end
121
121
  end
122
122
  end
@@ -164,8 +164,8 @@ module RuboCop
164
164
 
165
165
  def too_long_due_to_comment_after_modifier?(node, comment)
166
166
  source_length = processed_source.lines[node.first_line - 1].length
167
- source_length >= max_line_length &&
168
- source_length - comment.source_range.length <= max_line_length
167
+
168
+ max_line_length.between?(source_length - comment.source_range.length, source_length)
169
169
  end
170
170
 
171
171
  def allowed_patterns
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # `nonzero?` method is allowed by default.
11
11
  # These are customizable with `AllowedMethods` option.
12
12
  #
13
- # This cop targets only `if`s with a single `elsif` or `else` branch. The following
13
+ # This cop targets only ``if``s with a single `elsif` or `else` branch. The following
14
14
  # code will be allowed, because it has two `elsif` branches:
15
15
  #
16
16
  # [source,ruby]
@@ -67,7 +67,7 @@ module RuboCop
67
67
 
68
68
  # @!method if_with_boolean_literal_branches?(node)
69
69
  def_node_matcher :if_with_boolean_literal_branches?, <<~PATTERN
70
- (if #return_boolean_value? {(true) (false) | (false) (true)})
70
+ (if #return_boolean_value? <true false>)
71
71
  PATTERN
72
72
  # @!method double_negative?(node)
73
73
  def_node_matcher :double_negative?, '(send (send _ :!) :!)'
@@ -155,8 +155,7 @@ module RuboCop
155
155
  end
156
156
 
157
157
  def require_parentheses?(condition)
158
- condition.and_type? || condition.or_type? ||
159
- (condition.send_type? && condition.comparison_method?)
158
+ condition.operator_keyword? || (condition.send_type? && condition.comparison_method?)
160
159
  end
161
160
  end
162
161
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
 
24
24
  def on_normal_if_unless(node)
25
25
  return if node.parent&.if_type?
26
+ return if part_of_ignored_node?(node)
26
27
 
27
28
  beginning = node.loc.begin
28
29
  return unless beginning&.is?(';')
@@ -32,16 +33,17 @@ module RuboCop
32
33
  add_offense(node, message: message) do |corrector|
33
34
  autocorrect(corrector, node)
34
35
  end
36
+
37
+ ignore_node(node)
35
38
  end
36
39
 
37
40
  private
38
41
 
39
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
40
42
  def message(node)
41
- template = if node.if_branch&.begin_type?
43
+ template = if require_newline?(node)
42
44
  MSG_NEWLINE
43
- elsif node.else_branch&.if_type? || node.else_branch&.begin_type? ||
44
- use_block_in_branches?(node)
45
+ elsif node.else_branch&.type?(:if, :begin) ||
46
+ use_masgn_or_block_in_branches?(node)
45
47
  MSG_IF_ELSE
46
48
  else
47
49
  MSG_TERNARY
@@ -49,18 +51,27 @@ module RuboCop
49
51
 
50
52
  format(template, expr: node.condition.source)
51
53
  end
52
- # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
53
54
 
54
55
  def autocorrect(corrector, node)
55
- if node.branches.compact.any?(&:begin_type?) || use_block_in_branches?(node)
56
+ if require_newline?(node) || use_masgn_or_block_in_branches?(node)
56
57
  corrector.replace(node.loc.begin, "\n")
57
58
  else
58
59
  corrector.replace(node, replacement(node))
59
60
  end
60
61
  end
61
62
 
62
- def use_block_in_branches?(node)
63
- node.branches.compact.any? { |branch| branch.block_type? || branch.numblock_type? }
63
+ def require_newline?(node)
64
+ node.branches.compact.any?(&:begin_type?) || use_return_with_argument?(node)
65
+ end
66
+
67
+ def use_masgn_or_block_in_branches?(node)
68
+ node.branches.compact.any? do |branch|
69
+ branch.type?(:masgn, :any_block)
70
+ end
71
+ end
72
+
73
+ def use_return_with_argument?(node)
74
+ node.if_branch&.return_type? && node.if_branch&.arguments&.any?
64
75
  end
65
76
 
66
77
  def replacement(node)
@@ -111,7 +122,7 @@ module RuboCop
111
122
  end
112
123
 
113
124
  def require_argument_parentheses?(node)
114
- return false unless node.call_type?
125
+ return false if !node.call_type? || node.arithmetic_operation?
115
126
 
116
127
  !node.parenthesized? && node.arguments.any? && !node.method?(:[]) && !node.method?(:[]=)
117
128
  end
@@ -68,7 +68,7 @@ module RuboCop
68
68
  end
69
69
 
70
70
  def autocorrect(corrector, node)
71
- if node.while_post_type? || node.until_post_type?
71
+ if node.type?(:while_post, :until_post)
72
72
  replace_begin_end_with_modifier(corrector, node)
73
73
  elsif node.modifier_form?
74
74
  replace_source(corrector, node.source_range, modifier_replacement(node))
@@ -41,12 +41,12 @@ module RuboCop
41
41
  # f != 1
42
42
  # end
43
43
  class InverseMethods < Base
44
- include IgnoredNode
45
44
  include RangeHelp
46
45
  extend AutoCorrector
47
46
 
48
47
  MSG = 'Use `%<inverse>s` instead of inverting `%<method>s`.'
49
48
  CLASS_COMPARISON_METHODS = %i[<= >= < >].freeze
49
+ SAFE_NAVIGATION_INCOMPATIBLE_METHODS = (CLASS_COMPARISON_METHODS + %i[any? none?]).freeze
50
50
  EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
51
51
  NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
52
52
  CAMEL_CASE = /[A-Z]+[a-z]+/.freeze
@@ -61,24 +61,24 @@ module RuboCop
61
61
  def_node_matcher :inverse_candidate?, <<~PATTERN
62
62
  {
63
63
  (send $(call $(...) $_ $...) :!)
64
- (send ({block numblock} $(call $(...) $_) $...) :!)
64
+ (send (any_block $(call $(...) $_) $...) :!)
65
65
  (send (begin $(call $(...) $_ $...)) :!)
66
66
  }
67
67
  PATTERN
68
68
 
69
69
  # @!method inverse_block?(node)
70
70
  def_node_matcher :inverse_block?, <<~PATTERN
71
- ({block numblock} $(call (...) $_) ... { $(call ... :!)
72
- $(send (...) {:!= :!~} ...)
73
- (begin ... $(call ... :!))
74
- (begin ... $(send (...) {:!= :!~} ...))
75
- })
71
+ (any_block $(call (...) $_) ... { $(call ... :!)
72
+ $(send (...) {:!= :!~} ...)
73
+ (begin ... $(call ... :!))
74
+ (begin ... $(send (...) {:!= :!~} ...))
75
+ })
76
76
  PATTERN
77
77
 
78
78
  def on_send(node)
79
79
  inverse_candidate?(node) do |method_call, lhs, method, rhs|
80
80
  return unless inverse_methods.key?(method)
81
- return if negated?(node) || relational_comparison_with_safe_navigation?(method_call)
81
+ return if negated?(node) || safe_navigation_incompatible?(method_call)
82
82
  return if part_of_ignored_node?(node)
83
83
  return if possible_class_hierarchy_check?(lhs, rhs, method)
84
84
 
@@ -106,6 +106,7 @@ module RuboCop
106
106
  end
107
107
 
108
108
  alias on_numblock on_block
109
+ alias on_itblock on_block
109
110
 
110
111
  private
111
112
 
@@ -155,10 +156,6 @@ module RuboCop
155
156
  node.parent.respond_to?(:method?) && node.parent.method?(:!)
156
157
  end
157
158
 
158
- def relational_comparison_with_safe_navigation?(node)
159
- node.csend_type? && CLASS_COMPARISON_METHODS.include?(node.method_name)
160
- end
161
-
162
159
  def not_to_receiver(node, method_call)
163
160
  node.loc.selector.begin.join(method_call.source_range.begin)
164
161
  end
@@ -167,6 +164,12 @@ module RuboCop
167
164
  method_call.source_range.end.join(node.source_range.end)
168
165
  end
169
166
 
167
+ def safe_navigation_incompatible?(node)
168
+ return false unless node.csend_type?
169
+
170
+ SAFE_NAVIGATION_INCOMPATIBLE_METHODS.include?(node.method_name)
171
+ end
172
+
170
173
  # When comparing classes, `!(Integer < Numeric)` is not the same as
171
174
  # `Integer > Numeric`.
172
175
  def possible_class_hierarchy_check?(lhs, rhs, method)
@@ -89,8 +89,8 @@ module RuboCop
89
89
 
90
90
  def inheritance_check?(node)
91
91
  argument = node.first_argument
92
- node.method?(:<) &&
93
- (argument.const_type? && argument.short_name.to_s.upcase != argument.short_name.to_s)
92
+ node.method?(:<) && argument.const_type? &&
93
+ argument.short_name.to_s.upcase != argument.short_name.to_s
94
94
  end
95
95
 
96
96
  def preferred_condition(node)
@@ -32,7 +32,7 @@ module RuboCop
32
32
 
33
33
  # To try to avoid doing two regex checks on every string,
34
34
  # shortcut out if the string does not look like an IP address
35
- return false unless could_be_ip?(contents)
35
+ return false unless potential_ip?(contents)
36
36
 
37
37
  ::Resolv::IPv4::Regex.match?(contents) || ::Resolv::IPv6::Regex.match?(contents)
38
38
  end
@@ -52,7 +52,7 @@ module RuboCop
52
52
  Array(allowed_addresses).map(&:downcase)
53
53
  end
54
54
 
55
- def could_be_ip?(str)
55
+ def potential_ip?(str)
56
56
  # If the string is too long, it can't be an IP
57
57
  return false if too_long?(str)
58
58
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for assignments to a local `it` variable inside a block
7
+ # where `it` can refer to the first anonymous parameter as of Ruby 3.4.
8
+ #
9
+ # Although Ruby allows reassigning `it` in these cases, it could
10
+ # cause confusion if `it` is used as a block parameter elsewhere.
11
+ # For consistency, this also applies to numblocks and blocks with
12
+ # parameters, even though `it` cannot be used in those cases.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # foo { it = 5 }
17
+ # foo { |bar| it = bar }
18
+ # foo { it = _2 }
19
+ #
20
+ # # good - use a different variable name
21
+ # foo { var = 5 }
22
+ # foo { |bar| var = bar }
23
+ # foo { bar = _2 }
24
+ class ItAssignment < Base
25
+ MSG = '`it` is the default block parameter; consider another name.'
26
+
27
+ def on_lvasgn(node)
28
+ return unless node.name == :it
29
+ return unless node.each_ancestor(:any_block).any?
30
+
31
+ add_offense(node.loc.name)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for blocks with one argument where `it` block parameter can be used.
7
+ #
8
+ # It provides three `EnforcedStyle` options:
9
+ #
10
+ # 1. `only_numbered_parameters` (default) ... Detects only numbered block parameters.
11
+ # 2. `always` ... Always uses the `it` block parameter.
12
+ # 3. `disallow` ... Disallows the `it` block parameter.
13
+ #
14
+ # A single numbered parameter is detected when `only_numbered_parameters` or `always`.
15
+ #
16
+ # @example EnforcedStyle: only_numbered_parameters (default)
17
+ # # bad
18
+ # block { do_something(_1) }
19
+ #
20
+ # # good
21
+ # block { do_something(it) }
22
+ # block { |named_param| do_something(named_param) }
23
+ #
24
+ # @example EnforcedStyle: always
25
+ # # bad
26
+ # block { do_something(_1) }
27
+ # block { |named_param| do_something(named_param) }
28
+ #
29
+ # # good
30
+ # block { do_something(it) }
31
+ #
32
+ # @example EnforcedStyle: disallow
33
+ # # bad
34
+ # block { do_something(it) }
35
+ #
36
+ # # good
37
+ # block { do_something(_1) }
38
+ # block { |named_param| do_something(named_param) }
39
+ #
40
+ class ItBlockParameter < Base
41
+ include ConfigurableEnforcedStyle
42
+ extend TargetRubyVersion
43
+ extend AutoCorrector
44
+
45
+ MSG_USE_IT_BLOCK_PARAMETER = 'Use `it` block parameter.'
46
+ MSG_AVOID_IT_BLOCK_PARAMETER = 'Avoid using `it` block parameter.'
47
+
48
+ minimum_target_ruby_version 3.4
49
+
50
+ def on_block(node)
51
+ return unless style == :always
52
+ return unless node.arguments.one?
53
+
54
+ # `restarg`, `kwrestarg`, `blockarg` nodes can return early.
55
+ return unless node.first_argument.arg_type?
56
+
57
+ variables = find_block_variables(node, node.first_argument.source)
58
+
59
+ variables.each do |variable|
60
+ add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
61
+ corrector.remove(node.arguments)
62
+ corrector.replace(variable, 'it')
63
+ end
64
+ end
65
+ end
66
+
67
+ def on_numblock(node)
68
+ return if style == :disallow
69
+ return unless node.children[1] == 1
70
+
71
+ variables = find_block_variables(node, '_1')
72
+
73
+ variables.each do |variable|
74
+ add_offense(variable, message: MSG_USE_IT_BLOCK_PARAMETER) do |corrector|
75
+ corrector.replace(variable, 'it')
76
+ end
77
+ end
78
+ end
79
+
80
+ def on_itblock(node)
81
+ return unless style == :disallow
82
+
83
+ variables = find_block_variables(node, 'it')
84
+
85
+ variables.each do |variable|
86
+ add_offense(variable, message: MSG_AVOID_IT_BLOCK_PARAMETER)
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ def find_block_variables(node, block_argument_name)
93
+ node.each_descendant(:lvar).select do |descendant|
94
+ descendant.source == block_argument_name
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # When passing an existing hash as keyword arguments, provide additional arguments
7
+ # directly rather than using `merge`.
8
+ #
9
+ # Providing arguments directly is more performant than using `merge`, and
10
+ # also leads to shorter and simpler code.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # some_method(**opts.merge(foo: true))
15
+ # some_method(**opts.merge(other_opts))
16
+ #
17
+ # # good
18
+ # some_method(**opts, foo: true)
19
+ # some_method(**opts, **other_opts)
20
+ #
21
+ class KeywordArgumentsMerging < Base
22
+ extend AutoCorrector
23
+
24
+ MSG = 'Provide additional arguments directly rather than using `merge`.'
25
+
26
+ # @!method merge_kwargs?(node)
27
+ def_node_matcher :merge_kwargs?, <<~PATTERN
28
+ (send _ _
29
+ ...
30
+ (hash
31
+ (kwsplat
32
+ $(send $_ :merge $...))
33
+ ...))
34
+ PATTERN
35
+
36
+ def on_kwsplat(node)
37
+ return unless (ancestor = node.parent&.parent)
38
+
39
+ merge_kwargs?(ancestor) do |merge_node, hash_node, other_hash_node|
40
+ add_offense(merge_node) do |corrector|
41
+ autocorrect(corrector, node, hash_node, other_hash_node)
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def autocorrect(corrector, kwsplat_node, hash_node, other_hash_node)
49
+ other_hash_node_replacement =
50
+ other_hash_node.map do |node|
51
+ if node.hash_type?
52
+ if node.braces?
53
+ node.source[1...-1]
54
+ else
55
+ node.source
56
+ end
57
+ else
58
+ "**#{node.source}"
59
+ end
60
+ end.join(', ')
61
+
62
+ corrector.replace(kwsplat_node, "**#{hash_node.source}, #{other_hash_node_replacement}")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -42,22 +42,28 @@ module RuboCop
42
42
  return if kwarg_nodes.empty?
43
43
 
44
44
  add_offense(node) do |corrector|
45
- if node.parent.find(&:kwoptarg_type?) == node
46
- corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
45
+ defining_node = node.each_ancestor(:any_def, :block).first
46
+ next if processed_source.contains_comment?(arguments_range(defining_node))
47
+ next unless node.parent.find(&:kwoptarg_type?) == node
47
48
 
48
- arguments = node.each_ancestor(:def, :defs, :block).first.arguments
49
- append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
50
-
51
- remove_kwargs(kwarg_nodes, corrector)
52
- end
49
+ autocorrect(corrector, node, defining_node, kwarg_nodes)
53
50
  end
54
51
  end
55
52
 
56
53
  private
57
54
 
55
+ def autocorrect(corrector, node, defining_node, kwarg_nodes)
56
+ corrector.insert_before(node, "#{kwarg_nodes.map(&:source).join(', ')}, ")
57
+
58
+ arguments = defining_node.arguments
59
+ append_newline_to_last_kwoptarg(arguments, corrector) unless parentheses?(arguments)
60
+
61
+ remove_kwargs(kwarg_nodes, corrector)
62
+ end
63
+
58
64
  def append_newline_to_last_kwoptarg(arguments, corrector)
59
65
  last_argument = arguments.last
60
- return if last_argument.kwrestarg_type? || last_argument.blockarg_type?
66
+ return if last_argument.type?(:kwrestarg, :blockarg)
61
67
 
62
68
  last_kwoptarg = arguments.reverse.find(&:kwoptarg_type?)
63
69
  corrector.insert_after(last_kwoptarg, "\n") unless arguments.parent.block_type?
@@ -77,6 +77,7 @@ module RuboCop
77
77
  end
78
78
  end
79
79
  alias on_numblock on_block
80
+ alias on_itblock on_block
80
81
 
81
82
  private
82
83
 
@@ -20,7 +20,6 @@ module RuboCop
20
20
  # lambda.(x, y)
21
21
  class LambdaCall < Base
22
22
  include ConfigurableEnforcedStyle
23
- include IgnoredNode
24
23
  extend AutoCorrector
25
24
 
26
25
  MSG = 'Prefer the use of `%<prefer>s` over `%<current>s`.'
@@ -45,6 +44,7 @@ module RuboCop
45
44
  correct_style_detected
46
45
  end
47
46
  end
47
+ alias on_csend on_send
48
48
 
49
49
  private
50
50
 
@@ -54,10 +54,16 @@ module RuboCop
54
54
 
55
55
  def prefer(node)
56
56
  receiver = node.receiver.source
57
- arguments = node.arguments.map(&:source).join(', ')
58
- method = explicit_style? ? "call(#{arguments})" : "(#{arguments})"
57
+ dot = node.loc.dot.source
58
+ call_arguments = if node.arguments.empty?
59
+ ''
60
+ else
61
+ arguments = node.arguments.map(&:source).join(', ')
62
+ "(#{arguments})"
63
+ end
64
+ method = explicit_style? ? "call#{call_arguments}" : "(#{arguments})"
59
65
 
60
- "#{receiver}.#{method}"
66
+ "#{receiver}#{dot}#{method}"
61
67
  end
62
68
 
63
69
  def implicit_style?
@@ -36,7 +36,7 @@ module RuboCop
36
36
  include RangeHelp
37
37
  extend AutoCorrector
38
38
 
39
- MSG = 'Use `\\` instead of `+` or `<<` to concatenate those strings.'
39
+ MSG = 'Use `\\` instead of `%<operator>s` to concatenate multiline strings.'
40
40
  CONCAT_TOKEN_TYPES = %i[tPLUS tLSHFT].freeze
41
41
  SIMPLE_STRING_TOKEN_TYPE = :tSTRING
42
42
  COMPLEX_STRING_BEGIN_TOKEN = :tSTRING_BEG
@@ -61,14 +61,20 @@ module RuboCop
61
61
  successor = tokens[index + 2]
62
62
 
63
63
  return unless eligible_token_set?(predecessor, operator, successor)
64
-
65
64
  return if same_line?(operator, successor)
66
65
 
67
66
  next_successor = token_after_last_string(successor, index)
68
-
69
67
  return unless eligible_next_successor?(next_successor)
70
68
 
71
- add_offense(operator.pos) { |corrector| autocorrect(corrector, operator.pos) }
69
+ register_offense(operator)
70
+ end
71
+
72
+ def register_offense(operator)
73
+ message = format(MSG, operator: operator.text)
74
+
75
+ add_offense(operator.pos, message: message) do |corrector|
76
+ autocorrect(corrector, operator.pos)
77
+ end
72
78
  end
73
79
 
74
80
  def autocorrect(corrector, operator_range)
@@ -63,12 +63,17 @@ module RuboCop
63
63
 
64
64
  MSG = 'Use `%<new_method_name>s` instead of `each` to map elements into an array.'
65
65
 
66
+ # @!method suitable_argument_node?(node)
67
+ def_node_matcher :suitable_argument_node?, <<-PATTERN
68
+ !{splat forwarded-restarg forwarded-args (hash (forwarded-kwrestarg)) (block-pass nil?)}
69
+ PATTERN
70
+
66
71
  # @!method each_block_with_push?(node)
67
72
  def_node_matcher :each_block_with_push?, <<-PATTERN
68
73
  [
69
74
  ^({begin kwbegin block} ...)
70
- ({block numblock} (send !{nil? self} :each) _
71
- (send (lvar _) {:<< :push :append} {send lvar begin}))
75
+ (any_block (send !{nil? self} :each) _
76
+ (send (lvar _) {:<< :push :append} #suitable_argument_node?))
72
77
  ]
73
78
  PATTERN
74
79
 
@@ -122,6 +127,7 @@ module RuboCop
122
127
  end
123
128
 
124
129
  alias on_numblock on_block
130
+ alias on_itblock on_block
125
131
 
126
132
  private
127
133
 
@@ -206,9 +212,11 @@ module RuboCop
206
212
  end
207
213
 
208
214
  def correct_push_node(corrector, push_node)
215
+ arg_node = push_node.first_argument
209
216
  range = push_node.source_range
210
- arg_range = push_node.first_argument.source_range
217
+ arg_range = arg_node.source_range
211
218
 
219
+ corrector.wrap(arg_node, '{ ', ' }') if arg_node.hash_type? && !arg_node.braces?
212
220
  corrector.remove(range_between(range.begin_pos, arg_range.begin_pos))
213
221
  corrector.remove(range_between(arg_range.end_pos, range.end_pos))
214
222
  end
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # @!method map_to_h(node)
41
41
  def_node_matcher :map_to_h, <<~PATTERN
42
42
  {
43
- $(call ({block numblock} $(call _ {:map :collect}) ...) :to_h)
43
+ $(call (any_block $(call _ {:map :collect}) ...) :to_h)
44
44
  $(call $(call _ {:map :collect} (block_pass sym)) :to_h)
45
45
  }
46
46
  PATTERN