rubocop 1.24.0 → 1.24.1

Sign up to get free protection for your applications and to get access to all the features.
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'