rubocop 1.42.0 → 1.64.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -16,31 +16,38 @@ module RuboCop
16
16
  # File.open('file') do |f|
17
17
  # # ...
18
18
  # end
19
+ #
20
+ # # bad
21
+ # f = Tempfile.open('temp')
22
+ #
23
+ # # good
24
+ # Tempfile.open('temp') do |f|
25
+ # # ...
26
+ # end
19
27
  class AutoResourceCleanup < Base
20
- MSG = 'Use the block version of `%<class>s.%<method>s`.'
21
-
22
- TARGET_METHODS = { File: :open }.freeze
28
+ MSG = 'Use the block version of `%<current>s`.'
29
+ RESTRICT_ON_SEND = %i[open].freeze
23
30
 
24
- RESTRICT_ON_SEND = TARGET_METHODS.values.freeze
31
+ # @!method file_open_method?(node)
32
+ def_node_matcher :file_open_method?, <<~PATTERN
33
+ (send (const {nil? cbase} {:File :Tempfile}) :open ...)
34
+ PATTERN
25
35
 
26
36
  def on_send(node)
27
- TARGET_METHODS.each do |target_class, target_method|
28
- next if node.method_name != target_method
37
+ return if !file_open_method?(node) || cleanup?(node)
29
38
 
30
- target_receiver = s(:const, nil, target_class)
31
- next if node.receiver != target_receiver
39
+ current = node.receiver.source_range.begin.join(node.selector.end).source
32
40
 
33
- next if cleanup?(node)
34
-
35
- add_offense(node, message: format(MSG, class: target_class, method: target_method))
36
- end
41
+ add_offense(node, message: format(MSG, current: current))
37
42
  end
38
43
 
39
44
  private
40
45
 
41
46
  def cleanup?(node)
42
- parent = node.parent
43
- node.block_argument? || (parent && (parent.block_type? || !parent.lvasgn_type?))
47
+ return true if node.block_argument?
48
+ return false unless (parent = node.parent)
49
+
50
+ parent.block_type? || !parent.lvasgn_type?
44
51
  end
45
52
  end
46
53
  end
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- #
7
- # This cop checks for BEGIN blocks.
6
+ # Checks for BEGIN blocks.
8
7
  #
9
8
  # @example
10
9
  # # bad
@@ -33,7 +33,7 @@ module RuboCop
33
33
  def on_class(class_node)
34
34
  @macros_to_rewrite[class_node] = Set.new
35
35
 
36
- find_macros(class_node.body).each do |_visibility, macros|
36
+ find_macros(class_node.body).each_value do |macros|
37
37
  bisected = find_bisection(macros)
38
38
  next unless bisected.any?
39
39
 
@@ -55,7 +55,7 @@ module RuboCop
55
55
  def after_class(class_node)
56
56
  @macros_to_rewrite[class_node].each do |macro|
57
57
  node = macro.node
58
- range = range_by_whole_lines(node.loc.expression, include_final_newline: true)
58
+ range = range_by_whole_lines(node.source_range, include_final_newline: true)
59
59
 
60
60
  correct(range) do |corrector|
61
61
  if macro.writer?
@@ -74,7 +74,7 @@ module RuboCop
74
74
  def find_macros(class_def)
75
75
  # Find all the macros (`attr_reader`, `attr_writer`, etc.) in the class body
76
76
  # and turn them into `Macro` objects so that they can be processed.
77
- return [] if !class_def || class_def.def_type?
77
+ return {} if !class_def || class_def.def_type?
78
78
 
79
79
  send_nodes =
80
80
  if class_def.send_type?
@@ -35,7 +35,7 @@ module RuboCop
35
35
  unless contents.empty?
36
36
  corrector.replace(
37
37
  contents,
38
- contents.source.gsub(/\A/, '# ').gsub(/\n\n/, "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
38
+ contents.source.gsub(/\A/, '# ').gsub("\n\n", "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
39
39
  )
40
40
  end
41
41
  corrector.remove(eq_end)
@@ -46,7 +46,7 @@ module RuboCop
46
46
  private
47
47
 
48
48
  def parts(comment)
49
- expr = comment.loc.expression
49
+ expr = comment.source_range
50
50
  eq_begin = expr.resize(BEGIN_LENGTH)
51
51
  eq_end = eq_end_part(comment, expr)
52
52
  contents = range_between(eq_begin.end_pos, eq_end.begin_pos)
@@ -299,8 +299,8 @@ module RuboCop
299
299
 
300
300
  def move_comment_before_block(corrector, comment, block_node, closing_brace)
301
301
  range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
302
- comment_range = range_between(range.end_pos, comment.loc.expression.end_pos)
303
- corrector.remove(range_with_surrounding_space(comment_range, side: :right))
302
+ corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
303
+ remove_trailing_whitespace(corrector, range, comment)
304
304
  corrector.insert_after(range, "\n")
305
305
 
306
306
  corrector.insert_before(block_node, "#{comment.text}\n")
@@ -313,6 +313,12 @@ module RuboCop
313
313
  end_of_chain(node.parent)
314
314
  end
315
315
 
316
+ def remove_trailing_whitespace(corrector, range, comment)
317
+ range_of_trailing = range.end.join(comment.source_range.begin)
318
+
319
+ corrector.remove(range_of_trailing) if range_of_trailing.source.match?(/\A\s+\z/)
320
+ end
321
+
316
322
  def with_block?(node)
317
323
  node.respond_to?(:block_node) && node.block_node
318
324
  end
@@ -336,6 +342,7 @@ module RuboCop
336
342
  end
337
343
 
338
344
  def proper_block_style?(node)
345
+ return true if require_braces?(node)
339
346
  return special_method_proper_block_style?(node) if special_method?(node.method_name)
340
347
 
341
348
  case style
@@ -346,6 +353,14 @@ module RuboCop
346
353
  end
347
354
  end
348
355
 
356
+ def require_braces?(node)
357
+ return false unless node.braces?
358
+
359
+ node.each_ancestor(:send).any? do |send|
360
+ send.arithmetic_operation? && node.source_range.end_pos < send.loc.selector.begin_pos
361
+ end
362
+ end
363
+
349
364
  def special_method?(method_name)
350
365
  allowed_method?(method_name) ||
351
366
  matches_allowed_pattern?(method_name) ||
@@ -355,7 +370,8 @@ module RuboCop
355
370
  def special_method_proper_block_style?(node)
356
371
  method_name = node.method_name
357
372
  return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
358
- return node.braces? if braces_required_method?(method_name)
373
+
374
+ node.braces? if braces_required_method?(method_name)
359
375
  end
360
376
 
361
377
  def braces_required_method?(method_name)
@@ -396,7 +412,7 @@ module RuboCop
396
412
  end
397
413
 
398
414
  def correction_would_break_code?(node)
399
- return unless node.keywords?
415
+ return false unless node.keywords?
400
416
 
401
417
  node.send_node.arguments? && !node.send_node.parenthesized?
402
418
  end
@@ -418,7 +434,7 @@ module RuboCop
418
434
  end
419
435
 
420
436
  def return_value_used?(node)
421
- return unless node.parent
437
+ return false unless node.parent
422
438
 
423
439
  # If there are parentheses around the block, check if that
424
440
  # is being used.
@@ -430,7 +446,7 @@ module RuboCop
430
446
  end
431
447
 
432
448
  def return_value_of_scope?(node)
433
- return unless node.parent
449
+ return false unless node.parent
434
450
 
435
451
  conditional?(node.parent) || array_or_range?(node.parent) ||
436
452
  node.parent.children.last == node
@@ -11,12 +11,14 @@ module RuboCop
11
11
  # so if the original conditional used a different equality operator, the
12
12
  # behavior may be different.
13
13
  #
14
- # @example
14
+ # @example MinBranchesCount: 3 (default)
15
15
  # # bad
16
16
  # if status == :active
17
17
  # perform_action
18
18
  # elsif status == :inactive || status == :hibernating
19
19
  # check_timeout
20
+ # elsif status == :invalid
21
+ # report_invalid
20
22
  # else
21
23
  # final_action
22
24
  # end
@@ -27,12 +29,27 @@ module RuboCop
27
29
  # perform_action
28
30
  # when :inactive, :hibernating
29
31
  # check_timeout
32
+ # when :invalid
33
+ # report_invalid
34
+ # else
35
+ # final_action
36
+ # end
37
+ #
38
+ # @example MinBranchesCount: 4
39
+ # # good
40
+ # if status == :active
41
+ # perform_action
42
+ # elsif status == :inactive || status == :hibernating
43
+ # check_timeout
44
+ # elsif status == :invalid
45
+ # report_invalid
30
46
  # else
31
47
  # final_action
32
48
  # end
33
49
  #
34
50
  class CaseLikeIf < Base
35
51
  include RangeHelp
52
+ include MinBranchesCount
36
53
  extend AutoCorrector
37
54
 
38
55
  MSG = 'Convert `if-elsif` to `case-when`.'
@@ -78,7 +95,7 @@ module RuboCop
78
95
 
79
96
  def should_check?(node)
80
97
  !node.unless? && !node.elsif? && !node.modifier_form? && !node.ternary? &&
81
- node.elsif_conditional?
98
+ node.elsif_conditional? && min_branches_count?(node)
82
99
  end
83
100
 
84
101
  # rubocop:disable Metrics/MethodLength
@@ -108,7 +125,7 @@ module RuboCop
108
125
  when :==, :eql?, :equal?
109
126
  find_target_in_equality_node(node)
110
127
  when :===
111
- node.arguments.first
128
+ node.first_argument
112
129
  when :include?, :cover?
113
130
  find_target_in_include_or_cover_node(node)
114
131
  when :match, :match?, :=~
@@ -117,7 +134,7 @@ module RuboCop
117
134
  end
118
135
 
119
136
  def find_target_in_equality_node(node)
120
- argument = node.arguments.first
137
+ argument = node.first_argument
121
138
  receiver = node.receiver
122
139
  return unless argument && receiver
123
140
 
@@ -135,7 +152,7 @@ module RuboCop
135
152
  end
136
153
 
137
154
  def find_target_in_match_node(node)
138
- argument = node.arguments.first
155
+ argument = node.first_argument
139
156
  receiver = node.receiver
140
157
  return unless receiver
141
158
 
@@ -168,7 +185,7 @@ module RuboCop
168
185
  def condition_from_send_node(node, target)
169
186
  case node.method_name
170
187
  when :is_a?
171
- node.arguments.first if node.receiver == target
188
+ node.first_argument if node.receiver == target
172
189
  when :==, :eql?, :equal?
173
190
  condition_from_equality_node(node, target)
174
191
  when :=~, :match, :match?
@@ -213,7 +230,7 @@ module RuboCop
213
230
 
214
231
  def branch_conditions(node)
215
232
  conditions = []
216
- while node&.if_type?
233
+ while node&.if_type? && !node.ternary?
217
234
  conditions << node.condition
218
235
  node = node.else_branch
219
236
  end
@@ -239,7 +256,7 @@ module RuboCop
239
256
  end
240
257
 
241
258
  def correction_range(node)
242
- range_between(node.parent.loc.keyword.begin_pos, node.loc.expression.end_pos)
259
+ range_between(node.parent.loc.keyword.begin_pos, node.source_range.end_pos)
243
260
  end
244
261
 
245
262
  # Named captures work with `=~` (if regexp is on lhs) and with `match` (both sides)
@@ -11,7 +11,7 @@ module RuboCop
11
11
  #
12
12
  # Moving from compact to nested children requires knowledge of whether the
13
13
  # outer parent is a module or a class. Moving from nested to compact requires
14
- # verification that the outer parent is defined elsewhere. Rubocop does not
14
+ # verification that the outer parent is defined elsewhere. RuboCop does not
15
15
  # have the knowledge to perform either operation safely and thus requires
16
16
  # manual oversight.
17
17
  #
@@ -31,6 +31,7 @@ module RuboCop
31
31
  #
32
32
  # The compact style is only forced for classes/modules with one child.
33
33
  class ClassAndModuleChildren < Base
34
+ include Alignment
34
35
  include ConfigurableEnforcedStyle
35
36
  include RangeHelp
36
37
  extend AutoCorrector
@@ -59,7 +60,7 @@ module RuboCop
59
60
  end
60
61
 
61
62
  def nest_definition(corrector, node)
62
- padding = ((' ' * indent_width) + leading_spaces(node)).to_s
63
+ padding = indentation(node) + leading_spaces(node)
63
64
  padding_for_trailing_end = padding.sub(' ' * node.loc.end.column, '')
64
65
 
65
66
  replace_namespace_keyword(corrector, node)
@@ -124,10 +125,6 @@ module RuboCop
124
125
  corrector.remove(range)
125
126
  end
126
127
 
127
- def configured_indentation_width
128
- config.for_badge(Layout::IndentationWidth.badge).fetch('Width', 2)
129
- end
130
-
131
128
  def unindent(corrector, node)
132
129
  return if node.body.children.last.nil?
133
130
 
@@ -141,12 +138,8 @@ module RuboCop
141
138
  node.source_range.source_line[/\A\s*/]
142
139
  end
143
140
 
144
- def indent_width
145
- @config.for_cop('Layout/IndentationWidth')['Width'] || 2
146
- end
147
-
148
141
  def check_style(node, body)
149
- return if node.identifier.children[0]&.cbase_type?
142
+ return if node.identifier.namespace&.cbase_type?
150
143
 
151
144
  if style == :nested
152
145
  check_nested_style(node)
@@ -185,7 +178,7 @@ module RuboCop
185
178
  end
186
179
 
187
180
  def compact_node_name?(node)
188
- /::/.match?(node.identifier.source)
181
+ node.identifier.source.include?('::')
189
182
  end
190
183
  end
191
184
  end
@@ -40,6 +40,7 @@ module RuboCop
40
40
  corrector.replace(node.loc.selector, replacement)
41
41
  end
42
42
  end
43
+ alias on_csend on_send
43
44
 
44
45
  def message(node)
45
46
  if node.method?(:is_a?)
@@ -5,9 +5,14 @@ module RuboCop
5
5
  module Style
6
6
  # Enforces the use of `Object#instance_of?` instead of class comparison
7
7
  # for equality.
8
- # `==`, `equal?`, and `eql?` methods are allowed by default.
8
+ # `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
9
9
  # These are customizable with `AllowedMethods` option.
10
10
  #
11
+ # @safety
12
+ # This cop's autocorrection is unsafe because there is no guarantee that
13
+ # the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to
14
+ # `var.instance_of?(Foo)`.
15
+ #
11
16
  # @example
12
17
  # # bad
13
18
  # var.class == Date
@@ -18,45 +23,31 @@ module RuboCop
18
23
  # # good
19
24
  # var.instance_of?(Date)
20
25
  #
21
- # @example AllowedMethods: [] (default)
26
+ # @example AllowedMethods: ['==', 'equal?', 'eql?'] (default)
22
27
  # # good
23
- # var.instance_of?(Date)
24
- #
25
- # # bad
26
- # var.class == Date
27
- # var.class.equal?(Date)
28
- # var.class.eql?(Date)
29
- # var.class.name == 'Date'
28
+ # def ==(other)
29
+ # self.class == other.class && name == other.name
30
+ # end
30
31
  #
31
- # @example AllowedMethods: [`==`]
32
- # # good
33
- # var.instance_of?(Date)
34
- # var.class == Date
35
- # var.class.name == 'Date'
32
+ # def equal?(other)
33
+ # self.class.equal?(other.class) && name.equal?(other.name)
34
+ # end
36
35
  #
37
- # # bad
38
- # var.class.equal?(Date)
39
- # var.class.eql?(Date)
36
+ # def eql?(other)
37
+ # self.class.eql?(other.class) && name.eql?(other.name)
38
+ # end
40
39
  #
41
40
  # @example AllowedPatterns: [] (default)
42
- # # good
43
- # var.instance_of?(Date)
44
- #
45
41
  # # bad
46
- # var.class == Date
47
- # var.class.equal?(Date)
48
- # var.class.eql?(Date)
49
- # var.class.name == 'Date'
42
+ # def eq(other)
43
+ # self.class.eq(other.class) && name.eq(other.name)
44
+ # end
50
45
  #
51
46
  # @example AllowedPatterns: ['eq']
52
47
  # # good
53
- # var.instance_of?(Date)
54
- # var.class.equal?(Date)
55
- # var.class.eql?(Date)
56
- #
57
- # # bad
58
- # var.class == Date
59
- # var.class.name == 'Date'
48
+ # def eq(other)
49
+ # self.class.eq(other.class) && name.eq(other.name)
50
+ # end
60
51
  #
61
52
  class ClassEqualityComparison < Base
62
53
  include RangeHelp
@@ -64,14 +55,15 @@ module RuboCop
64
55
  include AllowedPattern
65
56
  extend AutoCorrector
66
57
 
67
- MSG = 'Use `instance_of?(%<class_name>s)` instead of comparing classes.'
58
+ MSG = 'Use `instance_of?%<class_argument>s` instead of comparing classes.'
68
59
 
69
60
  RESTRICT_ON_SEND = %i[== equal? eql?].freeze
61
+ CLASS_NAME_METHODS = %i[name to_s inspect].freeze
70
62
 
71
63
  # @!method class_comparison_candidate?(node)
72
64
  def_node_matcher :class_comparison_candidate?, <<~PATTERN
73
65
  (send
74
- {$(send _ :class) (send $(send _ :class) :name)}
66
+ {$(send _ :class) (send $(send _ :class) #class_name_method?)}
75
67
  {:== :equal? :eql?} $_)
76
68
  PATTERN
77
69
 
@@ -82,11 +74,15 @@ module RuboCop
82
74
  matches_allowed_pattern?(def_node.method_name))
83
75
 
84
76
  class_comparison_candidate?(node) do |receiver_node, class_node|
77
+ return if class_node.dstr_type?
78
+
85
79
  range = offense_range(receiver_node, node)
86
- class_name = class_name(class_node, node)
80
+ class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
87
81
 
88
- add_offense(range, message: format(MSG, class_name: class_name)) do |corrector|
89
- corrector.replace(range, "instance_of?(#{class_name})")
82
+ add_offense(range, message: format(MSG, class_argument: class_argument)) do |corrector|
83
+ next unless class_name
84
+
85
+ corrector.replace(range, "instance_of?#{class_argument}")
90
86
  end
91
87
  end
92
88
  end
@@ -94,19 +90,41 @@ module RuboCop
94
90
  private
95
91
 
96
92
  def class_name(class_node, node)
97
- if node.children.first.method?(:name)
98
- return class_node.receiver.source if class_node.receiver
93
+ if class_name_method?(node.children.first.method_name)
94
+ if (receiver = class_node.receiver) && class_name_method?(class_node.method_name)
95
+ return receiver.source
96
+ end
99
97
 
100
98
  if class_node.str_type?
101
- value = class_node.source.delete('"').delete("'")
102
- value.prepend('::') if class_node.each_ancestor(:class, :module).any?
99
+ value = trim_string_quotes(class_node)
100
+ value.prepend('::') if require_cbase?(class_node)
103
101
  return value
102
+ elsif unable_to_determine_type?(class_node)
103
+ # When a variable or return value of a method is used, it returns nil
104
+ # because the type is not known and cannot be suggested.
105
+ return
104
106
  end
105
107
  end
106
108
 
107
109
  class_node.source
108
110
  end
109
111
 
112
+ def class_name_method?(method_name)
113
+ CLASS_NAME_METHODS.include?(method_name)
114
+ end
115
+
116
+ def require_cbase?(class_node)
117
+ class_node.each_ancestor(:class, :module).any?
118
+ end
119
+
120
+ def unable_to_determine_type?(class_node)
121
+ class_node.variable? || class_node.call_type?
122
+ end
123
+
124
+ def trim_string_quotes(class_node)
125
+ class_node.source.delete('"').delete("'")
126
+ end
127
+
110
128
  def offense_range(receiver_node, node)
111
129
  range_between(receiver_node.loc.selector.begin_pos, node.source_range.end_pos)
112
130
  end
@@ -54,9 +54,9 @@ module RuboCop
54
54
  end
55
55
 
56
56
  def on_send(node)
57
- add_offense(
58
- node.first_argument, message: format(MSG, class_var: node.first_argument.source)
59
- )
57
+ return unless (first_argument = node.first_argument)
58
+
59
+ add_offense(first_argument, message: format(MSG, class_var: first_argument.source))
60
60
  end
61
61
  end
62
62
  end
@@ -9,8 +9,8 @@ module RuboCop
9
9
  # @safety
10
10
  # It is unsafe by default because false positives may occur in the
11
11
  # `nil` check of block arguments to the receiver object. Additionally,
12
- # we can't know the type of the receiver object for sure, which may
13
- # result in false positives as well.
12
+ # we can't know the type of the receiver object for sure, which may
13
+ # result in false positives as well.
14
14
  #
15
15
  # For example, `[[1, 2], [3, nil]].reject { |first, second| second.nil? }`
16
16
  # and `[[1, 2], [3, nil]].compact` are not compatible. This will work fine
@@ -21,29 +21,41 @@ module RuboCop
21
21
  # array.reject(&:nil?)
22
22
  # array.reject { |e| e.nil? }
23
23
  # array.select { |e| !e.nil? }
24
+ # array.grep_v(nil)
25
+ # array.grep_v(NilClass)
24
26
  #
25
27
  # # good
26
28
  # array.compact
27
29
  #
28
30
  # # bad
29
31
  # hash.reject!(&:nil?)
32
+ # array.delete_if(&:nil?)
30
33
  # hash.reject! { |k, v| v.nil? }
34
+ # array.delete_if { |e| e.nil? }
31
35
  # hash.select! { |k, v| !v.nil? }
32
36
  #
33
37
  # # good
34
38
  # hash.compact!
35
39
  #
40
+ # @example AllowedReceivers: ['params']
41
+ # # good
42
+ # params.reject(&:nil?)
43
+ #
36
44
  class CollectionCompact < Base
45
+ include AllowedReceivers
37
46
  include RangeHelp
38
47
  extend AutoCorrector
48
+ extend TargetRubyVersion
39
49
 
40
50
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
41
- RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
51
+ RESTRICT_ON_SEND = %i[reject delete_if reject! select select! grep_v].freeze
42
52
  TO_ENUM_METHODS = %i[to_enum lazy].freeze
43
53
 
54
+ minimum_target_ruby_version 2.4
55
+
44
56
  # @!method reject_method_with_block_pass?(node)
45
57
  def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
46
- (send !nil? {:reject :reject!}
58
+ (call !nil? {:reject :delete_if :reject!}
47
59
  (block_pass
48
60
  (sym :nil?)))
49
61
  PATTERN
@@ -51,38 +63,48 @@ module RuboCop
51
63
  # @!method reject_method?(node)
52
64
  def_node_matcher :reject_method?, <<~PATTERN
53
65
  (block
54
- (send
55
- !nil? {:reject :reject!})
66
+ (call
67
+ !nil? {:reject :delete_if :reject!})
56
68
  $(args ...)
57
- (send
69
+ (call
58
70
  $(lvar _) :nil?))
59
71
  PATTERN
60
72
 
61
73
  # @!method select_method?(node)
62
74
  def_node_matcher :select_method?, <<~PATTERN
63
75
  (block
64
- (send
76
+ (call
65
77
  !nil? {:select :select!})
66
78
  $(args ...)
67
- (send
68
- (send
79
+ (call
80
+ (call
69
81
  $(lvar _) :nil?) :!))
70
82
  PATTERN
71
83
 
84
+ # @!method grep_v_with_nil?(node)
85
+ def_node_matcher :grep_v_with_nil?, <<~PATTERN
86
+ (send _ :grep_v {(nil) (const {nil? cbase} :NilClass)})
87
+ PATTERN
88
+
72
89
  def on_send(node)
73
90
  return unless (range = offense_range(node))
74
- return if target_ruby_version <= 3.0 && to_enum_method?(node)
91
+ return if allowed_receiver?(node.receiver)
92
+ if (target_ruby_version <= 3.0 || node.method?(:delete_if)) && to_enum_method?(node)
93
+ return
94
+ end
75
95
 
76
96
  good = good_method_name(node)
77
97
  message = format(MSG, good: good, bad: range.source)
78
98
 
79
99
  add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
80
100
  end
101
+ alias on_csend on_send
81
102
 
82
103
  private
83
104
 
105
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
84
106
  def offense_range(node)
85
- if reject_method_with_block_pass?(node)
107
+ if reject_method_with_block_pass?(node) || grep_v_with_nil?(node)
86
108
  range(node, node)
87
109
  else
88
110
  block_node = node.parent
@@ -96,6 +118,7 @@ module RuboCop
96
118
  range(node, block_node)
97
119
  end
98
120
  end
121
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
99
122
 
100
123
  def to_enum_method?(node)
101
124
  return false unless node.receiver.send_type?
@@ -104,7 +127,7 @@ module RuboCop
104
127
  end
105
128
 
106
129
  def good_method_name(node)
107
- if node.bang_method?
130
+ if node.bang_method? || node.method?(:delete_if)
108
131
  'compact!'
109
132
  else
110
133
  'compact'
@@ -112,7 +135,7 @@ module RuboCop
112
135
  end
113
136
 
114
137
  def range(begin_pos_node, end_pos_node)
115
- range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.loc.expression.end_pos)
138
+ range_between(begin_pos_node.loc.selector.begin_pos, end_pos_node.source_range.end_pos)
116
139
  end
117
140
  end
118
141
  end