rubocop 1.66.0 → 1.72.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 (434) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +160 -14
  5. data/config/internal_affairs.yml +11 -0
  6. data/lib/rubocop/cached_data.rb +12 -4
  7. data/lib/rubocop/cli/command/auto_generate_config.rb +6 -7
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  12. data/lib/rubocop/cli/command/version.rb +2 -2
  13. data/lib/rubocop/comment_config.rb +6 -10
  14. data/lib/rubocop/config.rb +21 -20
  15. data/lib/rubocop/config_loader.rb +62 -16
  16. data/lib/rubocop/config_loader_resolver.rb +36 -11
  17. data/lib/rubocop/config_validator.rb +25 -18
  18. data/lib/rubocop/cop/autocorrect_logic.rb +36 -19
  19. data/lib/rubocop/cop/base.rb +13 -3
  20. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  21. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  22. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  23. data/lib/rubocop/cop/bundler/gem_version.rb +1 -0
  24. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  25. data/lib/rubocop/cop/cop.rb +8 -0
  26. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  27. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  28. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  29. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  30. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  31. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  32. data/lib/rubocop/cop/generator.rb +6 -0
  33. data/lib/rubocop/cop/internal_affairs/cop_description.rb +0 -4
  34. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  35. data/lib/rubocop/cop/internal_affairs/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 +2 -2
  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 +229 -0
  43. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  45. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  46. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  47. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  48. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  49. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  50. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  51. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  52. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  53. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  54. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  55. data/lib/rubocop/cop/internal_affairs.rb +6 -0
  56. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  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/class_structure.rb +9 -9
  62. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  63. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  64. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  65. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  66. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  67. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
  68. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  69. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  70. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  71. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  72. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  73. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  74. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  75. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  76. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  77. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  78. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  79. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  80. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  81. data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
  82. data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
  83. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  84. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  85. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  86. data/lib/rubocop/cop/layout/line_length.rb +119 -4
  87. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  88. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  89. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  90. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  91. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  92. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  93. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  94. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
  95. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
  96. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  97. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  98. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  99. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  102. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  103. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
  104. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  105. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  108. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  109. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  110. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  111. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  112. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  113. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  114. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  115. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  116. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  117. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  118. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  119. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  120. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  121. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  122. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  123. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  124. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  125. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  126. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  127. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  128. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  129. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  130. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  131. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  132. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  133. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  134. data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
  135. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  136. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  137. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  138. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +11 -5
  139. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  140. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  141. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  142. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  143. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
  144. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  145. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
  146. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  147. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  148. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  149. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  150. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  151. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  152. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  153. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  154. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  155. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  156. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  157. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  158. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  159. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  160. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  161. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  162. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  163. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  164. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
  165. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  166. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  167. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  168. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  169. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  170. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  171. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  172. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  173. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  174. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  175. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  176. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
  177. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  178. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  179. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  180. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  181. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  182. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  183. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  184. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  185. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  186. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  187. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +74 -0
  188. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  189. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  190. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  191. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  192. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  193. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  194. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  195. data/lib/rubocop/cop/lint/void.rb +8 -11
  196. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  197. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  198. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  199. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  200. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  201. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  202. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  203. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  204. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  205. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  206. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  207. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  208. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
  209. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  210. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  211. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  212. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  213. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
  214. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  215. data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
  216. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  217. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  218. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  219. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  220. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  221. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  222. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  223. data/lib/rubocop/cop/mixin/range_help.rb +3 -4
  224. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  225. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  226. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  227. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  228. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  229. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  230. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  231. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  232. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  233. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  234. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  235. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  236. data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
  237. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  238. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  239. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  240. data/lib/rubocop/cop/offense.rb +4 -5
  241. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  242. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  243. data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
  244. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  245. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  246. data/lib/rubocop/cop/style/and_or.rb +1 -1
  247. data/lib/rubocop/cop/style/arguments_forwarding.rb +78 -22
  248. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  249. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  250. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  251. data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
  252. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  253. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  254. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  255. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  256. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  257. data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
  258. data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
  259. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  260. data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
  261. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  262. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  263. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  264. data/lib/rubocop/cop/style/documentation.rb +1 -1
  265. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  266. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  267. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  268. data/lib/rubocop/cop/style/empty_else.rb +5 -2
  269. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  270. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  271. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  272. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  273. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  274. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  275. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  276. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  277. data/lib/rubocop/cop/style/file_null.rb +89 -0
  278. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  279. data/lib/rubocop/cop/style/float_division.rb +8 -4
  280. data/lib/rubocop/cop/style/for.rb +0 -1
  281. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  282. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  283. data/lib/rubocop/cop/style/guard_clause.rb +16 -3
  284. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  285. data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
  286. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  287. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  288. data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
  289. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  290. data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
  291. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  292. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
  293. data/lib/rubocop/cop/style/if_with_semicolon.rb +28 -6
  294. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  295. data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
  296. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  297. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  298. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  299. data/lib/rubocop/cop/style/lambda.rb +1 -1
  300. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  301. data/lib/rubocop/cop/style/magic_comment_format.rb +3 -8
  302. data/lib/rubocop/cop/style/map_into_array.rb +61 -12
  303. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  304. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  305. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +32 -20
  306. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  307. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  308. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  309. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  310. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  311. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  312. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  313. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  314. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  315. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  316. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  317. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  318. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  319. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  320. data/lib/rubocop/cop/style/not.rb +1 -1
  321. data/lib/rubocop/cop/style/object_then.rb +14 -15
  322. data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
  323. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  324. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  325. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  326. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  327. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  328. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  329. data/lib/rubocop/cop/style/proc.rb +1 -2
  330. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  331. data/lib/rubocop/cop/style/raise_args.rb +7 -5
  332. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  333. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  334. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  335. data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
  336. data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
  337. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  338. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  339. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  340. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  341. data/lib/rubocop/cop/style/redundant_format.rb +222 -0
  342. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  343. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  344. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +1 -1
  345. data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
  346. data/lib/rubocop/cop/style/redundant_parentheses.rb +38 -24
  347. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  348. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  349. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  350. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  351. data/lib/rubocop/cop/style/redundant_self.rb +8 -15
  352. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  353. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  354. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  355. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  356. data/lib/rubocop/cop/style/require_order.rb +1 -1
  357. data/lib/rubocop/cop/style/rescue_modifier.rb +15 -4
  358. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  359. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +54 -12
  360. data/lib/rubocop/cop/style/safe_navigation.rb +105 -51
  361. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  362. data/lib/rubocop/cop/style/select_by_regexp.rb +10 -7
  363. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  364. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  365. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  366. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  367. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  368. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  369. data/lib/rubocop/cop/style/single_line_do_end_block.rb +12 -3
  370. data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
  371. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  372. data/lib/rubocop/cop/style/sole_nested_conditional.rb +4 -5
  373. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  374. data/lib/rubocop/cop/style/string_concatenation.rb +14 -13
  375. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  376. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  377. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  378. data/lib/rubocop/cop/style/super_arguments.rb +65 -17
  379. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  380. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  381. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  382. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
  383. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  384. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  385. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  386. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  387. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  388. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  389. data/lib/rubocop/cop/team.rb +8 -1
  390. data/lib/rubocop/cop/util.rb +12 -5
  391. data/lib/rubocop/cop/utils/format_string.rb +7 -5
  392. data/lib/rubocop/cop/variable_force/assignment.rb +18 -3
  393. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  394. data/lib/rubocop/cop/variable_force/variable.rb +18 -2
  395. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  396. data/lib/rubocop/cop/variable_force.rb +4 -10
  397. data/lib/rubocop/cops_documentation_generator.rb +100 -51
  398. data/lib/rubocop/directive_comment.rb +44 -10
  399. data/lib/rubocop/file_finder.rb +9 -4
  400. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  401. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  402. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  403. data/lib/rubocop/lsp/logger.rb +2 -2
  404. data/lib/rubocop/lsp/routes.rb +7 -23
  405. data/lib/rubocop/lsp/runtime.rb +18 -48
  406. data/lib/rubocop/lsp/server.rb +0 -3
  407. data/lib/rubocop/lsp/stdin_runner.rb +83 -0
  408. data/lib/rubocop/magic_comment.rb +3 -3
  409. data/lib/rubocop/options.rb +28 -12
  410. data/lib/rubocop/path_util.rb +15 -8
  411. data/lib/rubocop/plugin/configuration_integrator.rb +141 -0
  412. data/lib/rubocop/plugin/load_error.rb +26 -0
  413. data/lib/rubocop/plugin/loader.rb +100 -0
  414. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  415. data/lib/rubocop/plugin.rb +39 -0
  416. data/lib/rubocop/rake_task.rb +4 -1
  417. data/lib/rubocop/result_cache.rb +13 -13
  418. data/lib/rubocop/rspec/cop_helper.rb +7 -0
  419. data/lib/rubocop/rspec/expect_offense.rb +7 -2
  420. data/lib/rubocop/rspec/shared_contexts.rb +4 -1
  421. data/lib/rubocop/rspec/support.rb +1 -2
  422. data/lib/rubocop/runner.rb +22 -12
  423. data/lib/rubocop/server/cache.rb +39 -1
  424. data/lib/rubocop/server/cli.rb +2 -2
  425. data/lib/rubocop/server/core.rb +1 -0
  426. data/lib/rubocop/target_finder.rb +1 -0
  427. data/lib/rubocop/target_ruby.rb +28 -13
  428. data/lib/rubocop/version.rb +42 -6
  429. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  430. data/lib/rubocop.rb +29 -0
  431. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  432. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
  433. metadata +75 -19
  434. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -109,7 +109,7 @@ module RuboCop
109
109
  end
110
110
 
111
111
  def max_line_length
112
- return unless config.for_cop('Layout/LineLength')['Enabled']
112
+ return unless config.cop_enabled?('Layout/LineLength')
113
113
 
114
114
  config.for_cop('Layout/LineLength')['Max']
115
115
  end
@@ -48,6 +48,7 @@ module RuboCop
48
48
  #
49
49
  class EndlessMethod < Base
50
50
  include ConfigurableEnforcedStyle
51
+ include EndlessMethodRewriter
51
52
  extend TargetRubyVersion
52
53
  extend AutoCorrector
53
54
 
@@ -81,20 +82,6 @@ module RuboCop
81
82
 
82
83
  add_offense(node) { |corrector| correct_to_multiline(corrector, node) }
83
84
  end
84
-
85
- def correct_to_multiline(corrector, node)
86
- replacement = <<~RUBY.strip
87
- def #{node.method_name}#{arguments(node)}
88
- #{node.body.source}
89
- end
90
- RUBY
91
-
92
- corrector.replace(node, replacement)
93
- end
94
-
95
- def arguments(node, missing = '')
96
- node.arguments.any? ? node.arguments.source : missing
97
- end
98
85
  end
99
86
  end
100
87
  end
@@ -86,7 +86,7 @@ module RuboCop
86
86
  return if node.method?(:eval) && !valid_eval_receiver?(node.receiver)
87
87
 
88
88
  code = node.first_argument
89
- return unless code && (code.str_type? || code.dstr_type?)
89
+ return unless code&.type?(:str, :dstr)
90
90
 
91
91
  check_location(node, code)
92
92
  end
@@ -136,7 +136,7 @@ module RuboCop
136
136
  actual: line_node.source,
137
137
  expected: expected)
138
138
 
139
- add_offense(line_node.source_range, message: message) do |corrector|
139
+ add_offense(line_node, message: message) do |corrector|
140
140
  corrector.replace(line_node, expected)
141
141
  end
142
142
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for exact regexp match inside Regexp literals.
6
+ # Checks for exact regexp match inside `Regexp` literals.
7
7
  #
8
8
  # @example
9
9
  #
@@ -40,8 +40,7 @@ module RuboCop
40
40
  def on_send(node)
41
41
  return unless (receiver = node.receiver)
42
42
  return unless (regexp = exact_regexp_match(node))
43
-
44
- parsed_regexp = Regexp::Parser.parse(regexp)
43
+ return unless (parsed_regexp = parse_regexp(regexp))
45
44
  return unless exact_match_pattern?(parsed_regexp)
46
45
 
47
46
  prefer = "#{receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
@@ -123,7 +123,7 @@ module RuboCop
123
123
  end
124
124
 
125
125
  def call_like?(node)
126
- node.call_type? || node.zsuper_type? || node.super_type?
126
+ node.type?(:call, :zsuper, :super)
127
127
  end
128
128
 
129
129
  def insert_argument(node, corrector, block_name)
@@ -135,7 +135,13 @@ module RuboCop
135
135
  end
136
136
 
137
137
  def correct_call_node(node, corrector, block_name)
138
- corrector.insert_after(node, "(&#{block_name})")
138
+ new_arguments = if node.zsuper_type?
139
+ args = build_new_arguments_for_zsuper(node) << "&#{block_name}"
140
+ args.join(', ')
141
+ else
142
+ "&#{block_name}"
143
+ end
144
+ corrector.insert_after(node, "(#{new_arguments})")
139
145
  return unless node.parenthesized?
140
146
 
141
147
  args_begin = Util.args_begin(node)
@@ -144,6 +150,13 @@ module RuboCop
144
150
  corrector.remove(range)
145
151
  end
146
152
 
153
+ def build_new_arguments_for_zsuper(node)
154
+ def_node = node.each_ancestor(:def, :defs).first
155
+ def_node.arguments.map do |arg|
156
+ arg.optarg_type? ? arg.node_parts[0] : arg.source
157
+ end
158
+ end
159
+
147
160
  def block_body_range(block_node, send_node)
148
161
  range_between(send_node.source_range.end_pos, block_node.loc.end.end_pos)
149
162
  end
@@ -8,7 +8,7 @@ module RuboCop
8
8
  #
9
9
  # * `scientific` which enforces a mantissa between 1 (inclusive) and 10 (exclusive).
10
10
  # * `engineering` which enforces the exponent to be a multiple of 3 and the mantissa
11
- # to be between 0.1 (inclusive) and 10 (exclusive).
11
+ # to be between 0.1 (inclusive) and 1000 (exclusive).
12
12
  # * `integral` which enforces the mantissa to always be a whole number without
13
13
  # trailing zeroes.
14
14
  #
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # Suggests `ENV.fetch` for the replacement of `ENV[]`.
7
7
  # `ENV[]` silently fails and returns `nil` when the environment variable is unset,
8
8
  # which may cause unexpected behaviors when the developer forgets to set it.
9
- # On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
9
+ # On the other hand, `ENV.fetch` raises `KeyError` or returns the explicitly
10
10
  # specified default value.
11
11
  #
12
12
  # @example
@@ -26,6 +26,7 @@ module RuboCop
26
26
  extend AutoCorrector
27
27
 
28
28
  MSG = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
29
+ RESTRICT_ON_SEND = [:[]].freeze
29
30
 
30
31
  # @!method env_with_bracket?(node)
31
32
  def_node_matcher :env_with_bracket?, <<~PATTERN
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Use `File::NULL` instead of hardcoding the null device (`/dev/null` on Unix-like
7
+ # OSes, `NUL` or `NUL:` on Windows), so that code is platform independent.
8
+ # Only looks for full string matches, substrings within a longer string are not
9
+ # considered.
10
+ #
11
+ # However, only files that use the string `'/dev/null'` are targeted for detection.
12
+ # This is because the string `'NUL'` is not limited to the null device.
13
+ # This behavior results in false negatives when the `'/dev/null'` string is not used,
14
+ # but it is a trade-off to avoid false positives. `NULL:`
15
+ # Unlike `'NUL'`, `'NUL:'` is regarded as something like `C:` and is always detected.
16
+ #
17
+ # NOTE: Uses inside arrays and hashes are ignored.
18
+ #
19
+ # @safety
20
+ # It is possible for a string value to be changed if code is being run
21
+ # on multiple platforms and was previously hardcoded to a specific null device.
22
+ #
23
+ # For example, the following string will change on Windows when changed to
24
+ # `File::NULL`:
25
+ #
26
+ # [source,ruby]
27
+ # ----
28
+ # path = "/dev/null"
29
+ # ----
30
+ #
31
+ # @example
32
+ # # bad
33
+ # '/dev/null'
34
+ # 'NUL'
35
+ # 'NUL:'
36
+ #
37
+ # # good
38
+ # File::NULL
39
+ #
40
+ # # ok - inside an array
41
+ # null_devices = %w[/dev/null nul]
42
+ #
43
+ # # ok - inside a hash
44
+ # { unix: "/dev/null", windows: "nul" }
45
+ class FileNull < Base
46
+ extend AutoCorrector
47
+
48
+ REGEXP = %r{\A(/dev/null|NUL:?)\z}i.freeze
49
+ MSG = 'Use `File::NULL` instead of `%<source>s`.'
50
+
51
+ def on_new_investigation
52
+ return unless (ast = processed_source.ast)
53
+
54
+ @contain_dev_null_string_in_file = ast.each_descendant(:str).any? do |str|
55
+ content = str.str_content
56
+
57
+ valid_string?(content) && content.downcase == '/dev/null' # rubocop:disable Style/FileNull
58
+ end
59
+ end
60
+
61
+ def on_str(node)
62
+ value = node.value
63
+ return unless valid_string?(value)
64
+ return if acceptable?(node)
65
+ return if value.downcase == 'nul' && !@contain_dev_null_string_in_file # rubocop:disable Style/FileNull
66
+ return unless REGEXP.match?(value)
67
+
68
+ add_offense(node, message: format(MSG, source: value)) do |corrector|
69
+ corrector.replace(node, 'File::NULL')
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def valid_string?(value)
76
+ !value.empty? && value.valid_encoding?
77
+ end
78
+
79
+ def acceptable?(node)
80
+ # Using a hardcoded null device is acceptable when inside an array or
81
+ # inside a hash to ensure behavior doesn't change.
82
+ return false unless node.parent
83
+
84
+ node.parent.type?(:array, :pair)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for usage of `File.open` in append mode with empty block.
7
+ #
8
+ # Such a usage only creates a new file, but it doesn't update
9
+ # timestamps for an existing file, which might have been the intention.
10
+ #
11
+ # For example, for an existing file `foo.txt`:
12
+ #
13
+ # ruby -e "puts File.mtime('foo.txt')"
14
+ # # 2024-11-26 12:17:23 +0100
15
+ #
16
+ # ruby -e "File.open('foo.txt', 'a') {}"
17
+ #
18
+ # ruby -e "puts File.mtime('foo.txt')"
19
+ # # 2024-11-26 12:17:23 +0100 -> unchanged
20
+ #
21
+ # If the intention was to update timestamps, `FileUtils.touch('foo.txt')`
22
+ # should be used instead.
23
+ #
24
+ # @safety
25
+ # Autocorrection is unsafe for this cop because unlike `File.open`,
26
+ # `FileUtils.touch` updates an existing file's timestamps.
27
+ #
28
+ # @example
29
+ # # bad
30
+ # File.open(filename, 'a') {}
31
+ # File.open(filename, 'a+') {}
32
+ #
33
+ # # good
34
+ # FileUtils.touch(filename)
35
+ #
36
+ class FileTouch < Base
37
+ extend AutoCorrector
38
+
39
+ MSG = 'Use `FileUtils.touch(%<argument>s)` instead of `File.open` in ' \
40
+ 'append mode with empty block.'
41
+
42
+ RESTRICT_ON_SEND = %i[open].freeze
43
+
44
+ APPEND_FILE_MODES = %w[a a+ ab a+b at a+t].to_set.freeze
45
+
46
+ # @!method file_open?(node)
47
+ def_node_matcher :file_open?, <<~PATTERN
48
+ (send
49
+ (const {nil? cbase} :File) :open
50
+ $(...)
51
+ (str %APPEND_FILE_MODES))
52
+ PATTERN
53
+
54
+ def on_send(node)
55
+ filename = file_open?(node)
56
+ parent = node.parent
57
+
58
+ return unless filename
59
+ return unless parent && empty_block?(parent)
60
+
61
+ message = format(MSG, argument: filename.source)
62
+ add_offense(parent, message: message) do |corrector|
63
+ corrector.replace(parent, "FileUtils.touch(#{filename.source})")
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def empty_block?(node)
70
+ node.block_type? && !node.body
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -65,19 +65,23 @@ module RuboCop
65
65
 
66
66
  # @!method right_coerce?(node)
67
67
  def_node_matcher :right_coerce?, <<~PATTERN
68
- (send _ :/ (send _ :to_f))
68
+ (send _ :/ #to_f_method?)
69
69
  PATTERN
70
70
  # @!method left_coerce?(node)
71
71
  def_node_matcher :left_coerce?, <<~PATTERN
72
- (send (send _ :to_f) :/ _)
72
+ (send #to_f_method? :/ _)
73
73
  PATTERN
74
74
  # @!method both_coerce?(node)
75
75
  def_node_matcher :both_coerce?, <<~PATTERN
76
- (send (send _ :to_f) :/ (send _ :to_f))
76
+ (send #to_f_method? :/ #to_f_method?)
77
77
  PATTERN
78
78
  # @!method any_coerce?(node)
79
79
  def_node_matcher :any_coerce?, <<~PATTERN
80
- {(send _ :/ (send _ :to_f)) (send (send _ :to_f) :/ _)}
80
+ {(send _ :/ #to_f_method?) (send #to_f_method? :/ _)}
81
+ PATTERN
82
+ # @!method to_f_method?(node)
83
+ def_node_matcher :to_f_method?, <<~PATTERN
84
+ (send !nil? :to_f)
81
85
  PATTERN
82
86
 
83
87
  def on_send(node)
@@ -44,7 +44,6 @@ module RuboCop
44
44
  #
45
45
  class For < Base
46
46
  include ConfigurableEnforcedStyle
47
- include RangeHelp
48
47
  extend AutoCorrector
49
48
 
50
49
  EACH_LENGTH = 'each'.length
@@ -151,7 +151,7 @@ module RuboCop
151
151
 
152
152
  def frozen_string_literal_comment(processed_source)
153
153
  processed_source.tokens.find do |token|
154
- token.text.start_with?(FROZEN_STRING_LITERAL)
154
+ token.text.start_with?(FROZEN_STRING_LITERAL_REGEXP)
155
155
  end
156
156
  end
157
157
 
@@ -70,9 +70,7 @@ module RuboCop
70
70
  end
71
71
 
72
72
  def check(node)
73
- global_var, = *node
74
-
75
- add_offense(node.loc.name) unless allowed_var?(global_var)
73
+ add_offense(node.loc.name) unless allowed_var?(node.name)
76
74
  end
77
75
  end
78
76
  end
@@ -234,11 +234,11 @@ module RuboCop
234
234
  end
235
235
 
236
236
  def autocorrect_heredoc_argument(corrector, node, heredoc_branch, leave_branch, guard)
237
+ remove_whole_lines(corrector, node.loc.end)
237
238
  return unless node.else?
238
239
 
239
240
  remove_whole_lines(corrector, leave_branch.source_range)
240
241
  remove_whole_lines(corrector, node.loc.else)
241
- remove_whole_lines(corrector, node.loc.end)
242
242
  remove_whole_lines(corrector, range_of_branch_to_remove(node, guard))
243
243
  corrector.insert_after(
244
244
  heredoc_branch.last_argument.loc.heredoc_end, "\n#{leave_branch.source}"
@@ -264,7 +264,7 @@ module RuboCop
264
264
 
265
265
  def and_or_guard_clause?(guard_clause)
266
266
  parent = guard_clause.parent
267
- parent.and_type? || parent.or_type?
267
+ parent.operator_keyword?
268
268
  end
269
269
 
270
270
  def too_long_for_single_line?(node, example)
@@ -283,7 +283,8 @@ module RuboCop
283
283
  end
284
284
 
285
285
  def accepted_if?(node, ending)
286
- return true if node.modifier_form? || node.ternary? || node.elsif_conditional?
286
+ return true if node.modifier_form? || node.ternary? || node.elsif_conditional? ||
287
+ assigned_lvar_used_in_if_branch?(node)
287
288
 
288
289
  if ending
289
290
  node.else?
@@ -292,6 +293,18 @@ module RuboCop
292
293
  end
293
294
  end
294
295
 
296
+ def assigned_lvar_used_in_if_branch?(node)
297
+ return false unless (if_branch = node.if_branch)
298
+
299
+ assigned_lvars_in_condition = node.condition.each_descendant(:lvasgn).map do |lvasgn|
300
+ lvar_name, = *lvasgn
301
+ lvar_name.to_s
302
+ end
303
+ used_lvars_in_branch = if_branch.each_descendant(:lvar).map(&:source) || []
304
+
305
+ (assigned_lvars_in_condition & used_lvars_in_branch).any?
306
+ end
307
+
295
308
  def remove_whole_lines(corrector, range)
296
309
  corrector.remove(range_by_whole_lines(range, include_final_newline: true))
297
310
  end
@@ -111,8 +111,7 @@ module RuboCop
111
111
  end
112
112
 
113
113
  def requires_parens?(node)
114
- (node.call_type? && node.arguments.any? && !node.parenthesized?) ||
115
- node.or_type? || node.and_type?
114
+ (node.call_type? && node.arguments.any? && !node.parenthesized?) || node.operator_keyword?
116
115
  end
117
116
 
118
117
  def multi_argument(node)
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for uses of `each_key` and `each_value` Hash methods.
6
+ # Checks for uses of `each_key` and `each_value` `Hash` methods.
7
7
  #
8
8
  # NOTE: If you have an array of two-element arrays, you can put
9
9
  # parentheses around the block arguments to indicate that you're not
@@ -44,7 +44,7 @@ module RuboCop
44
44
 
45
45
  # @!method kv_each(node)
46
46
  def_node_matcher :kv_each, <<~PATTERN
47
- ({block numblock} $(call (call _ ${:keys :values}) :each) ...)
47
+ (any_block $(call (call _ ${:keys :values}) :each) ...)
48
48
  PATTERN
49
49
 
50
50
  # @!method each_arguments(node)
@@ -57,6 +57,11 @@ module RuboCop
57
57
  (call $(call _ ${:keys :values}) :each (block_pass (sym _)))
58
58
  PATTERN
59
59
 
60
+ # @!method hash_mutated?(node, receiver)
61
+ def_node_matcher :hash_mutated?, <<~PATTERN
62
+ `(send %1 :[]= ...)
63
+ PATTERN
64
+
60
65
  def on_block(node)
61
66
  return unless handleable?(node)
62
67
 
@@ -103,6 +108,7 @@ module RuboCop
103
108
  def handleable?(node)
104
109
  return false if use_array_converter_method_as_preceding?(node)
105
110
  return false unless (root_receiver = root_receiver(node))
111
+ return false if hash_mutated?(node, root_receiver)
106
112
 
107
113
  !root_receiver.literal? || root_receiver.hash_type?
108
114
  end
@@ -156,10 +162,7 @@ module RuboCop
156
162
 
157
163
  def use_array_converter_method_as_preceding?(node)
158
164
  return false unless (preceding_method = node.children.first.children.first)
159
- unless preceding_method.call_type? ||
160
- preceding_method.block_type? || preceding_method.numblock_type?
161
- return false
162
- end
165
+ return false unless preceding_method.type?(:call, :any_block)
163
166
 
164
167
  ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
165
168
  end