rubocop 1.42.0 → 1.64.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 (498) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +7 -6
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +342 -64
  7. data/config/obsoletion.yml +5 -0
  8. data/lib/rubocop/cached_data.rb +11 -3
  9. data/lib/rubocop/cli/command/auto_generate_config.rb +27 -6
  10. data/lib/rubocop/cli/command/execute_runner.rb +7 -2
  11. data/lib/rubocop/cli/command/lsp.rb +19 -0
  12. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  13. data/lib/rubocop/cli.rb +68 -10
  14. data/lib/rubocop/comment_config.rb +19 -0
  15. data/lib/rubocop/config.rb +43 -15
  16. data/lib/rubocop/config_finder.rb +14 -4
  17. data/lib/rubocop/config_loader.rb +20 -24
  18. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  19. data/lib/rubocop/config_obsoletion.rb +13 -10
  20. data/lib/rubocop/config_validator.rb +14 -7
  21. data/lib/rubocop/cop/autocorrect_logic.rb +37 -14
  22. data/lib/rubocop/cop/base.rb +97 -28
  23. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  24. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  25. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  26. data/lib/rubocop/cop/bundler/gem_version.rb +5 -7
  27. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  28. data/lib/rubocop/cop/commissioner.rb +8 -2
  29. data/lib/rubocop/cop/cop.rb +25 -5
  30. data/lib/rubocop/cop/corrector.rb +11 -3
  31. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -3
  32. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  33. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +6 -14
  34. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  37. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +2 -7
  38. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  39. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
  40. data/lib/rubocop/cop/documentation.rb +16 -6
  41. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  42. data/lib/rubocop/cop/force.rb +12 -0
  43. data/lib/rubocop/cop/gemspec/dependency_version.rb +6 -8
  44. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +3 -3
  45. data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
  46. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  47. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  48. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  49. data/lib/rubocop/cop/internal_affairs/cop_description.rb +37 -13
  50. data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
  51. data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +3 -3
  52. data/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb +1 -1
  53. data/lib/rubocop/cop/internal_affairs/location_expression.rb +37 -0
  54. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  55. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  56. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  57. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  58. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +128 -34
  59. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  60. data/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb +42 -0
  61. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  62. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
  63. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  64. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -1
  65. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  66. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +66 -0
  67. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  68. data/lib/rubocop/cop/internal_affairs.rb +5 -0
  69. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  70. data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
  71. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -15
  72. data/lib/rubocop/cop/layout/class_structure.rb +15 -19
  73. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +2 -3
  74. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
  75. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  76. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  77. data/lib/rubocop/cop/layout/empty_comment.rb +6 -4
  78. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +42 -9
  79. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  80. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +28 -5
  81. data/lib/rubocop/cop/layout/empty_lines.rb +1 -1
  82. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -0
  83. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  84. data/lib/rubocop/cop/layout/end_alignment.rb +23 -3
  85. data/lib/rubocop/cop/layout/extra_spacing.rb +3 -4
  86. data/lib/rubocop/cop/layout/first_argument_indentation.rb +8 -3
  87. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
  88. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
  89. data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
  90. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
  91. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
  92. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  93. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +12 -6
  94. data/lib/rubocop/cop/layout/heredoc_indentation.rb +12 -12
  95. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  96. data/lib/rubocop/cop/layout/indentation_width.rb +3 -3
  97. data/lib/rubocop/cop/layout/initial_indentation.rb +1 -1
  98. data/lib/rubocop/cop/layout/leading_comment_space.rb +2 -2
  99. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +18 -12
  100. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +12 -8
  101. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  102. data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
  103. data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
  104. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
  105. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  106. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
  107. data/lib/rubocop/cop/layout/redundant_line_break.rb +33 -11
  108. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -6
  109. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  110. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  111. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  114. data/lib/rubocop/cop/layout/space_around_operators.rb +53 -21
  115. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  116. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -1
  117. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +2 -2
  118. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +11 -13
  119. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -1
  120. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  121. data/lib/rubocop/cop/layout/space_inside_parens.rb +3 -3
  122. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  123. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  124. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +4 -4
  125. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +6 -6
  126. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  127. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  128. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -1
  129. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
  130. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
  131. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  132. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  133. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  134. data/lib/rubocop/cop/lint/debugger.rb +49 -26
  135. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
  136. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -1
  137. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  138. data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +122 -0
  139. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  140. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +47 -22
  141. data/lib/rubocop/cop/lint/else_layout.rb +3 -7
  142. data/lib/rubocop/cop/lint/empty_block.rb +2 -2
  143. data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -4
  144. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  145. data/lib/rubocop/cop/lint/erb_new_arguments.rb +27 -21
  146. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  147. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -7
  148. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  149. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +16 -18
  150. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  151. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  152. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  153. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  154. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
  156. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  157. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  158. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +47 -5
  159. data/lib/rubocop/cop/lint/missing_super.rb +63 -5
  160. data/lib/rubocop/cop/lint/mixed_case_range.rb +116 -0
  161. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  162. data/lib/rubocop/cop/lint/nested_method_definition.rb +4 -9
  163. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
  164. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -7
  165. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  166. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  167. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  168. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +2 -0
  169. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  170. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +8 -12
  171. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
  172. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  173. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +11 -5
  174. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +5 -5
  175. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  176. data/lib/rubocop/cop/lint/redundant_require_statement.rb +21 -2
  177. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  178. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  179. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +35 -15
  180. data/lib/rubocop/cop/lint/redundant_with_index.rb +7 -3
  181. data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -3
  182. data/lib/rubocop/cop/lint/refinement_import_methods.rb +2 -1
  183. data/lib/rubocop/cop/lint/rescue_type.rb +2 -4
  184. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +14 -8
  185. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +1 -1
  186. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  187. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  188. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  189. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  190. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -12
  191. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +7 -1
  192. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  193. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  194. data/lib/rubocop/cop/lint/symbol_conversion.rb +8 -3
  195. data/lib/rubocop/cop/lint/syntax.rb +10 -3
  196. data/lib/rubocop/cop/lint/to_enum_arguments.rb +23 -6
  197. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  198. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  199. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +2 -2
  200. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
  201. data/lib/rubocop/cop/lint/unreachable_loop.rb +11 -5
  202. data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -9
  203. data/lib/rubocop/cop/lint/useless_assignment.rb +94 -10
  204. data/lib/rubocop/cop/lint/useless_method_definition.rb +12 -4
  205. data/lib/rubocop/cop/lint/useless_rescue.rb +89 -0
  206. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +9 -1
  207. data/lib/rubocop/cop/lint/useless_times.rb +3 -3
  208. data/lib/rubocop/cop/lint/void.rb +119 -20
  209. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  210. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  211. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  212. data/lib/rubocop/cop/metrics/class_length.rb +8 -2
  213. data/lib/rubocop/cop/metrics/collection_literal_length.rb +76 -0
  214. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
  215. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  216. data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
  217. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +3 -7
  218. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +38 -10
  219. data/lib/rubocop/cop/migration/department_name.rb +3 -3
  220. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  221. data/lib/rubocop/cop/mixin/allowed_methods.rb +3 -1
  222. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  223. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
  224. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  225. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  226. data/lib/rubocop/cop/mixin/comments_help.rb +21 -11
  227. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  228. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  229. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  230. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  231. data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +1 -1
  232. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +78 -29
  233. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  234. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  235. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -1
  236. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  237. data/lib/rubocop/cop/mixin/min_branches_count.rb +40 -0
  238. data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +0 -3
  239. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  240. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
  241. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  242. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  243. data/lib/rubocop/cop/mixin/range_help.rb +1 -6
  244. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  245. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  246. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  247. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -3
  248. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  249. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  250. data/lib/rubocop/cop/mixin/trailing_comma.rb +3 -3
  251. data/lib/rubocop/cop/naming/ascii_identifiers.rb +1 -1
  252. data/lib/rubocop/cop/naming/block_forwarding.rb +38 -7
  253. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +1 -1
  254. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  255. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  256. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +1 -1
  257. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  258. data/lib/rubocop/cop/naming/inclusive_language.rb +24 -6
  259. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  260. data/lib/rubocop/cop/naming/method_name.rb +3 -3
  261. data/lib/rubocop/cop/naming/predicate_name.rb +3 -3
  262. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -4
  263. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  264. data/lib/rubocop/cop/registry.rb +16 -9
  265. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  266. data/lib/rubocop/cop/security/open.rb +2 -2
  267. data/lib/rubocop/cop/style/access_modifier_declarations.rb +78 -13
  268. data/lib/rubocop/cop/style/accessor_grouping.rb +44 -18
  269. data/lib/rubocop/cop/style/alias.rb +10 -8
  270. data/lib/rubocop/cop/style/arguments_forwarding.rb +414 -62
  271. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  272. data/lib/rubocop/cop/style/array_intersect.rb +14 -6
  273. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  274. data/lib/rubocop/cop/style/attr.rb +11 -1
  275. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  276. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  277. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +3 -3
  278. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  279. data/lib/rubocop/cop/style/block_delimiters.rb +22 -6
  280. data/lib/rubocop/cop/style/case_like_if.rb +25 -8
  281. data/lib/rubocop/cop/style/class_and_module_children.rb +5 -12
  282. data/lib/rubocop/cop/style/class_check.rb +1 -0
  283. data/lib/rubocop/cop/style/class_equality_comparison.rb +58 -40
  284. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  285. data/lib/rubocop/cop/style/collection_compact.rb +37 -14
  286. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  287. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  288. data/lib/rubocop/cop/style/combinable_loops.rb +36 -8
  289. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  290. data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
  291. data/lib/rubocop/cop/style/commented_keyword.rb +7 -4
  292. data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
  293. data/lib/rubocop/cop/style/concat_array_literals.rb +12 -3
  294. data/lib/rubocop/cop/style/conditional_assignment.rb +15 -20
  295. data/lib/rubocop/cop/style/copyright.rb +37 -24
  296. data/lib/rubocop/cop/style/data_inheritance.rb +75 -0
  297. data/lib/rubocop/cop/style/date_time.rb +5 -4
  298. data/lib/rubocop/cop/style/dir.rb +1 -1
  299. data/lib/rubocop/cop/style/dir_empty.rb +54 -0
  300. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +2 -2
  301. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +3 -3
  302. data/lib/rubocop/cop/style/documentation.rb +36 -30
  303. data/lib/rubocop/cop/style/documentation_method.rb +30 -4
  304. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  305. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
  306. data/lib/rubocop/cop/style/each_with_object.rb +3 -3
  307. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  308. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  309. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  310. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  311. data/lib/rubocop/cop/style/eval_with_location.rb +14 -23
  312. data/lib/rubocop/cop/style/exact_regexp_match.rb +70 -0
  313. data/lib/rubocop/cop/style/explicit_block_argument.rb +3 -3
  314. data/lib/rubocop/cop/style/file_empty.rb +71 -0
  315. data/lib/rubocop/cop/style/file_read.rb +3 -3
  316. data/lib/rubocop/cop/style/file_write.rb +1 -1
  317. data/lib/rubocop/cop/style/for.rb +3 -1
  318. data/lib/rubocop/cop/style/format_string.rb +33 -12
  319. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +4 -2
  320. data/lib/rubocop/cop/style/guard_clause.rb +29 -1
  321. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  322. data/lib/rubocop/cop/style/hash_each_methods.rb +106 -21
  323. data/lib/rubocop/cop/style/hash_except.rb +25 -13
  324. data/lib/rubocop/cop/style/hash_like_case.rb +3 -9
  325. data/lib/rubocop/cop/style/hash_syntax.rb +29 -3
  326. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  327. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  328. data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
  329. data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
  330. data/lib/rubocop/cop/style/if_unless_modifier.rb +111 -15
  331. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +7 -3
  332. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
  333. data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
  334. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  335. data/lib/rubocop/cop/style/invertible_unless_condition.rb +160 -0
  336. data/lib/rubocop/cop/style/lambda.rb +3 -3
  337. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  338. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +8 -10
  339. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  340. data/lib/rubocop/cop/style/map_to_hash.rb +20 -7
  341. data/lib/rubocop/cop/style/map_to_set.rb +5 -2
  342. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +48 -28
  343. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +46 -41
  344. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +22 -0
  345. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  346. data/lib/rubocop/cop/style/min_max.rb +3 -3
  347. data/lib/rubocop/cop/style/min_max_comparison.rb +11 -1
  348. data/lib/rubocop/cop/style/missing_else.rb +13 -1
  349. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  350. data/lib/rubocop/cop/style/mixin_grouping.rb +5 -5
  351. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  352. data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
  353. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  354. data/lib/rubocop/cop/style/multiline_method_signature.rb +17 -5
  355. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +21 -4
  356. data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
  357. data/lib/rubocop/cop/style/negated_if_else_condition.rb +13 -12
  358. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  359. data/lib/rubocop/cop/style/next.rb +1 -1
  360. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  361. data/lib/rubocop/cop/style/nil_lambda.rb +2 -2
  362. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +11 -3
  363. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  364. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  365. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  366. data/lib/rubocop/cop/style/object_then.rb +5 -3
  367. data/lib/rubocop/cop/style/one_line_conditional.rb +4 -7
  368. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  369. data/lib/rubocop/cop/style/operator_method_call.rb +24 -4
  370. data/lib/rubocop/cop/style/parallel_assignment.rb +32 -24
  371. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  372. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -3
  373. data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
  374. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  375. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  376. data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
  377. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  378. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  379. data/lib/rubocop/cop/style/redundant_begin.rb +10 -2
  380. data/lib/rubocop/cop/style/redundant_condition.rb +18 -3
  381. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -14
  382. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
  383. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +103 -9
  384. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  385. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  386. data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -7
  387. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  388. data/lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb +58 -0
  389. data/lib/rubocop/cop/style/redundant_interpolation.rb +2 -2
  390. data/lib/rubocop/cop/style/redundant_line_continuation.rb +200 -0
  391. data/lib/rubocop/cop/style/redundant_parentheses.rb +73 -24
  392. data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -2
  393. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +100 -0
  394. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +7 -8
  395. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  396. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +13 -4
  397. data/lib/rubocop/cop/style/redundant_return.rb +14 -3
  398. data/lib/rubocop/cop/style/redundant_self.rb +17 -2
  399. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +8 -1
  400. data/lib/rubocop/cop/style/redundant_sort.rb +13 -12
  401. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  402. data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -5
  403. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  404. data/lib/rubocop/cop/style/require_order.rb +12 -15
  405. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
  406. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  407. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  408. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +95 -0
  409. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  410. data/lib/rubocop/cop/style/sample.rb +3 -4
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +22 -11
  412. data/lib/rubocop/cop/style/self_assignment.rb +3 -3
  413. data/lib/rubocop/cop/style/semicolon.rb +43 -5
  414. data/lib/rubocop/cop/style/send.rb +4 -4
  415. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +90 -0
  416. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  417. data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
  418. data/lib/rubocop/cop/style/single_line_do_end_block.rb +67 -0
  419. data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
  420. data/lib/rubocop/cop/style/slicing_with_range.rb +77 -11
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +9 -5
  422. data/lib/rubocop/cop/style/special_global_vars.rb +4 -6
  423. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  424. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  425. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
  426. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  427. data/lib/rubocop/cop/style/strip.rb +7 -4
  428. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  429. data/lib/rubocop/cop/style/super_arguments.rb +156 -0
  430. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  431. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  432. data/lib/rubocop/cop/style/symbol_proc.rb +68 -5
  433. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  434. data/lib/rubocop/cop/style/trailing_body_on_class.rb +1 -0
  435. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -1
  436. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  437. data/lib/rubocop/cop/style/unless_logical_operators.rb +1 -0
  438. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  439. data/lib/rubocop/cop/style/word_array.rb +18 -6
  440. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  441. data/lib/rubocop/cop/style/yoda_condition.rb +17 -8
  442. data/lib/rubocop/cop/style/yoda_expression.rb +26 -9
  443. data/lib/rubocop/cop/style/zero_length_predicate.rb +9 -5
  444. data/lib/rubocop/cop/team.rb +36 -23
  445. data/lib/rubocop/cop/util.rb +14 -5
  446. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  447. data/lib/rubocop/cop/variable_force/assignment.rb +45 -4
  448. data/lib/rubocop/cop/variable_force/scope.rb +3 -3
  449. data/lib/rubocop/cop/variable_force/variable.rb +5 -3
  450. data/lib/rubocop/cop/variable_force/variable_table.rb +5 -3
  451. data/lib/rubocop/cop/variable_force.rb +2 -1
  452. data/lib/rubocop/cops_documentation_generator.rb +26 -7
  453. data/lib/rubocop/directive_comment.rb +13 -11
  454. data/lib/rubocop/ext/comment.rb +18 -0
  455. data/lib/rubocop/ext/regexp_node.rb +10 -5
  456. data/lib/rubocop/ext/regexp_parser.rb +5 -2
  457. data/lib/rubocop/file_finder.rb +4 -7
  458. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  459. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  460. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  461. data/lib/rubocop/formatter/html_formatter.rb +35 -14
  462. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  463. data/lib/rubocop/formatter/junit_formatter.rb +4 -1
  464. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  465. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  466. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  467. data/lib/rubocop/formatter.rb +1 -2
  468. data/lib/rubocop/lockfile.rb +56 -7
  469. data/lib/rubocop/lsp/logger.rb +22 -0
  470. data/lib/rubocop/lsp/routes.rb +243 -0
  471. data/lib/rubocop/lsp/runtime.rb +99 -0
  472. data/lib/rubocop/lsp/server.rb +73 -0
  473. data/lib/rubocop/lsp/severity.rb +27 -0
  474. data/lib/rubocop/lsp.rb +36 -0
  475. data/lib/rubocop/magic_comment.rb +13 -11
  476. data/lib/rubocop/options.rb +49 -12
  477. data/lib/rubocop/path_util.rb +17 -8
  478. data/lib/rubocop/rake_task.rb +1 -1
  479. data/lib/rubocop/result_cache.rb +6 -3
  480. data/lib/rubocop/rspec/cop_helper.rb +9 -3
  481. data/lib/rubocop/rspec/expect_offense.rb +18 -8
  482. data/lib/rubocop/rspec/shared_contexts.rb +59 -19
  483. data/lib/rubocop/rspec/support.rb +3 -0
  484. data/lib/rubocop/runner.rb +59 -10
  485. data/lib/rubocop/server/cache.rb +11 -4
  486. data/lib/rubocop/server/cli.rb +37 -18
  487. data/lib/rubocop/server/client_command/exec.rb +4 -4
  488. data/lib/rubocop/server/client_command/start.rb +6 -1
  489. data/lib/rubocop/server/core.rb +24 -9
  490. data/lib/rubocop/server/helper.rb +1 -1
  491. data/lib/rubocop/server/server_command/exec.rb +1 -2
  492. data/lib/rubocop/string_interpreter.rb +3 -3
  493. data/lib/rubocop/target_finder.rb +91 -81
  494. data/lib/rubocop/target_ruby.rb +85 -78
  495. data/lib/rubocop/version.rb +27 -8
  496. data/lib/rubocop.rb +35 -0
  497. metadata +76 -35
  498. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -17,24 +17,24 @@ module RuboCop
17
17
  #
18
18
  # @example
19
19
  # # bad
20
- # if some_var = true
20
+ # if some_var = value
21
21
  # do_something
22
22
  # end
23
23
  #
24
24
  # # good
25
- # if some_var == true
25
+ # if some_var == value
26
26
  # do_something
27
27
  # end
28
28
  #
29
29
  # @example AllowSafeAssignment: true (default)
30
30
  # # good
31
- # if (some_var = true)
31
+ # if (some_var = value)
32
32
  # do_something
33
33
  # end
34
34
  #
35
35
  # @example AllowSafeAssignment: false
36
36
  # # bad
37
- # if (some_var = true)
37
+ # if (some_var = value)
38
38
  # do_something
39
39
  # end
40
40
  #
@@ -50,7 +50,7 @@ module RuboCop
50
50
  MSG_WITHOUT_SAFE_ASSIGNMENT_ALLOWED =
51
51
  'Use `==` if you meant to do a comparison or move the assignment ' \
52
52
  'up out of the condition.'
53
- ASGN_TYPES = [:begin, *AST::Node::EQUALS_ASSIGNMENTS, :send].freeze
53
+ ASGN_TYPES = [:begin, *AST::Node::EQUALS_ASSIGNMENTS, :send, :csend].freeze
54
54
 
55
55
  def on_if(node)
56
56
  return if node.condition.block_type?
@@ -88,7 +88,7 @@ module RuboCop
88
88
  end
89
89
 
90
90
  def skip_children?(asgn_node)
91
- (asgn_node.send_type? && !asgn_node.assignment_method?) ||
91
+ (asgn_node.call_type? && !asgn_node.assignment_method?) ||
92
92
  empty_condition?(asgn_node) ||
93
93
  (safe_assignment_allowed? && safe_assignment?(asgn_node))
94
94
  end
@@ -6,10 +6,10 @@ module RuboCop
6
6
  # Checks for places where binary operator has identical operands.
7
7
  #
8
8
  # It covers arithmetic operators: `-`, `/`, `%`;
9
- # comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, `<=`;
9
+ # comparison operators: `==`, `===`, `=~`, `>`, `>=`, `<`, ``<=``;
10
10
  # bitwise operators: `|`, `^`, `&`;
11
11
  # boolean operators: `&&`, `||`
12
- # and "spaceship" operator - `<=>`.
12
+ # and "spaceship" operator - ``<=>``.
13
13
  #
14
14
  # Simple arithmetic operations are allowed by this cop: `+`, `*`, `**`, `<<` and `>>`.
15
15
  # Although these can be rewritten in a different way, it should not be necessary to
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # Checks for overwriting an exception with an exception result by use `rescue =>`.
6
+ # Checks for overwriting an exception with an exception result by use ``rescue =>``.
7
7
  #
8
8
  # You intended to write as `rescue StandardError`.
9
9
  # However, you have written `rescue => StandardError`.
@@ -68,7 +68,7 @@ module RuboCop
68
68
  PATTERN
69
69
 
70
70
  def on_const(node)
71
- return if !unqualified_const?(node) || node.parent&.defined_module
71
+ return if !unqualified_const?(node) || node.parent&.defined_module || node.loc.nil?
72
72
 
73
73
  add_offense(node)
74
74
  end
@@ -29,6 +29,11 @@ module RuboCop
29
29
  # MyDebugger.debug_this
30
30
  # ----
31
31
  #
32
+ # Some gems also ship files that will start a debugging session when required,
33
+ # for example `require 'debug/start'` from `ruby/debug`. These requires can
34
+ # be configured through `DebuggerRequires`. It has the same structure as
35
+ # `DebuggerMethods`, which you can read about above.
36
+ #
32
37
  # @example
33
38
  #
34
39
  # # bad (ok during development)
@@ -64,13 +69,20 @@ module RuboCop
64
69
  # def some_method
65
70
  # my_debugger
66
71
  # end
72
+ #
73
+ # @example DebuggerRequires: [my_debugger/start]
74
+ #
75
+ # # bad (ok during development)
76
+ #
77
+ # require 'my_debugger/start'
67
78
  class Debugger < Base
68
79
  MSG = 'Remove debugger entry point `%<source>s`.'
80
+ BLOCK_TYPES = %i[block numblock kwbegin].freeze
69
81
 
70
82
  def on_send(node)
71
- return unless debugger_method?(node)
83
+ return if assumed_usage_context?(node)
72
84
 
73
- add_offense(node)
85
+ add_offense(node) if debugger_method?(node) || debugger_require?(node)
74
86
  end
75
87
 
76
88
  private
@@ -82,44 +94,55 @@ module RuboCop
82
94
  def debugger_methods
83
95
  @debugger_methods ||= begin
84
96
  config = cop_config.fetch('DebuggerMethods', [])
85
- values = config.is_a?(Array) ? config : config.values.flatten
86
- values.map do |v|
87
- next unless v
88
-
89
- *receiver, method_name = v.split('.')
90
- {
91
- receiver: receiver.empty? ? nil : receiver.map(&:to_sym),
92
- method_name: method_name.to_sym
93
- }
94
- end.compact
97
+ config.is_a?(Array) ? config : config.values.flatten
98
+ end
99
+ end
100
+
101
+ def debugger_requires
102
+ @debugger_requires ||= begin
103
+ config = cop_config.fetch('DebuggerRequires', [])
104
+ config.is_a?(Array) ? config : config.values.flatten
95
105
  end
96
106
  end
97
107
 
98
108
  def debugger_method?(send_node)
99
- method_name = send_node.method_name
109
+ return false if send_node.parent&.send_type? && send_node.parent.receiver == send_node
100
110
 
101
- debugger_methods.any? do |method|
102
- next unless method[:method_name] == method_name
111
+ debugger_methods.include?(chained_method_name(send_node))
112
+ end
113
+
114
+ def debugger_require?(send_node)
115
+ return false unless send_node.method?(:require) && send_node.arguments.one?
116
+ return false unless (argument = send_node.first_argument).str_type?
117
+
118
+ debugger_requires.include?(argument.value)
119
+ end
103
120
 
104
- if method[:receiver].nil?
105
- send_node.receiver.nil?
106
- else
107
- method[:receiver] == receiver_chain(send_node)
108
- end
121
+ def assumed_usage_context?(node)
122
+ # Basically, debugger methods are not used as a method argument without arguments.
123
+ return false unless node.arguments.empty? && node.each_ancestor(:send, :csend).any?
124
+ return true if assumed_argument?(node)
125
+
126
+ node.each_ancestor.none? do |ancestor|
127
+ BLOCK_TYPES.include?(ancestor.type) || ancestor.lambda_or_proc?
109
128
  end
110
129
  end
111
130
 
112
- def receiver_chain(send_node)
113
- receivers = []
131
+ def chained_method_name(send_node)
132
+ chained_method_name = send_node.method_name.to_s
114
133
  receiver = send_node.receiver
115
-
116
134
  while receiver
117
- name = receiver.send_type? ? receiver.method_name : receiver.const_name&.to_sym
118
- receivers.unshift(name)
135
+ name = receiver.send_type? ? receiver.method_name : receiver.const_name
136
+ chained_method_name = "#{name}.#{chained_method_name}"
119
137
  receiver = receiver.receiver
120
138
  end
139
+ chained_method_name
140
+ end
141
+
142
+ def assumed_argument?(node)
143
+ parent = node.parent
121
144
 
122
- receivers
145
+ parent.call_type? || parent.literal? || parent.pair_type?
123
146
  end
124
147
  end
125
148
  end
@@ -11,6 +11,8 @@ module RuboCop
11
11
  # File.exists?(some_path)
12
12
  # Dir.exists?(some_path)
13
13
  # iterator?
14
+ # attr :name, true
15
+ # attr :name, false
14
16
  # ENV.freeze # Calling `Env.freeze` raises `TypeError` since Ruby 2.7.
15
17
  # ENV.clone
16
18
  # ENV.dup # Calling `Env.dup` raises `TypeError` since Ruby 3.1.
@@ -21,6 +23,8 @@ module RuboCop
21
23
  # File.exist?(some_path)
22
24
  # Dir.exist?(some_path)
23
25
  # block_given?
26
+ # attr_accessor :name
27
+ # attr_reader :name
24
28
  # ENV # `ENV.freeze` cannot prohibit changes to environment variables.
25
29
  # ENV.to_h
26
30
  # ENV.to_h # `ENV.dup` cannot dup `ENV`, use `ENV.to_h` to get a copy of `ENV` as a hash.
@@ -29,138 +33,84 @@ module RuboCop
29
33
  class DeprecatedClassMethods < Base
30
34
  extend AutoCorrector
31
35
 
32
- # Inner class to DeprecatedClassMethods.
33
- # This class exists to add abstraction and clean naming
34
- # to the deprecated objects
35
- class DeprecatedClassMethod
36
- include RuboCop::AST::Sexp
36
+ MSG = '`%<current>s` is deprecated in favor of `%<prefer>s`.'
37
+ RESTRICT_ON_SEND = %i[
38
+ attr clone dup exists? freeze gethostbyaddr gethostbyname iterator?
39
+ ].freeze
40
+
41
+ PREFERRED_METHODS = {
42
+ clone: 'to_h',
43
+ dup: 'to_h',
44
+ exists?: 'exist?',
45
+ gethostbyaddr: 'Addrinfo#getnameinfo',
46
+ gethostbyname: 'Addrinfo#getaddrinfo',
47
+ iterator?: 'block_given?'
48
+ }.freeze
37
49
 
38
- attr_reader :method, :class_constant
50
+ DIR_ENV_FILE_CONSTANTS = %i[Dir ENV File].freeze
39
51
 
40
- def initialize(method, class_constant: nil, correctable: true)
41
- @method = method
42
- @class_constant = class_constant
43
- @correctable = correctable
44
- end
45
-
46
- def class_nodes
47
- @class_nodes ||=
48
- if class_constant
49
- [
50
- s(:const, nil, class_constant),
51
- s(:const, s(:cbase), class_constant)
52
- ]
53
- else
54
- [nil]
55
- end
56
- end
52
+ # @!method deprecated_class_method?(node)
53
+ def_node_matcher :deprecated_class_method?, <<~PATTERN
54
+ {
55
+ (send (const {cbase nil?} :ENV) {:clone :dup :freeze})
56
+ (send (const {cbase nil?} {:File :Dir}) :exists? _)
57
+ (send (const {cbase nil?} :Socket) {:gethostbyaddr :gethostbyname} ...)
58
+ (send nil? :attr _ boolean)
59
+ (send nil? :iterator?)
60
+ }
61
+ PATTERN
57
62
 
58
- def correctable?
59
- @correctable
60
- end
63
+ def on_send(node)
64
+ return unless deprecated_class_method?(node)
61
65
 
62
- def to_s
63
- [class_constant, method].compact.join(delimiter)
64
- end
66
+ offense_range = offense_range(node)
67
+ prefer = preferred_method(node)
68
+ message = format(MSG, current: offense_range.source, prefer: prefer)
65
69
 
66
- private
70
+ add_offense(offense_range, message: message) do |corrector|
71
+ next if socket_const?(node.receiver)
67
72
 
68
- def delimiter
69
- CLASS_METHOD_DELIMITER
73
+ if node.method?(:freeze)
74
+ corrector.replace(node, 'ENV')
75
+ else
76
+ corrector.replace(offense_range, prefer)
77
+ end
70
78
  end
71
79
  end
72
80
 
73
- # Inner class to DeprecatedClassMethods.
74
- # This class exists to add abstraction and clean naming
75
- # to the replacements for deprecated objects
76
- class Replacement
77
- attr_reader :method, :class_constant
78
-
79
- def initialize(method, class_constant: nil, instance_method: false)
80
- @method = method
81
- @class_constant = class_constant
82
- @instance_method = instance_method
83
- end
84
-
85
- def to_s
86
- [class_constant, method].compact.join(delimiter)
87
- end
88
-
89
- private
90
-
91
- def delimiter
92
- instance_method? ? INSTANCE_METHOD_DELIMITER : CLASS_METHOD_DELIMITER
93
- end
81
+ private
94
82
 
95
- def instance_method?
96
- @instance_method
83
+ def offense_range(node)
84
+ if socket_const?(node.receiver) || dir_env_file_const?(node.receiver)
85
+ node.source_range.begin.join(node.loc.selector.end)
86
+ elsif node.method?(:attr)
87
+ node
88
+ else
89
+ node.loc.selector
97
90
  end
98
91
  end
99
92
 
100
- MSG = '`%<current>s` is deprecated in favor of `%<prefer>s`.'
101
-
102
- DEPRECATED_METHODS_OBJECT = {
103
- DeprecatedClassMethod.new(:exists?, class_constant: :File) =>
104
- Replacement.new(:exist?, class_constant: :File),
105
-
106
- DeprecatedClassMethod.new(:exists?, class_constant: :Dir) =>
107
- Replacement.new(:exist?, class_constant: :Dir),
108
-
109
- DeprecatedClassMethod.new(:iterator?) => Replacement.new(:block_given?),
110
-
111
- DeprecatedClassMethod.new(:freeze, class_constant: :ENV) =>
112
- Replacement.new(nil, class_constant: :ENV),
93
+ def preferred_method(node)
94
+ if node.method?(:attr)
95
+ boolean_argument = node.arguments[1].source
96
+ preferred_attr_method = boolean_argument == 'true' ? 'attr_accessor' : 'attr_reader'
113
97
 
114
- DeprecatedClassMethod.new(:clone, class_constant: :ENV) =>
115
- Replacement.new(:to_h, class_constant: :ENV),
116
-
117
- DeprecatedClassMethod.new(:dup, class_constant: :ENV) =>
118
- Replacement.new(:to_h, class_constant: :ENV),
119
-
120
- DeprecatedClassMethod.new(:gethostbyaddr, class_constant: :Socket, correctable: false) =>
121
- Replacement.new(:getnameinfo, class_constant: :Addrinfo, instance_method: true),
122
-
123
- DeprecatedClassMethod.new(:gethostbyname, class_constant: :Socket, correctable: false) =>
124
- Replacement.new(:getaddrinfo, class_constant: :Addrinfo, instance_method: true)
125
- }.freeze
98
+ "#{preferred_attr_method} #{node.first_argument.source}"
99
+ elsif dir_env_file_const?(node.receiver)
100
+ prefer = PREFERRED_METHODS[node.method_name]
126
101
 
127
- RESTRICT_ON_SEND = DEPRECATED_METHODS_OBJECT.keys.map(&:method).freeze
128
-
129
- CLASS_METHOD_DELIMITER = '.'
130
- INSTANCE_METHOD_DELIMITER = '#'
131
-
132
- def on_send(node)
133
- check(node) do |deprecated|
134
- prefer = replacement(deprecated)
135
- message = format(MSG, current: deprecated, prefer: prefer)
136
- current_method = node.loc.selector
137
-
138
- add_offense(current_method, message: message) do |corrector|
139
- next unless deprecated.correctable?
140
-
141
- if (preferred_method = prefer.method)
142
- corrector.replace(current_method, preferred_method)
143
- else
144
- corrector.remove(node.loc.dot)
145
- corrector.remove(current_method)
146
- end
147
- end
102
+ prefer ? "#{node.receiver.source}.#{prefer}" : 'ENV'
103
+ else
104
+ PREFERRED_METHODS[node.method_name]
148
105
  end
149
106
  end
150
107
 
151
- private
152
-
153
- def check(node)
154
- DEPRECATED_METHODS_OBJECT.each_key do |deprecated|
155
- next unless deprecated.class_nodes.include?(node.receiver)
156
- next unless node.method?(deprecated.method)
157
-
158
- yield deprecated
159
- end
108
+ def socket_const?(node)
109
+ node&.short_name == :Socket
160
110
  end
161
111
 
162
- def replacement(deprecated)
163
- DEPRECATED_METHODS_OBJECT[deprecated]
112
+ def dir_env_file_const?(node)
113
+ DIR_ENV_FILE_CONSTANTS.include?(node&.short_name)
164
114
  end
165
115
  end
166
116
  end
@@ -100,7 +100,7 @@ module RuboCop
100
100
  end
101
101
 
102
102
  def correction_range(node)
103
- range_between(node.loc.dot.end_pos, node.loc.expression.end_pos)
103
+ range_between(node.loc.dot.end_pos, node.source_range.end_pos)
104
104
  end
105
105
 
106
106
  def openssl_class(node)
@@ -4,6 +4,7 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # Checks for duplicated keys in hash literals.
7
+ # This cop considers both primitive types and constants for the hash keys.
7
8
  #
8
9
  # This cop mirrors a warning in Ruby 2.2.
9
10
  #
@@ -24,7 +25,7 @@ module RuboCop
24
25
  MSG = 'Duplicated key in hash literal.'
25
26
 
26
27
  def on_hash(node)
27
- keys = node.keys.select(&:recursive_basic_literal?)
28
+ keys = node.keys.select { |key| key.recursive_basic_literal? || key.const_type? }
28
29
 
29
30
  return unless duplicates?(keys)
30
31
 
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks that there are no repeated patterns used in `in` keywords.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # case x
12
+ # in 'first'
13
+ # do_something
14
+ # in 'first'
15
+ # do_something_else
16
+ # end
17
+ #
18
+ # # good
19
+ # case x
20
+ # in 'first'
21
+ # do_something
22
+ # in 'second'
23
+ # do_something_else
24
+ # end
25
+ #
26
+ # # bad - repeated alternate patterns with the same conditions don't depend on the order
27
+ # case x
28
+ # in foo | bar
29
+ # first_method
30
+ # in bar | foo
31
+ # second_method
32
+ # end
33
+ #
34
+ # # good
35
+ # case x
36
+ # in foo | bar
37
+ # first_method
38
+ # in bar | baz
39
+ # second_method
40
+ # end
41
+ #
42
+ # # bad - repeated hash patterns with the same conditions don't depend on the order
43
+ # case x
44
+ # in foo: a, bar: b
45
+ # first_method
46
+ # in bar: b, foo: a
47
+ # second_method
48
+ # end
49
+ #
50
+ # # good
51
+ # case x
52
+ # in foo: a, bar: b
53
+ # first_method
54
+ # in bar: b, baz: c
55
+ # second_method
56
+ # end
57
+ #
58
+ # # bad - repeated array patterns with elements in the same order
59
+ # case x
60
+ # in [foo, bar]
61
+ # first_method
62
+ # in [foo, bar]
63
+ # second_method
64
+ # end
65
+ #
66
+ # # good
67
+ # case x
68
+ # in [foo, bar]
69
+ # first_method
70
+ # in [bar, foo]
71
+ # second_method
72
+ # end
73
+ #
74
+ # # bad - repeated the same patterns and guard conditions
75
+ # case x
76
+ # in foo if bar
77
+ # first_method
78
+ # in foo if bar
79
+ # second_method
80
+ # end
81
+ #
82
+ # # good
83
+ # case x
84
+ # in foo if bar
85
+ # first_method
86
+ # in foo if baz
87
+ # second_method
88
+ # end
89
+ #
90
+ class DuplicateMatchPattern < Base
91
+ extend TargetRubyVersion
92
+
93
+ MSG = 'Duplicate `in` pattern detected.'
94
+
95
+ minimum_target_ruby_version 2.7
96
+
97
+ def on_case_match(case_node)
98
+ case_node.in_pattern_branches.each_with_object(Set.new) do |in_pattern_node, previous|
99
+ pattern = in_pattern_node.pattern
100
+ next if previous.add?(pattern_identity(pattern))
101
+
102
+ add_offense(pattern)
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def pattern_identity(pattern)
109
+ pattern_source = if pattern.hash_pattern_type? || pattern.match_alt_type?
110
+ pattern.children.map(&:source).sort.to_s
111
+ else
112
+ pattern.source
113
+ end
114
+
115
+ return pattern_source unless (guard = pattern.parent.children[1])
116
+
117
+ pattern_source + guard.source
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -187,7 +187,7 @@ module RuboCop
187
187
  if DEF_TYPES.include?(node.type)
188
188
  node.loc.keyword.join(node.loc.name)
189
189
  else
190
- node.loc.expression
190
+ node.source_range
191
191
  end
192
192
  end
193
193
 
@@ -253,12 +253,12 @@ module RuboCop
253
253
  # Assume that if a method definition is inside any block call which
254
254
  # we can't identify, it could be a DSL
255
255
  node.each_ancestor(:block).any? do |ancestor|
256
- ancestor.method_name != :class_eval && !ancestor.class_constructor?
256
+ !ancestor.method?(:class_eval) && !ancestor.class_constructor?
257
257
  end
258
258
  end
259
259
 
260
260
  def source_location(node)
261
- range = node.location.expression
261
+ range = node.source_range
262
262
  path = smart_path(range.source_buffer.name)
263
263
  "#{path}:#{range.line}"
264
264
  end