rubocop 1.34.1 → 1.35.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +22 -0
  4. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +32 -2
  5. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  6. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  7. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  8. data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
  9. data/lib/rubocop/cop/layout/block_end_newline.rb +2 -0
  10. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
  11. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  12. data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
  13. data/lib/rubocop/cop/layout/line_length.rb +4 -1
  14. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  15. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  16. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  17. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  18. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  19. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
  20. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  21. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  22. data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
  23. data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
  24. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  25. data/lib/rubocop/cop/lint/unreachable_loop.rb +7 -1
  26. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -4
  27. data/lib/rubocop/cop/lint/void.rb +2 -0
  28. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +76 -1
  29. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  30. data/lib/rubocop/cop/mixin/method_complexity.rb +4 -4
  31. data/lib/rubocop/cop/mixin/range_help.rb +2 -3
  32. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  33. data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
  34. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  35. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  36. data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
  37. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  38. data/lib/rubocop/cop/style/each_with_object.rb +39 -8
  39. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  40. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  41. data/lib/rubocop/cop/style/for.rb +2 -0
  42. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
  43. data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
  44. data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
  45. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  46. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  47. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  48. data/lib/rubocop/cop/style/next.rb +2 -0
  49. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  50. data/lib/rubocop/cop/style/object_then.rb +2 -0
  51. data/lib/rubocop/cop/style/proc.rb +4 -1
  52. data/lib/rubocop/cop/style/redundant_begin.rb +2 -0
  53. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  54. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  55. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  56. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  57. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  58. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  59. data/lib/rubocop/feature_loader.rb +3 -1
  60. data/lib/rubocop/server/cache.rb +4 -2
  61. data/lib/rubocop/version.rb +1 -1
  62. data/lib/rubocop.rb +2 -1
  63. metadata +7 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 11dc3da37672d6576b483ea0d39db975af0044d4c960fa14944fadac1d6f5bd5
4
- data.tar.gz: e37200a88a516b923c5c86149de704eec9147f8f35a96df30ced1a0892be8ab4
3
+ metadata.gz: 6533c308e8ecd9193b09cd13fb1f967d1721cbfe4e4cb88bcb453861362b5152
4
+ data.tar.gz: a8ebb7e167336289eb9adf7e05cbf8bfe59ccc9669b9177b363a7d54b4d597fc
5
5
  SHA512:
6
- metadata.gz: 42deab573616fd15dfee978f2009b2dafc17b4bb0cf7528c0e0a26f415bad22ede108980403c6036b0b84d28b72981b3862b915a608495bc368935c1bc1ea18b
7
- data.tar.gz: 5afa69eeccbcf3ead2bb51f2feaf4dcd81420fa08b0b17b372909647d7b4b559fe1d76d376fec271c7b9d2e8f1ee1cb586075d9a461d5894c1263854fa6f2eea
6
+ metadata.gz: d49c12af4f602e15bf19903272b4ac0e834004f9eb07eecbca829a619559b6326dd95e2e9e10121763c73ff844968853e59dd89f84e9eded8d48bef0149cb379
7
+ data.tar.gz: 440d3e163691372ef95aa49847a58e611e669faf0d950f24b0135264d234c4bc4e35ef5c5a6d92394725cf3947295fd7b107dd48bfb7937df9a7fbac7ba70e90
data/README.md CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.34', require: false
56
+ gem 'rubocop', '~> 1.35', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -3839,6 +3839,8 @@ Style/HashSyntax:
3839
3839
  - never
3840
3840
  # accepts both shorthand and explicit use of hash literal value.
3841
3841
  - either
3842
+ # like "always", but will avoid mixing styles in a single hash
3843
+ - consistent
3842
3844
  # Force hashes that have a symbol value to use hash rockets
3843
3845
  UseHashRocketsWithSymbolValues: false
3844
3846
  # Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style
@@ -4015,6 +4017,26 @@ Style/LineEndConcatenation:
4015
4017
  VersionAdded: '0.18'
4016
4018
  VersionChanged: '0.64'
4017
4019
 
4020
+ Style/MagicCommentFormat:
4021
+ Description: 'Use a consistent style for magic comments.'
4022
+ Enabled: pending
4023
+ VersionAdded: '1.35'
4024
+ EnforcedStyle: snake_case
4025
+ SupportedStyles:
4026
+ # `snake` will enforce the magic comment is written
4027
+ # in snake case (words separated by underscores).
4028
+ # Eg: froze_string_literal: true
4029
+ - snake_case
4030
+ # `kebab` will enforce the magic comment is written
4031
+ # in kebab case (words separated by hyphens).
4032
+ # Eg: froze-string-literal: true
4033
+ - kebab_case
4034
+ DirectiveCapitalization: lowercase
4035
+ ValueCapitalization: ~
4036
+ SupportedCapitalizations:
4037
+ - lowercase
4038
+ - uppercase
4039
+
4018
4040
  Style/MapCompactWithConditionalBlock:
4019
4041
  Description: 'Prefer `select` or `reject` over `map { ... }.compact`.'
4020
4042
  Enabled: pending
@@ -7,6 +7,8 @@ module RuboCop
7
7
  class << self
8
8
  include RangeHelp
9
9
 
10
+ COMMA_REGEXP = /(?<=\))\s*,/.freeze
11
+
10
12
  def correct(corrector, node)
11
13
  corrector.remove(node.loc.begin)
12
14
  corrector.remove(node.loc.end)
@@ -39,7 +41,15 @@ module RuboCop
39
41
  def handle_orphaned_comma(corrector, node)
40
42
  return unless only_closing_paren_before_comma?(node)
41
43
 
42
- range = range_with_surrounding_space(
44
+ range = extend_range_for_heredoc(node, parens_range(node))
45
+ corrector.remove(range)
46
+
47
+ add_heredoc_comma(corrector, node)
48
+ end
49
+
50
+ # Get a range for the closing parenthesis and all whitespace to the left of it
51
+ def parens_range(node)
52
+ range_with_surrounding_space(
43
53
  range: node.loc.end,
44
54
  buffer: node.source_range.source_buffer,
45
55
  side: :left,
@@ -47,8 +57,28 @@ module RuboCop
47
57
  whitespace: true,
48
58
  continuations: true
49
59
  )
60
+ end
50
61
 
51
- corrector.remove(range)
62
+ # If the node contains a heredoc, remove the comma too
63
+ # It'll be added back in the right place later
64
+ def extend_range_for_heredoc(node, range)
65
+ return range unless heredoc?(node)
66
+
67
+ comma_line = range_by_whole_lines(node.loc.end, buffer: node.source_range.source_buffer)
68
+ offset = comma_line.source.match(COMMA_REGEXP)[0]&.size || 0
69
+
70
+ range.adjust(end_pos: offset)
71
+ end
72
+
73
+ # Add a comma back after the heredoc identifier
74
+ def add_heredoc_comma(corrector, node)
75
+ return unless heredoc?(node)
76
+
77
+ corrector.insert_after(node.child_nodes.last.loc.expression, ',')
78
+ end
79
+
80
+ def heredoc?(node)
81
+ node.child_nodes.last.loc.is_a?(Parser::Source::Map::Heredoc)
52
82
  end
53
83
  end
54
84
  end
@@ -84,7 +84,7 @@ module RuboCop
84
84
  (str "true")
85
85
  PATTERN
86
86
 
87
- def on_block(node) # rubocop:disable Metrics/MethodLength
87
+ def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler
88
88
  gem_specification(node) do |block_var|
89
89
  metadata_value = metadata(node)
90
90
  mfa_value = mfa_value(metadata_value)
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks for missing `numblock handlers. The blocks with numbered
7
+ # arguments introduced in Ruby 2.7 are parsed with a node type of
8
+ # `numblock` instead of block. Cops that define `block` handlers
9
+ # need to define `numblock` handlers or disable this cope for them.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # class BlockRelatedCop < Base
15
+ # def on_block(node)
16
+ # end
17
+ # end
18
+ #
19
+ # # good
20
+ # class BlockRelatedCop < Base
21
+ # def on_block(node)
22
+ # end
23
+ #
24
+ # alias on_numblock on_block
25
+ # end
26
+ #
27
+ # class BlockRelatedCop < Base
28
+ # def on_block(node)
29
+ # end
30
+ #
31
+ # alias_method :on_numblock, :on_block
32
+ # end
33
+ #
34
+ # class BlockRelatedCop < Base
35
+ # def on_block(node)
36
+ # end
37
+ #
38
+ # def on_numblock(node)
39
+ # end
40
+ # end
41
+ class NumblockHandler < Base
42
+ MSG = 'Define on_numblock to handle blocks with numbered arguments.'
43
+
44
+ def on_def(node)
45
+ return unless block_handler?(node)
46
+ return unless node.parent
47
+
48
+ add_offense(node) unless numblock_handler?(node.parent)
49
+ end
50
+
51
+ private
52
+
53
+ # @!method block_handler?(node)
54
+ def_node_matcher :block_handler?, <<~PATTERN
55
+ (def :on_block (args (arg :node)) ...)
56
+ PATTERN
57
+
58
+ # @!method numblock_handler?(node)
59
+ def_node_matcher :numblock_handler?, <<~PATTERN
60
+ {
61
+ `(def :on_numblock (args (arg :node)) ...)
62
+ `(alias (sym :on_numblock) (sym :on_block))
63
+ `(send nil? :alias_method (sym :on_numblock) (sym :on_block))
64
+ }
65
+ PATTERN
66
+ end
67
+ end
68
+ end
69
+ end
@@ -10,6 +10,7 @@ require_relative 'internal_affairs/method_name_equal'
10
10
  require_relative 'internal_affairs/node_destructuring'
11
11
  require_relative 'internal_affairs/node_matcher_directive'
12
12
  require_relative 'internal_affairs/node_type_predicate'
13
+ require_relative 'internal_affairs/numblock_handler'
13
14
  require_relative 'internal_affairs/offense_location_keyword'
14
15
  require_relative 'internal_affairs/redundant_context_config_parameter'
15
16
  require_relative 'internal_affairs/redundant_described_class_as_subject'
@@ -82,6 +82,8 @@ module RuboCop
82
82
  check_block_alignment(start_for_block_node(node), node)
83
83
  end
84
84
 
85
+ alias on_numblock on_block
86
+
85
87
  def style_parameter_name
86
88
  'EnforcedStyleAlignWith'
87
89
  end
@@ -39,6 +39,8 @@ module RuboCop
39
39
  register_offense(node)
40
40
  end
41
41
 
42
+ alias on_numblock on_block
43
+
42
44
  private
43
45
 
44
46
  def register_offense(node)
@@ -80,8 +80,11 @@ module RuboCop
80
80
  @block_line = node.source_range.first_line
81
81
  end
82
82
 
83
- def on_send(node)
84
- return unless node.bare_access_modifier? && !node.parent&.block_type?
83
+ alias on_numblock on_block
84
+
85
+ def on_send(node) # rubocop:disable Metrics/CyclomaticComplexity
86
+ return unless node.bare_access_modifier? &&
87
+ !(node.parent&.block_type? || node.parent&.numblock_type?)
85
88
  return if expected_empty_lines?(node)
86
89
 
87
90
  message = message(node)
@@ -32,6 +32,8 @@ module RuboCop
32
32
 
33
33
  check(node, node.body, adjusted_first_line: first_line)
34
34
  end
35
+
36
+ alias on_numblock on_block
35
37
  end
36
38
  end
37
39
  end
@@ -90,6 +90,8 @@ module RuboCop
90
90
  check_members(end_loc, [node.body])
91
91
  end
92
92
 
93
+ alias on_numblock on_block
94
+
93
95
  def on_class(node)
94
96
  base = node.loc.keyword
95
97
  return if same_line?(base, node.body)
@@ -22,6 +22,7 @@ module RuboCop
22
22
  # (Many of these are enabled by default.)
23
23
  #
24
24
  # * ArgumentAlignment
25
+ # * ArrayAlignment
25
26
  # * BlockAlignment
26
27
  # * BlockDelimiters
27
28
  # * BlockEndNewline
@@ -74,6 +75,8 @@ module RuboCop
74
75
  check_for_breakable_block(node)
75
76
  end
76
77
 
78
+ alias on_numblock on_block
79
+
77
80
  def on_potential_breakable_node(node)
78
81
  check_for_breakable_node(node)
79
82
  end
@@ -131,7 +134,7 @@ module RuboCop
131
134
  if block_node.arguments? && !block_node.lambda?
132
135
  block_node.arguments.loc.end
133
136
  else
134
- block_node.loc.begin
137
+ block_node.braces? ? block_node.loc.begin : block_node.loc.begin.adjust(begin_pos: 1)
135
138
  end
136
139
  end
137
140
 
@@ -68,6 +68,8 @@ module RuboCop
68
68
  add_offense_for_expression(node, node.body, MSG)
69
69
  end
70
70
 
71
+ alias on_numblock on_block
72
+
71
73
  private
72
74
 
73
75
  def args_on_beginning_line?(node)
@@ -29,7 +29,7 @@ module RuboCop
29
29
  include RangeHelp
30
30
  extend AutoCorrector
31
31
 
32
- def on_block(node)
32
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
33
33
  arguments = node.arguments
34
34
 
35
35
  return unless node.arguments? && pipes?(arguments)
@@ -41,7 +41,7 @@ module RuboCop
41
41
  check(node, [:operator].freeze) if node.keyword?
42
42
  end
43
43
 
44
- def on_block(node)
44
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
45
45
  check(node, %i[begin end].freeze)
46
46
  end
47
47
 
@@ -76,6 +76,8 @@ module RuboCop
76
76
  end
77
77
  end
78
78
 
79
+ alias on_numblock on_block
80
+
79
81
  private
80
82
 
81
83
  def check_empty(left_brace, space_plus_brace, used_style)
@@ -63,7 +63,7 @@ module RuboCop
63
63
  class EmptyBlock < Base
64
64
  MSG = 'Empty block detected.'
65
65
 
66
- def on_block(node)
66
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
67
67
  return if node.body
68
68
  return if allow_empty_lambdas? && lambda_or_proc?(node)
69
69
  return if cop_config['AllowComments'] && allow_comment?(node)
@@ -6,18 +6,18 @@ module RuboCop
6
6
  #
7
7
  # This cop emulates the following Ruby warnings in Ruby 2.6.
8
8
  #
9
+ # [source,console]
10
+ # ----
9
11
  # % cat example.rb
10
12
  # ERB.new('hi', nil, '-', '@output_buffer')
11
13
  # % ruby -rerb example.rb
12
- # example.rb:1: warning: Passing safe_level with the 2nd argument of
13
- # ERB.new is deprecated. Do not use it, and specify other arguments as
14
- # keyword arguments.
15
- # example.rb:1: warning: Passing trim_mode with the 3rd argument of
16
- # ERB.new is deprecated. Use keyword argument like
17
- # ERB.new(str, trim_mode:...) instead.
18
- # example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new
19
- # is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...)
20
- # instead.
14
+ # example.rb:1: warning: Passing safe_level with the 2nd argument of ERB.new is
15
+ # deprecated. Do not use it, and specify other arguments as keyword arguments.
16
+ # example.rb:1: warning: Passing trim_mode with the 3rd argument of ERB.new is
17
+ # deprecated. Use keyword argument like ERB.new(str, trim_mode:...) instead.
18
+ # example.rb:1: warning: Passing eoutvar with the 4th argument of ERB.new is
19
+ # deprecated. Use keyword argument like ERB.new(str, eoutvar: ...) instead.
20
+ # ----
21
21
  #
22
22
  # Now non-keyword arguments other than first one are softly deprecated
23
23
  # and will be removed when Ruby 2.5 becomes EOL.
@@ -25,13 +25,8 @@ module RuboCop
25
25
  class NextWithoutAccumulator < Base
26
26
  MSG = 'Use `next` with an accumulator argument in a `reduce`.'
27
27
 
28
- # @!method on_body_of_reduce(node)
29
- def_node_matcher :on_body_of_reduce, <<~PATTERN
30
- (block (send _recv {:reduce :inject} !sym) _blockargs $(begin ...))
31
- PATTERN
32
-
33
28
  def on_block(node)
34
- on_body_of_reduce(node) do |body|
29
+ on_block_body_of_reduce(node) do |body|
35
30
  void_next = body.each_node(:next).find do |n|
36
31
  n.children.empty? && parent_block_node(n) == node
37
32
  end
@@ -40,11 +35,35 @@ module RuboCop
40
35
  end
41
36
  end
42
37
 
38
+ def on_numblock(node)
39
+ on_numblock_body_of_reduce(node) do |body|
40
+ void_next = body.each_node(:next).find do |n|
41
+ n.children.empty? && parent_numblock_node(n) == node
42
+ end
43
+
44
+ add_offense(void_next) if void_next
45
+ end
46
+ end
47
+
43
48
  private
44
49
 
50
+ # @!method on_block_body_of_reduce(node)
51
+ def_node_matcher :on_block_body_of_reduce, <<~PATTERN
52
+ (block (send _recv {:reduce :inject} !sym) _blockargs $(begin ...))
53
+ PATTERN
54
+
55
+ # @!method on_numblock_body_of_reduce(node)
56
+ def_node_matcher :on_numblock_body_of_reduce, <<~PATTERN
57
+ (numblock (send _recv {:reduce :inject} !sym) _argscount $(begin ...))
58
+ PATTERN
59
+
45
60
  def parent_block_node(node)
46
61
  node.each_ancestor(:block).first
47
62
  end
63
+
64
+ def parent_numblock_node(node)
65
+ node.each_ancestor(:numblock).first
66
+ end
48
67
  end
49
68
  end
50
69
  end
@@ -74,6 +74,18 @@ module RuboCop
74
74
  end
75
75
  end
76
76
 
77
+ def on_numblock(node)
78
+ return if target_ruby_version >= 3.0
79
+ return unless node.body
80
+ return unless unsorted_dir_loop?(node.send_node)
81
+
82
+ node.argument_list
83
+ .filter { |argument| var_is_required?(node.body, argument.name) }
84
+ .each do
85
+ add_offense(node.send_node) { |corrector| correct_block(corrector, node.send_node) }
86
+ end
87
+ end
88
+
77
89
  def on_block_pass(node)
78
90
  return if target_ruby_version >= 3.0
79
91
  return unless method_require?(node)
@@ -33,16 +33,6 @@ module RuboCop
33
33
  MSG_EACH_WITH_INDEX = 'Use `each` instead of `each_with_index`.'
34
34
  MSG_WITH_INDEX = 'Remove redundant `with_index`.'
35
35
 
36
- # @!method redundant_with_index?(node)
37
- def_node_matcher :redundant_with_index?, <<~PATTERN
38
- (block
39
- $(send
40
- _ {:each_with_index :with_index} ...)
41
- (args
42
- (arg _))
43
- ...)
44
- PATTERN
45
-
46
36
  def on_block(node)
47
37
  return unless (send = redundant_with_index?(node))
48
38
 
@@ -58,8 +48,21 @@ module RuboCop
58
48
  end
59
49
  end
60
50
 
51
+ alias on_numblock on_block
52
+
61
53
  private
62
54
 
55
+ # @!method redundant_with_index?(node)
56
+ def_node_matcher :redundant_with_index?, <<~PATTERN
57
+ {
58
+ (block
59
+ $(send _ {:each_with_index :with_index} ...)
60
+ (args (arg _)) ...)
61
+ (numblock
62
+ $(send _ {:each_with_index :with_index} ...) 1 ...)
63
+ }
64
+ PATTERN
65
+
63
66
  def message(node)
64
67
  if node.method?(:each_with_index)
65
68
  MSG_EACH_WITH_INDEX
@@ -31,19 +31,8 @@ module RuboCop
31
31
  extend AutoCorrector
32
32
 
33
33
  MSG_EACH_WITH_OBJECT = 'Use `each` instead of `each_with_object`.'
34
-
35
34
  MSG_WITH_OBJECT = 'Remove redundant `with_object`.'
36
35
 
37
- # @!method redundant_with_object?(node)
38
- def_node_matcher :redundant_with_object?, <<~PATTERN
39
- (block
40
- $(send _ {:each_with_object :with_object}
41
- _)
42
- (args
43
- (arg _))
44
- ...)
45
- PATTERN
46
-
47
36
  def on_block(node)
48
37
  return unless (send = redundant_with_object?(node))
49
38
 
@@ -59,8 +48,20 @@ module RuboCop
59
48
  end
60
49
  end
61
50
 
51
+ alias on_numblock on_block
52
+
62
53
  private
63
54
 
55
+ # @!method redundant_with_object?(node)
56
+ def_node_matcher :redundant_with_object?, <<~PATTERN
57
+ {
58
+ (block
59
+ $(send _ {:each_with_object :with_object} _) (args (arg _)) ...)
60
+ (numblock
61
+ $(send _ {:each_with_object :with_object} _) 1 ...)
62
+ }
63
+ PATTERN
64
+
64
65
  def message(node)
65
66
  if node.method?(:each_with_object)
66
67
  MSG_EACH_WITH_OBJECT
@@ -69,6 +69,7 @@ module RuboCop
69
69
 
70
70
  outer_local_variable_node =
71
71
  find_conditional_node_from_ascendant(outer_local_variable.declaration_node)
72
+ return true unless outer_local_variable_node
72
73
 
73
74
  outer_local_variable_node.conditional? && variable_node == outer_local_variable_node
74
75
  end
@@ -101,10 +101,14 @@ module RuboCop
101
101
  check(node) if loop_method?(node)
102
102
  end
103
103
 
104
+ def on_numblock(node)
105
+ check(node) if loop_method?(node)
106
+ end
107
+
104
108
  private
105
109
 
106
110
  def loop_method?(node)
107
- return false unless node.block_type?
111
+ return false unless node.block_type? || node.numblock_type?
108
112
 
109
113
  send_node = node.send_node
110
114
  return false if matches_allowed_pattern?(send_node.source)
@@ -179,6 +183,8 @@ module RuboCop
179
183
 
180
184
  def preceded_by_continue_statement?(break_statement)
181
185
  break_statement.left_siblings.any? do |sibling|
186
+ # Numblocks have the arguments count as a number in the AST.
187
+ next if sibling.is_a?(Integer)
182
188
  next if sibling.loop_keyword? || loop_method?(sibling)
183
189
 
184
190
  sibling.each_descendant(*CONTINUE_KEYWORDS).any?
@@ -142,6 +142,8 @@ module RuboCop
142
142
  check_node(node.body)
143
143
  end
144
144
 
145
+ alias on_numblock on_block
146
+
145
147
  private
146
148
 
147
149
  def autocorrect(corrector, node)
@@ -157,17 +159,17 @@ module RuboCop
157
159
 
158
160
  # @!method dynamic_method_definition?(node)
159
161
  def_node_matcher :dynamic_method_definition?, <<~PATTERN
160
- {(send nil? :define_method ...) (block (send nil? :define_method ...) ...)}
162
+ {(send nil? :define_method ...) ({block numblock} (send nil? :define_method ...) ...)}
161
163
  PATTERN
162
164
 
163
165
  # @!method class_or_instance_eval?(node)
164
166
  def_node_matcher :class_or_instance_eval?, <<~PATTERN
165
- (block (send _ {:class_eval :instance_eval}) ...)
167
+ ({block numblock} (send _ {:class_eval :instance_eval}) ...)
166
168
  PATTERN
167
169
 
168
170
  # @!method class_or_module_or_struct_new_call?(node)
169
171
  def_node_matcher :class_or_module_or_struct_new_call?, <<~PATTERN
170
- (block (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
172
+ ({block numblock} (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
171
173
  PATTERN
172
174
 
173
175
  def check_node(node)
@@ -277,7 +279,7 @@ module RuboCop
277
279
  matcher_name = "#{m}_block?".to_sym
278
280
  unless respond_to?(matcher_name)
279
281
  self.class.def_node_matcher matcher_name, <<~PATTERN
280
- (block (send {nil? const} {:#{m}} ...) ...)
282
+ ({block numblock} (send {nil? const} {:#{m}} ...) ...)
281
283
  PATTERN
282
284
  end
283
285
 
@@ -67,6 +67,8 @@ module RuboCop
67
67
  check_expression(node.body)
68
68
  end
69
69
 
70
+ alias on_numblock on_block
71
+
70
72
  def on_begin(node)
71
73
  check_begin(node)
72
74
  end