rubocop 1.67.0 → 1.79.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +23 -19
  4. data/config/default.yml +371 -71
  5. data/config/internal_affairs.yml +20 -0
  6. data/config/obsoletion.yml +8 -3
  7. data/lib/rubocop/cached_data.rb +12 -4
  8. data/lib/rubocop/cli/command/execute_runner.rb +4 -4
  9. data/lib/rubocop/cli/command/show_cops.rb +24 -2
  10. data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
  11. data/lib/rubocop/cli/command/version.rb +2 -2
  12. data/lib/rubocop/cli.rb +13 -2
  13. data/lib/rubocop/comment_config.rb +2 -2
  14. data/lib/rubocop/config.rb +52 -10
  15. data/lib/rubocop/config_loader.rb +53 -47
  16. data/lib/rubocop/config_loader_resolver.rb +36 -10
  17. data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
  18. data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
  19. data/lib/rubocop/config_obsoletion.rb +46 -2
  20. data/lib/rubocop/config_validator.rb +25 -14
  21. data/lib/rubocop/cop/autocorrect_logic.rb +51 -26
  22. data/lib/rubocop/cop/base.rb +7 -1
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  24. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  25. data/lib/rubocop/cop/bundler/gem_filename.rb +0 -1
  26. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +0 -1
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  28. data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -12
  29. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +1 -1
  30. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
  31. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  32. data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
  33. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -2
  34. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
  35. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  36. data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
  37. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +0 -2
  38. data/lib/rubocop/cop/generator.rb +6 -0
  39. data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
  40. data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
  41. data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
  42. data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
  43. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -4
  44. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
  45. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
  46. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
  47. data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
  48. data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
  49. data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
  50. data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
  51. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
  52. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
  54. data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +48 -0
  55. data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
  56. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
  57. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
  58. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
  59. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +0 -2
  60. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
  61. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
  62. data/lib/rubocop/cop/internal_affairs.rb +7 -16
  63. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
  64. data/lib/rubocop/cop/layout/argument_alignment.rb +2 -9
  65. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  66. data/lib/rubocop/cop/layout/begin_end_alignment.rb +0 -1
  67. data/lib/rubocop/cop/layout/block_alignment.rb +3 -2
  68. data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
  69. data/lib/rubocop/cop/layout/class_structure.rb +44 -9
  70. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
  71. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  72. data/lib/rubocop/cop/layout/dot_position.rb +1 -1
  73. data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
  74. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +3 -3
  75. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
  76. data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +99 -0
  77. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +37 -7
  78. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
  79. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
  80. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +4 -5
  81. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +23 -1
  82. data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
  83. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  84. data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
  85. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
  86. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
  87. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
  88. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  89. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
  90. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
  91. data/lib/rubocop/cop/layout/indentation_width.rb +8 -7
  92. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  93. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
  94. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
  95. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
  96. data/lib/rubocop/cop/layout/line_length.rb +149 -9
  97. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
  98. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
  99. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
  100. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +2 -1
  101. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
  102. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +1 -1
  103. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
  104. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +3 -4
  105. data/lib/rubocop/cop/layout/parameter_alignment.rb +3 -4
  106. data/lib/rubocop/cop/layout/redundant_line_break.rb +19 -46
  107. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -7
  108. data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
  109. data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
  110. data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
  113. data/lib/rubocop/cop/layout/space_around_keyword.rb +8 -2
  114. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
  115. data/lib/rubocop/cop/layout/space_around_operators.rb +31 -21
  116. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
  117. data/lib/rubocop/cop/layout/space_before_brackets.rb +7 -40
  118. data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
  119. data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
  120. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +18 -3
  121. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +5 -0
  122. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +7 -0
  123. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +0 -1
  124. data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
  125. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
  126. data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
  127. data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
  128. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
  129. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +10 -12
  130. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
  131. data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -1
  132. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
  133. data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
  134. data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
  135. data/lib/rubocop/cop/lint/debugger.rb +3 -3
  136. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  137. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +3 -2
  138. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  139. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
  140. data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
  141. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
  142. data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
  143. data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
  144. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  145. data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
  146. data/lib/rubocop/cop/lint/empty_file.rb +0 -2
  147. data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
  148. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  149. data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
  150. data/lib/rubocop/cop/lint/float_comparison.rb +51 -18
  151. data/lib/rubocop/cop/lint/float_out_of_range.rb +2 -4
  152. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  153. data/lib/rubocop/cop/lint/hash_new_with_keyword_arguments_as_default.rb +55 -0
  154. data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
  155. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  156. data/lib/rubocop/cop/lint/interpolation_check.rb +9 -0
  157. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +3 -0
  158. data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
  159. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +1 -1
  160. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
  161. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
  162. data/lib/rubocop/cop/lint/missing_super.rb +2 -2
  163. data/lib/rubocop/cop/lint/mixed_case_range.rb +5 -8
  164. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  165. data/lib/rubocop/cop/lint/nested_method_definition.rb +10 -6
  166. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  167. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +2 -2
  168. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +12 -3
  169. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
  170. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
  171. data/lib/rubocop/cop/lint/number_conversion.rb +0 -1
  172. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -2
  173. data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +94 -0
  174. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -3
  175. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +3 -2
  176. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
  177. data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
  178. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
  179. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
  180. data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
  181. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +113 -9
  182. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -7
  183. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
  184. data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
  185. data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
  186. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
  187. data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
  188. data/lib/rubocop/cop/lint/regexp_as_condition.rb +0 -1
  189. data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
  190. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  191. data/lib/rubocop/cop/lint/rescue_type.rb +4 -8
  192. data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
  193. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -1
  194. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +5 -1
  195. data/lib/rubocop/cop/lint/self_assignment.rb +33 -10
  196. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -1
  197. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
  198. data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
  199. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  200. data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
  201. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  202. data/lib/rubocop/cop/lint/syntax.rb +4 -1
  203. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
  204. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
  205. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  206. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
  207. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
  208. data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
  209. data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
  210. data/lib/rubocop/cop/lint/unused_method_argument.rb +18 -2
  211. data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
  212. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
  213. data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
  214. data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
  215. data/lib/rubocop/cop/lint/useless_defined.rb +55 -0
  216. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
  217. data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
  218. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
  219. data/lib/rubocop/cop/lint/useless_or.rb +98 -0
  220. data/lib/rubocop/cop/lint/useless_rescue.rb +2 -2
  221. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
  222. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -25
  223. data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
  224. data/lib/rubocop/cop/lint/void.rb +16 -12
  225. data/lib/rubocop/cop/message_annotator.rb +7 -3
  226. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  227. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  228. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  229. data/lib/rubocop/cop/metrics/class_length.rb +9 -9
  230. data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
  231. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +5 -2
  232. data/lib/rubocop/cop/metrics/method_length.rb +9 -1
  233. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  234. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
  235. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  236. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +3 -4
  237. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
  238. data/lib/rubocop/cop/mixin/alignment.rb +3 -3
  239. data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
  240. data/lib/rubocop/cop/mixin/check_assignment.rb +4 -12
  241. data/lib/rubocop/cop/mixin/check_line_breakable.rb +22 -12
  242. data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +49 -0
  243. data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
  244. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  245. data/lib/rubocop/cop/mixin/dig_help.rb +27 -0
  246. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
  247. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  248. data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
  249. data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
  250. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -3
  251. data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
  252. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
  253. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
  254. data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
  255. data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
  256. data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
  257. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  258. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +7 -9
  259. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  260. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  261. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
  262. data/lib/rubocop/cop/mixin/range_help.rb +15 -4
  263. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  264. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
  265. data/lib/rubocop/cop/mixin/string_help.rb +2 -2
  266. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  267. data/lib/rubocop/cop/mixin/target_ruby_version.rb +17 -1
  268. data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
  269. data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
  270. data/lib/rubocop/cop/naming/block_forwarding.rb +20 -16
  271. data/lib/rubocop/cop/naming/constant_name.rb +6 -7
  272. data/lib/rubocop/cop/naming/file_name.rb +2 -4
  273. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +12 -13
  274. data/lib/rubocop/cop/naming/method_name.rb +185 -15
  275. data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
  276. data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
  277. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +6 -14
  278. data/lib/rubocop/cop/naming/variable_name.rb +50 -6
  279. data/lib/rubocop/cop/naming/variable_number.rb +2 -3
  280. data/lib/rubocop/cop/offense.rb +2 -3
  281. data/lib/rubocop/cop/registry.rb +9 -6
  282. data/lib/rubocop/cop/security/compound_hash.rb +2 -0
  283. data/lib/rubocop/cop/security/eval.rb +2 -1
  284. data/lib/rubocop/cop/security/open.rb +1 -0
  285. data/lib/rubocop/cop/security/yaml_load.rb +3 -2
  286. data/lib/rubocop/cop/style/access_modifier_declarations.rb +114 -34
  287. data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
  288. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  289. data/lib/rubocop/cop/style/and_or.rb +1 -1
  290. data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
  291. data/lib/rubocop/cop/style/array_first_last.rb +18 -2
  292. data/lib/rubocop/cop/style/array_intersect.rb +84 -42
  293. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  294. data/lib/rubocop/cop/style/block_delimiters.rb +44 -26
  295. data/lib/rubocop/cop/style/case_like_if.rb +9 -12
  296. data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
  297. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
  298. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  299. data/lib/rubocop/cop/style/collection_querying.rb +167 -0
  300. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  301. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  302. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  303. data/lib/rubocop/cop/style/commented_keyword.rb +20 -3
  304. data/lib/rubocop/cop/style/comparable_between.rb +78 -0
  305. data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
  306. data/lib/rubocop/cop/style/conditional_assignment.rb +42 -28
  307. data/lib/rubocop/cop/style/constant_visibility.rb +3 -12
  308. data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
  309. data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
  310. data/lib/rubocop/cop/style/dig_chain.rb +89 -0
  311. data/lib/rubocop/cop/style/documentation.rb +1 -1
  312. data/lib/rubocop/cop/style/double_negation.rb +4 -4
  313. data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
  314. data/lib/rubocop/cop/style/each_with_object.rb +2 -3
  315. data/lib/rubocop/cop/style/empty_else.rb +4 -2
  316. data/lib/rubocop/cop/style/empty_literal.rb +5 -1
  317. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  318. data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
  319. data/lib/rubocop/cop/style/endless_method.rb +150 -18
  320. data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
  321. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
  322. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
  323. data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
  324. data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
  325. data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
  326. data/lib/rubocop/cop/style/file_null.rb +89 -0
  327. data/lib/rubocop/cop/style/file_touch.rb +75 -0
  328. data/lib/rubocop/cop/style/float_division.rb +8 -4
  329. data/lib/rubocop/cop/style/for.rb +1 -1
  330. data/lib/rubocop/cop/style/format_string_token.rb +38 -11
  331. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
  332. data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
  333. data/lib/rubocop/cop/style/global_vars.rb +1 -3
  334. data/lib/rubocop/cop/style/guard_clause.rb +17 -3
  335. data/lib/rubocop/cop/style/hash_conversion.rb +16 -9
  336. data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
  337. data/lib/rubocop/cop/style/hash_except.rb +35 -147
  338. data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
  339. data/lib/rubocop/cop/style/hash_slice.rb +80 -0
  340. data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
  341. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  342. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  343. data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
  344. data/lib/rubocop/cop/style/if_inside_else.rb +10 -14
  345. data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
  346. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
  347. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +3 -4
  348. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -9
  349. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  350. data/lib/rubocop/cop/style/inverse_methods.rb +16 -13
  351. data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
  352. data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
  353. data/lib/rubocop/cop/style/it_assignment.rb +93 -0
  354. data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
  355. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  356. data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
  357. data/lib/rubocop/cop/style/lambda.rb +1 -0
  358. data/lib/rubocop/cop/style/lambda_call.rb +10 -4
  359. data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
  360. data/lib/rubocop/cop/style/map_into_array.rb +11 -3
  361. data/lib/rubocop/cop/style/map_to_hash.rb +12 -1
  362. data/lib/rubocop/cop/style/map_to_set.rb +3 -2
  363. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +28 -20
  364. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
  365. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +8 -11
  366. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
  367. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  368. data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
  369. data/lib/rubocop/cop/style/missing_else.rb +2 -0
  370. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +33 -3
  371. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  372. data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
  373. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  374. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
  375. data/lib/rubocop/cop/style/multiple_comparison.rb +52 -51
  376. data/lib/rubocop/cop/style/mutable_constant.rb +7 -8
  377. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -5
  378. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  379. data/lib/rubocop/cop/style/nested_ternary_operator.rb +5 -4
  380. data/lib/rubocop/cop/style/next.rb +44 -0
  381. data/lib/rubocop/cop/style/not.rb +1 -1
  382. data/lib/rubocop/cop/style/object_then.rb +15 -15
  383. data/lib/rubocop/cop/style/one_line_conditional.rb +25 -4
  384. data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
  385. data/lib/rubocop/cop/style/operator_method_call.rb +5 -6
  386. data/lib/rubocop/cop/style/or_assignment.rb +3 -6
  387. data/lib/rubocop/cop/style/parallel_assignment.rb +41 -38
  388. data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
  389. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  390. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  391. data/lib/rubocop/cop/style/proc.rb +2 -2
  392. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  393. data/lib/rubocop/cop/style/raise_args.rb +15 -13
  394. data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
  395. data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
  396. data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
  397. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -1
  398. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  399. data/lib/rubocop/cop/style/redundant_condition.rb +95 -23
  400. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
  401. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
  402. data/lib/rubocop/cop/style/redundant_each.rb +1 -1
  403. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  404. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
  405. data/lib/rubocop/cop/style/redundant_format.rb +262 -0
  406. data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
  407. data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
  408. data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
  409. data/lib/rubocop/cop/style/redundant_line_continuation.rb +55 -19
  410. data/lib/rubocop/cop/style/redundant_parentheses.rb +86 -26
  411. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -0
  412. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  413. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  414. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  415. data/lib/rubocop/cop/style/redundant_self.rb +15 -18
  416. data/lib/rubocop/cop/style/redundant_self_assignment.rb +20 -32
  417. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +4 -4
  418. data/lib/rubocop/cop/style/redundant_sort.rb +3 -3
  419. data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
  420. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
  421. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  422. data/lib/rubocop/cop/style/rescue_modifier.rb +5 -3
  423. data/lib/rubocop/cop/style/return_nil.rb +2 -2
  424. data/lib/rubocop/cop/style/safe_navigation.rb +56 -16
  425. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  426. data/lib/rubocop/cop/style/select_by_regexp.rb +5 -2
  427. data/lib/rubocop/cop/style/self_assignment.rb +11 -17
  428. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  429. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
  430. data/lib/rubocop/cop/style/signal_exception.rb +2 -3
  431. data/lib/rubocop/cop/style/single_argument_dig.rb +9 -5
  432. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  433. data/lib/rubocop/cop/style/single_line_do_end_block.rb +15 -4
  434. data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
  435. data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
  436. data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -102
  437. data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
  438. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
  439. data/lib/rubocop/cop/style/string_concatenation.rb +15 -15
  440. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  441. data/lib/rubocop/cop/style/string_methods.rb +1 -1
  442. data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
  443. data/lib/rubocop/cop/style/super_arguments.rb +66 -19
  444. data/lib/rubocop/cop/style/swap_values.rb +4 -15
  445. data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
  446. data/lib/rubocop/cop/style/ternary_parentheses.rb +25 -4
  447. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
  448. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
  449. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
  450. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  451. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
  452. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -4
  453. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  454. data/lib/rubocop/cop/style/variable_interpolation.rb +1 -2
  455. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  456. data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
  457. data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
  458. data/lib/rubocop/cop/team.rb +1 -1
  459. data/lib/rubocop/cop/util.rb +12 -5
  460. data/lib/rubocop/cop/utils/format_string.rb +10 -5
  461. data/lib/rubocop/cop/variable_force/assignment.rb +24 -5
  462. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  463. data/lib/rubocop/cop/variable_force/scope.rb +1 -1
  464. data/lib/rubocop/cop/variable_force/variable.rb +14 -3
  465. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -5
  466. data/lib/rubocop/cop/variable_force.rb +23 -18
  467. data/lib/rubocop/cops_documentation_generator.rb +51 -25
  468. data/lib/rubocop/directive_comment.rb +45 -11
  469. data/lib/rubocop/ext/regexp_node.rb +0 -1
  470. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
  471. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  472. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  473. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  474. data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
  475. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  476. data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
  477. data/lib/rubocop/lsp/diagnostic.rb +189 -0
  478. data/lib/rubocop/lsp/logger.rb +2 -2
  479. data/lib/rubocop/lsp/routes.rb +10 -26
  480. data/lib/rubocop/lsp/runtime.rb +18 -50
  481. data/lib/rubocop/lsp/server.rb +0 -2
  482. data/lib/rubocop/lsp/stdin_runner.rb +85 -0
  483. data/lib/rubocop/magic_comment.rb +11 -3
  484. data/lib/rubocop/options.rb +28 -12
  485. data/lib/rubocop/path_util.rb +15 -8
  486. data/lib/rubocop/pending_cops_reporter.rb +56 -0
  487. data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
  488. data/lib/rubocop/plugin/load_error.rb +26 -0
  489. data/lib/rubocop/plugin/loader.rb +100 -0
  490. data/lib/rubocop/plugin/not_supported_error.rb +29 -0
  491. data/lib/rubocop/plugin.rb +46 -0
  492. data/lib/rubocop/rake_task.rb +4 -1
  493. data/lib/rubocop/result_cache.rb +13 -13
  494. data/lib/rubocop/rspec/cop_helper.rb +13 -1
  495. data/lib/rubocop/rspec/expect_offense.rb +15 -5
  496. data/lib/rubocop/rspec/shared_contexts.rb +38 -1
  497. data/lib/rubocop/rspec/support.rb +4 -2
  498. data/lib/rubocop/runner.rb +26 -15
  499. data/lib/rubocop/server/cache.rb +51 -13
  500. data/lib/rubocop/server/cli.rb +2 -2
  501. data/lib/rubocop/server/client_command/base.rb +10 -0
  502. data/lib/rubocop/server/client_command/exec.rb +2 -1
  503. data/lib/rubocop/server/client_command/start.rb +11 -1
  504. data/lib/rubocop/target_finder.rb +7 -2
  505. data/lib/rubocop/target_ruby.rb +17 -2
  506. data/lib/rubocop/version.rb +53 -12
  507. data/lib/rubocop.rb +43 -2
  508. data/lib/ruby_lsp/rubocop/addon.rb +75 -0
  509. data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
  510. metadata +89 -17
  511. data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
  512. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -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,90 @@
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
+ # A `fetch` call without a receiver is considered a custom method and does not register
14
+ # an offense.
15
+ #
16
+ # @safety
17
+ # This cop is unsafe because the receiver could have nonstandard implementation
18
+ # of `fetch`, or be a class other than the one listed above.
19
+ #
20
+ # It is also unsafe because default value argument could have side effects:
21
+ #
22
+ # [source,ruby]
23
+ # ----
24
+ # def x(a) = puts "side effect"
25
+ # Array.new(5, x(1)) { 2 }
26
+ # ----
27
+ #
28
+ # so removing it would change behavior.
29
+ #
30
+ # @example
31
+ # # bad
32
+ # x.fetch(key, default_value) { block_value }
33
+ # Array.new(size, default_value) { block_value }
34
+ #
35
+ # # good
36
+ # x.fetch(key) { block_value }
37
+ # Array.new(size) { block_value }
38
+ #
39
+ # # also good - in case default value argument is desired instead
40
+ # x.fetch(key, default_value)
41
+ # Array.new(size, default_value)
42
+ #
43
+ # # good - keyword arguments aren't registered as offenses
44
+ # x.fetch(key, keyword: :arg) { block_value }
45
+ #
46
+ # @example AllowedReceivers: ['Rails.cache']
47
+ # # good
48
+ # Rails.cache.fetch(name, options) { block }
49
+ #
50
+ class UselessDefaultValueArgument < Base
51
+ include AllowedReceivers
52
+ extend AutoCorrector
53
+
54
+ MSG = 'Block supersedes default value argument.'
55
+
56
+ RESTRICT_ON_SEND = %i[fetch new].freeze
57
+
58
+ # @!method default_value_argument_and_block(node)
59
+ def_node_matcher :default_value_argument_and_block, <<~PATTERN
60
+ (any_block
61
+ {
62
+ (call !nil? :fetch $_key $_default_value)
63
+ (send (const _ :Array) :new $_size $_default_value)
64
+ }
65
+ _args
66
+ _block_body)
67
+ PATTERN
68
+
69
+ def on_send(node)
70
+ unless (prev_arg_node, default_value_node = default_value_argument_and_block(node.parent))
71
+ return
72
+ end
73
+ return if allowed_receiver?(node.receiver)
74
+ return if hash_without_braces?(default_value_node)
75
+
76
+ add_offense(default_value_node) do |corrector|
77
+ corrector.remove(prev_arg_node.source_range.end.join(default_value_node.source_range))
78
+ end
79
+ end
80
+ alias on_csend on_send
81
+
82
+ private
83
+
84
+ def hash_without_braces?(node)
85
+ node.hash_type? && !node.braces?
86
+ end
87
+ end
88
+ end
89
+ end
90
+ 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)
@@ -31,11 +31,12 @@ module RuboCop
31
31
  #
32
32
  class UselessNumericOperation < Base
33
33
  extend AutoCorrector
34
+
34
35
  MSG = 'Do not apply inconsequential numeric operations to variables.'
35
36
  RESTRICT_ON_SEND = %i[+ - * / **].freeze
36
37
 
37
38
  # @!method useless_operation?(node)
38
- def_node_matcher :useless_operation?, '(send (send nil? $_) $_ (int $_))'
39
+ def_node_matcher :useless_operation?, '(call (call nil? $_) $_ (int $_))'
39
40
 
40
41
  # @!method useless_abbreviated_assignment?(node)
41
42
  def_node_matcher :useless_abbreviated_assignment?, '(op-asgn (lvasgn $_) $_ (int $_))'
@@ -50,6 +51,7 @@ module RuboCop
50
51
  corrector.replace(node, variable)
51
52
  end
52
53
  end
54
+ alias on_csend on_send
53
55
 
54
56
  def on_op_asgn(node)
55
57
  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
 
@@ -89,7 +89,7 @@ module RuboCop
89
89
  private
90
90
 
91
91
  def inspect_def(node, def_node)
92
- return if allowed_arguments(def_node.arguments)
92
+ return if allowed_arguments?(def_node.arguments)
93
93
 
94
94
  add_offense(node.loc.selector, message: format(MSG, method_name: def_node.method_name))
95
95
  end
@@ -101,21 +101,21 @@ module RuboCop
101
101
  definition = find_method_definition(node, method_name)
102
102
 
103
103
  return unless definition
104
- return if allowed_arguments(definition.arguments)
104
+ return if allowed_arguments?(definition.arguments)
105
105
 
106
106
  add_offense(node, message: format(MSG, method_name: method_name))
107
107
  end
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)
115
115
  end
116
116
 
117
117
  # `ruby2_keywords` is only allowed if there's a `restarg` and no keyword arguments
118
- def allowed_arguments(arguments)
118
+ def allowed_arguments?(arguments)
119
119
  return false if arguments.empty?
120
120
 
121
121
  arguments.each_child_node(:restarg).any? &&
@@ -102,24 +102,18 @@ module RuboCop
102
102
  when :op_asgn
103
103
  process_binary_operator_assignment(node)
104
104
  when *ASSIGNMENT_TYPES
105
- _, rhs_node = *node
106
- process_assignment(node, rhs_node) if rhs_node
105
+ process_assignment(node, node.rhs) if node.rhs
107
106
  end
108
107
  end
109
108
 
110
109
  def process_multiple_assignment(masgn_node)
111
- mlhs_node, mrhs_node = *masgn_node
112
-
113
- mlhs_node.children.each_with_index do |lhs_node, index|
110
+ masgn_node.assignments.each_with_index do |lhs_node, index|
114
111
  next unless ASSIGNMENT_TYPES.include?(lhs_node.type)
115
112
 
116
- lhs_variable_name, = *lhs_node
117
- rhs_node = mrhs_node.children[index]
118
-
119
- if mrhs_node.array_type? && rhs_node
120
- process_assignment(lhs_variable_name, rhs_node)
113
+ if masgn_node.rhs.array_type? && (rhs_node = masgn_node.rhs.children[index])
114
+ process_assignment(lhs_node, rhs_node)
121
115
  else
122
- @local[lhs_variable_name] = true
116
+ @local[lhs_node.name] = true
123
117
  end
124
118
  end
125
119
 
@@ -127,33 +121,28 @@ module RuboCop
127
121
  end
128
122
 
129
123
  def process_logical_operator_assignment(asgn_node)
130
- lhs_node, rhs_node = *asgn_node
131
- return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
124
+ return unless ASSIGNMENT_TYPES.include?(asgn_node.lhs.type)
132
125
 
133
- process_assignment(lhs_node, rhs_node)
126
+ process_assignment(asgn_node.lhs, asgn_node.rhs)
134
127
 
135
128
  throw :skip_children
136
129
  end
137
130
 
138
131
  def process_binary_operator_assignment(op_asgn_node)
139
- lhs_node, = *op_asgn_node
132
+ lhs_node = op_asgn_node.lhs
140
133
  return unless ASSIGNMENT_TYPES.include?(lhs_node.type)
141
134
 
142
- lhs_variable_name, = *lhs_node
143
- @local[lhs_variable_name] = true
135
+ @local[lhs_node.name] = true
144
136
 
145
137
  throw :skip_children
146
138
  end
147
139
 
148
140
  def process_assignment(asgn_node, rhs_node)
149
- lhs_variable_name, = *asgn_node
150
-
151
- @local[lhs_variable_name] = if rhs_node.variable?
152
- rhs_variable_name, = *rhs_node
153
- @local[rhs_variable_name]
154
- else
155
- constructor?(rhs_node)
156
- end
141
+ @local[asgn_node.name] = if rhs_node.variable?
142
+ @local[rhs_node.name]
143
+ else
144
+ constructor?(rhs_node)
145
+ end
157
146
  end
158
147
 
159
148
  def constructor?(node)
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ module Utils
7
+ # Utility class that checks if the receiver can't be nil.
8
+ class NilReceiverChecker
9
+ NIL_METHODS = (nil.methods + %i[!]).to_set.freeze
10
+
11
+ def initialize(receiver, additional_nil_methods)
12
+ @receiver = receiver
13
+ @additional_nil_methods = additional_nil_methods
14
+ @checked_nodes = {}.compare_by_identity
15
+ end
16
+
17
+ def cant_be_nil?
18
+ sole_condition_of_parent_if?(@receiver) || _cant_be_nil?(@receiver.parent, @receiver)
19
+ end
20
+
21
+ private
22
+
23
+ # rubocop:disable Metrics
24
+ def _cant_be_nil?(node, receiver)
25
+ return false unless node
26
+
27
+ # For some nodes, we check their parent and then some children for these parents.
28
+ # This is added to avoid infinite loops.
29
+ return false if @checked_nodes.key?(node)
30
+
31
+ @checked_nodes[node] = true
32
+
33
+ case node.type
34
+ when :def, :class, :module, :sclass
35
+ return false
36
+ when :send
37
+ return non_nil_method?(node.method_name) if node.receiver == receiver
38
+
39
+ node.arguments.each do |argument|
40
+ return true if _cant_be_nil?(argument, receiver)
41
+ end
42
+
43
+ return true if _cant_be_nil?(node.receiver, receiver)
44
+ when :begin
45
+ return true if _cant_be_nil?(node.children.first, receiver)
46
+ when :if, :case
47
+ return true if _cant_be_nil?(node.condition, receiver)
48
+ when :and, :or
49
+ return true if _cant_be_nil?(node.lhs, receiver)
50
+ when :pair
51
+ if _cant_be_nil?(node.key, receiver) ||
52
+ _cant_be_nil?(node.value, receiver)
53
+ return true
54
+ end
55
+ when :when
56
+ node.each_condition do |condition|
57
+ return true if _cant_be_nil?(condition, receiver)
58
+ end
59
+ when :lvasgn, :ivasgn, :cvasgn, :gvasgn, :casgn
60
+ return true if _cant_be_nil?(node.expression, receiver)
61
+ end
62
+
63
+ # Due to how `if/else` are implemented (`elsif` is a child of `if` or another `elsif`),
64
+ # using left_siblings will not work correctly for them.
65
+ if !else_branch?(node) || (node.if_type? && !node.elsif?)
66
+ node.left_siblings.reverse_each do |sibling|
67
+ next unless sibling.is_a?(AST::Node)
68
+
69
+ return true if _cant_be_nil?(sibling, receiver)
70
+ end
71
+ end
72
+
73
+ if node.parent
74
+ _cant_be_nil?(node.parent, receiver)
75
+ else
76
+ false
77
+ end
78
+ end
79
+ # rubocop:enable Metrics
80
+
81
+ def non_nil_method?(method_name)
82
+ !NIL_METHODS.include?(method_name) && !@additional_nil_methods.include?(method_name)
83
+ end
84
+
85
+ # rubocop:disable Metrics/PerceivedComplexity
86
+ def sole_condition_of_parent_if?(node)
87
+ parent = node.parent
88
+
89
+ while parent
90
+ if parent.if_type?
91
+ if parent.condition == node
92
+ return true
93
+ elsif parent.elsif?
94
+ parent = find_top_if(parent)
95
+ end
96
+ elsif else_branch?(parent)
97
+ # Find the top `if` for `else`.
98
+ parent = parent.parent
99
+ end
100
+
101
+ parent = parent&.parent
102
+ end
103
+
104
+ false
105
+ end
106
+ # rubocop:enable Metrics/PerceivedComplexity
107
+
108
+ def else_branch?(node)
109
+ node.parent&.if_type? && node.parent.else_branch == node
110
+ end
111
+
112
+ def find_top_if(node)
113
+ node = node.parent while node.elsif?
114
+
115
+ node
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end