rubocop 1.67.0 → 1.79.1

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 (512) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +371 -71
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  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 +13 -2
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +53 -47
  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 +51 -26
  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/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  31. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  32. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  33. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  34. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  35. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  36. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  37. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  38. data/lib/rubocop/cop/generator.rb +6 -0
  39. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  40. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  41. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  42. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  43. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  44. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  46. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  48. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  49. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  50. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  51. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  52. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  54. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  55. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  56. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  57. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  58. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  59. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  60. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  61. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  62. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  63. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  64. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  65. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  66. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  67. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  68. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  69. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  70. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  71. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  72. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  73. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  74. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  75. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  76. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +99 -0
  77. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  78. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  79. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  81. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  82. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  83. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  84. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  85. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  86. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  87. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  88. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  89. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  90. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  91. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  92. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  93. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  94. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  95. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  96. data/lib/rubocop/cop/layout/line_length.rb +149 -9
  97. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  98. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  99. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  100. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  101. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  102. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  103. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  104. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  105. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  106. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  107. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  108. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  109. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  110. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  113. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  114. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  115. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  116. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  117. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  118. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  119. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  121. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  122. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  123. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  124. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  125. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  126. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  127. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  128. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  129. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  130. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  131. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  132. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  133. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  134. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  135. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  136. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  137. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  138. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  139. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  140. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  141. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  142. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  143. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  144. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  145. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  146. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  147. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  148. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  149. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  150. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  151. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  152. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  153. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  154. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  155. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  156. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  157. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  158. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  159. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  160. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  161. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  162. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  163. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  164. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  165. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  166. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  167. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  168. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  169. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  170. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  171. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  172. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  173. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  174. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  175. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  176. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  177. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  178. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  179. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  180. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  181. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  182. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  183. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  184. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  185. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  186. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  187. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  188. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  189. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  190. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  191. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  192. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  193. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  194. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  195. data/lib/rubocop/cop/lint/self_assignment.rb +33 -10
  196. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  197. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  198. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  199. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  200. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  201. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  202. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  203. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  204. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  205. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  206. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  207. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  208. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  209. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  210. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  211. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  212. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  213. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  214. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  215. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  216. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  217. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  218. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  219. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  220. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  221. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  222. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  223. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  224. data/lib/rubocop/cop/lint/void.rb +16 -12
  225. data/lib/rubocop/cop/message_annotator.rb +7 -3
  226. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  227. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  228. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  229. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  230. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  231. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  232. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  233. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  234. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  235. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  236. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  237. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  238. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  239. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  240. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  241. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  242. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  243. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  244. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  245. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  246. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  247. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  248. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  249. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  250. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  251. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  252. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  253. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  254. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  255. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  256. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  257. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  258. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  259. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  260. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  261. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  262. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  263. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  264. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  265. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  266. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  267. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  268. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  269. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  270. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  271. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  272. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  273. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  274. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  275. data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
  276. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  277. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  278. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  279. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  280. data/lib/rubocop/cop/offense.rb +2 -3
  281. data/lib/rubocop/cop/registry.rb +9 -6
  282. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  283. data/lib/rubocop/cop/security/eval.rb +2 -1
  284. data/lib/rubocop/cop/security/open.rb +1 -0
  285. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  286. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  287. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  288. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  289. data/lib/rubocop/cop/style/and_or.rb +1 -1
  290. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  291. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  292. data/lib/rubocop/cop/style/array_intersect.rb +84 -42
  293. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  294. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  295. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  296. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  297. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  298. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  299. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  300. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  301. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  302. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  303. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  304. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  305. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  306. data/lib/rubocop/cop/style/conditional_assignment.rb +42 -28
  307. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  308. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  309. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  310. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  311. data/lib/rubocop/cop/style/documentation.rb +1 -1
  312. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  313. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  314. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  315. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  316. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  317. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  318. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  319. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  320. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  321. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  322. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  323. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  324. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  325. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  326. data/lib/rubocop/cop/style/file_null.rb +89 -0
  327. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  328. data/lib/rubocop/cop/style/float_division.rb +8 -4
  329. data/lib/rubocop/cop/style/for.rb +1 -1
  330. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  331. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  332. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  333. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  334. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  335. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  336. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  337. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  338. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  339. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  340. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  341. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  342. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  343. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  344. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  345. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  346. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  347. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  348. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  349. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  350. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  351. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  352. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  353. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  354. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  355. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  356. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  357. data/lib/rubocop/cop/style/lambda.rb +1 -0
  358. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  359. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  360. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  361. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  362. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  363. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  364. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  365. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  366. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  367. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  368. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  369. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  370. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  371. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  372. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  373. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  374. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  375. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  376. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  377. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  378. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  379. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  380. data/lib/rubocop/cop/style/next.rb +44 -0
  381. data/lib/rubocop/cop/style/not.rb +1 -1
  382. data/lib/rubocop/cop/style/object_then.rb +15 -15
  383. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  384. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  385. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  386. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  387. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  388. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  389. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  390. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  391. data/lib/rubocop/cop/style/proc.rb +2 -2
  392. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  393. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  394. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  395. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  396. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  397. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  398. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  399. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  400. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  401. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  402. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  403. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  404. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  405. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  406. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  407. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  408. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  409. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  410. data/lib/rubocop/cop/style/redundant_parentheses.rb +86 -26
  411. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  412. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  413. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  414. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  415. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  416. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  417. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  418. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  419. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  420. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  421. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  422. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  423. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  424. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  425. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  426. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  427. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  428. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  429. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  430. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  431. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  432. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  433. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  434. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  435. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  436. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  437. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  438. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  439. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  440. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  441. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  442. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  443. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  444. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  445. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  446. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  447. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  448. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  449. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  450. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  451. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  452. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  453. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  454. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  455. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  456. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  457. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  458. data/lib/rubocop/cop/team.rb +1 -1
  459. data/lib/rubocop/cop/util.rb +12 -5
  460. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  461. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  462. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  463. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  464. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  465. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  466. data/lib/rubocop/cop/variable_force.rb +23 -18
  467. data/lib/rubocop/cops_documentation_generator.rb +51 -25
  468. data/lib/rubocop/directive_comment.rb +45 -11
  469. data/lib/rubocop/ext/regexp_node.rb +0 -1
  470. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  471. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  472. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  473. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  474. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  475. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  476. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  477. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  478. data/lib/rubocop/lsp/logger.rb +2 -2
  479. data/lib/rubocop/lsp/routes.rb +10 -26
  480. data/lib/rubocop/lsp/runtime.rb +18 -50
  481. data/lib/rubocop/lsp/server.rb +0 -2
  482. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  483. data/lib/rubocop/magic_comment.rb +11 -3
  484. data/lib/rubocop/options.rb +28 -12
  485. data/lib/rubocop/path_util.rb +15 -8
  486. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  487. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  488. data/lib/rubocop/plugin/load_error.rb +26 -0
  489. data/lib/rubocop/plugin/loader.rb +100 -0
  490. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  491. data/lib/rubocop/plugin.rb +46 -0
  492. data/lib/rubocop/rake_task.rb +4 -1
  493. data/lib/rubocop/result_cache.rb +13 -13
  494. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  495. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  496. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  497. data/lib/rubocop/rspec/support.rb +4 -2
  498. data/lib/rubocop/runner.rb +26 -15
  499. data/lib/rubocop/server/cache.rb +51 -13
  500. data/lib/rubocop/server/cli.rb +2 -2
  501. data/lib/rubocop/server/client_command/base.rb +10 -0
  502. data/lib/rubocop/server/client_command/exec.rb +2 -1
  503. data/lib/rubocop/server/client_command/start.rb +11 -1
  504. data/lib/rubocop/target_finder.rb +7 -2
  505. data/lib/rubocop/target_ruby.rb +17 -2
  506. data/lib/rubocop/version.rb +53 -12
  507. data/lib/rubocop.rb +43 -2
  508. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  509. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  510. metadata +89 -17
  511. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  512. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -28,19 +28,16 @@ module RuboCop
28
28
 
29
29
  MSG = 'Avoid modifier `%<keyword>s` after another conditional.'
30
30
 
31
+ # rubocop:disable Metrics/AbcSize
31
32
  def on_if(node)
32
33
  return unless node.modifier_form? && node.body.if_type?
33
34
 
34
35
  add_offense(node.loc.keyword, message: format(MSG, keyword: node.keyword)) do |corrector|
35
- keyword = node.if? ? 'if' : 'unless'
36
-
37
- corrector.replace(node, <<~RUBY.chop)
38
- #{keyword} #{node.condition.source}
39
- #{node.if_branch.source}
40
- end
41
- RUBY
36
+ corrector.wrap(node.if_branch, "#{node.keyword} #{node.condition.source}\n", "\nend")
37
+ corrector.remove(node.if_branch.source_range.end.join(node.condition.source_range.end))
42
38
  end
43
39
  end
40
+ # rubocop:enable Metrics/AbcSize
44
41
  end
45
42
  end
46
43
  end
@@ -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))
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Check for usages of not (`not` or `!`) called on a method
6
+ # Checks for usages of not (`not` or `!`) called on a method
7
7
  # when an inverse of that method can be used instead.
8
8
  #
9
9
  # Methods that can be inverted by a not (`not` or `!`) should be defined
@@ -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,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for local variables and method parameters named `it`,
7
+ # where `it` can refer to the first anonymous parameter as of Ruby 3.4.
8
+ # Use a meaningful variable name instead.
9
+ #
10
+ # NOTE: Although Ruby allows reassigning `it` in these cases, it could
11
+ # cause confusion if `it` is used as a block parameter elsewhere.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # it = 5
16
+ #
17
+ # # good
18
+ # var = 5
19
+ #
20
+ # # bad
21
+ # def foo(it)
22
+ # end
23
+ #
24
+ # # good
25
+ # def foo(arg)
26
+ # end
27
+ #
28
+ # # bad
29
+ # def foo(it = 5)
30
+ # end
31
+ #
32
+ # # good
33
+ # def foo(arg = 5)
34
+ # end
35
+ #
36
+ # # bad
37
+ # def foo(*it)
38
+ # end
39
+ #
40
+ # # good
41
+ # def foo(*args)
42
+ # end
43
+ #
44
+ # # bad
45
+ # def foo(it:)
46
+ # end
47
+ #
48
+ # # good
49
+ # def foo(arg:)
50
+ # end
51
+ #
52
+ # # bad
53
+ # def foo(it: 5)
54
+ # end
55
+ #
56
+ # # good
57
+ # def foo(arg: 5)
58
+ # end
59
+ #
60
+ # # bad
61
+ # def foo(**it)
62
+ # end
63
+ #
64
+ # # good
65
+ # def foo(**kwargs)
66
+ # end
67
+ #
68
+ # # bad
69
+ # def foo(&it)
70
+ # end
71
+ #
72
+ # # good
73
+ # def foo(&block)
74
+ # end
75
+ class ItAssignment < Base
76
+ MSG = '`it` is the default block parameter; consider another name.'
77
+
78
+ def on_lvasgn(node)
79
+ return unless node.name == :it
80
+
81
+ add_offense(node.loc.name)
82
+ end
83
+ alias on_arg on_lvasgn
84
+ alias on_optarg on_lvasgn
85
+ alias on_restarg on_lvasgn
86
+ alias on_blockarg on_lvasgn
87
+ alias on_kwarg on_lvasgn
88
+ alias on_kwoptarg on_lvasgn
89
+ alias on_kwrestarg on_lvasgn
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,121 @@
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 four `EnforcedStyle` options:
9
+ #
10
+ # 1. `allow_single_line` (default) ... Always uses the `it` block parameter in a single line.
11
+ # 2. `only_numbered_parameters` ... Detects only numbered block parameters.
12
+ # 3. `always` ... Always uses the `it` block parameter.
13
+ # 4. `disallow` ... Disallows the `it` block parameter.
14
+ #
15
+ # A single numbered parameter is detected when `allow_single_line`,
16
+ # `only_numbered_parameters`, or `always`.
17
+ #
18
+ # @example EnforcedStyle: allow_single_line (default)
19
+ # # bad
20
+ # block do
21
+ # do_something(it)
22
+ # end
23
+ # block { do_something(_1) }
24
+ #
25
+ # # good
26
+ # block { do_something(it) }
27
+ # block { |named_param| do_something(named_param) }
28
+ #
29
+ # @example EnforcedStyle: only_numbered_parameters
30
+ # # bad
31
+ # block { do_something(_1) }
32
+ #
33
+ # # good
34
+ # block { do_something(it) }
35
+ # block { |named_param| do_something(named_param) }
36
+ #
37
+ # @example EnforcedStyle: always
38
+ # # bad
39
+ # block { do_something(_1) }
40
+ # block { |named_param| do_something(named_param) }
41
+ #
42
+ # # good
43
+ # block { do_something(it) }
44
+ #
45
+ # @example EnforcedStyle: disallow
46
+ # # bad
47
+ # block { do_something(it) }
48
+ #
49
+ # # good
50
+ # block { do_something(_1) }
51
+ # block { |named_param| do_something(named_param) }
52
+ #
53
+ class ItBlockParameter < Base
54
+ include ConfigurableEnforcedStyle
55
+ extend TargetRubyVersion
56
+ extend AutoCorrector
57
+
58
+ MSG_USE_IT_PARAMETER = 'Use `it` block parameter.'
59
+ MSG_AVOID_IT_PARAMETER = 'Avoid using `it` block parameter.'
60
+ MSG_AVOID_IT_PARAMETER_MULTILINE = 'Avoid using `it` block parameter for multi-line blocks.'
61
+
62
+ minimum_target_ruby_version 3.4
63
+
64
+ def on_block(node)
65
+ return unless style == :always
66
+ return unless node.arguments.one?
67
+
68
+ # `restarg`, `kwrestarg`, `blockarg` nodes can return early.
69
+ return unless node.first_argument.arg_type?
70
+
71
+ variables = find_block_variables(node, node.first_argument.source)
72
+
73
+ variables.each do |variable|
74
+ add_offense(variable, message: MSG_USE_IT_PARAMETER) do |corrector|
75
+ corrector.remove(node.arguments)
76
+ corrector.replace(variable, 'it')
77
+ end
78
+ end
79
+ end
80
+
81
+ def on_numblock(node)
82
+ return if style == :disallow
83
+ return unless node.children[1] == 1
84
+
85
+ variables = find_block_variables(node, '_1')
86
+
87
+ variables.each do |variable|
88
+ add_offense(variable, message: MSG_USE_IT_PARAMETER) do |corrector|
89
+ corrector.replace(variable, 'it')
90
+ end
91
+ end
92
+ end
93
+
94
+ def on_itblock(node)
95
+ case style
96
+ when :allow_single_line
97
+ return if node.single_line?
98
+
99
+ add_offense(node, message: MSG_AVOID_IT_PARAMETER_MULTILINE)
100
+ when :disallow
101
+ variables = find_block_variables(node, 'it')
102
+
103
+ variables.each do |variable|
104
+ add_offense(variable, message: MSG_AVOID_IT_PARAMETER)
105
+ end
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ def find_block_variables(node, block_argument_name)
112
+ return [] unless node.body
113
+
114
+ node.body.each_descendant(:lvar).select do |descendant|
115
+ descendant.source == block_argument_name
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ 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)