rubocop 1.66.1 → 1.72.2

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 +162 -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 +2 -2
  14. data/lib/rubocop/config.rb +17 -4
  15. data/lib/rubocop/config_loader.rb +48 -8
  16. data/lib/rubocop/config_loader_resolver.rb +36 -11
  17. data/lib/rubocop/config_validator.rb +20 -9
  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/example_description.rb +4 -2
  36. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  37. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  38. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  39. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  40. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  41. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  42. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  43. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +229 -0
  44. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  45. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  46. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  47. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  48. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  49. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  50. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  51. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +11 -2
  52. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  53. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  54. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +7 -1
  55. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +0 -5
  56. data/lib/rubocop/cop/internal_affairs.rb +6 -0
  57. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -2
  58. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  59. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  60. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  61. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  62. data/lib/rubocop/cop/layout/class_structure.rb +9 -9
  63. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  64. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  65. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  66. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  67. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  68. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +3 -3
  69. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  70. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  71. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  72. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  73. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  74. data/lib/rubocop/cop/layout/first_argument_indentation.rb +3 -8
  75. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  76. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  77. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  78. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  79. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  80. data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
  81. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  82. data/lib/rubocop/cop/layout/indentation_width.rb +11 -12
  83. data/lib/rubocop/cop/layout/leading_comment_space.rb +71 -1
  84. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  85. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  86. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/line_length.rb +119 -4
  88. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  89. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  90. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  91. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  92. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  93. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -3
  94. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  95. data/lib/rubocop/cop/layout/redundant_line_break.rb +10 -41
  96. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -3
  97. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  98. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  99. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  100. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  101. data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
  102. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  103. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -20
  105. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  106. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  108. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +6 -0
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +4 -0
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +4 -0
  111. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  112. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  113. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  114. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  115. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
  116. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  117. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  118. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  119. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  120. data/lib/rubocop/cop/lint/circular_argument_reference.rb +6 -0
  121. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  122. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  123. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  124. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  125. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
  126. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  127. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  128. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  129. data/lib/rubocop/cop/lint/duplicate_set_element.rb +87 -0
  130. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  131. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  132. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  133. data/lib/rubocop/cop/lint/ensure_return.rb +1 -4
  134. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  135. data/lib/rubocop/cop/lint/float_comparison.rb +20 -9
  136. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  137. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  138. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  139. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +11 -5
  140. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  141. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +8 -14
  142. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -0
  143. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  144. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +49 -8
  145. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  146. data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -6
  147. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  148. data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
  149. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  150. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  151. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  152. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  153. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  154. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  155. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  156. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  157. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -2
  158. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  159. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +6 -11
  160. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  161. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  162. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +13 -8
  163. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  164. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  165. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +231 -0
  166. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  167. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  168. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  169. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  170. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  171. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +109 -41
  172. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  173. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  174. data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
  175. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  176. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  177. data/lib/rubocop/cop/lint/symbol_conversion.rb +2 -2
  178. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  179. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  180. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
  181. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  182. data/lib/rubocop/cop/lint/unreachable_code.rb +51 -2
  183. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
  184. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  185. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  186. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
  187. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  188. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +80 -0
  189. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  190. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  191. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  192. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  193. data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
  194. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  195. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  196. data/lib/rubocop/cop/lint/void.rb +8 -11
  197. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  198. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  199. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  200. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  201. data/lib/rubocop/cop/metrics/method_length.rb +8 -1
  202. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  203. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  204. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  205. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -3
  206. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  207. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  208. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  209. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  210. data/lib/rubocop/cop/mixin/check_line_breakable.rb +20 -10
  211. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  212. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  213. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  214. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  215. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -2
  216. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  217. data/lib/rubocop/cop/mixin/hash_subset.rb +188 -0
  218. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  219. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  220. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  221. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +5 -9
  222. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  223. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  224. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  225. data/lib/rubocop/cop/mixin/range_help.rb +3 -4
  226. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  227. data/lib/rubocop/cop/mixin/statement_modifier.rb +11 -5
  228. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  229. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  230. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  231. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  232. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  233. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  234. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  235. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  236. data/lib/rubocop/cop/naming/inclusive_language.rb +12 -3
  237. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +11 -12
  238. data/lib/rubocop/cop/naming/predicate_name.rb +45 -1
  239. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  240. data/lib/rubocop/cop/naming/variable_name.rb +3 -4
  241. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  242. data/lib/rubocop/cop/offense.rb +4 -5
  243. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  244. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  245. data/lib/rubocop/cop/style/access_modifier_declarations.rb +96 -28
  246. data/lib/rubocop/cop/style/accessor_grouping.rb +10 -2
  247. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  248. data/lib/rubocop/cop/style/and_or.rb +1 -1
  249. data/lib/rubocop/cop/style/arguments_forwarding.rb +78 -22
  250. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  251. data/lib/rubocop/cop/style/array_intersect.rb +5 -4
  252. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  253. data/lib/rubocop/cop/style/block_delimiters.rb +49 -19
  254. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  255. data/lib/rubocop/cop/style/class_and_module_children.rb +6 -3
  256. data/lib/rubocop/cop/style/collection_compact.rb +10 -10
  257. data/lib/rubocop/cop/style/collection_methods.rb +1 -1
  258. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  259. data/lib/rubocop/cop/style/combinable_loops.rb +9 -2
  260. data/lib/rubocop/cop/style/commented_keyword.rb +17 -1
  261. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  262. data/lib/rubocop/cop/style/conditional_assignment.rb +26 -26
  263. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  264. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  265. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  266. data/lib/rubocop/cop/style/documentation.rb +1 -1
  267. data/lib/rubocop/cop/style/double_negation.rb +3 -3
  268. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  269. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  270. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  271. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  272. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  273. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  274. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  275. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  276. data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
  277. data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
  278. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  279. data/lib/rubocop/cop/style/file_null.rb +89 -0
  280. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  281. data/lib/rubocop/cop/style/float_division.rb +8 -4
  282. data/lib/rubocop/cop/style/for.rb +0 -1
  283. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  284. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  285. data/lib/rubocop/cop/style/guard_clause.rb +16 -3
  286. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  287. data/lib/rubocop/cop/style/hash_each_methods.rb +9 -6
  288. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  289. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  290. data/lib/rubocop/cop/style/hash_syntax.rb +8 -5
  291. data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
  292. data/lib/rubocop/cop/style/if_inside_else.rb +1 -2
  293. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -3
  294. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -3
  295. data/lib/rubocop/cop/style/if_with_semicolon.rb +26 -11
  296. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  297. data/lib/rubocop/cop/style/inverse_methods.rb +6 -7
  298. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  299. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  300. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -1
  301. data/lib/rubocop/cop/style/lambda.rb +1 -1
  302. data/lib/rubocop/cop/style/lambda_call.rb +3 -2
  303. data/lib/rubocop/cop/style/map_into_array.rb +60 -9
  304. data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
  305. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  306. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +32 -20
  307. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  308. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  309. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
  310. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  311. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  312. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  313. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  314. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  315. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  316. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  317. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  318. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  319. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -2
  320. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  321. data/lib/rubocop/cop/style/not.rb +1 -1
  322. data/lib/rubocop/cop/style/object_then.rb +14 -15
  323. data/lib/rubocop/cop/style/one_line_conditional.rb +29 -4
  324. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  325. data/lib/rubocop/cop/style/operator_method_call.rb +25 -7
  326. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  327. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  328. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  329. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  330. data/lib/rubocop/cop/style/proc.rb +1 -2
  331. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  332. data/lib/rubocop/cop/style/raise_args.rb +7 -5
  333. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  334. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  335. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  336. data/lib/rubocop/cop/style/redundant_begin.rb +5 -1
  337. data/lib/rubocop/cop/style/redundant_condition.rb +39 -24
  338. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
  339. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  340. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  341. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  342. data/lib/rubocop/cop/style/redundant_format.rb +238 -0
  343. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -2
  344. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  345. data/lib/rubocop/cop/style/redundant_line_continuation.rb +56 -17
  346. data/lib/rubocop/cop/style/redundant_parentheses.rb +37 -25
  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 +143 -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 +9 -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 -27
  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
@@ -43,23 +43,21 @@ module RuboCop
43
43
  alias on_csend on_send
44
44
 
45
45
  def on_lvasgn(node)
46
- lhs, rhs = *node
47
- return unless rhs
46
+ return unless node.rhs
48
47
 
49
48
  rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
50
49
 
51
- add_offense(node) if rhs.type == rhs_type && rhs.source == lhs.to_s
50
+ add_offense(node) if node.rhs.type == rhs_type && node.rhs.source == node.lhs.to_s
52
51
  end
53
52
  alias on_ivasgn on_lvasgn
54
53
  alias on_cvasgn on_lvasgn
55
54
  alias on_gvasgn on_lvasgn
56
55
 
57
56
  def on_casgn(node)
58
- lhs_scope, lhs_name, rhs = *node
59
- return unless rhs&.const_type?
57
+ return unless node.rhs&.const_type?
60
58
 
61
- rhs_scope, rhs_name = *rhs
62
- add_offense(node) if lhs_scope == rhs_scope && lhs_name == rhs_name
59
+ add_offense(node) if node.namespace == node.rhs.namespace &&
60
+ node.short_name == node.rhs.short_name
63
61
  end
64
62
 
65
63
  def on_masgn(node)
@@ -67,15 +65,15 @@ module RuboCop
67
65
  end
68
66
 
69
67
  def on_or_asgn(node)
70
- lhs, rhs = *node
71
- add_offense(node) if rhs_matches_lhs?(rhs, lhs)
68
+ add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs)
72
69
  end
73
70
  alias on_and_asgn on_or_asgn
74
71
 
75
72
  private
76
73
 
77
74
  def multiple_self_assignment?(node)
78
- lhs, rhs = *node
75
+ lhs = node.lhs
76
+ rhs = node.rhs
79
77
  return false unless rhs.array_type?
80
78
  return false unless lhs.children.size == rhs.children.size
81
79
 
@@ -67,7 +67,7 @@ module RuboCop
67
67
  def on_rescue(node)
68
68
  return if rescue_modifier?(node)
69
69
 
70
- _body, *rescues, _else = *node
70
+ rescues = node.resbody_branches
71
71
  rescued_groups = rescued_groups_for(rescues)
72
72
 
73
73
  rescue_group_rescues_multiple_levels = rescued_groups.any? do |group|
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for `Hash` creation with a mutable default value.
7
+ # Creating a `Hash` in such a way will share the default value
8
+ # across all keys, causing unexpected behavior when modifying it.
9
+ #
10
+ # For example, when the `Hash` was created with an `Array` as the argument,
11
+ # calling `hash[:foo] << 'bar'` will also change the value of all
12
+ # other keys that have not been explicitly assigned to.
13
+ #
14
+ # @example
15
+ # # bad
16
+ # Hash.new([])
17
+ # Hash.new({})
18
+ # Hash.new(Array.new)
19
+ # Hash.new(Hash.new)
20
+ #
21
+ # # okay -- In rare cases that intentionally have this behavior,
22
+ # # without disabling the cop, you can set the default explicitly.
23
+ # h = Hash.new
24
+ # h.default = []
25
+ # h[:a] << 1
26
+ # h[:b] << 2
27
+ # h # => {:a => [1, 2], :b => [1, 2]}
28
+ #
29
+ # # okay -- beware this will discard mutations and only remember assignments
30
+ # Hash.new { Array.new }
31
+ # Hash.new { Hash.new }
32
+ # Hash.new { {} }
33
+ # Hash.new { [] }
34
+ #
35
+ # # good - frozen solution will raise an error when mutation attempted
36
+ # Hash.new([].freeze)
37
+ # Hash.new({}.freeze)
38
+ #
39
+ # # good - using a proc will create a new object for each key
40
+ # h = Hash.new
41
+ # h.default_proc = ->(h, k) { [] }
42
+ # h.default_proc = ->(h, k) { {} }
43
+ #
44
+ # # good - using a block will create a new object for each key
45
+ # Hash.new { |h, k| h[k] = [] }
46
+ # Hash.new { |h, k| h[k] = {} }
47
+ class SharedMutableDefault < Base
48
+ MSG = 'Do not create a Hash with a mutable default value ' \
49
+ 'as the default value can accidentally be changed.'
50
+ RESTRICT_ON_SEND = %i[new].freeze
51
+
52
+ # @!method hash_initialized_with_mutable_shared_object?(node)
53
+ def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
54
+ (send (const {nil? cbase} :Hash) :new {array hash (send (const {nil? cbase} {:Array :Hash}) :new)})
55
+ PATTERN
56
+
57
+ def on_send(node)
58
+ return unless hash_initialized_with_mutable_shared_object?(node)
59
+
60
+ add_offense(node)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -116,7 +116,7 @@ module RuboCop
116
116
  private
117
117
 
118
118
  def comment_between_rescue_and_end?(node)
119
- ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block, :numblock).first
119
+ ancestor = node.each_ancestor(:kwbegin, :def, :defs, :any_block).first
120
120
  return false unless ancestor
121
121
 
122
122
  end_line = ancestor.loc.end&.line || ancestor.loc.last_line
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for cases where exceptions unrelated to the numeric constructors `Integer()`,
7
+ # `Float()`, `BigDecimal()`, `Complex()`, and `Rational()` may be unintentionally swallowed.
8
+ #
9
+ # @safety
10
+ # The cop is unsafe for autocorrection because unexpected errors occurring in the argument
11
+ # passed to numeric constructor (e.g., `Integer()`) can lead to incompatible behavior.
12
+ # For example, changing it to `Integer(potential_exception_method_call, exception: false)`
13
+ # ensures that exceptions raised by `potential_exception_method_call` are not ignored.
14
+ #
15
+ # [source,ruby]
16
+ # ----
17
+ # Integer(potential_exception_method_call) rescue nil
18
+ # ----
19
+ #
20
+ # @example
21
+ #
22
+ # # bad
23
+ # Integer(arg) rescue nil
24
+ #
25
+ # # bad
26
+ # begin
27
+ # Integer(arg)
28
+ # rescue
29
+ # nil
30
+ # end
31
+ #
32
+ # # bad
33
+ # begin
34
+ # Integer(arg)
35
+ # rescue
36
+ # end
37
+ #
38
+ # # good
39
+ # Integer(arg, exception: false)
40
+ #
41
+ class SuppressedExceptionInNumberConversion < Base
42
+ extend AutoCorrector
43
+ extend TargetRubyVersion
44
+
45
+ MSG = 'Use `%<prefer>s` instead.'
46
+ EXPECTED_EXCEPTION_CLASSES = %w[ArgumentError TypeError ::ArgumentError ::TypeError].freeze
47
+
48
+ # @!method numeric_constructor_rescue_nil(node)
49
+ def_node_matcher :numeric_constructor_rescue_nil, <<~PATTERN
50
+ (rescue
51
+ $#numeric_method?
52
+ (resbody nil? nil? (nil)) nil?)
53
+ PATTERN
54
+
55
+ # @!method begin_numeric_constructor_rescue_nil(node)
56
+ def_node_matcher :begin_numeric_constructor_rescue_nil, <<~PATTERN
57
+ (kwbegin
58
+ (rescue
59
+ $#numeric_method?
60
+ (resbody $_? nil?
61
+ {(nil) nil?}) nil?))
62
+ PATTERN
63
+
64
+ # @!method numeric_method?(node)
65
+ def_node_matcher :numeric_method?, <<~PATTERN
66
+ {
67
+ (call #constructor_receiver? {:Integer :BigDecimal :Complex :Rational}
68
+ _ _?)
69
+ (call #constructor_receiver? :Float
70
+ _)
71
+ }
72
+ PATTERN
73
+
74
+ # @!method constructor_receiver?(node)
75
+ def_node_matcher :constructor_receiver?, <<~PATTERN
76
+ {nil? (const {nil? cbase} :Kernel)}
77
+ PATTERN
78
+
79
+ minimum_target_ruby_version 2.6
80
+
81
+ # rubocop:disable Metrics/AbcSize
82
+ def on_rescue(node)
83
+ if (method, exception_classes = begin_numeric_constructor_rescue_nil(node.parent))
84
+ return unless expected_exception_classes_only?(exception_classes)
85
+
86
+ node = node.parent
87
+ else
88
+ return unless (method = numeric_constructor_rescue_nil(node))
89
+ end
90
+
91
+ arguments = method.arguments.map(&:source) << 'exception: false'
92
+ prefer = "#{method.method_name}(#{arguments.join(', ')})"
93
+ prefer = "#{method.receiver.source}#{method.loc.dot.source}#{prefer}" if method.receiver
94
+
95
+ add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
96
+ corrector.replace(node, prefer)
97
+ end
98
+ end
99
+ # rubocop:enable Metrics/AbcSize
100
+
101
+ private
102
+
103
+ def expected_exception_classes_only?(exception_classes)
104
+ return true unless (arguments = exception_classes.first)
105
+
106
+ (arguments.values.map(&:source) - EXPECTED_EXCEPTION_CLASSES).none?
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -78,7 +78,7 @@ module RuboCop
78
78
  def on_send(node)
79
79
  return unless node.receiver
80
80
 
81
- if node.receiver.str_type? || node.receiver.sym_type?
81
+ if node.receiver.type?(:str, :sym)
82
82
  register_offense(node, correction: node.receiver.value.to_sym.inspect)
83
83
  elsif node.receiver.dstr_type?
84
84
  register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"")
@@ -141,7 +141,7 @@ module RuboCop
141
141
  end
142
142
 
143
143
  def in_percent_literal_array?(node)
144
- node.parent&.array_type? && node.parent&.percent_literal?
144
+ node.parent&.array_type? && node.parent.percent_literal?
145
145
  end
146
146
 
147
147
  def correct_hash_key(node)
@@ -6,9 +6,12 @@ module RuboCop
6
6
  # Repacks Parser's diagnostics/errors
7
7
  # into RuboCop's offenses.
8
8
  class Syntax < Base
9
+ LEVELS = %i[error fatal].freeze
10
+
9
11
  def on_other_file
10
12
  add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
11
- processed_source.diagnostics.each do |diagnostic|
13
+ syntax_errors = processed_source.diagnostics.select { |d| LEVELS.include?(d.level) }
14
+ syntax_errors.each do |diagnostic|
12
15
  add_offense_from_diagnostic(diagnostic, processed_source.ruby_version)
13
16
  end
14
17
  super
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for Regexpes (both literals and via `Regexp.new` / `Regexp.compile`)
7
+ # that contain unescaped `]` characters.
8
+ #
9
+ # It emulates the following Ruby warning:
10
+ #
11
+ # [source,ruby]
12
+ # ----
13
+ # $ ruby -e '/abc]123/'
14
+ # -e:1: warning: regular expression has ']' without escape: /abc]123/
15
+ # ----
16
+ #
17
+ # @example
18
+ # # bad
19
+ # /abc]123/
20
+ # %r{abc]123}
21
+ # Regexp.new('abc]123')
22
+ # Regexp.compile('abc]123')
23
+ #
24
+ # # good
25
+ # /abc\]123/
26
+ # %r{abc\]123}
27
+ # Regexp.new('abc\]123')
28
+ # Regexp.compile('abc\]123')
29
+ #
30
+ class UnescapedBracketInRegexp < Base
31
+ extend AutoCorrector
32
+
33
+ MSG = 'Regular expression has `]` without escape.'
34
+ RESTRICT_ON_SEND = %i[new compile].freeze
35
+
36
+ # @!method regexp_constructor(node)
37
+ def_node_search :regexp_constructor, <<~PATTERN
38
+ (send
39
+ (const {nil? cbase} :Regexp) {:new :compile}
40
+ $str
41
+ ...
42
+ )
43
+ PATTERN
44
+
45
+ def on_regexp(node)
46
+ RuboCop::Util.silence_warnings do
47
+ node.parsed_tree&.each_expression do |expr|
48
+ detect_offenses(node, expr)
49
+ end
50
+ end
51
+ end
52
+
53
+ def on_send(node)
54
+ # Ignore nodes that contain interpolation
55
+ return if node.each_descendant(:dstr).any?
56
+
57
+ regexp_constructor(node) do |text|
58
+ parse_regexp(text.value)&.each_expression do |expr|
59
+ detect_offenses(text, expr)
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def detect_offenses(node, expr)
67
+ return unless expr.type?(:literal)
68
+
69
+ expr.text.scan(/(?<!\\)\]/) do
70
+ pos = Regexp.last_match.begin(0)
71
+ next if pos.zero? # if the unescaped bracket is the first character, Ruby does not warn
72
+
73
+ location = range_at_index(node, expr.ts, pos)
74
+
75
+ add_offense(location) do |corrector|
76
+ corrector.replace(location, '\]')
77
+ end
78
+ end
79
+ end
80
+
81
+ def range_at_index(node, index, offset)
82
+ adjustment = index + offset
83
+ node.loc.begin.end.adjust(begin_pos: adjustment, end_pos: adjustment + 1)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -81,7 +81,7 @@ module RuboCop
81
81
  node.arguments.count do |arg|
82
82
  return Float::INFINITY if arg.restarg_type?
83
83
 
84
- arg.arg_type? || arg.optarg_type? || arg.mlhs_type?
84
+ arg.type?(:arg, :optarg, :mlhs)
85
85
  end
86
86
  end
87
87
  end
@@ -130,7 +130,7 @@ module RuboCop
130
130
 
131
131
  block_body_node.each_descendant(:next, :break) do |n|
132
132
  # Ignore `next`/`break` inside an inner block
133
- next if n.each_ancestor(:block).first != block_body_node.parent
133
+ next if n.each_ancestor(:any_block).first != block_body_node.parent
134
134
  next unless n.first_argument
135
135
 
136
136
  nodes << n.first_argument
@@ -32,6 +32,22 @@ module RuboCop
32
32
  class UnreachableCode < Base
33
33
  MSG = 'Unreachable code detected.'
34
34
 
35
+ def initialize(config = nil, options = nil)
36
+ super
37
+ @redefined = []
38
+ @instance_eval_count = 0
39
+ end
40
+
41
+ def on_block(node)
42
+ @instance_eval_count += 1 if instance_eval_block?(node)
43
+ end
44
+
45
+ alias on_numblock on_block
46
+
47
+ def after_block(node)
48
+ @instance_eval_count -= 1 if instance_eval_block?(node)
49
+ end
50
+
35
51
  def on_begin(node)
36
52
  expressions = *node
37
53
 
@@ -46,19 +62,23 @@ module RuboCop
46
62
 
47
63
  private
48
64
 
65
+ def redefinable_flow_method?(method)
66
+ %i[raise fail throw exit exit! abort].include? method
67
+ end
68
+
49
69
  # @!method flow_command?(node)
50
70
  def_node_matcher :flow_command?, <<~PATTERN
51
71
  {
52
72
  return next break retry redo
53
73
  (send
54
74
  {nil? (const {nil? cbase} :Kernel)}
55
- {:raise :fail :throw :exit :exit! :abort}
75
+ #redefinable_flow_method?
56
76
  ...)
57
77
  }
58
78
  PATTERN
59
79
 
60
80
  def flow_expression?(node)
61
- return true if flow_command?(node)
81
+ return report_on_flow_command?(node) if flow_command?(node)
62
82
 
63
83
  case node.type
64
84
  when :begin, :kwbegin
@@ -68,6 +88,8 @@ module RuboCop
68
88
  check_if(node)
69
89
  when :case, :case_match
70
90
  check_case(node)
91
+ when :def
92
+ register_redefinition(node)
71
93
  else
72
94
  false
73
95
  end
@@ -88,6 +110,33 @@ module RuboCop
88
110
 
89
111
  branches.all? { |branch| branch.body && flow_expression?(branch.body) }
90
112
  end
113
+
114
+ def register_redefinition(node)
115
+ @redefined << node.method_name if redefinable_flow_method? node.method_name
116
+ false
117
+ end
118
+
119
+ def instance_eval_block?(node)
120
+ node.any_block_type? && node.method?(:instance_eval)
121
+ end
122
+
123
+ def report_on_flow_command?(node)
124
+ return true unless node.send_type?
125
+
126
+ # By the contract of this function, this case means that
127
+ # the method is called on `Kernel` in which case we
128
+ # always want to report a warning.
129
+ return true if node.receiver
130
+
131
+ # Inside an `instance_eval` we have no way to tell the
132
+ # type of `self` just by looking at the AST, so we can't
133
+ # tell if the give function that's called has been
134
+ # redefined or not, so to avoid false positives, we silence
135
+ # the warning.
136
+ return false if @instance_eval_count.positive?
137
+
138
+ !@redefined.include? node.method_name
139
+ end
91
140
  end
92
141
  end
93
142
  end
@@ -108,7 +108,7 @@ module RuboCop
108
108
  private
109
109
 
110
110
  def loop_method?(node)
111
- return false unless node.block_type? || node.numblock_type?
111
+ return false unless node.any_block_type?
112
112
 
113
113
  send_node = node.send_node
114
114
  loopable = send_node.enumerable_method? || send_node.enumerator_method? ||
@@ -39,6 +39,8 @@ module RuboCop
39
39
  # end
40
40
  #
41
41
  # @example IgnoreNotImplementedMethods: true (default)
42
+ # # with default value of `NotImplementedExceptions: ['NotImplementedError']`
43
+ #
42
44
  # # good
43
45
  # def do_something(unused)
44
46
  # raise NotImplementedError
@@ -48,6 +50,14 @@ module RuboCop
48
50
  # fail "TODO"
49
51
  # end
50
52
  #
53
+ # @example IgnoreNotImplementedMethods: true
54
+ # # with `NotImplementedExceptions: ['AbstractMethodError']`
55
+ #
56
+ # # good
57
+ # def do_something(unused)
58
+ # raise AbstractMethodError
59
+ # end
60
+ #
51
61
  # @example IgnoreNotImplementedMethods: false
52
62
  # # bad
53
63
  # def do_something(unused)
@@ -57,14 +67,13 @@ module RuboCop
57
67
  # def do_something_else(unused)
58
68
  # fail "TODO"
59
69
  # end
60
- #
61
70
  class UnusedMethodArgument < Base
62
71
  include UnusedArgument
63
72
  extend AutoCorrector
64
73
 
65
74
  # @!method not_implemented?(node)
66
75
  def_node_matcher :not_implemented?, <<~PATTERN
67
- {(send nil? :raise (const {nil? cbase} :NotImplementedError) ...)
76
+ {(send nil? :raise #allowed_exception_class? ...)
68
77
  (send nil? :fail ...)}
69
78
  PATTERN
70
79
 
@@ -115,6 +124,13 @@ module RuboCop
115
124
 
116
125
  message
117
126
  end
127
+
128
+ def allowed_exception_class?(node)
129
+ return false unless node.const_type?
130
+
131
+ allowed_class_names = Array(cop_config.fetch('NotImplementedExceptions', []))
132
+ allowed_class_names.include?(node.const_name)
133
+ end
118
134
  end
119
135
  end
120
136
  end
@@ -3,29 +3,47 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Identifies places where `URI.regexp` is obsolete and should
7
- # not be used. Instead, use `URI::DEFAULT_PARSER.make_regexp`.
6
+ # Identifies places where `URI.regexp` is obsolete and should not be used.
7
+ #
8
+ # For Ruby 3.3 or lower, use `URI::DEFAULT_PARSER.make_regexp`.
9
+ # For Ruby 3.4 or higher, use `URI::RFC2396_PARSER.make_regexp`.
10
+ #
11
+ # NOTE: If you need to support both Ruby 3.3 and lower as well as Ruby 3.4 and higher,
12
+ # consider manually changing the code as follows:
13
+ #
14
+ # [source,ruby]
15
+ # ----
16
+ # defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
17
+ # ----
8
18
  #
9
19
  # @example
10
20
  # # bad
11
21
  # URI.regexp('http://example.com')
12
22
  #
13
- # # good
23
+ # # good - Ruby 3.3 or lower
14
24
  # URI::DEFAULT_PARSER.make_regexp('http://example.com')
15
25
  #
26
+ # # good - Ruby 3.4 or higher
27
+ # URI::RFC2396_PARSER.make_regexp('http://example.com')
28
+ #
16
29
  class UriRegexp < Base
17
30
  extend AutoCorrector
18
31
 
19
32
  MSG = '`%<current>s` is obsolete and should not be used. Instead, use `%<preferred>s`.'
20
- URI_CONSTANTS = ['URI', '::URI'].freeze
21
33
  RESTRICT_ON_SEND = %i[regexp].freeze
22
34
 
35
+ # @!method uri_constant?(node)
36
+ def_node_matcher :uri_constant?, <<~PATTERN
37
+ (const {cbase nil?} :URI)
38
+ PATTERN
39
+
23
40
  def on_send(node)
24
- return unless node.receiver
25
- return unless URI_CONSTANTS.include?(node.receiver.source)
41
+ return unless uri_constant?(node.receiver)
26
42
 
43
+ parser = target_ruby_version >= 3.4 ? 'RFC2396_PARSER' : 'DEFAULT_PARSER'
27
44
  argument = node.first_argument ? "(#{node.first_argument.source})" : ''
28
- preferred_method = "#{node.receiver.source}::DEFAULT_PARSER.make_regexp#{argument}"
45
+
46
+ preferred_method = "#{node.receiver.source}::#{parser}.make_regexp#{argument}"
29
47
  message = format(MSG, current: node.source, preferred: preferred_method)
30
48
 
31
49
  add_offense(node.loc.selector, message: message) do |corrector|
@@ -159,12 +159,12 @@ module RuboCop
159
159
 
160
160
  # @!method dynamic_method_definition?(node)
161
161
  def_node_matcher :dynamic_method_definition?, <<~PATTERN
162
- {(send nil? :define_method ...) ({block numblock} (send nil? :define_method ...) ...)}
162
+ {(send nil? :define_method ...) (any_block (send nil? :define_method ...) ...)}
163
163
  PATTERN
164
164
 
165
165
  # @!method class_or_instance_eval?(node)
166
166
  def_node_matcher :class_or_instance_eval?, <<~PATTERN
167
- ({block numblock} (send _ {:class_eval :instance_eval}) ...)
167
+ (any_block (send _ {:class_eval :instance_eval}) ...)
168
168
  PATTERN
169
169
 
170
170
  def check_node(node)
@@ -268,7 +268,7 @@ module RuboCop
268
268
  end
269
269
 
270
270
  def start_of_new_scope?(child)
271
- child.module_type? || child.class_type? || child.sclass_type? || eval_call?(child)
271
+ child.type?(:module, :class, :sclass) || eval_call?(child)
272
272
  end
273
273
 
274
274
  def eval_call?(child)
@@ -282,7 +282,7 @@ module RuboCop
282
282
  matcher_name = :"#{m}_block?"
283
283
  unless respond_to?(matcher_name)
284
284
  self.class.def_node_matcher matcher_name, <<~PATTERN
285
- ({block numblock} (send {nil? const} {:#{m}} ...) ...)
285
+ (any_block (send {nil? const} {:#{m}} ...) ...)
286
286
  PATTERN
287
287
  end
288
288
 
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # rescue, ensure, etc.
18
18
  #
19
19
  # This cop's autocorrection avoids cases like `a ||= 1` because removing assignment from
20
- # operator assignment can cause NameError if this assignment has been used to declare
20
+ # operator assignment can cause `NameError` if this assignment has been used to declare
21
21
  # a local variable. For example, replacing `a ||= 1` with `a || 1` may cause
22
22
  # "undefined local variable or method `a' for main:Object (NameError)".
23
23
  #