rubocop 1.67.0 → 1.81.6

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 (526) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +384 -72
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/exe/rubocop +1 -8
  8. data/lib/rubocop/cached_data.rb +12 -4
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +2 -2
  10. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  11. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  12. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  13. data/lib/rubocop/cli/command/version.rb +2 -2
  14. data/lib/rubocop/cli.rb +19 -4
  15. data/lib/rubocop/comment_config.rb +2 -2
  16. data/lib/rubocop/config.rb +52 -10
  17. data/lib/rubocop/config_loader.rb +56 -48
  18. data/lib/rubocop/config_loader_resolver.rb +36 -10
  19. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  20. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  21. data/lib/rubocop/config_obsoletion.rb +46 -2
  22. data/lib/rubocop/config_store.rb +5 -0
  23. data/lib/rubocop/config_validator.rb +25 -14
  24. data/lib/rubocop/cop/autocorrect_logic.rb +53 -28
  25. data/lib/rubocop/cop/base.rb +7 -1
  26. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  27. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  28. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +8 -16
  32. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +8 -3
  33. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  34. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  35. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  36. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  37. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  38. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  40. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  41. data/lib/rubocop/cop/generator.rb +6 -0
  42. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  43. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  44. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  45. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  46. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  47. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  48. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  49. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  50. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  51. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +233 -0
  52. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  53. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  54. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  55. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  56. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  57. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  58. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  59. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  60. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  61. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  62. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  63. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  64. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  66. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  67. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  68. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  70. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  72. data/lib/rubocop/cop/layout/class_structure.rb +45 -10
  73. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  74. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  75. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  76. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  77. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  78. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +34 -20
  79. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  81. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
  82. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  83. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  84. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
  85. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  86. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  87. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  88. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  89. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  90. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  91. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  92. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  93. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  94. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -11
  95. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  97. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  98. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  99. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  100. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  101. data/lib/rubocop/cop/layout/line_length.rb +158 -10
  102. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  105. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  106. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  107. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  108. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  109. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +11 -8
  110. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  111. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  112. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +14 -7
  113. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  115. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  116. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  118. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  119. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  121. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  122. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  123. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  125. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  126. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  127. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  128. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  129. data/lib/rubocop/cop/layout/trailing_whitespace.rb +6 -4
  130. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  131. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  132. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  133. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  134. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  135. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  136. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  137. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  138. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
  139. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  140. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +90 -0
  141. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  142. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  143. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +7 -3
  144. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  145. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  146. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  147. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +6 -43
  148. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  149. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  150. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  151. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  152. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  153. data/lib/rubocop/cop/lint/empty_interpolation.rb +14 -1
  154. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  155. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  156. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  157. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  158. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  159. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  160. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  161. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  162. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  163. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  164. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  165. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  166. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  167. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -2
  168. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  169. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  170. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  171. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  172. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  173. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  174. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  175. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  176. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  177. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  178. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  179. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  180. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  181. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  182. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  183. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  184. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  185. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  186. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  187. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  188. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  189. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  190. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  191. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  192. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  193. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  194. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  195. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  196. data/lib/rubocop/cop/lint/rescue_exception.rb +2 -5
  197. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  198. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  199. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  200. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  201. data/lib/rubocop/cop/lint/self_assignment.rb +39 -15
  202. data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
  203. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  204. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  205. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  206. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  207. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  208. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  209. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  210. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  211. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  212. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  213. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  214. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  215. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  216. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  217. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  218. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +2 -0
  219. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  220. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  221. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  222. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  223. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  224. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  225. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  226. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  227. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  228. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  229. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  230. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  231. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  232. data/lib/rubocop/cop/lint/void.rb +23 -12
  233. data/lib/rubocop/cop/message_annotator.rb +7 -3
  234. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  235. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  236. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  237. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  238. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  239. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  240. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  241. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  242. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  243. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  244. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  245. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  246. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  247. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  248. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  249. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  250. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  251. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  252. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  253. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  254. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  255. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -7
  256. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  257. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  258. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  259. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  260. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  261. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  262. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  263. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  264. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  265. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  266. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  267. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  268. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  269. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  270. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  271. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  272. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  273. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  274. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  275. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  276. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  277. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  278. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  279. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  280. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  281. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  282. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  283. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  284. data/lib/rubocop/cop/naming/predicate_method.rb +319 -0
  285. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  286. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  287. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  288. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  289. data/lib/rubocop/cop/offense.rb +2 -3
  290. data/lib/rubocop/cop/registry.rb +9 -6
  291. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  292. data/lib/rubocop/cop/security/eval.rb +2 -1
  293. data/lib/rubocop/cop/security/json_load.rb +33 -11
  294. data/lib/rubocop/cop/security/open.rb +1 -0
  295. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  296. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  297. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  298. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  299. data/lib/rubocop/cop/style/and_or.rb +1 -1
  300. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  301. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  302. data/lib/rubocop/cop/style/array_intersect.rb +115 -39
  303. data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
  304. data/lib/rubocop/cop/style/bitwise_predicate.rb +107 -0
  305. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  306. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  307. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  308. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  309. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  310. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  311. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  312. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  313. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  314. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  315. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  316. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  317. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -31
  318. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  319. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  320. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  321. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  322. data/lib/rubocop/cop/style/documentation.rb +1 -1
  323. data/lib/rubocop/cop/style/double_negation.rb +5 -5
  324. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  325. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  326. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  327. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  328. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  329. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  330. data/lib/rubocop/cop/style/endless_method.rb +163 -18
  331. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  332. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  333. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  334. data/lib/rubocop/cop/style/explicit_block_argument.rb +17 -4
  335. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  336. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  337. data/lib/rubocop/cop/style/file_null.rb +89 -0
  338. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  339. data/lib/rubocop/cop/style/float_division.rb +8 -4
  340. data/lib/rubocop/cop/style/for.rb +1 -1
  341. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  342. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  343. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  344. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  345. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  346. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  347. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  348. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  349. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  350. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  351. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  352. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  353. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  354. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  355. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  356. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  357. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  358. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  359. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  360. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  361. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  362. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  363. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  364. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  365. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  366. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  367. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  368. data/lib/rubocop/cop/style/lambda.rb +1 -0
  369. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  370. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  371. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  372. data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
  373. data/lib/rubocop/cop/style/map_to_set.rb +4 -5
  374. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  379. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  380. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  381. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  382. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  383. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  384. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  385. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  386. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  387. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  388. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  389. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  390. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  391. data/lib/rubocop/cop/style/next.rb +44 -0
  392. data/lib/rubocop/cop/style/nil_comparison.rb +9 -7
  393. data/lib/rubocop/cop/style/not.rb +1 -1
  394. data/lib/rubocop/cop/style/object_then.rb +15 -15
  395. data/lib/rubocop/cop/style/one_line_conditional.rb +42 -13
  396. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  397. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  398. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  399. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  400. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  401. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  402. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  403. data/lib/rubocop/cop/style/proc.rb +2 -2
  404. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  405. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  406. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  407. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  408. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  409. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  410. data/lib/rubocop/cop/style/redundant_begin.rb +36 -1
  411. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  412. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  413. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  414. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  415. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  416. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  417. data/lib/rubocop/cop/style/redundant_format.rb +283 -0
  418. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  419. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  420. data/lib/rubocop/cop/style/redundant_interpolation.rb +12 -3
  421. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  422. data/lib/rubocop/cop/style/redundant_parentheses.rb +105 -36
  423. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +8 -0
  424. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  425. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -1
  426. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  427. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  428. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  429. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  430. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  431. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  432. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  433. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  434. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  435. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  436. data/lib/rubocop/cop/style/safe_navigation.rb +75 -16
  437. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  438. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  439. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  440. data/lib/rubocop/cop/style/semicolon.rb +21 -6
  441. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  442. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  443. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  444. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  445. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  446. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  447. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  448. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  449. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  450. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  451. data/lib/rubocop/cop/style/string_concatenation.rb +21 -17
  452. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  453. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  454. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  455. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  456. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  457. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  458. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  459. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  460. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  461. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +56 -2
  462. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  463. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  464. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  465. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  466. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  467. data/lib/rubocop/cop/style/unless_else.rb +10 -9
  468. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  469. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  470. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  471. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  472. data/lib/rubocop/cop/team.rb +1 -1
  473. data/lib/rubocop/cop/util.rb +12 -5
  474. data/lib/rubocop/cop/utils/format_string.rb +20 -5
  475. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  476. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  477. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  478. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  479. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  480. data/lib/rubocop/cop/variable_force.rb +30 -19
  481. data/lib/rubocop/cops_documentation_generator.rb +54 -28
  482. data/lib/rubocop/directive_comment.rb +45 -11
  483. data/lib/rubocop/ext/regexp_node.rb +0 -1
  484. data/lib/rubocop/formatter/disabled_config_formatter.rb +20 -6
  485. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  486. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  487. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  488. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  489. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  490. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  491. data/lib/rubocop/lsp/diagnostic.rb +190 -0
  492. data/lib/rubocop/lsp/logger.rb +2 -2
  493. data/lib/rubocop/lsp/routes.rb +66 -26
  494. data/lib/rubocop/lsp/runtime.rb +18 -50
  495. data/lib/rubocop/lsp/server.rb +2 -4
  496. data/lib/rubocop/lsp/stdin_runner.rb +69 -0
  497. data/lib/rubocop/magic_comment.rb +11 -3
  498. data/lib/rubocop/options.rb +28 -12
  499. data/lib/rubocop/path_util.rb +15 -8
  500. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  501. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  502. data/lib/rubocop/plugin/load_error.rb +26 -0
  503. data/lib/rubocop/plugin/loader.rb +100 -0
  504. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  505. data/lib/rubocop/plugin.rb +46 -0
  506. data/lib/rubocop/rake_task.rb +4 -1
  507. data/lib/rubocop/result_cache.rb +27 -25
  508. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  509. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  510. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  511. data/lib/rubocop/rspec/support.rb +4 -2
  512. data/lib/rubocop/runner.rb +31 -18
  513. data/lib/rubocop/server/cache.rb +51 -13
  514. data/lib/rubocop/server/cli.rb +2 -2
  515. data/lib/rubocop/server/client_command/base.rb +10 -0
  516. data/lib/rubocop/server/client_command/exec.rb +2 -1
  517. data/lib/rubocop/server/client_command/start.rb +11 -1
  518. data/lib/rubocop/target_finder.rb +14 -9
  519. data/lib/rubocop/target_ruby.rb +27 -3
  520. data/lib/rubocop/version.rb +53 -12
  521. data/lib/rubocop.rb +44 -2
  522. data/lib/ruby_lsp/rubocop/addon.rb +90 -0
  523. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +99 -0
  524. metadata +91 -21
  525. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  526. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -33,11 +33,13 @@ module RuboCop
33
33
  def_node_matcher :bad_method?, <<~PATTERN
34
34
  {
35
35
  (send $(csend ...) $_ ...)
36
- (send $({block numblock} (csend ...) ...) $_ ...)
36
+ (send $(any_block (csend ...) ...) $_ ...)
37
37
  }
38
38
  PATTERN
39
39
 
40
40
  def on_send(node)
41
+ return unless require_safe_navigation?(node)
42
+
41
43
  bad_method?(node) do |safe_nav, method|
42
44
  return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
43
45
 
@@ -52,6 +54,13 @@ module RuboCop
52
54
 
53
55
  private
54
56
 
57
+ def require_safe_navigation?(node)
58
+ parent = node.parent
59
+ return true unless parent&.and_type?
60
+
61
+ parent.rhs != node || parent.lhs.receiver != parent.rhs.receiver
62
+ end
63
+
55
64
  # @param [Parser::Source::Range] offense_range
56
65
  # @param [RuboCop::AST::SendNode] send_node
57
66
  # @return [String]
@@ -88,12 +97,19 @@ module RuboCop
88
97
  end
89
98
 
90
99
  def require_parentheses?(send_node)
100
+ return true if operator_inside_collection_literal?(send_node)
91
101
  return false unless send_node.comparison_method?
92
102
  return false unless (node = send_node.parent)
93
103
 
94
104
  (node.respond_to?(:logical_operator?) && node.logical_operator?) ||
95
105
  (node.respond_to?(:comparison_method?) && node.comparison_method?)
96
106
  end
107
+
108
+ def operator_inside_collection_literal?(send_node)
109
+ # If an operator call (without a dot) is inside an array or a hash, it needs
110
+ # to be parenthesized when converted to safe navigation.
111
+ send_node.parent&.type?(:array, :pair) && !send_node.loc.dot
112
+ end
97
113
  end
98
114
  end
99
115
  end
@@ -83,6 +83,8 @@ module RuboCop
83
83
  def find_consistent_parts(grouped_operands)
84
84
  csend_in_and, csend_in_or, send_in_and, send_in_or = most_left_indices(grouped_operands)
85
85
 
86
+ return if csend_in_and && csend_in_or && csend_in_and < csend_in_or
87
+
86
88
  if csend_in_and
87
89
  ['.', (send_in_and ? [send_in_and, csend_in_and].min : csend_in_and) + 1]
88
90
  elsif send_in_or && csend_in_or
@@ -94,7 +96,9 @@ module RuboCop
94
96
  # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
95
97
 
96
98
  def already_appropriate_call?(operand, dot_op)
97
- (operand.safe_navigation? && dot_op == '&.') || (operand.dot? && dot_op == '.')
99
+ return true if operand.safe_navigation? && dot_op == '&.'
100
+
101
+ (operand.dot? || operand.operator_method?) && dot_op == '.'
98
102
  end
99
103
 
100
104
  def register_offense(operand, dot_operator)
@@ -23,6 +23,14 @@ module RuboCop
23
23
  # # good (method calls possibly can return different results)
24
24
  # hash[foo] = hash[foo]
25
25
  #
26
+ # @example AllowRBSInlineAnnotation:true
27
+ # # good
28
+ # foo = foo #: Integer
29
+ # foo, bar = foo, bar #: Integer
30
+ # Foo = Foo #: Integer
31
+ # hash['foo'] = hash['foo'] #: Integer
32
+ # obj.attr = obj.attr #: Integer
33
+ #
26
34
  class SelfAssignment < Base
27
35
  MSG = 'Self-assignment detected.'
28
36
 
@@ -34,8 +42,10 @@ module RuboCop
34
42
  }.freeze
35
43
 
36
44
  def on_send(node)
45
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.receiver)
46
+
37
47
  if node.method?(:[]=)
38
- handle_key_assignment(node) if node.arguments.size == 2
48
+ handle_key_assignment(node)
39
49
  elsif node.assignment_method?
40
50
  handle_attribute_assignment(node) if node.arguments.size == 1
41
51
  end
@@ -43,39 +53,44 @@ module RuboCop
43
53
  alias on_csend on_send
44
54
 
45
55
  def on_lvasgn(node)
46
- lhs, rhs = *node
47
- return unless rhs
56
+ return unless node.rhs
57
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.rhs)
48
58
 
49
59
  rhs_type = ASSIGNMENT_TYPE_TO_RHS_TYPE[node.type]
50
60
 
51
- add_offense(node) if rhs.type == rhs_type && rhs.source == lhs.to_s
61
+ add_offense(node) if node.rhs.type == rhs_type && node.rhs.source == node.lhs.to_s
52
62
  end
53
63
  alias on_ivasgn on_lvasgn
54
64
  alias on_cvasgn on_lvasgn
55
65
  alias on_gvasgn on_lvasgn
56
66
 
57
67
  def on_casgn(node)
58
- lhs_scope, lhs_name, rhs = *node
59
- return unless rhs&.const_type?
68
+ return unless node.rhs&.const_type?
69
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.rhs)
60
70
 
61
- rhs_scope, rhs_name = *rhs
62
- add_offense(node) if lhs_scope == rhs_scope && lhs_name == rhs_name
71
+ add_offense(node) if node.namespace == node.rhs.namespace &&
72
+ node.short_name == node.rhs.short_name
63
73
  end
64
74
 
65
75
  def on_masgn(node)
76
+ first_lhs = node.lhs.assignments.first
77
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(first_lhs)
78
+
66
79
  add_offense(node) if multiple_self_assignment?(node)
67
80
  end
68
81
 
69
82
  def on_or_asgn(node)
70
- lhs, rhs = *node
71
- add_offense(node) if rhs_matches_lhs?(rhs, lhs)
83
+ return if allow_rbs_inline_annotation? && rbs_inline_annotation?(node.lhs)
84
+
85
+ add_offense(node) if rhs_matches_lhs?(node.rhs, node.lhs)
72
86
  end
73
87
  alias on_and_asgn on_or_asgn
74
88
 
75
89
  private
76
90
 
77
91
  def multiple_self_assignment?(node)
78
- lhs, rhs = *node
92
+ lhs = node.lhs
93
+ rhs = node.rhs
79
94
  return false unless rhs.array_type?
80
95
  return false unless lhs.children.size == rhs.children.size
81
96
 
@@ -90,12 +105,13 @@ module RuboCop
90
105
  end
91
106
 
92
107
  def handle_key_assignment(node)
93
- value_node = node.arguments[1]
108
+ value_node = node.last_argument
109
+ node_arguments = node.arguments[0...-1]
94
110
 
95
- if value_node.send_type? && value_node.method?(:[]) &&
111
+ if value_node.respond_to?(:method?) && value_node.method?(:[]) &&
96
112
  node.receiver == value_node.receiver &&
97
- !node.first_argument.call_type? &&
98
- node.first_argument == value_node.first_argument
113
+ node_arguments.none?(&:call_type?) &&
114
+ node_arguments == value_node.arguments
99
115
  add_offense(node)
100
116
  end
101
117
  end
@@ -110,6 +126,14 @@ module RuboCop
110
126
  add_offense(node)
111
127
  end
112
128
  end
129
+
130
+ def rbs_inline_annotation?(node)
131
+ processed_source.ast_with_comments[node].any? { |comment| comment.text.start_with?('#:') }
132
+ end
133
+
134
+ def allow_rbs_inline_annotation?
135
+ cop_config['AllowRBSInlineAnnotation']
136
+ end
113
137
  end
114
138
  end
115
139
  end
@@ -125,13 +125,13 @@ module RuboCop
125
125
  next false if assignment_node.shorthand_asgn?
126
126
  next false unless assignment_node.parent
127
127
 
128
- node_within_block_or_conditional =
129
- node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
128
+ conditional_assignment =
129
+ conditional_assignment?(assignment_node.parent, argument.scope.node)
130
130
 
131
131
  unless uses_var?(assignment_node, argument.name)
132
132
  # It's impossible to decide whether a branch or block is executed,
133
133
  # so the precise reassignment location is undecidable.
134
- next false if node_within_block_or_conditional
134
+ next false if conditional_assignment
135
135
 
136
136
  yield(assignment.node, location_known)
137
137
  break
@@ -147,13 +147,13 @@ module RuboCop
147
147
  node.source_range.begin_pos
148
148
  end
149
149
 
150
- # Check whether the given node is nested into block or conditional.
150
+ # Check whether the given node is always executed or not
151
151
  #
152
- def node_within_block_or_conditional?(node, stop_search_node)
152
+ def conditional_assignment?(node, stop_search_node)
153
153
  return false if node == stop_search_node
154
154
 
155
- node.conditional? || node.block_type? ||
156
- node_within_block_or_conditional?(node.parent, stop_search_node)
155
+ node.conditional? || node.type?(:block, :rescue) ||
156
+ conditional_assignment?(node.parent, stop_search_node)
157
157
  end
158
158
 
159
159
  # Get argument references without assignments' references
@@ -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|
@@ -8,6 +8,11 @@ module RuboCop
8
8
  # given by `ruby -cw` prior to Ruby 2.6:
9
9
  # "shadowing outer local variable - foo".
10
10
  #
11
+ # The cop is now disabled by default to match the upstream Ruby behavior.
12
+ # It's useful, however, if you'd like to avoid shadowing variables from outer
13
+ # scopes, which some people consider an anti-pattern that makes it harder
14
+ # to keep track of what's going on in a program.
15
+ #
11
16
  # NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed
12
17
  # because `Ractor` should not access outer variables.
13
18
  # eg. following style is encouraged:
@@ -56,19 +61,26 @@ module RuboCop
56
61
 
57
62
  outer_local_variable = variable_table.find_variable(variable.name)
58
63
  return unless outer_local_variable
64
+ return if variable_used_in_declaration_of_outer?(variable, outer_local_variable)
59
65
  return if same_conditions_node_different_branch?(variable, outer_local_variable)
60
66
 
61
67
  message = format(MSG, variable: variable.name)
62
68
  add_offense(variable.declaration_node, message: message)
63
69
  end
64
70
 
71
+ private
72
+
73
+ def variable_used_in_declaration_of_outer?(variable, outer_local_variable)
74
+ variable.scope.node.each_ancestor.any?(outer_local_variable.declaration_node)
75
+ end
76
+
65
77
  def same_conditions_node_different_branch?(variable, outer_local_variable)
66
78
  variable_node = variable_node(variable)
67
79
  return false unless node_or_its_ascendant_conditional?(variable_node)
68
80
 
69
81
  outer_local_variable_node =
70
82
  find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
71
- return true unless outer_local_variable_node
83
+ return false unless outer_local_variable_node
72
84
  return false unless outer_local_variable_node.conditional?
73
85
  return true if variable_node == outer_local_variable_node
74
86
 
@@ -0,0 +1,76 @@
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
+ {
55
+ (send (const {nil? cbase} :Hash) :new [
56
+ {array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
57
+ !#capacity_keyword_argument?
58
+ ])
59
+ (send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
60
+ }
61
+ PATTERN
62
+
63
+ # @!method capacity_keyword_argument?(node)
64
+ def_node_matcher :capacity_keyword_argument?, <<~PATTERN
65
+ (hash (pair (sym :capacity) _))
66
+ PATTERN
67
+
68
+ def on_send(node)
69
+ return unless hash_initialized_with_mutable_shared_object?(node)
70
+
71
+ add_offense(node)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ 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, :any_def, :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}\"")
@@ -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
@@ -45,7 +45,7 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_send(node)
48
- def_node = node.each_ancestor(:def, :defs).first
48
+ def_node = node.each_ancestor(:any_def).first
49
49
  return unless def_node
50
50
 
51
51
  enum_conversion_call?(node) do |method_node, arguments|
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # top-level return node's ancestors should not be of block, def, or
41
41
  # defs type.
42
42
  def top_level_return?(return_node)
43
- return_node.each_ancestor(:block, :def, :defs).none?
43
+ return_node.each_ancestor(:block, :any_def).none?
44
44
  end
45
45
  end
46
46
  end
@@ -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
@@ -53,6 +53,7 @@ module RuboCop
53
53
  end
54
54
 
55
55
  alias on_numblock on_block
56
+ alias on_itblock on_block
56
57
 
57
58
  private
58
59
 
@@ -74,6 +75,7 @@ module RuboCop
74
75
 
75
76
  def arg_count(node)
76
77
  return node.children[1] if node.numblock_type? # the maximum numbered param for the block
78
+ return 1 if node.itblock_type? # `it` block parameter is always one
77
79
 
78
80
  # Only `arg`, `optarg` and `mlhs` (destructuring) count as arguments that
79
81
  # can be used. Keyword arguments are not used for these methods so are
@@ -81,7 +83,7 @@ module RuboCop
81
83
  node.arguments.count do |arg|
82
84
  return Float::INFINITY if arg.restarg_type?
83
85
 
84
- arg.arg_type? || arg.optarg_type? || arg.mlhs_type?
86
+ arg.type?(:arg, :optarg, :mlhs)
85
87
  end
86
88
  end
87
89
  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