rubocop 1.24.0 → 1.24.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3080860c5102e2d42274c71316c7d9910e6e26019c9f39005e38fba136657c8e
4
- data.tar.gz: 879fa716afcb1051f05f0ebc6832291cfb06655763e1aaac752cf6997096bcf2
3
+ metadata.gz: a2e7d2cbe48c6ff81a071b353132db29ed017af57a32bcd142038e2e551f3a5b
4
+ data.tar.gz: 8ae72a3ce8b6ab13b4d451bbdb1dbcdf54f898711a3009dae81450a49fb037e0
5
5
  SHA512:
6
- metadata.gz: 21bd87b421b7cae8c95a44cdfc9ef85e4b4259fc08bfd53b37f02f16d9808ef487d1ec385a4e5047fed1d3358cf185f8bc2ca2bfa504eeedd05c47d4ea9cb411
7
- data.tar.gz: 933d030bae14fbaf659e21901ab49db9418dcb8afcaff33b68d765c9fa47576f6c957fe1b0771f23a3faa94c100353f739298d85b68c8a96e65b6b15c1a8f60e
6
+ metadata.gz: d868781732056622d0f5157a50553c0b521f81f2ca14d2ede65b4c7372ef0e3b89be5146db8664fac5b28a39c82be52fc297a43d8280647b1b7426ce9ee87337
7
+ data.tar.gz: e3d8f4dc8ab53859197eb3f05c62290cf72ba11c7e742869d619d6c4564e28f5c0fc70e4e15f90fc4f9bfe2d46cafdeedde8aa16d982adfc7d6eb482f7d20093
data/README.md CHANGED
@@ -9,7 +9,6 @@
9
9
  [![Actions Status](https://github.com/rubocop/rubocop/workflows/CI/badge.svg?branch=master)](https://github.com/rubocop/rubocop/actions?query=workflow%3ACI)
10
10
  [![Test Coverage](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/test_coverage)](https://codeclimate.com/github/rubocop/rubocop/test_coverage)
11
11
  [![Maintainability](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/maintainability)](https://codeclimate.com/github/rubocop/rubocop/maintainability)
12
- [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=rubocop&package-manager=bundler&version-scheme=semver)
13
12
  [![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.gg/wJjWvGRDmm)
14
13
 
15
14
  > Role models are important. <br/>
data/config/default.yml CHANGED
@@ -2489,6 +2489,7 @@ Naming/BinaryOperatorParameterName:
2489
2489
 
2490
2490
  Naming/BlockForwarding:
2491
2491
  Description: 'Use anonymous block forwarding.'
2492
+ StyleGuide: '#block-forwarding'
2492
2493
  Enabled: pending
2493
2494
  VersionAdded: '1.24'
2494
2495
  EnforcedStyle: anonymous
@@ -117,7 +117,7 @@ module RuboCop
117
117
 
118
118
  correct_metadata(corrector, metadata)
119
119
  else
120
- correct_missing_metadata(corrector, node, block_var)
120
+ insert_mfa_required(corrector, node, block_var)
121
121
  end
122
122
  end
123
123
 
@@ -129,11 +129,9 @@ module RuboCop
129
129
  end
130
130
  end
131
131
 
132
- def correct_missing_metadata(corrector, node, block_var)
132
+ def insert_mfa_required(corrector, node, block_var)
133
133
  corrector.insert_before(node.loc.end, <<~RUBY)
134
- #{block_var}.metadata = {
135
- 'rubygems_mfa_required' => 'true'
136
- }
134
+ #{block_var}.metadata['rubygems_mfa_required'] = 'true'
137
135
  RUBY
138
136
  end
139
137
 
@@ -33,8 +33,9 @@ module RuboCop
33
33
 
34
34
  def on_send(node)
35
35
  return unless (dispatch_node = dispatch_method(node))
36
+ return unless (dot = dispatch_node.loc.dot)
36
37
 
37
- range = range_between(dispatch_node.loc.dot.begin_pos, dispatch_node.loc.selector.end_pos)
38
+ range = range_between(dot.begin_pos, dispatch_node.loc.selector.end_pos)
38
39
 
39
40
  add_offense(range) do |corrector|
40
41
  corrector.remove(range)
@@ -27,7 +27,7 @@ module RuboCop
27
27
 
28
28
  # @!method each_with_object?(node)
29
29
  def_node_matcher :each_with_object?, <<~PATTERN
30
- ({send csend} _ :each_with_object $_)
30
+ (call _ :each_with_object $_)
31
31
  PATTERN
32
32
 
33
33
  def on_send(node)
@@ -41,7 +41,11 @@ module RuboCop
41
41
  end
42
42
 
43
43
  node.operator_method? || node.setter_method? || chained_calls?(node) ||
44
- operator_keyword?(node) || node.first_argument.hash_type?
44
+ valid_first_argument?(node.first_argument)
45
+ end
46
+
47
+ def valid_first_argument?(first_arg)
48
+ first_arg.operator_keyword? || first_arg.hash_type? || ternary_expression?(first_arg)
45
49
  end
46
50
 
47
51
  def first_argument_starts_with_left_parenthesis?(node)
@@ -53,9 +57,8 @@ module RuboCop
53
57
  first_argument.send_type? && (node.children.last&.children&.count || 0) > 1
54
58
  end
55
59
 
56
- def operator_keyword?(node)
57
- first_argument = node.first_argument
58
- first_argument.operator_keyword?
60
+ def ternary_expression?(node)
61
+ node.if_type? && node.ternary?
59
62
  end
60
63
 
61
64
  def spaces_before_left_parenthesis(node)
@@ -59,7 +59,7 @@ module RuboCop
59
59
 
60
60
  # @!method attribute_call?(node)
61
61
  def_node_matcher :attribute_call?, <<~PATTERN
62
- ( {csend send} _receiver _method # and no parameters
62
+ (call _receiver _method # and no parameters
63
63
  )
64
64
  PATTERN
65
65
 
@@ -36,6 +36,7 @@ module RuboCop
36
36
  #
37
37
  class BlockForwarding < Base
38
38
  include ConfigurableEnforcedStyle
39
+ include RangeHelp
39
40
  extend AutoCorrector
40
41
  extend TargetRubyVersion
41
42
 
@@ -94,6 +95,10 @@ module RuboCop
94
95
  def register_offense(block_argument)
95
96
  add_offense(block_argument, message: format(MSG, style: style)) do |corrector|
96
97
  corrector.replace(block_argument, '&')
98
+
99
+ arguments = block_argument.parent
100
+
101
+ add_parentheses(arguments, corrector) unless arguments.parenthesized_call?
97
102
  end
98
103
  end
99
104
  end
@@ -64,7 +64,7 @@ module RuboCop
64
64
 
65
65
  add_offense(write_node, message: message) do |corrector|
66
66
  range = range_between(node.loc.selector.begin_pos, write_node.loc.expression.end_pos)
67
- replacement = "#{write_method(mode)}(#{filename.source}, #{content.source})"
67
+ replacement = replacement(mode, filename, content, write_node)
68
68
 
69
69
  corrector.replace(range, replacement)
70
70
  end
@@ -92,6 +92,32 @@ module RuboCop
92
92
  def write_method(mode)
93
93
  mode.end_with?('b') ? :binwrite : :write
94
94
  end
95
+
96
+ def replacement(mode, filename, content, write_node)
97
+ replacement = "#{write_method(mode)}(#{filename.source}, #{content.source})"
98
+
99
+ if heredoc?(write_node)
100
+ first_argument = write_node.body.first_argument
101
+
102
+ <<~REPLACEMENT.chomp
103
+ #{replacement}
104
+ #{heredoc_range(first_argument).source}
105
+ REPLACEMENT
106
+ else
107
+ replacement
108
+ end
109
+ end
110
+
111
+ def heredoc?(write_node)
112
+ write_node.block_type? && (first_argument = write_node.body.first_argument) &&
113
+ first_argument.respond_to?(:heredoc?) && first_argument.heredoc?
114
+ end
115
+
116
+ def heredoc_range(first_argument)
117
+ range_between(
118
+ first_argument.loc.heredoc_body.begin_pos, first_argument.loc.heredoc_end.end_pos
119
+ )
120
+ end
95
121
  end
96
122
  end
97
123
  end
@@ -30,13 +30,13 @@ module RuboCop
30
30
  # @!method on_bad_each_with_object(node)
31
31
  def_node_matcher :on_bad_each_with_object, <<~PATTERN
32
32
  (block
33
- ({send csend} !#array_receiver? :each_with_object (hash))
33
+ (call !#array_receiver? :each_with_object (hash))
34
34
  (args
35
35
  (mlhs
36
36
  (arg $_)
37
37
  (arg _val))
38
38
  (arg _memo))
39
- ({send csend} (lvar _memo) :[]= $!`_memo $(lvar _val)))
39
+ (call (lvar _memo) :[]= $!`_memo $(lvar _val)))
40
40
  PATTERN
41
41
 
42
42
  # @!method on_bad_hash_brackets_map(node)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  (const _ :Hash)
46
46
  :[]
47
47
  (block
48
- ({send csend} !#array_receiver? {:map :collect})
48
+ (call !#array_receiver? {:map :collect})
49
49
  (args
50
50
  (arg $_)
51
51
  (arg _val))
@@ -54,9 +54,9 @@ module RuboCop
54
54
 
55
55
  # @!method on_bad_map_to_h(node)
56
56
  def_node_matcher :on_bad_map_to_h, <<~PATTERN
57
- ({send csend}
57
+ (call
58
58
  (block
59
- ({send csend} !#array_receiver? {:map :collect})
59
+ (call !#array_receiver? {:map :collect})
60
60
  (args
61
61
  (arg $_)
62
62
  (arg _val))
@@ -67,7 +67,7 @@ module RuboCop
67
67
  # @!method on_bad_to_h(node)
68
68
  def_node_matcher :on_bad_to_h, <<~PATTERN
69
69
  (block
70
- ({send csend} !#array_receiver? :to_h)
70
+ (call !#array_receiver? :to_h)
71
71
  (args
72
72
  (arg $_)
73
73
  (arg _val))
@@ -30,13 +30,13 @@ module RuboCop
30
30
  # @!method on_bad_each_with_object(node)
31
31
  def_node_matcher :on_bad_each_with_object, <<~PATTERN
32
32
  (block
33
- ({send csend} !#array_receiver? :each_with_object (hash))
33
+ (call !#array_receiver? :each_with_object (hash))
34
34
  (args
35
35
  (mlhs
36
36
  (arg _key)
37
37
  (arg $_))
38
38
  (arg _memo))
39
- ({send csend} (lvar _memo) :[]= $(lvar _key) $!`_memo))
39
+ (call (lvar _memo) :[]= $(lvar _key) $!`_memo))
40
40
  PATTERN
41
41
 
42
42
  # @!method on_bad_hash_brackets_map(node)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  (const _ :Hash)
46
46
  :[]
47
47
  (block
48
- ({send csend} !#array_receiver? {:map :collect})
48
+ (call !#array_receiver? {:map :collect})
49
49
  (args
50
50
  (arg _key)
51
51
  (arg $_))
@@ -54,9 +54,9 @@ module RuboCop
54
54
 
55
55
  # @!method on_bad_map_to_h(node)
56
56
  def_node_matcher :on_bad_map_to_h, <<~PATTERN
57
- ({send csend}
57
+ (call
58
58
  (block
59
- ({send csend} !#array_receiver? {:map :collect})
59
+ (call !#array_receiver? {:map :collect})
60
60
  (args
61
61
  (arg _key)
62
62
  (arg $_))
@@ -67,7 +67,7 @@ module RuboCop
67
67
  # @!method on_bad_to_h(node)
68
68
  def_node_matcher :on_bad_to_h, <<~PATTERN
69
69
  (block
70
- ({send csend} !#array_receiver? :to_h)
70
+ (call !#array_receiver? :to_h)
71
71
  (args
72
72
  (arg _key)
73
73
  (arg $_))
@@ -59,7 +59,7 @@ module RuboCop
59
59
  def autocorrect(corrector, to_h, map)
60
60
  removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
61
61
 
62
- corrector.remove(removal_range)
62
+ corrector.remove(range_with_surrounding_space(range: removal_range, side: :left))
63
63
  corrector.replace(map.loc.selector, 'to_h')
64
64
  end
65
65
  end
@@ -13,9 +13,11 @@ module RuboCop
13
13
 
14
14
  private
15
15
 
16
+ # rubocop:disable Metrics/PerceivedComplexity
16
17
  def omit_parentheses(node)
17
18
  return unless node.parenthesized?
18
19
  return if inside_endless_method_def?(node)
20
+ return if require_parentheses_for_hash_value_omission?(node)
19
21
  return if syntax_like_method_call?(node)
20
22
  return if super_call_without_arguments?(node)
21
23
  return if allowed_camel_case_method_call?(node)
@@ -26,6 +28,7 @@ module RuboCop
26
28
  auto_correct(corrector, node)
27
29
  end
28
30
  end
31
+ # rubocop:enable Metrics/PerceivedComplexity
29
32
 
30
33
  def auto_correct(corrector, node)
31
34
  if parentheses_at_the_end_of_multiline_call?(node)
@@ -45,6 +48,16 @@ module RuboCop
45
48
  node.each_ancestor(:def, :defs).any?(&:endless?) && node.arguments.any?
46
49
  end
47
50
 
51
+ # Require hash value omission be enclosed in parentheses to prevent the following issue:
52
+ # https://bugs.ruby-lang.org/issues/18396.
53
+ def require_parentheses_for_hash_value_omission?(node)
54
+ return unless (last_argument = node.last_argument)
55
+
56
+ return false unless (right_sibling = node.right_sibling)
57
+
58
+ last_argument.hash_type? && last_argument.pairs.last&.value_omission? && right_sibling
59
+ end
60
+
48
61
  def syntax_like_method_call?(node)
49
62
  node.implicit_call? || node.operator_method?
50
63
  end
@@ -43,9 +43,11 @@ module RuboCop
43
43
  # NOTE: Parentheses are still allowed in cases where omitting them
44
44
  # results in ambiguous or syntactically incorrect code. For example,
45
45
  # parentheses are required around a method with arguments when inside an
46
- # endless method definition introduced in Ruby 3.0. Parentheses are also
46
+ # endless method definition introduced in Ruby 3.0. Parentheses are also
47
47
  # allowed when forwarding arguments with the triple-dot syntax introduced
48
48
  # in Ruby 2.7 as omitting them starts an endless range.
49
+ # And Ruby 3.1's hash omission syntax has a case that requires parentheses
50
+ # because the issue https://bugs.ruby-lang.org/issues/18396.
49
51
  #
50
52
  # @example EnforcedStyle: require_parentheses (default)
51
53
  #
@@ -6,8 +6,13 @@ module RuboCop
6
6
  # This cop checks for parentheses around the arguments in method
7
7
  # definitions. Both instance and class/singleton methods are checked.
8
8
  #
9
- # This cop does not consider endless methods, since parentheses are
10
- # always required for them.
9
+ # Regardless of style, parentheses are necessary for:
10
+ #
11
+ # 1. Endless methods
12
+ # 2. Argument lists containing a `forward-arg` (`...`)
13
+ # 3. Argument lists containing an anonymous block forwarding (`&`)
14
+ #
15
+ # Removing the parens would be a syntax error here.
11
16
  #
12
17
  # @example EnforcedStyle: require_parentheses (default)
13
18
  # # The `require_parentheses` style requires method definitions
@@ -121,21 +126,13 @@ module RuboCop
121
126
  corrector.remove(arg_node.loc.end)
122
127
  end
123
128
 
124
- def correct_definition(def_node, corrector)
125
- arguments_range = def_node.arguments.source_range
126
- args_with_space = range_with_surrounding_space(range: arguments_range, side: :left)
127
- leading_space = range_between(args_with_space.begin_pos, arguments_range.begin_pos)
128
- corrector.replace(leading_space, '(')
129
- corrector.insert_after(arguments_range, ')')
130
- end
131
-
132
129
  def forced_parentheses?(node)
133
130
  # Regardless of style, parentheses are necessary for:
134
131
  # 1. Endless methods
135
132
  # 2. Argument lists containing a `forward-arg` (`...`)
133
+ # 3. Argument lists containing an anonymous block forwarding (`&`)
136
134
  # Removing the parens would be a syntax error here.
137
-
138
- node.endless? || node.arguments.any?(&:forward_arg_type?)
135
+ node.endless? || node.arguments.any?(&:forward_arg_type?) || anonymous_block_arg?(node)
139
136
  end
140
137
 
141
138
  def require_parentheses?(args)
@@ -151,7 +148,8 @@ module RuboCop
151
148
  location = node.arguments.source_range
152
149
 
153
150
  add_offense(location, message: MSG_MISSING) do |corrector|
154
- correct_definition(node, corrector)
151
+ add_parentheses(node.arguments, corrector)
152
+
155
153
  unexpected_style_detected 'require_no_parentheses'
156
154
  end
157
155
  end
@@ -163,6 +161,12 @@ module RuboCop
163
161
  unexpected_style_detected 'require_parentheses'
164
162
  end
165
163
  end
164
+
165
+ def anonymous_block_arg?(node)
166
+ return false unless (last_argument = node.arguments.last)
167
+
168
+ last_argument.blockarg_type? && last_argument.name.nil?
169
+ end
166
170
  end
167
171
  end
168
172
  end
@@ -30,8 +30,15 @@ module RuboCop
30
30
  node.loc.respond_to?(:end) && node.loc.end && node.loc.end.is?(')')
31
31
  end
32
32
 
33
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
33
34
  def add_parentheses(node, corrector)
34
- if !node.respond_to?(:arguments)
35
+ if node.args_type?
36
+ arguments_range = node.source_range
37
+ args_with_space = range_with_surrounding_space(range: arguments_range, side: :left)
38
+ leading_space = range_between(args_with_space.begin_pos, arguments_range.begin_pos)
39
+ corrector.replace(leading_space, '(')
40
+ corrector.insert_after(arguments_range, ')')
41
+ elsif !node.respond_to?(:arguments)
35
42
  corrector.wrap(node, '(', ')')
36
43
  elsif node.arguments.empty?
37
44
  corrector.insert_after(node, '()')
@@ -43,6 +50,7 @@ module RuboCop
43
50
  corrector.insert_after(args_end(node), ')')
44
51
  end
45
52
  end
53
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
46
54
 
47
55
  def args_begin(node)
48
56
  loc = node.loc
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.24.0'
6
+ STRING = '1.24.1'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.0
4
+ version: 1.24.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-12-23 00:00:00.000000000 Z
13
+ date: 2021-12-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -100,7 +100,7 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 1.15.0
103
+ version: 1.15.1
104
104
  - - "<"
105
105
  - !ruby/object:Gem::Version
106
106
  version: '2.0'
@@ -110,7 +110,7 @@ dependencies:
110
110
  requirements:
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 1.15.0
113
+ version: 1.15.1
114
114
  - - "<"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '2.0'