rubocop 1.59.0 → 1.65.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -4
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +93 -17
  7. data/lib/rubocop/cached_data.rb +11 -3
  8. data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  11. data/lib/rubocop/cli.rb +10 -1
  12. data/lib/rubocop/config.rb +36 -12
  13. data/lib/rubocop/config_finder.rb +12 -2
  14. data/lib/rubocop/config_loader.rb +1 -2
  15. data/lib/rubocop/config_loader_resolver.rb +9 -3
  16. data/lib/rubocop/config_obsoletion.rb +1 -1
  17. data/lib/rubocop/config_validator.rb +14 -7
  18. data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
  19. data/lib/rubocop/cop/base.rb +63 -16
  20. data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
  21. data/lib/rubocop/cop/cop.rb +22 -4
  22. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  23. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  24. data/lib/rubocop/cop/documentation.rb +16 -6
  25. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  26. data/lib/rubocop/cop/force.rb +12 -0
  27. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  28. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  29. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  30. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  31. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  32. data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
  33. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  34. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
  35. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  36. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  37. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  38. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  39. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  40. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  41. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  42. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  43. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  44. data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
  45. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  46. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -1
  47. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  49. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
  50. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  51. data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  54. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  55. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  56. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  57. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
  58. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  59. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  60. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  61. data/lib/rubocop/cop/lint/boolean_symbol.rb +0 -2
  62. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  63. data/lib/rubocop/cop/lint/debugger.rb +27 -6
  64. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  65. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  66. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  67. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
  68. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
  69. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  70. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  71. data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
  72. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  73. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  74. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  75. data/lib/rubocop/cop/lint/ensure_return.rb +1 -6
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
  77. data/lib/rubocop/cop/lint/float_comparison.rb +3 -1
  78. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  79. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  80. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +15 -12
  81. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  82. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  83. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  84. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
  85. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +0 -4
  86. data/lib/rubocop/cop/lint/loop.rb +6 -12
  87. data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
  88. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  89. data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
  90. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  91. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  92. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  93. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  94. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  95. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  96. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
  97. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  98. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
  99. data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
  100. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  101. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  102. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  103. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  104. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +0 -4
  105. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  106. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  107. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
  108. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  109. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
  110. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  111. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  112. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  113. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  114. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -5
  115. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  116. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  117. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  118. data/lib/rubocop/cop/lint/void.rb +11 -1
  119. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  120. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
  121. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  122. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  123. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  124. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  125. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  126. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  127. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
  128. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  129. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  130. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  131. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  132. data/lib/rubocop/cop/naming/block_forwarding.rb +32 -5
  133. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  134. data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
  135. data/lib/rubocop/cop/naming/predicate_name.rb +54 -28
  136. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
  137. data/lib/rubocop/cop/registry.rb +1 -1
  138. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  139. data/lib/rubocop/cop/security/open.rb +2 -2
  140. data/lib/rubocop/cop/style/access_modifier_declarations.rb +50 -0
  141. data/lib/rubocop/cop/style/alias.rb +1 -0
  142. data/lib/rubocop/cop/style/arguments_forwarding.rb +89 -17
  143. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  144. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  145. data/lib/rubocop/cop/style/collection_compact.rb +14 -5
  146. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  147. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
  148. data/lib/rubocop/cop/style/copyright.rb +31 -21
  149. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  150. data/lib/rubocop/cop/style/documentation.rb +24 -24
  151. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  152. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  153. data/lib/rubocop/cop/style/eval_with_location.rb +15 -23
  154. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
  155. data/lib/rubocop/cop/style/file_read.rb +2 -5
  156. data/lib/rubocop/cop/style/file_write.rb +2 -5
  157. data/lib/rubocop/cop/style/for.rb +2 -0
  158. data/lib/rubocop/cop/style/format_string.rb +9 -9
  159. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  160. data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
  161. data/lib/rubocop/cop/style/hash_except.rb +8 -5
  162. data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
  163. data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
  164. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  165. data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
  166. data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
  167. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
  168. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  169. data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
  170. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  171. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +18 -5
  172. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  173. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  174. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  175. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
  176. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  177. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  178. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  179. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  180. data/lib/rubocop/cop/style/object_then.rb +5 -3
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  182. data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
  183. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  184. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  185. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  186. data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
  187. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  188. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  189. data/lib/rubocop/cop/style/redundant_condition.rb +0 -1
  190. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
  191. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  192. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  193. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  194. data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -2
  195. data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
  196. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  197. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
  198. data/lib/rubocop/cop/style/redundant_return.rb +6 -0
  199. data/lib/rubocop/cop/style/require_order.rb +1 -1
  200. data/lib/rubocop/cop/style/sample.rb +1 -3
  201. data/lib/rubocop/cop/style/send.rb +4 -4
  202. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
  203. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  204. data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
  205. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  206. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  207. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  208. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  209. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  210. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  211. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  212. data/lib/rubocop/cop/team.rb +13 -0
  213. data/lib/rubocop/cop/util.rb +7 -1
  214. data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
  215. data/lib/rubocop/cop/variable_force.rb +13 -1
  216. data/lib/rubocop/cops_documentation_generator.rb +16 -4
  217. data/lib/rubocop/core_ext/string.rb +2 -6
  218. data/lib/rubocop/directive_comment.rb +10 -8
  219. data/lib/rubocop/ext/regexp_node.rb +18 -35
  220. data/lib/rubocop/ext/regexp_parser.rb +4 -21
  221. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  222. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  223. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  224. data/lib/rubocop/formatter/html_formatter.rb +32 -10
  225. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  226. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  227. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  228. data/lib/rubocop/formatter.rb +1 -1
  229. data/lib/rubocop/lockfile.rb +56 -7
  230. data/lib/rubocop/lsp/logger.rb +1 -1
  231. data/lib/rubocop/lsp/routes.rb +12 -15
  232. data/lib/rubocop/lsp/runtime.rb +1 -1
  233. data/lib/rubocop/lsp/server.rb +7 -2
  234. data/lib/rubocop/lsp/severity.rb +1 -1
  235. data/lib/rubocop/lsp.rb +36 -0
  236. data/lib/rubocop/magic_comment.rb +1 -1
  237. data/lib/rubocop/options.rb +17 -12
  238. data/lib/rubocop/path_util.rb +6 -2
  239. data/lib/rubocop/rake_task.rb +1 -1
  240. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  241. data/lib/rubocop/rspec/expect_offense.rb +16 -8
  242. data/lib/rubocop/rspec/shared_contexts.rb +73 -16
  243. data/lib/rubocop/rspec/support.rb +3 -0
  244. data/lib/rubocop/runner.rb +14 -3
  245. data/lib/rubocop/server/cache.rb +11 -2
  246. data/lib/rubocop/server/client_command/exec.rb +2 -3
  247. data/lib/rubocop/server/client_command/start.rb +1 -1
  248. data/lib/rubocop/server/core.rb +4 -0
  249. data/lib/rubocop/server/server_command/exec.rb +0 -1
  250. data/lib/rubocop/target_finder.rb +84 -78
  251. data/lib/rubocop/target_ruby.rb +82 -80
  252. data/lib/rubocop/version.rb +19 -4
  253. data/lib/rubocop.rb +9 -0
  254. metadata +18 -11
  255. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -28,16 +28,12 @@ module RuboCop
28
28
  # @example
29
29
  #
30
30
  # # bad
31
- #
32
31
  # def some_method
33
32
  # some_var = 1
34
33
  # do_something
35
34
  # end
36
35
  #
37
- # @example
38
- #
39
36
  # # good
40
- #
41
37
  # def some_method
42
38
  # some_var = 1
43
39
  # do_something(some_var)
@@ -61,7 +57,7 @@ module RuboCop
61
57
  def check_for_unused_assignments(variable)
62
58
  return if variable.should_be_unused?
63
59
 
64
- variable.assignments.each do |assignment|
60
+ variable.assignments.reverse_each do |assignment|
65
61
  next if assignment.used? || part_of_ignored_node?(assignment.node)
66
62
 
67
63
  message = message_for_useless_assignment(assignment)
@@ -10,17 +10,13 @@ module RuboCop
10
10
  # @example
11
11
  #
12
12
  # # bad
13
- #
14
13
  # begin
15
14
  # do_something
16
15
  # else
17
16
  # do_something_else # This will never be run.
18
17
  # end
19
18
  #
20
- # @example
21
- #
22
19
  # # good
23
- #
24
20
  # begin
25
21
  # do_something
26
22
  # rescue
@@ -17,16 +17,12 @@ module RuboCop
17
17
  # @example
18
18
  #
19
19
  # # bad
20
- #
21
20
  # def something
22
21
  # x = Something.new
23
22
  # x.attr = 5
24
23
  # end
25
24
  #
26
- # @example
27
- #
28
25
  # # good
29
- #
30
26
  # def something
31
27
  # x = Something.new
32
28
  # x.attr = 5
@@ -64,7 +64,7 @@ module RuboCop
64
64
  remove_node(corrector, node)
65
65
  elsif !proc_name.empty?
66
66
  autocorrect_block_pass(corrector, node, proc_name)
67
- else
67
+ elsif node.block_type?
68
68
  autocorrect_block(corrector, node)
69
69
  end
70
70
  end
@@ -100,12 +100,19 @@ module RuboCop
100
100
  expressions = *node
101
101
  expressions.pop unless in_void_context?(node)
102
102
  expressions.each do |expr|
103
- check_void_op(expr)
103
+ check_void_op(expr) do
104
+ block_node = node.each_ancestor(:block).first
105
+
106
+ block_node&.method?(:each)
107
+ end
108
+
104
109
  check_expression(expr)
105
110
  end
106
111
  end
107
112
 
108
113
  def check_expression(expr)
114
+ expr = expr.body if expr.if_type? && expr.modifier_form?
115
+
109
116
  check_literal(expr)
110
117
  check_var(expr)
111
118
  check_self(expr)
@@ -116,6 +123,7 @@ module RuboCop
116
123
  end
117
124
 
118
125
  def check_void_op(node, &block)
126
+ node = node.children.first while node.begin_type?
119
127
  return unless node.send_type? && OPERATORS.include?(node.method_name)
120
128
  return if block && yield(node)
121
129
 
@@ -206,6 +214,8 @@ module RuboCop
206
214
  end
207
215
 
208
216
  def autocorrect_void_expression(corrector, node)
217
+ return if node.parent.if_type? && node.parent.modifier_form?
218
+
209
219
  corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
210
220
  end
211
221
 
@@ -3,12 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Metrics
6
- # Checks for excessive nesting of conditional and looping
7
- # constructs.
6
+ # Checks for excessive nesting of conditional and looping constructs.
8
7
  #
9
- # You can configure if blocks are considered using the `CountBlocks`
10
- # option. When set to `false` (the default) blocks are not counted
11
- # towards the nesting level. Set to `true` to count blocks as well.
8
+ # You can configure if blocks are considered using the `CountBlocks` and `CountModifierForms`
9
+ # options. When both are set to `false` (the default) blocks and modifier forms are not
10
+ # counted towards the nesting level. Set them to `true` to include these in the nesting level
11
+ # calculation as well.
12
12
  #
13
13
  # The maximum level of nesting allowed is configurable.
14
14
  class BlockNesting < Base
@@ -27,7 +27,7 @@ module RuboCop
27
27
 
28
28
  def check_nesting_level(node, max, current_level)
29
29
  if consider_node?(node)
30
- current_level += 1 unless node.if_type? && node.elsif?
30
+ current_level += 1 if count_if_block?(node)
31
31
  if current_level > max
32
32
  self.max = current_level
33
33
  unless part_of_ignored_node?(node)
@@ -41,6 +41,14 @@ module RuboCop
41
41
  end
42
42
  end
43
43
 
44
+ def count_if_block?(node)
45
+ return true unless node.if_type?
46
+ return false if node.elsif?
47
+ return count_modifier_forms? if node.modifier_form?
48
+
49
+ true
50
+ end
51
+
44
52
  def consider_node?(node)
45
53
  return true if NESTING_BLOCKS.include?(node.type)
46
54
 
@@ -52,7 +60,11 @@ module RuboCop
52
60
  end
53
61
 
54
62
  def count_blocks?
55
- cop_config['CountBlocks']
63
+ cop_config.fetch('CountBlocks', false)
64
+ end
65
+
66
+ def count_modifier_forms?
67
+ cop_config.fetch('CountModifierForms', false)
56
68
  end
57
69
  end
58
70
  end
@@ -43,16 +43,16 @@ module RuboCop
43
43
  types.map do |type|
44
44
  case type
45
45
  when :array
46
- ->(node) { node.array_type? }
46
+ lambda(&:array_type?)
47
47
  when :hash
48
- ->(node) { node.hash_type? }
48
+ lambda(&:hash_type?)
49
49
  when :heredoc
50
50
  ->(node) { heredoc_node?(node) }
51
51
  when :method_call
52
- ->(node) { node.call_type? }
52
+ lambda(&:call_type?)
53
53
  else
54
- raise ArgumentError, "Unknown foldable type: #{type.inspect}. " \
55
- "Valid foldable types are: #{FOLDABLE_TYPES.join(', ')}."
54
+ raise Warning, "Unknown foldable type: #{type.inspect}. " \
55
+ "Valid foldable types are: #{FOLDABLE_TYPES.join(', ')}."
56
56
  end
57
57
  end
58
58
  end
@@ -65,8 +65,12 @@ module RuboCop
65
65
  inner.begin_pos >= outer.begin_pos && inner.end_pos <= outer.end_pos
66
66
  end
67
67
 
68
- # @deprecated Use processed_source.comment_at_line(line)
68
+ # @deprecated Use processed_source.line_with_comment?(line)
69
69
  def end_of_line_comment(line)
70
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
71
+ `end_of_line_comment` is deprecated. Use `processed_source.line_with_comment?` instead.
72
+ WARNING
73
+
70
74
  processed_source.line_with_comment?(line)
71
75
  end
72
76
 
@@ -15,7 +15,13 @@ module RuboCop
15
15
  end
16
16
 
17
17
  # @deprecated Use allowed_method? instead
18
- alias ignored_method? allowed_method?
18
+ def ignored_method?
19
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
20
+ `ignored_method?` is deprecated. Use `allowed_method?` instead.
21
+ WARNING
22
+
23
+ allowed_method?
24
+ end
19
25
 
20
26
  # @api public
21
27
  def allowed_methods
@@ -18,14 +18,26 @@ module RuboCop
18
18
  end
19
19
 
20
20
  # @deprecated Use allowed_line? instead
21
- alias ignored_line? allowed_line?
21
+ def ignored_line?
22
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
23
+ `ignored_line?` is deprecated. Use `allowed_line?` instead.
24
+ WARNING
25
+
26
+ allowed_line?
27
+ end
22
28
 
23
29
  def matches_allowed_pattern?(line)
24
30
  allowed_patterns.any? { |pattern| Regexp.new(pattern).match?(line) }
25
31
  end
26
32
 
27
- # @deprecated Use matches_allowed_pattern?? instead
28
- alias matches_ignored_pattern? matches_allowed_pattern?
33
+ # @deprecated Use matches_allowed_pattern? instead
34
+ def matches_ignored_pattern?
35
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
36
+ `matches_ignored_pattern?` is deprecated. Use `matches_allowed_pattern?` instead.
37
+ WARNING
38
+
39
+ matches_allowed_pattern?
40
+ end
29
41
 
30
42
  def allowed_patterns
31
43
  # Since there could be a pattern specified in the default config, merge the two
@@ -36,7 +36,7 @@ module RuboCop
36
36
  length = calculator.calculate
37
37
  return if length <= max_length
38
38
 
39
- location = node.casgn_type? ? node.loc.name : node.source_range
39
+ location = location(node)
40
40
 
41
41
  add_offense(location, message: message(length, max_length)) { self.max = length }
42
42
  end
@@ -54,6 +54,17 @@ module RuboCop
54
54
  foldable_types: count_as_one
55
55
  )
56
56
  end
57
+
58
+ def location(node)
59
+ return node.loc.name if node.casgn_type?
60
+
61
+ if LSP.enabled?
62
+ end_range = node.loc.respond_to?(:name) ? node.loc.name : node.loc.begin
63
+ node.source_range.begin.join(end_range)
64
+ else
65
+ node.source_range
66
+ end
67
+ end
57
68
  end
58
69
  end
59
70
  end
@@ -18,6 +18,7 @@ module RuboCop
18
18
  alternative_styles.each do |alternative|
19
19
  return unexpected_style_detected(alternative) if valid_name?(node, name, alternative)
20
20
  end
21
+ unrecognized_style_detected
21
22
  end
22
23
 
23
24
  def valid_name?(node, name, given_style = style)
@@ -4,11 +4,15 @@ module RuboCop
4
4
  module Cop
5
5
  # Handles `Max` configuration parameters, especially setting them to an
6
6
  # appropriate value with --auto-gen-config.
7
- # @deprecated Use `exclude_limit ParameterName` instead.
7
+ # @deprecated Use `exclude_limit <ParameterName>` instead.
8
8
  module ConfigurableMax
9
9
  private
10
10
 
11
11
  def max=(value)
12
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
13
+ `max=` is deprecated. Use `exclude_limit <ParameterName>` instead.
14
+ WARNING
15
+
12
16
  cfg = config_to_allow_offenses
13
17
  cfg[:exclude_limit] ||= {}
14
18
  current_max = cfg[:exclude_limit][max_parameter_name]
@@ -67,13 +67,14 @@ module RuboCop
67
67
  end
68
68
 
69
69
  def ignore_mixed_hash_shorthand_syntax?(hash_node)
70
- target_ruby_version <= 3.0 || enforced_shorthand_syntax != 'consistent' ||
70
+ target_ruby_version <= 3.0 ||
71
+ !%w[consistent either_consistent].include?(enforced_shorthand_syntax) ||
71
72
  !hash_node.hash_type?
72
73
  end
73
74
 
74
75
  def ignore_hash_shorthand_syntax?(pair_node)
75
76
  target_ruby_version <= 3.0 || enforced_shorthand_syntax == 'either' ||
76
- enforced_shorthand_syntax == 'consistent' ||
77
+ %w[consistent either_consistent].include?(enforced_shorthand_syntax) ||
77
78
  !pair_node.parent.hash_type?
78
79
  end
79
80
 
@@ -172,6 +173,11 @@ module RuboCop
172
173
  hash_value_type_breakdown[:value_needed]&.any?
173
174
  end
174
175
 
176
+ def ignore_explicit_omissible_hash_shorthand_syntax?(hash_value_type_breakdown)
177
+ hash_value_type_breakdown.keys == [:value_omittable] &&
178
+ enforced_shorthand_syntax == 'either_consistent'
179
+ end
180
+
175
181
  def each_omitted_value_pair(hash_value_type_breakdown, &block)
176
182
  hash_value_type_breakdown[:value_omitted]&.each(&block)
177
183
  end
@@ -198,6 +204,7 @@ module RuboCop
198
204
 
199
205
  def no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
200
206
  return if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
207
+ return if ignore_explicit_omissible_hash_shorthand_syntax?(hash_value_type_breakdown)
201
208
 
202
209
  each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
203
210
  hash_key_source = pair_node.key.source
@@ -49,13 +49,13 @@ module RuboCop
49
49
 
50
50
  return unless complexity > max
51
51
 
52
- msg = format(self.class::MSG,
53
- method: method_name,
54
- complexity: complexity,
55
- abc_vector: abc_vector,
56
- max: max)
52
+ msg = format(
53
+ self.class::MSG,
54
+ method: method_name, complexity: complexity, abc_vector: abc_vector, max: max
55
+ )
56
+ location = location(node)
57
57
 
58
- add_offense(node, message: msg) { self.max = complexity.ceil }
58
+ add_offense(location, message: msg) { self.max = complexity.ceil }
59
59
  end
60
60
 
61
61
  def complexity(body)
@@ -69,6 +69,15 @@ module RuboCop
69
69
  end
70
70
  score
71
71
  end
72
+
73
+ def location(node)
74
+ if LSP.enabled?
75
+ end_range = node.loc.respond_to?(:name) ? node.loc.name : node.loc.begin
76
+ node.source_range.begin.join(end_range)
77
+ else
78
+ node.source_range
79
+ end
80
+ end
72
81
  end
73
82
  end
74
83
  end
@@ -189,7 +189,7 @@ module RuboCop
189
189
  case node.type
190
190
  when :casgn then _scope, _lhs, rhs = *node
191
191
  when :op_asgn then _lhs, _op, rhs = *node
192
- when :send then rhs = node.last_argument
192
+ when :send, :csend then rhs = node.last_argument
193
193
  else _lhs, rhs = *node
194
194
  end
195
195
  rhs
@@ -18,6 +18,10 @@ module RuboCop
18
18
 
19
19
  # @deprecated Use ResbodyNode#exceptions instead
20
20
  def rescued_exceptions(resbody)
21
+ warn Rainbow(<<~WARNING).yellow, uplevel: 1
22
+ `rescued_exceptions` is deprecated. Use `ResbodyNode#exceptions` instead.
23
+ WARNING
24
+
21
25
  rescue_group, = *resbody
22
26
  if rescue_group
23
27
  rescue_group.values
@@ -14,7 +14,7 @@ module RuboCop
14
14
  def_node_matcher :empty_condition?, '(begin)'
15
15
 
16
16
  # @!method setter_method?(node)
17
- def_node_matcher :setter_method?, '[(send ...) setter_method?]'
17
+ def_node_matcher :setter_method?, '[(call ...) setter_method?]'
18
18
 
19
19
  # @!method safe_assignment?(node)
20
20
  def_node_matcher :safe_assignment?, '(begin {equals_asgn? #setter_method?})'
@@ -57,14 +57,18 @@ module RuboCop
57
57
  last_argument = node.last_argument
58
58
  return if expected_block_forwarding_style?(node, last_argument)
59
59
 
60
- register_offense(last_argument, node)
60
+ forwarded_args = node.each_descendant(:block_pass).with_object([]) do |block_pass, result|
61
+ return nil if invalidates_syntax?(block_pass)
62
+ next unless block_argument_name_matched?(block_pass, last_argument)
61
63
 
62
- node.each_descendant(:block_pass) do |block_pass_node|
63
- next if block_pass_node.children.first&.sym_type? ||
64
- last_argument.source != block_pass_node.source
64
+ result << block_pass
65
+ end
65
66
 
66
- register_offense(block_pass_node, node)
67
+ forwarded_args.each do |forwarded_arg|
68
+ register_offense(forwarded_arg, node)
67
69
  end
70
+
71
+ register_offense(last_argument, node)
68
72
  end
69
73
  alias on_defs on_def
70
74
 
@@ -80,6 +84,29 @@ module RuboCop
80
84
  end
81
85
  end
82
86
 
87
+ def block_argument_name_matched?(block_pass_node, last_argument)
88
+ return false if block_pass_node.children.first&.sym_type?
89
+
90
+ last_argument.source == block_pass_node.source
91
+ end
92
+
93
+ # Prevents the following syntax error:
94
+ #
95
+ # # foo.rb
96
+ # def foo(&)
97
+ # block_method do
98
+ # bar(&)
99
+ # end
100
+ # end
101
+ #
102
+ # $ ruby -vc foo.rb
103
+ # ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
104
+ # foo.rb: foo.rb:4: anonymous block parameter is also used within block (SyntaxError)
105
+ #
106
+ def invalidates_syntax?(block_pass_node)
107
+ block_pass_node.each_ancestor(:block, :numblock).any?
108
+ end
109
+
83
110
  def use_kwarg_in_method_definition?(node)
84
111
  node.arguments.each_descendant(:kwarg, :kwoptarg).any?
85
112
  end
@@ -57,7 +57,7 @@ module RuboCop
57
57
  file_path = processed_source.file_path
58
58
  return if config.file_to_exclude?(file_path) || config.allowed_camel_case_file?(file_path)
59
59
 
60
- for_bad_filename(file_path) { |range, msg| add_offense(range, message: msg) }
60
+ for_bad_filename(file_path)
61
61
  end
62
62
 
63
63
  private
@@ -71,7 +71,7 @@ module RuboCop
71
71
  msg = other_message(basename) unless bad_filename_allowed?
72
72
  end
73
73
 
74
- yield source_range(processed_source.buffer, 1, 0), msg if msg
74
+ add_global_offense(msg) if msg
75
75
  end
76
76
 
77
77
  def perform_class_and_module_naming_checks(file_path, basename)
@@ -207,8 +207,7 @@ module RuboCop
207
207
  message = create_multiple_word_message_for_file(words)
208
208
  end
209
209
 
210
- range = source_range(processed_source.buffer, 1, 0)
211
- add_offense(range, message: message)
210
+ add_global_offense(message)
212
211
  end
213
212
 
214
213
  def create_single_word_message_for_file(word)
@@ -3,59 +3,75 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Naming
6
- # Checks that predicate methods names end with a question mark and
6
+ # Checks that predicate method names end with a question mark and
7
7
  # do not start with a forbidden prefix.
8
8
  #
9
- # A method is determined to be a predicate method if its name starts
10
- # with one of the prefixes defined in the `NamePrefix` configuration.
11
- # You can change what prefixes are considered by changing this option.
12
- # Any method name that starts with one of these prefixes is required by
13
- # the cop to end with a `?`. Other methods can be allowed by adding to
14
- # the `AllowedMethods` configuration.
9
+ # A method is determined to be a predicate method if its name starts with
10
+ # one of the prefixes listed in the `NamePrefix` configuration. The list
11
+ # defaults to `is_`, `has_`, and `have_` but may be overridden.
15
12
  #
16
- # NOTE: The `is_a?` method is allowed by default.
13
+ # Predicate methods must end with a question mark.
17
14
  #
18
- # If `ForbiddenPrefixes` is set, methods that start with the configured
19
- # prefixes will not be allowed and will be removed by autocorrection.
15
+ # When `ForbiddenPrefixes` is also set (as it is by default), predicate
16
+ # methods which begin with a forbidden prefix are not allowed, even if
17
+ # they end with a `?`. These methods should be changed to remove the
18
+ # prefix.
20
19
  #
21
- # In other words, if `ForbiddenPrefixes` is empty, a method named `is_foo`
22
- # will register an offense only due to the lack of question mark (and will be
23
- # autocorrected to `is_foo?`). If `ForbiddenPrefixes` contains `is_`,
24
- # `is_foo` will register an offense both because the ? is missing and because of
25
- # the `is_` prefix, and will be corrected to `foo?`.
26
- #
27
- # NOTE: `ForbiddenPrefixes` is only applied to prefixes in `NamePrefix`;
28
- # a prefix in the former but not the latter will not be considered by
29
- # this cop.
30
- #
31
- # @example
20
+ # @example NamePrefix: ['is_', 'has_', 'have_'] (default)
32
21
  # # bad
33
22
  # def is_even(value)
34
23
  # end
35
24
  #
36
- # def is_even?(value)
25
+ # # When ForbiddenPrefixes: ['is_', 'has_', 'have_'] (default)
26
+ # # good
27
+ # def even?(value)
37
28
  # end
38
29
  #
30
+ # # When ForbiddenPrefixes: []
39
31
  # # good
40
- # def even?(value)
32
+ # def is_even?(value)
41
33
  # end
42
34
  #
35
+ # @example NamePrefix: ['seems_to_be_']
43
36
  # # bad
44
- # def has_value
37
+ # def seems_to_be_even(value)
45
38
  # end
46
39
  #
47
- # def has_value?
40
+ # # When ForbiddenPrefixes: ['seems_to_be_']
41
+ # # good
42
+ # def even?(value)
48
43
  # end
49
44
  #
45
+ # # When ForbiddenPrefixes: []
50
46
  # # good
51
- # def value?
47
+ # def seems_to_be_even?(value)
52
48
  # end
53
49
  #
54
50
  # @example AllowedMethods: ['is_a?'] (default)
51
+ # # Despite starting with the `is_` prefix, this method is allowed
55
52
  # # good
56
53
  # def is_a?(value)
57
54
  # end
58
55
  #
56
+ # @example AllowedMethods: ['is_even?']
57
+ # # good
58
+ # def is_even?(value)
59
+ # end
60
+ #
61
+ # @example MethodDefinitionMacros: ['define_method', 'define_singleton_method'] (default)
62
+ # # bad
63
+ # define_method(:is_even) { |value| }
64
+ #
65
+ # # good
66
+ # define_method(:even?) { |value| }
67
+ #
68
+ # @example MethodDefinitionMacros: ['def_node_matcher']
69
+ # # bad
70
+ # def_node_matcher(:is_even) { |value| }
71
+ #
72
+ # # good
73
+ # # def_node_matcher(:even?) { |value| }
74
+ #
59
75
  class PredicateName < Base
60
76
  include AllowedMethods
61
77
 
@@ -93,13 +109,23 @@ module RuboCop
93
109
  end
94
110
  alias on_defs on_def
95
111
 
112
+ def validate_config
113
+ forbidden_prefixes.each do |forbidden_prefix|
114
+ next if predicate_prefixes.include?(forbidden_prefix)
115
+
116
+ raise ValidationError, <<~MSG.chomp
117
+ The `Naming/PredicateName` cop is misconfigured. Prefix #{forbidden_prefix} must be included in NamePrefix because it is included in ForbiddenPrefixes.
118
+ MSG
119
+ end
120
+ end
121
+
96
122
  private
97
123
 
98
124
  def allowed_method_name?(method_name, prefix)
99
125
  !(method_name.start_with?(prefix) && # cheap check to avoid allocating Regexp
100
126
  method_name.match?(/^#{prefix}[^0-9]/)) ||
101
127
  method_name == expected_name(method_name, prefix) ||
102
- method_name.end_with?('=') || # rubocop:todo InternalAffairs/MethodNameEndWith
128
+ method_name.end_with?('=') ||
103
129
  allowed_method?(method_name)
104
130
  end
105
131
 
@@ -109,7 +135,7 @@ module RuboCop
109
135
  else
110
136
  method_name.dup
111
137
  end
112
- new_name << '?' unless method_name.end_with?('?') # rubocop:todo InternalAffairs/MethodNameEndWith
138
+ new_name << '?' unless method_name.end_with?('?')
113
139
  new_name
114
140
  end
115
141
 
@@ -113,13 +113,21 @@ module RuboCop
113
113
  end
114
114
  end
115
115
 
116
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
116
117
  def correct_node(corrector, node, offending_name, preferred_name)
117
118
  return unless node
118
119
 
119
120
  node.each_node(:lvar, :lvasgn, :masgn) do |child_node|
120
121
  next unless variable_name_matches?(child_node, offending_name)
121
122
 
122
- corrector.replace(child_node, preferred_name) if child_node.lvar_type?
123
+ if child_node.lvar_type?
124
+ parent_node = child_node.parent
125
+ if parent_node.respond_to?(:value_omission?) && parent_node.value_omission?
126
+ corrector.insert_after(parent_node.loc.operator, " #{preferred_name}")
127
+ else
128
+ corrector.replace(child_node, preferred_name)
129
+ end
130
+ end
123
131
 
124
132
  if child_node.masgn_type? || child_node.lvasgn_type?
125
133
  correct_reassignment(corrector, child_node, offending_name, preferred_name)
@@ -127,6 +135,7 @@ module RuboCop
127
135
  end
128
136
  end
129
137
  end
138
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
130
139
 
131
140
  # If the exception variable is reassigned, that assignment needs to be corrected.
132
141
  # Further `lvar` nodes will not be corrected though since they now refer to a