rubocop 1.50.2 → 1.68.0

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 (494) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +73 -72
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +316 -38
  7. data/config/internal_affairs.yml +11 -0
  8. data/config/obsoletion.yml +5 -0
  9. data/exe/rubocop +4 -3
  10. data/lib/rubocop/cached_data.rb +21 -5
  11. data/lib/rubocop/cli/command/auto_generate_config.rb +28 -15
  12. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  13. data/lib/rubocop/cli/command/lsp.rb +19 -0
  14. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  15. data/lib/rubocop/cli/command/version.rb +2 -2
  16. data/lib/rubocop/cli.rb +14 -2
  17. data/lib/rubocop/comment_config.rb +1 -1
  18. data/lib/rubocop/config.rb +45 -13
  19. data/lib/rubocop/config_finder.rb +14 -4
  20. data/lib/rubocop/config_loader.rb +15 -10
  21. data/lib/rubocop/config_loader_resolver.rb +17 -11
  22. data/lib/rubocop/config_obsoletion/parameter_rule.rb +9 -1
  23. data/lib/rubocop/config_obsoletion.rb +13 -10
  24. data/lib/rubocop/config_validator.rb +17 -9
  25. data/lib/rubocop/cop/autocorrect_logic.rb +30 -3
  26. data/lib/rubocop/cop/base.rb +78 -19
  27. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -0
  28. data/lib/rubocop/cop/bundler/duplicated_group.rb +127 -0
  29. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  30. data/lib/rubocop/cop/bundler/gem_version.rb +6 -7
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +9 -1
  32. data/lib/rubocop/cop/cop.rb +30 -4
  33. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -13
  34. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  35. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  36. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +7 -4
  37. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  38. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -1
  39. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +10 -0
  40. data/lib/rubocop/cop/documentation.rb +32 -5
  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/add_runtime_dependency.rb +38 -0
  44. data/lib/rubocop/cop/gemspec/dependency_version.rb +5 -7
  45. data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
  46. data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
  47. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  48. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +9 -1
  49. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  50. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  51. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  52. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -12
  53. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  54. data/lib/rubocop/cop/internal_affairs/example_description.rb +46 -24
  55. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +3 -1
  56. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  57. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
  58. data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
  59. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +128 -34
  60. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  61. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +6 -21
  62. data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
  63. data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +8 -1
  64. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  65. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -5
  66. data/lib/rubocop/cop/internal_affairs.rb +18 -0
  67. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +5 -1
  68. data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
  69. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  70. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  71. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  72. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  73. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  74. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  75. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  76. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  77. data/lib/rubocop/cop/layout/dot_position.rb +1 -5
  78. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  79. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +43 -10
  80. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  81. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  82. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +29 -5
  83. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +10 -3
  84. data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
  85. data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
  86. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  87. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -10
  88. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +8 -0
  89. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  90. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +4 -4
  91. data/lib/rubocop/cop/layout/heredoc_indentation.rb +5 -2
  92. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  93. data/lib/rubocop/cop/layout/indentation_width.rb +8 -9
  94. data/lib/rubocop/cop/layout/leading_comment_space.rb +57 -2
  95. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +17 -9
  96. data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
  97. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -0
  98. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  99. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
  100. data/lib/rubocop/cop/layout/redundant_line_break.rb +30 -7
  101. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
  102. data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
  103. data/lib/rubocop/cop/layout/space_after_comma.rb +9 -1
  104. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  105. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -2
  106. data/lib/rubocop/cop/layout/space_around_operators.rb +56 -21
  107. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  108. data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -5
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +6 -0
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
  112. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  114. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +5 -0
  115. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  116. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +13 -3
  117. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  118. data/lib/rubocop/cop/lint/ambiguous_range.rb +4 -1
  119. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  120. data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
  121. data/lib/rubocop/cop/lint/big_decimal_new.rb +4 -7
  122. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
  123. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -3
  124. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  125. data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
  126. data/lib/rubocop/cop/lint/debugger.rb +45 -10
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  128. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  129. data/lib/rubocop/cop/lint/duplicate_branch.rb +39 -4
  130. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  131. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -5
  132. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -11
  133. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  134. data/lib/rubocop/cop/lint/duplicate_set_element.rb +74 -0
  135. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  136. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  137. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  138. data/lib/rubocop/cop/lint/empty_conditional_body.rb +29 -8
  139. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  140. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  141. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  142. data/lib/rubocop/cop/lint/ensure_return.rb +1 -9
  143. data/lib/rubocop/cop/lint/erb_new_arguments.rb +27 -21
  144. data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
  145. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  146. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  147. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
  148. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  149. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  150. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +23 -12
  151. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -3
  152. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  153. data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
  154. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  155. data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +47 -0
  156. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
  157. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  158. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
  159. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +26 -7
  160. data/lib/rubocop/cop/lint/loop.rb +6 -12
  161. data/lib/rubocop/cop/lint/missing_super.rb +34 -5
  162. data/lib/rubocop/cop/lint/mixed_case_range.rb +116 -0
  163. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  164. data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -25
  165. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  166. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +17 -7
  167. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
  168. data/lib/rubocop/cop/lint/number_conversion.rb +14 -4
  169. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
  170. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  171. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
  172. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -6
  173. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  174. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  175. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  176. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  177. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +130 -0
  178. data/lib/rubocop/cop/lint/redundant_require_statement.rb +12 -3
  179. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +72 -8
  180. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  181. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -5
  182. data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
  183. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  184. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  185. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  186. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  187. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  188. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +23 -12
  189. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +107 -41
  190. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  191. data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
  192. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  193. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  194. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  195. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -11
  196. data/lib/rubocop/cop/lint/struct_new_override.rb +12 -12
  197. data/lib/rubocop/cop/lint/suppressed_exception.rb +2 -2
  198. data/lib/rubocop/cop/lint/symbol_conversion.rb +9 -4
  199. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  200. data/lib/rubocop/cop/lint/to_enum_arguments.rb +6 -6
  201. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
  202. data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
  203. data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +88 -0
  204. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  205. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +3 -2
  206. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  207. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  208. data/lib/rubocop/cop/lint/uri_regexp.rb +25 -7
  209. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
  210. data/lib/rubocop/cop/lint/useless_assignment.rb +102 -15
  211. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  212. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  213. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  214. data/lib/rubocop/cop/lint/useless_times.rb +2 -2
  215. data/lib/rubocop/cop/lint/void.rb +128 -15
  216. data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
  217. data/lib/rubocop/cop/metrics/block_length.rb +7 -6
  218. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  219. data/lib/rubocop/cop/metrics/class_length.rb +14 -8
  220. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -1
  221. data/lib/rubocop/cop/metrics/method_length.rb +7 -6
  222. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  223. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  224. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +37 -9
  225. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  226. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  227. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  228. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  229. data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
  230. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  231. data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -1
  232. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  233. data/lib/rubocop/cop/mixin/comments_help.rb +19 -11
  234. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  235. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  236. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  237. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  238. data/lib/rubocop/cop/mixin/endless_method_rewriter.rb +24 -0
  239. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +22 -10
  240. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
  241. data/lib/rubocop/cop/mixin/heredoc.rb +6 -2
  242. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  243. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  244. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +4 -3
  245. data/lib/rubocop/cop/mixin/percent_array.rb +1 -1
  246. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  247. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -8
  248. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  249. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  250. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  251. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  252. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -2
  253. data/lib/rubocop/cop/mixin/string_help.rb +4 -2
  254. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  255. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  256. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  257. data/lib/rubocop/cop/naming/block_forwarding.rb +35 -8
  258. data/lib/rubocop/cop/naming/constant_name.rb +2 -3
  259. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  260. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +3 -1
  261. data/lib/rubocop/cop/naming/inclusive_language.rb +13 -5
  262. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +26 -11
  263. data/lib/rubocop/cop/naming/predicate_name.rb +55 -29
  264. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -4
  265. data/lib/rubocop/cop/naming/variable_name.rb +6 -1
  266. data/lib/rubocop/cop/offense.rb +4 -5
  267. data/lib/rubocop/cop/registry.rb +1 -1
  268. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  269. data/lib/rubocop/cop/security/open.rb +2 -2
  270. data/lib/rubocop/cop/style/access_modifier_declarations.rb +63 -3
  271. data/lib/rubocop/cop/style/accessor_grouping.rb +14 -2
  272. data/lib/rubocop/cop/style/alias.rb +11 -9
  273. data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +79 -0
  274. data/lib/rubocop/cop/style/arguments_forwarding.rb +459 -63
  275. data/lib/rubocop/cop/style/array_first_last.rb +64 -0
  276. data/lib/rubocop/cop/style/array_intersect.rb +13 -5
  277. data/lib/rubocop/cop/style/attr.rb +11 -1
  278. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
  279. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  280. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
  281. data/lib/rubocop/cop/style/bitwise_predicate.rb +100 -0
  282. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  283. data/lib/rubocop/cop/style/block_delimiters.rb +36 -7
  284. data/lib/rubocop/cop/style/case_like_if.rb +5 -5
  285. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  286. data/lib/rubocop/cop/style/class_check.rb +1 -0
  287. data/lib/rubocop/cop/style/class_equality_comparison.rb +24 -39
  288. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  289. data/lib/rubocop/cop/style/collection_compact.rb +31 -11
  290. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  291. data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
  292. data/lib/rubocop/cop/style/combinable_defined.rb +115 -0
  293. data/lib/rubocop/cop/style/combinable_loops.rb +43 -8
  294. data/lib/rubocop/cop/style/commented_keyword.rb +12 -3
  295. data/lib/rubocop/cop/style/concat_array_literals.rb +2 -1
  296. data/lib/rubocop/cop/style/conditional_assignment.rb +13 -12
  297. data/lib/rubocop/cop/style/copyright.rb +36 -23
  298. data/lib/rubocop/cop/style/data_inheritance.rb +1 -1
  299. data/lib/rubocop/cop/style/date_time.rb +5 -4
  300. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  301. data/lib/rubocop/cop/style/dir.rb +1 -1
  302. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  303. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  304. data/lib/rubocop/cop/style/documentation.rb +25 -25
  305. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  306. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  307. data/lib/rubocop/cop/style/each_with_object.rb +2 -2
  308. data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
  309. data/lib/rubocop/cop/style/empty_else.rb +6 -5
  310. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  311. data/lib/rubocop/cop/style/empty_literal.rb +32 -23
  312. data/lib/rubocop/cop/style/endless_method.rb +1 -14
  313. data/lib/rubocop/cop/style/eval_with_location.rb +24 -32
  314. data/lib/rubocop/cop/style/exact_regexp_match.rb +70 -0
  315. data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
  316. data/lib/rubocop/cop/style/file_read.rb +4 -7
  317. data/lib/rubocop/cop/style/file_write.rb +2 -5
  318. data/lib/rubocop/cop/style/for.rb +3 -1
  319. data/lib/rubocop/cop/style/format_string.rb +33 -12
  320. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  321. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -1
  322. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  323. data/lib/rubocop/cop/style/guard_clause.rb +45 -2
  324. data/lib/rubocop/cop/style/hash_conversion.rb +10 -0
  325. data/lib/rubocop/cop/style/hash_each_methods.rb +112 -33
  326. data/lib/rubocop/cop/style/hash_except.rb +29 -14
  327. data/lib/rubocop/cop/style/hash_syntax.rb +26 -4
  328. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  329. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  330. data/lib/rubocop/cop/style/identical_conditional_branches.rb +34 -5
  331. data/lib/rubocop/cop/style/if_inside_else.rb +7 -1
  332. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
  333. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  334. data/lib/rubocop/cop/style/if_with_semicolon.rb +51 -8
  335. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  336. data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
  337. data/lib/rubocop/cop/style/invertible_unless_condition.rb +56 -10
  338. data/lib/rubocop/cop/style/keyword_arguments_merging.rb +67 -0
  339. data/lib/rubocop/cop/style/lambda.rb +4 -4
  340. data/lib/rubocop/cop/style/lambda_call.rb +5 -0
  341. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  342. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
  343. data/lib/rubocop/cop/style/map_into_array.rb +233 -0
  344. data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
  345. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  346. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +40 -15
  347. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -5
  348. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +22 -2
  349. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
  350. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  351. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
  352. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  353. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  354. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  355. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  356. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +6 -4
  357. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  358. data/lib/rubocop/cop/style/multiple_comparison.rb +41 -46
  359. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  360. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
  361. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
  362. data/lib/rubocop/cop/style/next.rb +1 -1
  363. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  364. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  365. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  366. data/lib/rubocop/cop/style/numeric_predicate.rb +12 -4
  367. data/lib/rubocop/cop/style/object_then.rb +5 -3
  368. data/lib/rubocop/cop/style/one_line_conditional.rb +6 -2
  369. data/lib/rubocop/cop/style/open_struct_use.rb +1 -1
  370. data/lib/rubocop/cop/style/operator_method_call.rb +32 -7
  371. data/lib/rubocop/cop/style/parallel_assignment.rb +8 -9
  372. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  373. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  374. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  375. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -3
  376. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  377. data/lib/rubocop/cop/style/redundant_argument.rb +33 -4
  378. data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
  379. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  380. data/lib/rubocop/cop/style/redundant_begin.rb +15 -3
  381. data/lib/rubocop/cop/style/redundant_condition.rb +4 -4
  382. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -10
  383. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +39 -0
  384. data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +93 -5
  385. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  386. data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
  387. data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
  388. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  389. data/lib/rubocop/cop/style/redundant_filter_chain.rb +118 -0
  390. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  391. data/lib/rubocop/cop/style/redundant_line_continuation.rb +48 -9
  392. data/lib/rubocop/cop/style/redundant_parentheses.rb +80 -33
  393. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  394. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +103 -0
  395. data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
  396. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -24
  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 +10 -9
  401. data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
  402. data/lib/rubocop/cop/style/redundant_string_escape.rb +3 -1
  403. data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
  404. data/lib/rubocop/cop/style/require_order.rb +13 -7
  405. data/lib/rubocop/cop/style/rescue_modifier.rb +14 -4
  406. data/lib/rubocop/cop/style/return_nil.rb +6 -2
  407. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +137 -0
  408. data/lib/rubocop/cop/style/safe_navigation.rb +106 -52
  409. data/lib/rubocop/cop/style/safe_navigation_chain_length.rb +52 -0
  410. data/lib/rubocop/cop/style/sample.rb +3 -4
  411. data/lib/rubocop/cop/style/select_by_regexp.rb +29 -15
  412. data/lib/rubocop/cop/style/self_assignment.rb +1 -1
  413. data/lib/rubocop/cop/style/semicolon.rb +21 -5
  414. data/lib/rubocop/cop/style/send.rb +4 -4
  415. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -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 +76 -10
  421. data/lib/rubocop/cop/style/sole_nested_conditional.rb +27 -4
  422. data/lib/rubocop/cop/style/special_global_vars.rb +4 -6
  423. data/lib/rubocop/cop/style/string_chars.rb +1 -0
  424. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +30 -5
  425. data/lib/rubocop/cop/style/strip.rb +7 -4
  426. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  427. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  428. data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
  429. data/lib/rubocop/cop/style/symbol_array.rb +35 -15
  430. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  431. data/lib/rubocop/cop/style/ternary_parentheses.rb +26 -5
  432. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  433. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  434. data/lib/rubocop/cop/style/unpack_first.rb +11 -14
  435. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  436. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  437. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  438. data/lib/rubocop/cop/style/yoda_condition.rb +4 -2
  439. data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
  440. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  441. data/lib/rubocop/cop/team.rb +27 -3
  442. data/lib/rubocop/cop/util.rb +9 -3
  443. data/lib/rubocop/cop/utils/regexp_ranges.rb +113 -0
  444. data/lib/rubocop/cop/variable_force/assignment.rb +62 -6
  445. data/lib/rubocop/cop/variable_force/branch.rb +1 -1
  446. data/lib/rubocop/cop/variable_force/variable.rb +5 -1
  447. data/lib/rubocop/cop/variable_force/variable_table.rb +4 -4
  448. data/lib/rubocop/cop/variable_force.rb +14 -1
  449. data/lib/rubocop/cops_documentation_generator.rb +97 -44
  450. data/lib/rubocop/core_ext/string.rb +2 -6
  451. data/lib/rubocop/directive_comment.rb +10 -8
  452. data/lib/rubocop/ext/regexp_node.rb +18 -35
  453. data/lib/rubocop/ext/regexp_parser.rb +7 -21
  454. data/lib/rubocop/file_finder.rb +11 -9
  455. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  456. data/lib/rubocop/formatter/disabled_config_formatter.rb +24 -9
  457. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  458. data/lib/rubocop/formatter/html_formatter.rb +37 -14
  459. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  460. data/lib/rubocop/formatter/junit_formatter.rb +71 -24
  461. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  462. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  463. data/lib/rubocop/formatter.rb +1 -1
  464. data/lib/rubocop/lockfile.rb +58 -7
  465. data/lib/rubocop/lsp/logger.rb +22 -0
  466. data/lib/rubocop/lsp/routes.rb +243 -0
  467. data/lib/rubocop/lsp/runtime.rb +101 -0
  468. data/lib/rubocop/lsp/server.rb +72 -0
  469. data/lib/rubocop/lsp/severity.rb +27 -0
  470. data/lib/rubocop/lsp.rb +36 -0
  471. data/lib/rubocop/magic_comment.rb +13 -11
  472. data/lib/rubocop/options.rb +28 -13
  473. data/lib/rubocop/path_util.rb +6 -2
  474. data/lib/rubocop/rake_task.rb +1 -1
  475. data/lib/rubocop/remote_config.rb +5 -1
  476. data/lib/rubocop/result_cache.rb +7 -10
  477. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  478. data/lib/rubocop/rspec/expect_offense.rb +17 -8
  479. data/lib/rubocop/rspec/shared_contexts.rb +77 -21
  480. data/lib/rubocop/rspec/support.rb +3 -0
  481. data/lib/rubocop/runner.rb +36 -12
  482. data/lib/rubocop/server/cache.rb +16 -1
  483. data/lib/rubocop/server/client_command/exec.rb +5 -5
  484. data/lib/rubocop/server/client_command/start.rb +1 -1
  485. data/lib/rubocop/server/core.rb +5 -0
  486. data/lib/rubocop/server/server_command/exec.rb +0 -1
  487. data/lib/rubocop/string_interpreter.rb +3 -3
  488. data/lib/rubocop/target_finder.rb +91 -81
  489. data/lib/rubocop/target_ruby.rb +90 -79
  490. data/lib/rubocop/version.rb +53 -13
  491. data/lib/rubocop/yaml_duplication_checker.rb +20 -26
  492. data/lib/rubocop.rb +40 -1
  493. metadata +73 -36
  494. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -24,7 +24,7 @@ module RuboCop
24
24
  def on_send(node)
25
25
  return unless node.command?(:attr) && node.arguments?
26
26
  # check only for method definitions in class/module body
27
- return if node.parent && !node.parent.class_type? && !class_eval?(node.parent)
27
+ return if allowed_context?(node)
28
28
 
29
29
  message = message(node)
30
30
  add_offense(node.loc.selector, message: message) do |corrector|
@@ -34,6 +34,16 @@ module RuboCop
34
34
 
35
35
  private
36
36
 
37
+ def allowed_context?(node)
38
+ return false unless (class_node = node.each_ancestor(:class, :block).first)
39
+
40
+ (!class_node.class_type? && !class_eval?(class_node)) || define_attr_method?(class_node)
41
+ end
42
+
43
+ def define_attr_method?(node)
44
+ node.each_descendant(:def).any? { |def_node| def_node.method?(:attr) }
45
+ end
46
+
37
47
  def autocorrect(corrector, node)
38
48
  attr_name, setter = *node.arguments
39
49
 
@@ -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
 
@@ -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?
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Prefer bitwise predicate methods over direct comparison operations.
7
+ #
8
+ # @safety
9
+ # This cop is unsafe, as it can produce false positives if the receiver
10
+ # is not an `Integer` object.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad - checks any set bits
15
+ # (variable & flags).positive?
16
+ #
17
+ # # good
18
+ # variable.anybits?(flags)
19
+ #
20
+ # # bad - checks all set bits
21
+ # (variable & flags) == flags
22
+ #
23
+ # # good
24
+ # variable.allbits?(flags)
25
+ #
26
+ # # bad - checks no set bits
27
+ # (variable & flags).zero?
28
+ #
29
+ # # good
30
+ # variable.nobits?(flags)
31
+ #
32
+ class BitwisePredicate < Base
33
+ extend AutoCorrector
34
+ extend TargetRubyVersion
35
+
36
+ MSG = 'Replace with `%<preferred>s` for comparison with bit flags.'
37
+ RESTRICT_ON_SEND = %i[!= == > >= positive? zero?].freeze
38
+
39
+ minimum_target_ruby_version 2.5
40
+
41
+ # @!method anybits?(node)
42
+ def_node_matcher :anybits?, <<~PATTERN
43
+ {
44
+ (send #bit_operation? :positive?)
45
+ (send #bit_operation? :> (int 0))
46
+ (send #bit_operation? :>= (int 1))
47
+ (send #bit_operation? :!= (int 0))
48
+ }
49
+ PATTERN
50
+
51
+ # @!method allbits?(node)
52
+ def_node_matcher :allbits?, <<~PATTERN
53
+ {
54
+ (send (begin (send _ :& _flags)) :== _flags)
55
+ (send (begin (send _flags :& _)) :== _flags)
56
+ }
57
+ PATTERN
58
+
59
+ # @!method nobits?(node)
60
+ def_node_matcher :nobits?, <<~PATTERN
61
+ {
62
+ (send #bit_operation? :zero?)
63
+ (send #bit_operation? :== (int 0))
64
+ }
65
+ PATTERN
66
+
67
+ # @!method bit_operation?(node)
68
+ def_node_matcher :bit_operation?, <<~PATTERN
69
+ (begin
70
+ (send _ :& _))
71
+ PATTERN
72
+
73
+ def on_send(node)
74
+ return unless node.receiver.begin_type?
75
+ return unless (preferred_method = preferred_method(node))
76
+
77
+ bit_operation = node.receiver.children.first
78
+ lhs, _operator, rhs = *bit_operation
79
+ preferred = "#{lhs.source}.#{preferred_method}(#{rhs.source})"
80
+
81
+ add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
82
+ corrector.replace(node, preferred)
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def preferred_method(node)
89
+ if anybits?(node)
90
+ 'anybits?'
91
+ elsif allbits?(node)
92
+ 'allbits?'
93
+ elsif nobits?(node)
94
+ 'nobits?'
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -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)
@@ -176,6 +176,10 @@ module RuboCop
176
176
 
177
177
  BRACES_REQUIRED_MESSAGE = "Brace delimiters `{...}` required for '%<method_name>s' method."
178
178
 
179
+ def self.autocorrect_incompatible_with
180
+ [Style::RedundantBegin]
181
+ end
182
+
179
183
  def on_send(node)
180
184
  return unless node.arguments?
181
185
  return if node.parenthesized?
@@ -299,13 +303,28 @@ module RuboCop
299
303
 
300
304
  def move_comment_before_block(corrector, comment, block_node, closing_brace)
301
305
  range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
306
+
307
+ # It is possible that there is code between the block and the comment
308
+ # which needs to be preserved and trimmed.
309
+ pre_comment_range = source_range_before_comment(range, comment)
310
+
302
311
  corrector.remove(range_with_surrounding_space(comment.source_range, side: :right))
303
- remove_trailing_whitespace(corrector, range, comment)
304
- corrector.insert_after(range, "\n")
312
+ remove_trailing_whitespace(corrector, pre_comment_range, comment)
313
+ corrector.insert_after(pre_comment_range, "\n")
305
314
 
306
315
  corrector.insert_before(block_node, "#{comment.text}\n")
307
316
  end
308
317
 
318
+ def source_range_before_comment(range, comment)
319
+ range = range.end.join(comment.source_range.begin)
320
+
321
+ # End the range before any whitespace that precedes the comment
322
+ trailing_whitespace_count = range.source[/\s+\z/]&.length
323
+ range = range.adjust(end_pos: -trailing_whitespace_count) if trailing_whitespace_count
324
+
325
+ range
326
+ end
327
+
309
328
  def end_of_chain(node)
310
329
  return end_of_chain(node.block_node) if with_block?(node)
311
330
  return node unless node.chained?
@@ -341,8 +360,9 @@ module RuboCop
341
360
  end
342
361
  end
343
362
 
363
+ # rubocop:disable Metrics/CyclomaticComplexity
344
364
  def proper_block_style?(node)
345
- return true if require_braces?(node)
365
+ return true if require_braces?(node) || require_do_end?(node)
346
366
  return special_method_proper_block_style?(node) if special_method?(node.method_name)
347
367
 
348
368
  case style
@@ -352,6 +372,7 @@ module RuboCop
352
372
  when :always_braces then braces_style?(node)
353
373
  end
354
374
  end
375
+ # rubocop:enable Metrics/CyclomaticComplexity
355
376
 
356
377
  def require_braces?(node)
357
378
  return false unless node.braces?
@@ -361,6 +382,13 @@ module RuboCop
361
382
  end
362
383
  end
363
384
 
385
+ def require_do_end?(node)
386
+ return false if node.braces? || node.multiline?
387
+ return false unless (resbody = node.each_descendant(:resbody).first)
388
+
389
+ resbody.children.first&.array_type?
390
+ end
391
+
364
392
  def special_method?(method_name)
365
393
  allowed_method?(method_name) ||
366
394
  matches_allowed_pattern?(method_name) ||
@@ -370,7 +398,8 @@ module RuboCop
370
398
  def special_method_proper_block_style?(node)
371
399
  method_name = node.method_name
372
400
  return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
373
- return node.braces? if braces_required_method?(method_name)
401
+
402
+ node.braces? if braces_required_method?(method_name)
374
403
  end
375
404
 
376
405
  def braces_required_method?(method_name)
@@ -411,7 +440,7 @@ module RuboCop
411
440
  end
412
441
 
413
442
  def correction_would_break_code?(node)
414
- return unless node.keywords?
443
+ return false unless node.keywords?
415
444
 
416
445
  node.send_node.arguments? && !node.send_node.parenthesized?
417
446
  end
@@ -433,7 +462,7 @@ module RuboCop
433
462
  end
434
463
 
435
464
  def return_value_used?(node)
436
- return unless node.parent
465
+ return false unless node.parent
437
466
 
438
467
  # If there are parentheses around the block, check if that
439
468
  # is being used.
@@ -445,7 +474,7 @@ module RuboCop
445
474
  end
446
475
 
447
476
  def return_value_of_scope?(node)
448
- return unless node.parent
477
+ return false unless node.parent
449
478
 
450
479
  conditional?(node.parent) || array_or_range?(node.parent) ||
451
480
  node.parent.children.last == node
@@ -125,7 +125,7 @@ module RuboCop
125
125
  when :==, :eql?, :equal?
126
126
  find_target_in_equality_node(node)
127
127
  when :===
128
- node.arguments.first
128
+ node.first_argument
129
129
  when :include?, :cover?
130
130
  find_target_in_include_or_cover_node(node)
131
131
  when :match, :match?, :=~
@@ -134,7 +134,7 @@ module RuboCop
134
134
  end
135
135
 
136
136
  def find_target_in_equality_node(node)
137
- argument = node.arguments.first
137
+ argument = node.first_argument
138
138
  receiver = node.receiver
139
139
  return unless argument && receiver
140
140
 
@@ -152,7 +152,7 @@ module RuboCop
152
152
  end
153
153
 
154
154
  def find_target_in_match_node(node)
155
- argument = node.arguments.first
155
+ argument = node.first_argument
156
156
  receiver = node.receiver
157
157
  return unless receiver
158
158
 
@@ -185,7 +185,7 @@ module RuboCop
185
185
  def condition_from_send_node(node, target)
186
186
  case node.method_name
187
187
  when :is_a?
188
- node.arguments.first if node.receiver == target
188
+ node.first_argument if node.receiver == target
189
189
  when :==, :eql?, :equal?
190
190
  condition_from_equality_node(node, target)
191
191
  when :=~, :match, :match?
@@ -230,7 +230,7 @@ module RuboCop
230
230
 
231
231
  def branch_conditions(node)
232
232
  conditions = []
233
- while node&.if_type?
233
+ while node&.if_type? && !node.ternary?
234
234
  conditions << node.condition
235
235
  node = node.else_branch
236
236
  end
@@ -139,7 +139,7 @@ module RuboCop
139
139
  end
140
140
 
141
141
  def check_style(node, body)
142
- return if node.identifier.children[0]&.cbase_type?
142
+ return if node.identifier.namespace&.cbase_type?
143
143
 
144
144
  if style == :nested
145
145
  check_nested_style(node)
@@ -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,53 +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)
28
+ # def ==(other)
29
+ # self.class == other.class && name == other.name
30
+ # end
24
31
  #
25
- # # bad
26
- # var.class == Date
27
- # var.class.equal?(Date)
28
- # var.class.eql?(Date)
29
- # var.class.name == 'Date'
30
- # var.class.to_s == 'Date'
31
- # var.class.inspect == 'Date'
32
+ # def equal?(other)
33
+ # self.class.equal?(other.class) && name.equal?(other.name)
34
+ # end
32
35
  #
33
- # @example AllowedMethods: [`==`]
34
- # # good
35
- # var.instance_of?(Date)
36
- # var.class == Date
37
- # var.class.name == 'Date'
38
- # var.class.to_s == 'Date'
39
- # var.class.inspect == 'Date'
40
- #
41
- # # bad
42
- # var.class.equal?(Date)
43
- # var.class.eql?(Date)
36
+ # def eql?(other)
37
+ # self.class.eql?(other.class) && name.eql?(other.name)
38
+ # end
44
39
  #
45
40
  # @example AllowedPatterns: [] (default)
46
- # # good
47
- # var.instance_of?(Date)
48
- #
49
41
  # # bad
50
- # var.class == Date
51
- # var.class.equal?(Date)
52
- # var.class.eql?(Date)
53
- # var.class.name == 'Date'
54
- # var.class.to_s == 'Date'
55
- # var.class.inspect == 'Date'
42
+ # def eq(other)
43
+ # self.class.eq(other.class) && name.eq(other.name)
44
+ # end
56
45
  #
57
46
  # @example AllowedPatterns: ['eq']
58
47
  # # good
59
- # var.instance_of?(Date)
60
- # var.class.equal?(Date)
61
- # var.class.eql?(Date)
62
- #
63
- # # bad
64
- # var.class == Date
65
- # var.class.name == 'Date'
66
- # var.class.to_s == 'Date'
67
- # var.class.inspect == 'Date'
48
+ # def eq(other)
49
+ # self.class.eq(other.class) && name.eq(other.name)
50
+ # end
68
51
  #
69
52
  class ClassEqualityComparison < Base
70
53
  include RangeHelp
@@ -91,6 +74,8 @@ module RuboCop
91
74
  matches_allowed_pattern?(def_node.method_name))
92
75
 
93
76
  class_comparison_candidate?(node) do |receiver_node, class_node|
77
+ return if class_node.dstr_type?
78
+
94
79
  range = offense_range(receiver_node, node)
95
80
  class_argument = (class_name = class_name(class_node, node)) ? "(#{class_name})" : ''
96
81
 
@@ -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,6 +21,9 @@ module RuboCop
21
21
  # array.reject(&:nil?)
22
22
  # array.reject { |e| e.nil? }
23
23
  # array.select { |e| !e.nil? }
24
+ # array.filter { |e| !e.nil? }
25
+ # array.grep_v(nil)
26
+ # array.grep_v(NilClass)
24
27
  #
25
28
  # # good
26
29
  # array.compact
@@ -29,24 +32,31 @@ module RuboCop
29
32
  # hash.reject!(&:nil?)
30
33
  # hash.reject! { |k, v| v.nil? }
31
34
  # hash.select! { |k, v| !v.nil? }
35
+ # hash.filter! { |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
39
48
  extend TargetRubyVersion
40
49
 
41
50
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
42
- RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
51
+ RESTRICT_ON_SEND = %i[reject reject! select select! filter filter! grep_v].freeze
43
52
  TO_ENUM_METHODS = %i[to_enum lazy].freeze
53
+ FILTER_METHODS = %i[filter filter!].freeze
44
54
 
45
55
  minimum_target_ruby_version 2.4
46
56
 
47
57
  # @!method reject_method_with_block_pass?(node)
48
58
  def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
49
- (send !nil? {:reject :reject!}
59
+ (call !nil? {:reject :reject!}
50
60
  (block_pass
51
61
  (sym :nil?)))
52
62
  PATTERN
@@ -54,26 +64,33 @@ module RuboCop
54
64
  # @!method reject_method?(node)
55
65
  def_node_matcher :reject_method?, <<~PATTERN
56
66
  (block
57
- (send
67
+ (call
58
68
  !nil? {:reject :reject!})
59
69
  $(args ...)
60
- (send
70
+ (call
61
71
  $(lvar _) :nil?))
62
72
  PATTERN
63
73
 
64
74
  # @!method select_method?(node)
65
75
  def_node_matcher :select_method?, <<~PATTERN
66
76
  (block
67
- (send
68
- !nil? {:select :select!})
77
+ (call
78
+ !nil? {:select :select! :filter :filter!})
69
79
  $(args ...)
70
- (send
71
- (send
80
+ (call
81
+ (call
72
82
  $(lvar _) :nil?) :!))
73
83
  PATTERN
74
84
 
85
+ # @!method grep_v_with_nil?(node)
86
+ def_node_matcher :grep_v_with_nil?, <<~PATTERN
87
+ (send _ :grep_v {(nil) (const {nil? cbase} :NilClass)})
88
+ PATTERN
89
+
75
90
  def on_send(node)
91
+ return if target_ruby_version < 2.6 && FILTER_METHODS.include?(node.method_name)
76
92
  return unless (range = offense_range(node))
93
+ return if allowed_receiver?(node.receiver)
77
94
  return if target_ruby_version <= 3.0 && to_enum_method?(node)
78
95
 
79
96
  good = good_method_name(node)
@@ -81,11 +98,13 @@ module RuboCop
81
98
 
82
99
  add_offense(range, message: message) { |corrector| corrector.replace(range, good) }
83
100
  end
101
+ alias on_csend on_send
84
102
 
85
103
  private
86
104
 
105
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
87
106
  def offense_range(node)
88
- if reject_method_with_block_pass?(node)
107
+ if reject_method_with_block_pass?(node) || grep_v_with_nil?(node)
89
108
  range(node, node)
90
109
  else
91
110
  block_node = node.parent
@@ -99,6 +118,7 @@ module RuboCop
99
118
  range(node, block_node)
100
119
  end
101
120
  end
121
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
102
122
 
103
123
  def to_enum_method?(node)
104
124
  return false unless node.receiver.send_type?
@@ -25,6 +25,7 @@ module RuboCop
25
25
  # # bad
26
26
  # items.collect
27
27
  # items.collect!
28
+ # items.collect_concat
28
29
  # items.inject
29
30
  # items.detect
30
31
  # items.find_all
@@ -33,6 +34,7 @@ module RuboCop
33
34
  # # good
34
35
  # items.map
35
36
  # items.map!
37
+ # items.flat_map
36
38
  # items.reduce
37
39
  # items.find
38
40
  # items.select
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for methods invoked via the :: operator instead
7
- # of the . operator (like FileUtils::rmdir instead of FileUtils.rmdir).
6
+ # Checks for methods invoked via the `::` operator instead
7
+ # of the `.` operator (like `FileUtils::rmdir` instead of `FileUtils.rmdir`).
8
8
  #
9
9
  # @example
10
10
  # # bad