rubocop 1.34.1 → 1.35.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 (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