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
@@ -22,6 +22,15 @@ module RuboCop
22
22
  # # bad
23
23
  # [:foo, :bar, :baz]
24
24
  #
25
+ # # bad (contains spaces)
26
+ # %i[foo\ bar baz\ quux]
27
+ #
28
+ # # bad (contains [] with spaces)
29
+ # %i[foo \[ \]]
30
+ #
31
+ # # bad (contains () with spaces)
32
+ # %i(foo \( \))
33
+ #
25
34
  # @example EnforcedStyle: brackets
26
35
  # # good
27
36
  # [:foo, :bar, :baz]
@@ -40,6 +49,15 @@ module RuboCop
40
49
 
41
50
  PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'
42
51
  ARRAY_MSG = 'Use %<prefer>s for an array of symbols.'
52
+ DELIMITERS = ['[', ']', '(', ')'].freeze
53
+ SPECIAL_GVARS = %w[
54
+ $! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
55
+ $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
56
+ ].freeze
57
+ REDEFINABLE_OPERATORS = %w(
58
+ | ^ & <=> == === =~ > >= < <= << >>
59
+ + - * / % ** ~ +@ -@ [] []= ` ! != !~
60
+ ).freeze
43
61
 
44
62
  class << self
45
63
  attr_accessor :largest_brackets
@@ -47,7 +65,7 @@ module RuboCop
47
65
 
48
66
  def on_array(node)
49
67
  if bracketed_array_of?(:sym, node)
50
- return if symbols_contain_spaces?(node)
68
+ return if complex_content?(node)
51
69
 
52
70
  check_bracketed_array(node, 'i')
53
71
  elsif node.percent_literal?(:symbol)
@@ -57,13 +75,24 @@ module RuboCop
57
75
 
58
76
  private
59
77
 
60
- def symbols_contain_spaces?(node)
78
+ def complex_content?(node)
61
79
  node.children.any? do |sym|
62
- content, = *sym
63
- content.to_s.include?(' ')
80
+ return false if DELIMITERS.include?(sym.source)
81
+
82
+ content = *sym
83
+ content = content.map { |c| c.is_a?(AST::Node) ? c.source : c }.join
84
+ content_without_delimiter_pairs = content.gsub(/(\[[^\s\[\]]*\])|(\([^\s\(\)]*\))/, '')
85
+
86
+ content.include?(' ') || DELIMITERS.any? do |delimiter|
87
+ content_without_delimiter_pairs.include?(delimiter)
88
+ end
64
89
  end
65
90
  end
66
91
 
92
+ def invalid_percent_array_contents?(node)
93
+ complex_content?(node)
94
+ end
95
+
67
96
  def build_bracketed_array(node)
68
97
  return '[]' if node.children.empty?
69
98
 
@@ -88,15 +117,6 @@ module RuboCop
88
117
  end
89
118
 
90
119
  def symbol_without_quote?(string)
91
- special_gvars = %w[
92
- $! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
93
- $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
94
- ]
95
- redefinable_operators = %w(
96
- | ^ & <=> == === =~ > >= < <= << >>
97
- + - * / % ** ~ +@ -@ [] []= ` ! != !~
98
- )
99
-
100
120
  # method name
101
121
  /\A[a-zA-Z_]\w*[!?]?\z/.match?(string) ||
102
122
  # instance / class variable
@@ -104,8 +124,8 @@ module RuboCop
104
124
  # global variable
105
125
  /\A\$[1-9]\d*\z/.match?(string) ||
106
126
  /\A\$[a-zA-Z_]\w*\z/.match?(string) ||
107
- special_gvars.include?(string) ||
108
- redefinable_operators.include?(string)
127
+ SPECIAL_GVARS.include?(string) ||
128
+ REDEFINABLE_OPERATORS.include?(string)
109
129
  end
110
130
  end
111
131
  end
@@ -37,6 +37,42 @@ module RuboCop
37
37
  # # ArgumentError: wrong number of arguments (given 1, expected 0)
38
38
  # ----
39
39
  #
40
+ # It is also unsafe because `Symbol#to_proc` does not work with
41
+ # `protected` methods which would otherwise be accessible.
42
+ #
43
+ # For example:
44
+ #
45
+ # [source,ruby]
46
+ # ----
47
+ # class Box
48
+ # def initialize
49
+ # @secret = rand
50
+ # end
51
+ #
52
+ # def normal_matches?(*others)
53
+ # others.map { |other| other.secret }.any?(secret)
54
+ # end
55
+ #
56
+ # def symbol_to_proc_matches?(*others)
57
+ # others.map(&:secret).any?(secret)
58
+ # end
59
+ #
60
+ # protected
61
+ #
62
+ # attr_reader :secret
63
+ # end
64
+ #
65
+ # boxes = [Box.new, Box.new]
66
+ # Box.new.normal_matches?(*boxes)
67
+ # # => false
68
+ # boxes.first.normal_matches?(*boxes)
69
+ # # => true
70
+ # Box.new.symbol_to_proc_matches?(*boxes)
71
+ # # => NoMethodError: protected method `secret' called for #<Box...>
72
+ # boxes.first.symbol_to_proc_matches?(*boxes)
73
+ # # => NoMethodError: protected method `secret' called for #<Box...>
74
+ # ----
75
+ #
40
76
  # @example
41
77
  # # bad
42
78
  # something.map { |s| s.upcase }
@@ -84,6 +120,23 @@ module RuboCop
84
120
  # # good
85
121
  # something.map { |s| s.upcase }
86
122
  #
123
+ # @example AllCops:ActiveSupportExtensionsEnabled: false (default)
124
+ # # bad
125
+ # ->(x) { x.foo }
126
+ # proc { |x| x.foo }
127
+ # Proc.new { |x| x.foo }
128
+ #
129
+ # # good
130
+ # lambda(&:foo)
131
+ # proc(&:foo)
132
+ # Proc.new(&:foo)
133
+ #
134
+ # @example AllCops:ActiveSupportExtensionsEnabled: true
135
+ # # good
136
+ # ->(x) { x.foo }
137
+ # proc { |x| x.foo }
138
+ # Proc.new { |x| x.foo }
139
+ #
87
140
  class SymbolProc < Base
88
141
  include CommentsHelp
89
142
  include RangeHelp
@@ -93,6 +146,7 @@ module RuboCop
93
146
 
94
147
  MSG = 'Pass `&:%<method>s` as an argument to `%<block_method>s` instead of a block.'
95
148
  SUPER_TYPES = %i[super zsuper].freeze
149
+ LAMBDA_OR_PROC = %i[lambda proc].freeze
96
150
 
97
151
  # @!method proc_node?(node)
98
152
  def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
@@ -115,13 +169,12 @@ module RuboCop
115
169
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
116
170
  def on_block(node)
117
171
  symbol_proc?(node) do |dispatch_node, arguments_node, method_name|
118
- # TODO: Rails-specific handling that we should probably make
119
- # configurable - https://github.com/rubocop/rubocop/issues/1485
120
- # we should allow lambdas & procs
121
- return if proc_node?(dispatch_node)
172
+ if active_support_extensions_enabled?
173
+ return if proc_node?(dispatch_node)
174
+ return if LAMBDA_OR_PROC.include?(dispatch_node.method_name)
175
+ end
122
176
  return if unsafe_hash_usage?(dispatch_node)
123
177
  return if unsafe_array_usage?(dispatch_node)
124
- return if %i[lambda proc].include?(dispatch_node.method_name)
125
178
  return if allowed_method_name?(dispatch_node.method_name)
126
179
  return if allow_if_method_has_argument?(node.send_node)
127
180
  return if node.block_type? && destructuring_block_argument?(arguments_node)
@@ -170,6 +223,15 @@ module RuboCop
170
223
  end
171
224
 
172
225
  def autocorrect_without_args(corrector, node)
226
+ if node.send_node.lambda_literal?
227
+ if node.send_node.loc.selector.source == '->'
228
+ corrector.replace(node, "lambda(&:#{node.body.method_name})")
229
+ return
230
+ else
231
+ autocorrect_lambda_block(corrector, node)
232
+ end
233
+ end
234
+
173
235
  corrector.replace(block_range_with_space(node), "(&:#{node.body.method_name})")
174
236
  end
175
237
 
@@ -182,6 +244,14 @@ module RuboCop
182
244
  corrector.remove(block_range_with_space(node))
183
245
  end
184
246
 
247
+ def autocorrect_lambda_block(corrector, node)
248
+ send_node_loc = node.send_node.loc
249
+ corrector.replace(send_node_loc.selector, 'lambda')
250
+
251
+ range = range_between(send_node_loc.selector.end_pos, node.loc.begin.end_pos - 2)
252
+ corrector.remove(range)
253
+ end
254
+
185
255
  def block_range_with_space(node)
186
256
  block_range = range_between(begin_pos_for_replacement(node), node.loc.end.end_pos)
187
257
  range_with_surrounding_space(block_range, side: :left)
@@ -75,7 +75,7 @@ module RuboCop
75
75
 
76
76
  message = message(node)
77
77
 
78
- add_offense(node.source_range, message: message) do |corrector|
78
+ add_offense(node, message: message) do |corrector|
79
79
  autocorrect(corrector, node)
80
80
  end
81
81
  end
@@ -171,9 +171,7 @@ module RuboCop
171
171
  end
172
172
 
173
173
  def unsafe_autocorrect?(condition)
174
- condition.children.any? do |child|
175
- unparenthesized_method_call?(child) || below_ternary_precedence?(child)
176
- end
174
+ condition.children.any? { |child| below_ternary_precedence?(child) }
177
175
  end
178
176
 
179
177
  def unparenthesized_method_call?(child)
@@ -192,7 +190,7 @@ module RuboCop
192
190
  # @!method method_name(node)
193
191
  def_node_matcher :method_name, <<~PATTERN
194
192
  {($:defined? _ ...)
195
- (send {_ nil?} $_ _ ...)}
193
+ (call {_ nil?} $_ _ ...)}
196
194
  PATTERN
197
195
 
198
196
  def correct_parenthesized(corrector, condition)
@@ -203,16 +201,39 @@ module RuboCop
203
201
  # If we remove the parentheses, we need to add a space or we'll
204
202
  # generate invalid code.
205
203
  corrector.insert_after(condition.loc.end, ' ') unless whitespace_after?(condition)
204
+
205
+ if (send_node = condition.child_nodes.last) && node_args_need_parens?(send_node)
206
+ parenthesize_condition_arguments(corrector, send_node)
207
+ end
206
208
  end
207
209
 
208
210
  def correct_unparenthesized(corrector, condition)
209
211
  corrector.wrap(condition, '(', ')')
210
212
  end
211
213
 
214
+ def parenthesize_condition_arguments(corrector, send_node)
215
+ range_start = send_node.defined_type? ? send_node.loc.keyword : send_node.loc.selector
216
+ opening_range = range_start.end.join(send_node.first_argument.source_range.begin)
217
+
218
+ corrector.replace(opening_range, '(')
219
+ corrector.insert_after(send_node.last_argument, ')')
220
+ end
221
+
212
222
  def whitespace_after?(node)
213
223
  last_token = processed_source.last_token_of(node)
214
224
  last_token.space_after?
215
225
  end
226
+
227
+ def node_args_need_parens?(send_node)
228
+ return false unless node_with_args?(send_node)
229
+ return false if send_node.arguments.none? || send_node.parenthesized?
230
+
231
+ send_node.dot? || send_node.safe_navigation? || unparenthesized_method_call?(send_node)
232
+ end
233
+
234
+ def node_with_args?(node)
235
+ node.call_type? || node.defined_type?
236
+ end
216
237
  end
217
238
  end
218
239
  end
@@ -77,7 +77,7 @@ module RuboCop
77
77
 
78
78
  # @!method define_method_block?(node)
79
79
  def_node_matcher :define_method_block?, <<~PATTERN
80
- ({block numblock} (send _ {:define_method} _) ...)
80
+ ({block numblock} (send _ :define_method _) ...)
81
81
  PATTERN
82
82
  end
83
83
  end
@@ -179,7 +179,7 @@ module RuboCop
179
179
  end
180
180
 
181
181
  def looks_like_trivial_reader?(node)
182
- !node.arguments? && node.body && node.body.ivar_type?
182
+ !node.arguments? && node.body&.ivar_type?
183
183
  end
184
184
 
185
185
  def trivial_writer?(node)
@@ -23,38 +23,35 @@ module RuboCop
23
23
 
24
24
  minimum_target_ruby_version 2.4
25
25
 
26
- MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of ' \
27
- '`%<receiver>s.unpack(%<format>s)%<method>s`.'
26
+ MSG = 'Use `unpack1(%<format>s)` instead of `%<current>s`.'
28
27
  RESTRICT_ON_SEND = %i[first [] slice at].freeze
29
28
 
30
29
  # @!method unpack_and_first_element?(node)
31
30
  def_node_matcher :unpack_and_first_element?, <<~PATTERN
32
31
  {
33
- (send $(send (...) :unpack $(...)) :first)
34
- (send $(send (...) :unpack $(...)) {:[] :slice :at} (int 0))
32
+ (call $(call (...) :unpack $(...)) :first)
33
+ (call $(call (...) :unpack $(...)) {:[] :slice :at} (int 0))
35
34
  }
36
35
  PATTERN
37
36
 
38
37
  def on_send(node)
39
38
  unpack_and_first_element?(node) do |unpack_call, unpack_arg|
40
- range = first_element_range(node, unpack_call)
41
- message = format(MSG,
42
- receiver: unpack_call.receiver.source,
43
- format: unpack_arg.source,
44
- method: range.source)
45
- add_offense(node, message: message) do |corrector|
46
- corrector.remove(first_element_range(node, unpack_call))
39
+ first_element_range = first_element_range(node, unpack_call)
40
+ offense_range = unpack_call.loc.selector.join(node.source_range.end)
41
+ message = format(MSG, format: unpack_arg.source, current: offense_range.source)
42
+
43
+ add_offense(offense_range, message: message) do |corrector|
44
+ corrector.remove(first_element_range)
47
45
  corrector.replace(unpack_call.loc.selector, 'unpack1')
48
46
  end
49
47
  end
50
48
  end
49
+ alias on_csend on_send
51
50
 
52
51
  private
53
52
 
54
53
  def first_element_range(node, unpack_call)
55
- Parser::Source::Range.new(node.source_range.source_buffer,
56
- unpack_call.source_range.end_pos,
57
- node.source_range.end_pos)
54
+ unpack_call.source_range.end.join(node.source_range.end)
58
55
  end
59
56
  end
60
57
  end
@@ -17,8 +17,6 @@ module RuboCop
17
17
  # do_something(x.pop)
18
18
  # end
19
19
  #
20
- # @example
21
- #
22
20
  # # bad
23
21
  # until x.empty? do
24
22
  # do_something(x.pop)
@@ -16,7 +16,6 @@ module RuboCop
16
16
  # # good
17
17
  # x += 1 while x < 10
18
18
  #
19
- # @example
20
19
  # # bad
21
20
  # until x > 10
22
21
  # x += 1
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with
7
+ # `File.read` argument.
8
+ #
9
+ # NOTE: `YAML.safe_load_file` was introduced in Ruby 3.0.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # YAML.load(File.read(path))
15
+ # YAML.parse(File.read(path))
16
+ #
17
+ # # good
18
+ # YAML.load_file(path)
19
+ # YAML.parse_file(path)
20
+ #
21
+ # # bad
22
+ # YAML.safe_load(File.read(path)) # Ruby 3.0 and newer
23
+ #
24
+ # # good
25
+ # YAML.safe_load_file(path) # Ruby 3.0 and newer
26
+ #
27
+ class YAMLFileRead < Base
28
+ extend AutoCorrector
29
+
30
+ MSG = 'Use `%<prefer>s` instead.'
31
+ RESTRICT_ON_SEND = %i[load safe_load parse].freeze
32
+
33
+ # @!method yaml_file_read?(node)
34
+ def_node_matcher :yaml_file_read?, <<~PATTERN
35
+ (send
36
+ (const {cbase nil?} :YAML) _
37
+ (send
38
+ (const {cbase nil?} :File) :read $_) $...)
39
+ PATTERN
40
+
41
+ def on_send(node)
42
+ return if node.method?(:safe_load) && target_ruby_version <= 2.7
43
+ return unless (file_path, rest_arguments = yaml_file_read?(node))
44
+
45
+ range = offense_range(node)
46
+ rest_arguments = if rest_arguments.empty?
47
+ ''
48
+ else
49
+ ", #{rest_arguments.map(&:source).join(', ')}"
50
+ end
51
+ prefer = "#{node.method_name}_file(#{file_path.source}#{rest_arguments})"
52
+
53
+ add_offense(range, message: format(MSG, prefer: prefer)) do |corrector|
54
+ corrector.replace(range, prefer)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def offense_range(node)
61
+ node.loc.selector.join(node.source_range.end)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -118,16 +118,18 @@ module RuboCop
118
118
  node.comparison_method? && !noncommutative_operator?(node)
119
119
  end
120
120
 
121
+ # rubocop:disable Metrics/CyclomaticComplexity
121
122
  def valid_yoda?(node)
122
- lhs = node.receiver
123
- rhs = node.first_argument
123
+ return true unless (rhs = node.first_argument)
124
124
 
125
+ lhs = node.receiver
125
126
  return true if (constant_portion?(lhs) && constant_portion?(rhs)) ||
126
127
  (!constant_portion?(lhs) && !constant_portion?(rhs)) ||
127
128
  interpolation?(lhs)
128
129
 
129
130
  enforce_yoda? ? constant_portion?(lhs) : constant_portion?(rhs)
130
131
  end
132
+ # rubocop:enable Metrics/CyclomaticComplexity
131
133
 
132
134
  def message(node)
133
135
  format(MSG, source: node.source)
@@ -19,22 +19,23 @@ module RuboCop
19
19
  # differently on different classes, and are not guaranteed to
20
20
  # have the same result if reversed.
21
21
  #
22
- # @example SupportedOperators: ['*', '+', '&'']
22
+ # @example SupportedOperators: ['*', '+', '&', '|', '^'] (default)
23
23
  # # bad
24
- # 1 + x
25
24
  # 10 * y
25
+ # 1 + x
26
26
  # 1 & z
27
+ # 1 | x
28
+ # 1 ^ x
27
29
  # 1 + CONST
28
30
  #
29
31
  # # good
30
- # 60 * 24
31
- # x + 1
32
32
  # y * 10
33
+ # x + 1
33
34
  # z & 1
35
+ # x | 1
36
+ # x ^ 1
34
37
  # CONST + 1
35
- #
36
- # # good
37
- # 1 | x
38
+ # 60 * 24
38
39
  #
39
40
  class YodaExpression < Base
40
41
  extend AutoCorrector
@@ -48,14 +48,19 @@ module RuboCop
48
48
  check_nonzero_length_comparison(node)
49
49
  end
50
50
 
51
+ def on_csend(node)
52
+ check_zero_length_predicate(node)
53
+ check_zero_length_comparison(node)
54
+ end
55
+
51
56
  private
52
57
 
53
58
  def check_zero_length_predicate(node)
54
- return unless (length_method = zero_length_predicate(node.parent))
59
+ return unless zero_length_predicate?(node.parent)
55
60
  return if non_polymorphic_collection?(node.parent)
56
61
 
57
62
  offense = node.loc.selector.join(node.parent.source_range.end)
58
- message = format(ZERO_MSG, current: "#{length_method}.zero?")
63
+ message = format(ZERO_MSG, current: offense.source)
59
64
 
60
65
  add_offense(offense, message: message) do |corrector|
61
66
  corrector.replace(offense, 'empty?')
@@ -92,44 +97,47 @@ module RuboCop
92
97
  end
93
98
  end
94
99
 
95
- # @!method zero_length_predicate(node)
96
- def_node_matcher :zero_length_predicate, <<~PATTERN
97
- (send (send (...) ${:length :size}) :zero?)
100
+ # @!method zero_length_predicate?(node)
101
+ def_node_matcher :zero_length_predicate?, <<~PATTERN
102
+ (call (call (...) {:length :size}) :zero?)
98
103
  PATTERN
99
104
 
100
105
  # @!method zero_length_comparison(node)
101
106
  def_node_matcher :zero_length_comparison, <<~PATTERN
102
- {(send (send (...) ${:length :size}) $:== (int $0))
103
- (send (int $0) $:== (send (...) ${:length :size}))
104
- (send (send (...) ${:length :size}) $:< (int $1))
105
- (send (int $1) $:> (send (...) ${:length :size}))}
107
+ {(call (call (...) ${:length :size}) $:== (int $0))
108
+ (call (int $0) $:== (call (...) ${:length :size}))
109
+ (call (call (...) ${:length :size}) $:< (int $1))
110
+ (call (int $1) $:> (call (...) ${:length :size}))}
106
111
  PATTERN
107
112
 
108
113
  # @!method nonzero_length_comparison(node)
109
114
  def_node_matcher :nonzero_length_comparison, <<~PATTERN
110
- {(send (send (...) ${:length :size}) ${:> :!=} (int $0))
111
- (send (int $0) ${:< :!=} (send (...) ${:length :size}))}
115
+ {(call (call (...) ${:length :size}) ${:> :!=} (int $0))
116
+ (call (int $0) ${:< :!=} (call (...) ${:length :size}))}
112
117
  PATTERN
113
118
 
114
119
  def replacement(node)
115
- receiver = zero_length_receiver(node)
116
- return "#{receiver.source}.empty?" if receiver
120
+ length_node = zero_length_node(node)
121
+ if length_node&.receiver
122
+ return "#{length_node.receiver.source}#{length_node.loc.dot.source}empty?"
123
+ end
117
124
 
118
- "!#{other_receiver(node).source}.empty?"
125
+ other_length_node = other_length_node(node)
126
+ "!#{other_length_node.receiver.source}#{other_length_node.loc.dot.source}empty?"
119
127
  end
120
128
 
121
- # @!method zero_length_receiver(node)
122
- def_node_matcher :zero_length_receiver, <<~PATTERN
123
- {(send (send $_ _) :== (int 0))
124
- (send (int 0) :== (send $_ _))
125
- (send (send $_ _) :< (int 1))
126
- (send (int 1) :> (send $_ _))}
129
+ # @!method zero_length_node(node)
130
+ def_node_matcher :zero_length_node, <<~PATTERN
131
+ {(send $(call _ _) :== (int 0))
132
+ (send (int 0) :== $(call _ _))
133
+ (send $(call _ _) :< (int 1))
134
+ (send (int 1) :> $(call _ _))}
127
135
  PATTERN
128
136
 
129
- # @!method other_receiver(node)
130
- def_node_matcher :other_receiver, <<~PATTERN
131
- {(send (send $_ _) _ _)
132
- (send _ _ (send $_ _))}
137
+ # @!method other_length_node(node)
138
+ def_node_matcher :other_length_node, <<~PATTERN
139
+ {(call $(call _ _) _ _)
140
+ (call _ _ $(call _ _))}
133
141
  PATTERN
134
142
 
135
143
  # Some collection like objects in the Ruby standard library
@@ -9,11 +9,17 @@ module RuboCop
9
9
  # For performance reasons, Team will first dispatch cops & forces in two groups,
10
10
  # first the ones needed for autocorrection (if any), then the rest
11
11
  # (unless autocorrections happened).
12
+ # rubocop:disable Metrics/ClassLength
12
13
  class Team
13
14
  # @return [Team]
14
15
  def self.new(cop_or_classes, config, options = {})
15
16
  # Support v0 api:
16
- return mobilize(cop_or_classes, config, options) if cop_or_classes.first.is_a?(Class)
17
+ if cop_or_classes.first.is_a?(Class)
18
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
19
+ `Team.new` with cop classes is deprecated. Use `Team.mobilize` instead.
20
+ WARNING
21
+ return mobilize(cop_or_classes, config, options)
22
+ end
17
23
 
18
24
  super
19
25
  end
@@ -74,6 +80,10 @@ module RuboCop
74
80
  # @deprecated. Use investigate
75
81
  # @return Array<offenses>
76
82
  def inspect_file(processed_source)
83
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
84
+ `inspect_file` is deprecated. Use `investigate` instead.
85
+ WARNING
86
+
77
87
  investigate(processed_source).offenses
78
88
  end
79
89
 
@@ -108,12 +118,20 @@ module RuboCop
108
118
 
109
119
  # @deprecated
110
120
  def forces
121
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
122
+ `forces` is deprecated.
123
+ WARNING
124
+
111
125
  @forces ||= self.class.forces_for(cops)
112
126
  end
113
127
 
114
128
  def external_dependency_checksum
115
- keys = cops.map(&:external_dependency_checksum).compact
116
- Digest::SHA1.hexdigest(keys.join)
129
+ # The external dependency checksums are cached per RuboCop team so that
130
+ # the checksums don't need to be recomputed for each file.
131
+ @external_dependency_checksum ||= begin
132
+ keys = cops.filter_map(&:external_dependency_checksum)
133
+ Digest::SHA1.hexdigest(keys.join)
134
+ end
117
135
  end
118
136
 
119
137
  private
@@ -174,6 +192,9 @@ module RuboCop
174
192
  end
175
193
 
176
194
  def support_target_rails_version?(cop)
195
+ # In this case, the rails version was already checked by `#excluded_file?`
196
+ return true if defined?(RuboCop::Rails::TargetRailsVersion::USES_REQUIRES_GEM_API)
197
+
177
198
  return true unless cop.class.respond_to?(:support_target_rails_version?)
178
199
 
179
200
  cop.class.support_target_rails_version?(cop.target_rails_version)
@@ -237,6 +258,8 @@ module RuboCop
237
258
 
238
259
  if cause.is_a?(Warning)
239
260
  handle_warning(cause, location)
261
+ elsif cause.is_a?(Force::HookError)
262
+ handle_error(cause.cause, location, cause.joining_cop)
240
263
  else
241
264
  handle_error(cause, location, error.cop)
242
265
  end
@@ -262,5 +285,6 @@ module RuboCop
262
285
  end
263
286
  end
264
287
  end
288
+ # rubocop:enable Metrics/ClassLength
265
289
  end
266
290
  end