rubocop 1.67.0 → 1.76.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +22 -16
  4. data/config/default.yml +315 -53
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +1 -1
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +52 -9
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +51 -26
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  31. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  32. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +50 -6
  33. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  35. data/lib/rubocop/cop/generator.rb +6 -0
  36. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  37. data/lib/rubocop/cop/internal_affairs/example_description.rb +8 -4
  38. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  39. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  40. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  41. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  42. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  43. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  44. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  45. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  46. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -0
  47. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  48. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  49. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  50. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  51. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  52. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  53. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  54. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  55. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  56. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  57. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  58. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  59. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  60. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  61. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  62. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  63. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  64. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  65. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  66. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
  67. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  68. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  69. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  70. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  71. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  72. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +36 -6
  73. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  74. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  75. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  76. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  77. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  78. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  79. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  80. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  81. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  82. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  83. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  84. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  85. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  86. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  87. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  88. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  89. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  90. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  91. data/lib/rubocop/cop/layout/line_length.rb +123 -4
  92. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  93. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  94. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  95. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  96. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  97. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  98. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  99. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  100. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  101. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  102. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  103. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  104. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  105. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  106. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  107. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  108. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -1
  109. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  110. data/lib/rubocop/cop/layout/space_around_operators.rb +23 -21
  111. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  112. data/lib/rubocop/cop/layout/space_before_brackets.rb +8 -34
  113. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  114. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  115. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -1
  116. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  117. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  118. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  119. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  120. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  121. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  122. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  123. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  124. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  125. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  126. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  127. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  128. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  129. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  130. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  131. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  132. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  133. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  134. data/lib/rubocop/cop/lint/duplicate_methods.rb +86 -19
  135. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  136. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  137. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  138. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  139. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  140. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  141. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  142. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  143. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  144. data/lib/rubocop/cop/lint/float_comparison.rb +47 -14
  145. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  146. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  147. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  148. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  149. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  150. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  151. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  152. data/lib/rubocop/cop/lint/literal_as_condition.rb +110 -9
  153. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  154. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  155. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  156. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  157. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  158. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  159. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  160. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  161. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  162. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  163. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  164. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  165. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  166. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  167. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +93 -0
  168. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  169. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  170. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  171. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  172. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  173. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +1 -1
  174. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  175. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +12 -7
  176. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  177. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  178. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  179. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  180. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  181. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  182. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  183. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  184. data/lib/rubocop/cop/lint/rescue_type.rb +3 -7
  185. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  186. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  187. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  188. data/lib/rubocop/cop/lint/self_assignment.rb +8 -10
  189. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  190. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  191. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  192. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  193. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  194. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  195. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  196. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  197. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  198. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  199. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  200. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  201. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  202. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  203. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  204. data/lib/rubocop/cop/lint/useless_access_modifier.rb +5 -4
  205. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  206. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  207. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +87 -0
  208. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  209. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  210. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  211. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
  212. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  213. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  214. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
  215. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  216. data/lib/rubocop/cop/lint/void.rb +16 -12
  217. data/lib/rubocop/cop/message_annotator.rb +7 -3
  218. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  219. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  220. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  221. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  222. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  223. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  224. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  225. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  226. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  227. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  228. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  229. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  230. data/lib/rubocop/cop/mixin/alignment.rb +2 -2
  231. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  232. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  233. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  234. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  235. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  236. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  237. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  238. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  239. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  240. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  241. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  242. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +3 -2
  243. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  244. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  245. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  246. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  247. data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
  248. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  249. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  250. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  251. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  252. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  253. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  254. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  255. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  256. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  257. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  258. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  259. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  260. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  261. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  262. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  263. data/lib/rubocop/cop/naming/file_name.rb +0 -2
  264. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  265. data/lib/rubocop/cop/naming/method_name.rb +64 -8
  266. data/lib/rubocop/cop/naming/predicate_method.rb +216 -0
  267. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +46 -2
  268. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  269. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  270. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  271. data/lib/rubocop/cop/offense.rb +2 -3
  272. data/lib/rubocop/cop/registry.rb +9 -6
  273. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  274. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  275. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  276. data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
  277. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  278. data/lib/rubocop/cop/style/and_or.rb +1 -1
  279. data/lib/rubocop/cop/style/arguments_forwarding.rb +47 -28
  280. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  281. data/lib/rubocop/cop/style/array_intersect.rb +42 -30
  282. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  283. data/lib/rubocop/cop/style/block_delimiters.rb +43 -25
  284. data/lib/rubocop/cop/style/case_like_if.rb +8 -11
  285. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  286. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  287. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  288. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  289. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  290. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  291. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  292. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  293. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  294. data/lib/rubocop/cop/style/conditional_assignment.rb +39 -27
  295. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  296. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  297. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  298. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  299. data/lib/rubocop/cop/style/documentation.rb +1 -1
  300. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  301. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  302. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  303. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  304. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  305. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  306. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  307. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  308. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  309. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  310. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  311. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  312. data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
  313. data/lib/rubocop/cop/style/fetch_env_var.rb +2 -1
  314. data/lib/rubocop/cop/style/file_null.rb +89 -0
  315. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  316. data/lib/rubocop/cop/style/float_division.rb +8 -4
  317. data/lib/rubocop/cop/style/for.rb +1 -1
  318. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  319. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  320. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  321. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  322. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  323. data/lib/rubocop/cop/style/hash_conversion.rb +1 -2
  324. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  325. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  326. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  327. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  328. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  329. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  330. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  331. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  332. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  333. data/lib/rubocop/cop/style/if_unless_modifier.rb +25 -7
  334. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  335. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  336. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  337. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  338. data/lib/rubocop/cop/style/inverse_methods.rb +15 -12
  339. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  340. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  341. data/lib/rubocop/cop/style/it_assignment.rb +36 -0
  342. data/lib/rubocop/cop/style/it_block_parameter.rb +119 -0
  343. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  344. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  345. data/lib/rubocop/cop/style/lambda.rb +1 -0
  346. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  347. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  348. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  349. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  350. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  351. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -17
  352. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
  353. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  354. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  355. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  356. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  357. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  358. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  359. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  360. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  361. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  362. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  363. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  364. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  365. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  366. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  367. data/lib/rubocop/cop/style/next.rb +44 -0
  368. data/lib/rubocop/cop/style/not.rb +1 -1
  369. data/lib/rubocop/cop/style/object_then.rb +15 -15
  370. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  371. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  372. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  373. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  374. data/lib/rubocop/cop/style/parallel_assignment.rb +9 -18
  375. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  376. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  377. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  378. data/lib/rubocop/cop/style/proc.rb +2 -2
  379. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  380. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  381. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  382. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  383. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  384. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  385. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  386. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  387. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  388. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  389. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  390. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  391. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  392. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
  393. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  394. data/lib/rubocop/cop/style/redundant_line_continuation.rb +54 -18
  395. data/lib/rubocop/cop/style/redundant_parentheses.rb +68 -26
  396. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  397. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  398. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  399. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  400. data/lib/rubocop/cop/style/redundant_self.rb +9 -15
  401. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  402. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  403. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  404. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  405. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  406. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  407. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  408. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  409. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  410. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  412. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  413. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  414. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  415. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  416. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  417. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  418. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  419. data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
  420. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +42 -106
  422. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  423. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  424. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  425. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  426. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  427. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  428. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  429. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  430. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  431. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  432. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  433. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  434. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  435. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  436. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  437. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  438. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  439. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  440. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  441. data/lib/rubocop/cop/team.rb +1 -1
  442. data/lib/rubocop/cop/util.rb +12 -5
  443. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  444. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  445. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  446. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  447. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  448. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  449. data/lib/rubocop/cop/variable_force.rb +5 -11
  450. data/lib/rubocop/cops_documentation_generator.rb +50 -25
  451. data/lib/rubocop/directive_comment.rb +45 -11
  452. data/lib/rubocop/ext/regexp_node.rb +0 -1
  453. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  454. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  455. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  456. data/lib/rubocop/formatter/pacman_formatter.rb +1 -1
  457. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  458. data/lib/rubocop/lsp/logger.rb +2 -2
  459. data/lib/rubocop/lsp/routes.rb +7 -23
  460. data/lib/rubocop/lsp/runtime.rb +18 -50
  461. data/lib/rubocop/lsp/server.rb +0 -2
  462. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  463. data/lib/rubocop/magic_comment.rb +11 -3
  464. data/lib/rubocop/options.rb +28 -12
  465. data/lib/rubocop/path_util.rb +15 -8
  466. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  467. data/lib/rubocop/plugin/load_error.rb +26 -0
  468. data/lib/rubocop/plugin/loader.rb +100 -0
  469. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  470. data/lib/rubocop/plugin.rb +46 -0
  471. data/lib/rubocop/rake_task.rb +4 -1
  472. data/lib/rubocop/result_cache.rb +13 -13
  473. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  474. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  475. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  476. data/lib/rubocop/rspec/support.rb +4 -2
  477. data/lib/rubocop/runner.rb +26 -15
  478. data/lib/rubocop/server/cache.rb +47 -11
  479. data/lib/rubocop/server/cli.rb +2 -2
  480. data/lib/rubocop/target_finder.rb +7 -2
  481. data/lib/rubocop/target_ruby.rb +17 -2
  482. data/lib/rubocop/version.rb +53 -12
  483. data/lib/rubocop.rb +38 -2
  484. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  485. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  486. metadata +85 -21
  487. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  488. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -32,6 +32,23 @@ 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
+ alias on_itblock on_block
47
+
48
+ def after_block(node)
49
+ @instance_eval_count -= 1 if instance_eval_block?(node)
50
+ end
51
+
35
52
  def on_begin(node)
36
53
  expressions = *node
37
54
 
@@ -46,19 +63,23 @@ module RuboCop
46
63
 
47
64
  private
48
65
 
66
+ def redefinable_flow_method?(method)
67
+ %i[raise fail throw exit exit! abort].include? method
68
+ end
69
+
49
70
  # @!method flow_command?(node)
50
71
  def_node_matcher :flow_command?, <<~PATTERN
51
72
  {
52
73
  return next break retry redo
53
74
  (send
54
75
  {nil? (const {nil? cbase} :Kernel)}
55
- {:raise :fail :throw :exit :exit! :abort}
76
+ #redefinable_flow_method?
56
77
  ...)
57
78
  }
58
79
  PATTERN
59
80
 
60
81
  def flow_expression?(node)
61
- return true if flow_command?(node)
82
+ return report_on_flow_command?(node) if flow_command?(node)
62
83
 
63
84
  case node.type
64
85
  when :begin, :kwbegin
@@ -68,6 +89,8 @@ module RuboCop
68
89
  check_if(node)
69
90
  when :case, :case_match
70
91
  check_case(node)
92
+ when :def
93
+ register_redefinition(node)
71
94
  else
72
95
  false
73
96
  end
@@ -88,6 +111,33 @@ module RuboCop
88
111
 
89
112
  branches.all? { |branch| branch.body && flow_expression?(branch.body) }
90
113
  end
114
+
115
+ def register_redefinition(node)
116
+ @redefined << node.method_name if redefinable_flow_method? node.method_name
117
+ false
118
+ end
119
+
120
+ def instance_eval_block?(node)
121
+ node.any_block_type? && node.method?(:instance_eval)
122
+ end
123
+
124
+ def report_on_flow_command?(node)
125
+ return true unless node.send_type?
126
+
127
+ # By the contract of this function, this case means that
128
+ # the method is called on `Kernel` in which case we
129
+ # always want to report a warning.
130
+ return true if node.receiver
131
+
132
+ # Inside an `instance_eval` we have no way to tell the
133
+ # type of `self` just by looking at the AST, so we can't
134
+ # tell if the give function that's called has been
135
+ # redefined or not, so to avoid false positives, we silence
136
+ # the warning.
137
+ return false if @instance_eval_count.positive?
138
+
139
+ !@redefined.include? node.method_name
140
+ end
91
141
  end
92
142
  end
93
143
  end
@@ -101,14 +101,13 @@ module RuboCop
101
101
  check(node) if loop_method?(node)
102
102
  end
103
103
 
104
- def on_numblock(node)
105
- check(node) if loop_method?(node)
106
- end
104
+ alias on_numblock on_block
105
+ alias on_itblock on_block
107
106
 
108
107
  private
109
108
 
110
109
  def loop_method?(node)
111
- return false unless node.block_type? || node.numblock_type?
110
+ return false unless node.any_block_type?
112
111
 
113
112
  send_node = node.send_node
114
113
  loopable = send_node.enumerable_method? || send_node.enumerator_method? ||
@@ -189,8 +188,9 @@ module RuboCop
189
188
 
190
189
  def preceded_by_continue_statement?(break_statement)
191
190
  break_statement.left_siblings.any? do |sibling|
192
- # Numblocks have the arguments count as a number in the AST.
193
- next if sibling.is_a?(Integer)
191
+ # Numblocks have the arguments count as a number or,
192
+ # itblocks have `:it` symbol in the AST.
193
+ next if sibling.is_a?(Integer) || sibling.is_a?(Symbol)
194
194
  next if sibling.loop_keyword? || loop_method?(sibling)
195
195
 
196
196
  sibling.each_descendant(*CONTINUE_KEYWORDS).any?
@@ -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
@@ -143,6 +143,7 @@ module RuboCop
143
143
  end
144
144
 
145
145
  alias on_numblock on_block
146
+ alias on_itblock on_block
146
147
 
147
148
  private
148
149
 
@@ -159,12 +160,12 @@ module RuboCop
159
160
 
160
161
  # @!method dynamic_method_definition?(node)
161
162
  def_node_matcher :dynamic_method_definition?, <<~PATTERN
162
- {(send nil? :define_method ...) ({block numblock} (send nil? :define_method ...) ...)}
163
+ {(send nil? :define_method ...) (any_block (send nil? :define_method ...) ...)}
163
164
  PATTERN
164
165
 
165
166
  # @!method class_or_instance_eval?(node)
166
167
  def_node_matcher :class_or_instance_eval?, <<~PATTERN
167
- ({block numblock} (send _ {:class_eval :instance_eval}) ...)
168
+ (any_block (send _ {:class_eval :instance_eval}) ...)
168
169
  PATTERN
169
170
 
170
171
  def check_node(node)
@@ -268,7 +269,7 @@ module RuboCop
268
269
  end
269
270
 
270
271
  def start_of_new_scope?(child)
271
- child.module_type? || child.class_type? || child.sclass_type? || eval_call?(child)
272
+ child.type?(:module, :class, :sclass) || eval_call?(child)
272
273
  end
273
274
 
274
275
  def eval_call?(child)
@@ -282,7 +283,7 @@ module RuboCop
282
283
  matcher_name = :"#{m}_block?"
283
284
  unless respond_to?(matcher_name)
284
285
  self.class.def_node_matcher matcher_name, <<~PATTERN
285
- ({block numblock} (send {nil? const} {:#{m}} ...) ...)
286
+ (any_block (send {nil? const} {:#{m}} ...) ...)
286
287
  PATTERN
287
288
  end
288
289
 
@@ -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
  #
@@ -104,6 +104,8 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def chained_assignment?(node)
107
+ return true if node.lvasgn_type? && node.expression&.send_type?
108
+
107
109
  node.respond_to?(:expression) && node.expression&.lvasgn_type?
108
110
  end
109
111
 
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for useless constant scoping. Private constants must be defined using
7
+ # `private_constant`. Even if `private` access modifier is used, it is public scope despite
8
+ # its appearance.
9
+ #
10
+ # It does not support autocorrection due to behavior change and multiple ways to fix it.
11
+ # Or a public constant may be intended.
12
+ #
13
+ # @example
14
+ #
15
+ # # bad
16
+ # class Foo
17
+ # private
18
+ # PRIVATE_CONST = 42
19
+ # end
20
+ #
21
+ # # good
22
+ # class Foo
23
+ # PRIVATE_CONST = 42
24
+ # private_constant :PRIVATE_CONST
25
+ # end
26
+ #
27
+ # # good
28
+ # class Foo
29
+ # PUBLIC_CONST = 42 # If private scope is not intended.
30
+ # end
31
+ #
32
+ class UselessConstantScoping < Base
33
+ MSG = 'Useless `private` access modifier for constant scope.'
34
+
35
+ # @!method private_constants(node)
36
+ def_node_matcher :private_constants, <<~PATTERN
37
+ (send nil? :private_constant $...)
38
+ PATTERN
39
+
40
+ def on_casgn(node)
41
+ return unless after_private_modifier?(node.left_siblings)
42
+ return if private_constantize?(node.right_siblings, node.name)
43
+
44
+ add_offense(node)
45
+ end
46
+
47
+ private
48
+
49
+ def after_private_modifier?(left_siblings)
50
+ access_modifier_candidates = left_siblings.compact.select do |left_sibling|
51
+ left_sibling.respond_to?(:send_type?) && left_sibling.send_type?
52
+ end
53
+
54
+ access_modifier_candidates.any? do |candidate|
55
+ candidate.command?(:private) && candidate.arguments.none?
56
+ end
57
+ end
58
+
59
+ def private_constantize?(right_siblings, const_value)
60
+ private_constant_arguments = right_siblings.map { |node| private_constants(node) }
61
+
62
+ private_constant_values = private_constant_arguments.flatten.filter_map do |constant|
63
+ constant.value.to_sym if constant.respond_to?(:value)
64
+ end
65
+
66
+ private_constant_values.include?(const_value)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for usage of method `fetch` or `Array.new` with default value argument
7
+ # and block. In such cases, block will always be used as default value.
8
+ #
9
+ # This cop emulates Ruby warning "block supersedes default value argument" which
10
+ # applies to `Array.new`, `Array#fetch`, `Hash#fetch`, `ENV.fetch` and
11
+ # `Thread#fetch`.
12
+ #
13
+ # @safety
14
+ # This cop is unsafe because the receiver could have nonstandard implementation
15
+ # of `fetch`, or be a class other than the one listed above.
16
+ #
17
+ # It is also unsafe because default value argument could have side effects:
18
+ #
19
+ # [source,ruby]
20
+ # ----
21
+ # def x(a) = puts "side effect"
22
+ # Array.new(5, x(1)) { 2 }
23
+ # ----
24
+ #
25
+ # so removing it would change behavior.
26
+ #
27
+ # @example
28
+ # # bad
29
+ # x.fetch(key, default_value) { block_value }
30
+ # Array.new(size, default_value) { block_value }
31
+ #
32
+ # # good
33
+ # x.fetch(key) { block_value }
34
+ # Array.new(size) { block_value }
35
+ #
36
+ # # also good - in case default value argument is desired instead
37
+ # x.fetch(key, default_value)
38
+ # Array.new(size, default_value)
39
+ #
40
+ # # good - keyword arguments aren't registered as offenses
41
+ # x.fetch(key, keyword: :arg) { block_value }
42
+ #
43
+ # @example AllowedReceivers: ['Rails.cache']
44
+ # # good
45
+ # Rails.cache.fetch(name, options) { block }
46
+ #
47
+ class UselessDefaultValueArgument < Base
48
+ include AllowedReceivers
49
+ extend AutoCorrector
50
+
51
+ MSG = 'Block supersedes default value argument.'
52
+
53
+ RESTRICT_ON_SEND = %i[fetch new].freeze
54
+
55
+ # @!method default_value_argument_and_block(node)
56
+ def_node_matcher :default_value_argument_and_block, <<~PATTERN
57
+ (any_block
58
+ {
59
+ (call _receiver :fetch $_key $_default_value)
60
+ (send (const _ :Array) :new $_size $_default_value)
61
+ }
62
+ _args
63
+ _block_body)
64
+ PATTERN
65
+
66
+ def on_send(node)
67
+ unless (prev_arg_node, default_value_node = default_value_argument_and_block(node.parent))
68
+ return
69
+ end
70
+ return if allowed_receiver?(node.receiver)
71
+ return if hash_without_braces?(default_value_node)
72
+
73
+ add_offense(default_value_node) do |corrector|
74
+ corrector.remove(prev_arg_node.source_range.end.join(default_value_node.source_range))
75
+ end
76
+ end
77
+ alias on_csend on_send
78
+
79
+ private
80
+
81
+ def hash_without_braces?(node)
82
+ node.hash_type? && !node.braces?
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for calls to `defined?` with strings or symbols as the argument.
7
+ # Such calls will always return `'expression'`, you probably meant to
8
+ # check for the existence of a constant, method, or variable instead.
9
+ #
10
+ # `defined?` is part of the Ruby syntax and doesn't behave like normal methods.
11
+ # You can safely pass in what you are checking for directly, without encountering
12
+ # a `NameError`.
13
+ #
14
+ # When interpolation is used, oftentimes it is not possible to write the
15
+ # code with `defined?`. In these cases, switch to one of the more specific methods:
16
+ #
17
+ # * `class_variable_defined?`
18
+ # * `const_defined?`
19
+ # * `method_defined?`
20
+ # * `instance_variable_defined?`
21
+ # * `binding.local_variable_defined?`
22
+ #
23
+ # @example
24
+ #
25
+ # # bad
26
+ # defined?('FooBar')
27
+ # defined?(:FooBar)
28
+ # defined?(:foo_bar)
29
+ # defined?('foo_bar')
30
+ #
31
+ # # good
32
+ # defined?(FooBar)
33
+ # defined?(foo_bar)
34
+ #
35
+ # # bad - interpolation
36
+ # bar = 'Bar'
37
+ # defined?("Foo::#{bar}::Baz")
38
+ #
39
+ # # good
40
+ # bar = 'Bar'
41
+ # defined?(Foo) && Foo.const_defined?(bar) && Foo.const_get(bar).const_defined?(:Baz)
42
+ class UselessDefined < Base
43
+ MSG = 'Calling `defined?` with a %<type>s argument will always return a truthy value.'
44
+ TYPES = { str: 'string', dstr: 'string', sym: 'symbol', dsym: 'symbol' }.freeze
45
+
46
+ def on_defined?(node)
47
+ # NOTE: `defined?` always takes one argument. Anything else is a syntax error.
48
+ return unless (type = TYPES[node.first_argument.type])
49
+
50
+ add_offense(node, message: format(MSG, type: type))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -25,8 +25,12 @@ module RuboCop
25
25
  # do_something_else
26
26
  # end
27
27
  class UselessElseWithoutRescue < Base
28
+ extend TargetRubyVersion
29
+
28
30
  MSG = '`else` without `rescue` is useless.'
29
31
 
32
+ maximum_target_ruby_version 2.5
33
+
30
34
  def on_new_investigation
31
35
  processed_source.diagnostics.each do |diagnostic|
32
36
  next unless diagnostic.reason == :useless_else
@@ -59,7 +59,7 @@ module RuboCop
59
59
  end
60
60
 
61
61
  def use_rest_or_optional_args?(node)
62
- node.arguments.any? { |arg| arg.restarg_type? || arg.optarg_type? || arg.kwoptarg_type? }
62
+ node.arguments.any? { |arg| arg.type?(:restarg, :optarg, :kwoptarg) }
63
63
  end
64
64
 
65
65
  def delegating?(node, def_node)
@@ -35,7 +35,7 @@ module RuboCop
35
35
  RESTRICT_ON_SEND = %i[+ - * / **].freeze
36
36
 
37
37
  # @!method useless_operation?(node)
38
- def_node_matcher :useless_operation?, '(send (send nil? $_) $_ (int $_))'
38
+ def_node_matcher :useless_operation?, '(call (call nil? $_) $_ (int $_))'
39
39
 
40
40
  # @!method useless_abbreviated_assignment?(node)
41
41
  def_node_matcher :useless_abbreviated_assignment?, '(op-asgn (lvasgn $_) $_ (int $_))'
@@ -50,6 +50,7 @@ module RuboCop
50
50
  corrector.replace(node, variable)
51
51
  end
52
52
  end
53
+ alias on_csend on_send
53
54
 
54
55
  def on_op_asgn(node)
55
56
  return unless useless_abbreviated_assignment?(node)
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for useless OR (`||` and `or`) expressions.
7
+ #
8
+ # Some methods always return a truthy value, even when called
9
+ # on `nil` (e.g. `nil.to_i` evaluates to `0`). Therefore, OR expressions
10
+ # appended after these methods will never evaluate.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ # x.to_a || fallback
16
+ # x.to_c || fallback
17
+ # x.to_d || fallback
18
+ # x.to_i || fallback
19
+ # x.to_f || fallback
20
+ # x.to_h || fallback
21
+ # x.to_r || fallback
22
+ # x.to_s || fallback
23
+ # x.to_sym || fallback
24
+ # x.intern || fallback
25
+ # x.inspect || fallback
26
+ # x.hash || fallback
27
+ # x.object_id || fallback
28
+ # x.__id__ || fallback
29
+ #
30
+ # x.to_s or fallback
31
+ #
32
+ # # good - if fallback is same as return value of method called on nil
33
+ # x.to_a # nil.to_a returns []
34
+ # x.to_c # nil.to_c returns (0+0i)
35
+ # x.to_d # nil.to_d returns 0.0
36
+ # x.to_i # nil.to_i returns 0
37
+ # x.to_f # nil.to_f returns 0.0
38
+ # x.to_h # nil.to_h returns {}
39
+ # x.to_r # nil.to_r returns (0/1)
40
+ # x.to_s # nil.to_s returns ''
41
+ # x.to_sym # nil.to_sym raises an error
42
+ # x.intern # nil.intern raises an error
43
+ # x.inspect # nil.inspect returns "nil"
44
+ # x.hash # nil.hash returns an Integer
45
+ # x.object_id # nil.object_id returns an Integer
46
+ # x.__id__ # nil.object_id returns an Integer
47
+ #
48
+ # # good - if the intention is not to call the method on nil
49
+ # x&.to_a || fallback
50
+ # x&.to_c || fallback
51
+ # x&.to_d || fallback
52
+ # x&.to_i || fallback
53
+ # x&.to_f || fallback
54
+ # x&.to_h || fallback
55
+ # x&.to_r || fallback
56
+ # x&.to_s || fallback
57
+ # x&.to_sym || fallback
58
+ # x&.intern || fallback
59
+ # x&.inspect || fallback
60
+ # x&.hash || fallback
61
+ # x&.object_id || fallback
62
+ # x&.__id__ || fallback
63
+ #
64
+ # x&.to_s or fallback
65
+ #
66
+ class UselessOr < Base
67
+ MSG = '`%<rhs>s` will never evaluate because `%<lhs>s` always returns a truthy value.'
68
+
69
+ TRUTHY_RETURN_VALUE_METHODS = Set[:to_a, :to_c, :to_d, :to_i, :to_f, :to_h, :to_r,
70
+ :to_s, :to_sym, :intern, :inspect, :hash, :object_id,
71
+ :__id__].freeze
72
+
73
+ # @!method truthy_return_value_method?(node)
74
+ def_node_matcher :truthy_return_value_method?, <<~PATTERN
75
+ (send _ %TRUTHY_RETURN_VALUE_METHODS)
76
+ PATTERN
77
+
78
+ def on_or(node)
79
+ if truthy_return_value_method?(node.lhs)
80
+ report_offense(node, node.lhs)
81
+ elsif truthy_return_value_method?(node.rhs)
82
+ parent = node.parent
83
+ parent = parent.parent if parent&.begin_type?
84
+
85
+ report_offense(parent, node.rhs) if parent&.or_type?
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ def report_offense(or_node, truthy_node)
92
+ add_offense(or_node.loc.operator.join(or_node.rhs.source_range),
93
+ message: format(MSG, lhs: truthy_node.source, rhs: or_node.rhs.source))
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for useless `rescue`s, which only reraise rescued exceptions.
6
+ # Checks for useless ``rescue``s, which only reraise rescued exceptions.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -75,7 +75,7 @@ module RuboCop
75
75
  def use_exception_variable_in_ensure?(resbody_node)
76
76
  return false unless (exception_variable = resbody_node.exception_variable)
77
77
  return false unless (ensure_node = resbody_node.each_ancestor(:ensure).first)
78
- return false unless (ensure_body = ensure_node.body)
78
+ return false unless (ensure_body = ensure_node.branch)
79
79
 
80
80
  ensure_body.each_descendant(:lvar).map(&:source).include?(exception_variable.source)
81
81
  end
@@ -72,7 +72,7 @@ module RuboCop
72
72
  def_node_matcher :method_definition, <<~PATTERN
73
73
  {
74
74
  (def %1 ...)
75
- ({block numblock} (send _ :define_method (sym %1)) ...)
75
+ (any_block (send _ :define_method (sym %1)) ...)
76
76
  }
77
77
  PATTERN
78
78
 
@@ -108,7 +108,7 @@ module RuboCop
108
108
 
109
109
  def find_method_definition(node, method_name)
110
110
  node.each_ancestor.lazy.map do |ancestor|
111
- ancestor.each_child_node(:def, :block, :numblock).find do |child|
111
+ ancestor.each_child_node(:def, :any_block).find do |child|
112
112
  method_definition(child, method_name)
113
113
  end
114
114
  end.find(&:itself)