rubocop 1.60.0 → 1.60.2

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: 8154c812a06c819d2014cca8c0967d9b9eb01ff0481b33318accfb61781b04ce
4
- data.tar.gz: d39b524c83cd84df683815b59ac1377fb9dc235dcce337507a56bf611eaa90af
3
+ metadata.gz: a5baa438e333ac7dbae0d7481f0a512e950f9ef11014f09d78f360d3bc64d528
4
+ data.tar.gz: bfba21f2555729c81554baad4910a35088fef9ba39538402e54841fdff1c8d8f
5
5
  SHA512:
6
- metadata.gz: '0787d7ca9354c20ef1fbbee33dc551cd2e45e8c3ea4aac96a51f8348b3a03a3ae1cc5262e0e6d00f61591f48ce4ffbf9140d7f1ddd19b9716d0596df3bbaa55c'
7
- data.tar.gz: de7a48105e8126e9f2c323dc516d4c9862b8c239d881e8285496eb3e79cefdecf487a37e0cb3e0b98fc25264f33c3a2d104fb1e6a4e382d1619f21dace50cc99
6
+ metadata.gz: 247eadb99d0c3d9f46067a707a0511433567fea2326ded958381c55cabe9a24ef6c2328e6d4ab901454a6af60cba185d5f87364fc9c1399684bbf3a657ef383b
7
+ data.tar.gz: 675be6aba0374927f8bf17df0d1dc51d4fc7a05431981d164ae62715fd9008b8ae6208b50f4b509afadb4622a0b19e0bf5d4c650aa203407ece15e9d88ebe031
@@ -63,10 +63,10 @@ module RuboCop
63
63
  expect_correction: EXPECT_CORRECTION_DESCRIPTION_MAPPING
64
64
  }.freeze
65
65
 
66
- # @!method offense_example?(node)
67
- def_node_matcher :offense_example?, <<~PATTERN
66
+ # @!method offense_example(node)
67
+ def_node_matcher :offense_example, <<~PATTERN
68
68
  (block
69
- (send _ {:it :specify} $_description)
69
+ (send _ {:it :specify} $...)
70
70
  _args
71
71
  `(send nil? %RESTRICT_ON_SEND ...)
72
72
  )
@@ -74,7 +74,7 @@ module RuboCop
74
74
 
75
75
  def on_send(node)
76
76
  parent = node.each_ancestor(:block).first
77
- return unless parent && (current_description = offense_example?(parent))
77
+ return unless parent && (current_description = offense_example(parent)&.first)
78
78
 
79
79
  method_name = node.method_name
80
80
  message = format(MSG, method_name: method_name)
@@ -85,7 +85,11 @@ module RuboCop
85
85
 
86
86
  def offense?(node)
87
87
  node.multiline? && !too_long?(node) && suitable_as_single_line?(node) &&
88
- !configured_to_not_be_inspected?(node)
88
+ !index_access_call_chained?(node) && !configured_to_not_be_inspected?(node)
89
+ end
90
+
91
+ def index_access_call_chained?(node)
92
+ node.send_type? && node.method?(:[]) && node.children.first.method?(:[])
89
93
  end
90
94
 
91
95
  def configured_to_not_be_inspected?(node)
@@ -240,12 +240,12 @@ module RuboCop
240
240
  self
241
241
  end
242
242
 
243
- def select(...)
244
- cops.select(...)
243
+ def select(&block)
244
+ cops.select(&block)
245
245
  end
246
246
 
247
- def each(...)
248
- cops.each(...)
247
+ def each(&block)
248
+ cops.each(&block)
249
249
  end
250
250
 
251
251
  # @param [String] cop_name
@@ -104,7 +104,7 @@ module RuboCop
104
104
  # end
105
105
  #
106
106
  # @example RedundantBlockArgumentNames: ['blk', 'block', 'proc'] (default)
107
- # # bad
107
+ # # bad - But it is good with `EnforcedStyle: explicit` set for `Naming/BlockForwarding`.
108
108
  # def foo(&block)
109
109
  # bar(&block)
110
110
  # end
@@ -126,6 +126,7 @@ module RuboCop
126
126
  FORWARDING_MSG = 'Use shorthand syntax `...` for arguments forwarding.'
127
127
  ARGS_MSG = 'Use anonymous positional arguments forwarding (`*`).'
128
128
  KWARGS_MSG = 'Use anonymous keyword arguments forwarding (`**`).'
129
+ BLOCK_MSG = 'Use anonymous block arguments forwarding (`&`).'
129
130
 
130
131
  def self.autocorrect_incompatible_with
131
132
  [Naming::BlockForwarding]
@@ -171,21 +172,36 @@ module RuboCop
171
172
  send_classifications.all? { |_, c, _, _| c == :all }
172
173
  end
173
174
 
175
+ # rubocop:disable Metrics/MethodLength
174
176
  def add_forward_all_offenses(node, send_classifications, forwardable_args)
175
- send_classifications.each do |send_node, _c, forward_rest, _forward_kwrest|
176
- register_forward_all_offense(send_node, send_node, forward_rest)
177
+ _rest_arg, _kwrest_arg, block_arg = *forwardable_args
178
+ registered_block_arg_offense = false
179
+
180
+ send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, forward_block_arg| # rubocop:disable Layout/LineLength
181
+ if !forward_rest && !forward_kwrest
182
+ register_forward_block_arg_offense(!forward_rest, node.arguments, block_arg)
183
+ register_forward_block_arg_offense(!forward_rest, send_node, forward_block_arg)
184
+
185
+ registered_block_arg_offense = true
186
+ break
187
+ else
188
+ register_forward_all_offense(send_node, send_node, forward_rest)
189
+ end
177
190
  end
178
191
 
192
+ return if registered_block_arg_offense
193
+
179
194
  rest_arg, _kwrest_arg, _block_arg = *forwardable_args
180
195
  register_forward_all_offense(node, node.arguments, rest_arg)
181
196
  end
197
+ # rubocop:enable Metrics/MethodLength
182
198
 
183
199
  def add_post_ruby_32_offenses(def_node, send_classifications, forwardable_args)
184
200
  return unless use_anonymous_forwarding?
185
201
 
186
202
  rest_arg, kwrest_arg, _block_arg = *forwardable_args
187
203
 
188
- send_classifications.each do |send_node, _c, forward_rest, forward_kwrest|
204
+ send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, _forward_block_arg| # rubocop:disable Layout/LineLength
189
205
  if outside_block?(forward_rest)
190
206
  register_forward_args_offense(def_node.arguments, rest_arg)
191
207
  register_forward_args_offense(send_node, forward_rest)
@@ -225,10 +241,7 @@ module RuboCop
225
241
 
226
242
  def classification_and_forwards(def_node, send_node, referenced_lvars, forwardable_args)
227
243
  classifier = SendNodeClassifier.new(
228
- def_node,
229
- send_node,
230
- referenced_lvars,
231
- forwardable_args,
244
+ def_node, send_node, referenced_lvars, forwardable_args,
232
245
  target_ruby_version: target_ruby_version,
233
246
  allow_only_rest_arguments: allow_only_rest_arguments?
234
247
  )
@@ -237,7 +250,12 @@ module RuboCop
237
250
 
238
251
  return unless classification
239
252
 
240
- [classification, classifier.forwarded_rest_arg, classifier.forwarded_kwrest_arg]
253
+ [
254
+ classification,
255
+ classifier.forwarded_rest_arg,
256
+ classifier.forwarded_kwrest_arg,
257
+ classifier.forwarded_block_arg
258
+ ]
241
259
  end
242
260
 
243
261
  def redundant_named_arg(arg, config_name, keyword)
@@ -272,6 +290,16 @@ module RuboCop
272
290
  end
273
291
  end
274
292
 
293
+ def register_forward_block_arg_offense(add_parens, def_arguments_or_send, block_arg)
294
+ return if target_ruby_version <= 3.0 || block_arg.source == '&' || explicit_block_name?
295
+
296
+ add_offense(block_arg, message: BLOCK_MSG) do |corrector|
297
+ add_parens_if_missing(def_arguments_or_send, corrector) if add_parens
298
+
299
+ corrector.replace(block_arg, '&')
300
+ end
301
+ end
302
+
275
303
  def register_forward_all_offense(def_or_send, send_or_arguments, rest_or_splat)
276
304
  arg_range = arguments_range(def_or_send, rest_or_splat)
277
305
 
@@ -441,6 +469,13 @@ module RuboCop
441
469
  (@kwrest_arg_name && !forwarded_kwrest_arg)
442
470
  end
443
471
  end
472
+
473
+ def explicit_block_name?
474
+ block_forwarding_config = config.for_cop('Naming/BlockForwarding')
475
+ return false unless block_forwarding_config['Enabled']
476
+
477
+ block_forwarding_config['EnforcedStyle'] == 'explicit'
478
+ end
444
479
  end
445
480
  end
446
481
  end
@@ -23,6 +23,8 @@ module RuboCop
23
23
  # array.reject { |e| e.nil? }
24
24
  # array.delete_if { |e| e.nil? }
25
25
  # array.select { |e| !e.nil? }
26
+ # array.grep_v(nil)
27
+ # array.grep_v(NilClass)
26
28
  #
27
29
  # # good
28
30
  # array.compact
@@ -46,7 +48,7 @@ module RuboCop
46
48
  extend TargetRubyVersion
47
49
 
48
50
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
49
- RESTRICT_ON_SEND = %i[reject delete_if reject! select select!].freeze
51
+ RESTRICT_ON_SEND = %i[reject delete_if reject! select select! grep_v].freeze
50
52
  TO_ENUM_METHODS = %i[to_enum lazy].freeze
51
53
 
52
54
  minimum_target_ruby_version 2.4
@@ -79,6 +81,11 @@ module RuboCop
79
81
  $(lvar _) :nil?) :!))
80
82
  PATTERN
81
83
 
84
+ # @!method grep_v_with_nil?(node)
85
+ def_node_matcher :grep_v_with_nil?, <<~PATTERN
86
+ (send _ :grep_v {(nil) (const {nil? cbase} :NilClass)})
87
+ PATTERN
88
+
82
89
  def on_send(node)
83
90
  return unless (range = offense_range(node))
84
91
  return if allowed_receiver?(node.receiver)
@@ -95,8 +102,9 @@ module RuboCop
95
102
 
96
103
  private
97
104
 
105
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
98
106
  def offense_range(node)
99
- if reject_method_with_block_pass?(node)
107
+ if reject_method_with_block_pass?(node) || grep_v_with_nil?(node)
100
108
  range(node, node)
101
109
  else
102
110
  block_node = node.parent
@@ -110,6 +118,7 @@ module RuboCop
110
118
  range(node, block_node)
111
119
  end
112
120
  end
121
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
113
122
 
114
123
  def to_enum_method?(node)
115
124
  return false unless node.receiver.send_type?
@@ -40,6 +40,7 @@ module RuboCop
40
40
 
41
41
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
42
42
  UNUSED_BLOCK_ARG_MSG = "#{MSG.chop} and remove the unused `%<unused_code>s` block argument."
43
+ ARRAY_CONVERTER_METHODS = %i[assoc flatten rassoc sort sort_by to_a].freeze
43
44
 
44
45
  # @!method kv_each(node)
45
46
  def_node_matcher :kv_each, <<~PATTERN
@@ -56,7 +57,6 @@ module RuboCop
56
57
  (call $(call _ ${:keys :values}) :each (block_pass (sym _)))
57
58
  PATTERN
58
59
 
59
- # rubocop:disable Metrics/AbcSize
60
60
  def on_block(node)
61
61
  return unless handleable?(node)
62
62
 
@@ -66,12 +66,24 @@ module RuboCop
66
66
 
67
67
  return unless (key, value = each_arguments(node))
68
68
 
69
- if unused_block_arg_exist?(node, value)
69
+ check_unused_block_args(node, key, value)
70
+ end
71
+ alias on_numblock on_block
72
+
73
+ # rubocop:disable Metrics/AbcSize
74
+ def check_unused_block_args(node, key, value)
75
+ return if node.body.nil?
76
+
77
+ value_unused = unused_block_arg_exist?(node, value)
78
+ key_unused = unused_block_arg_exist?(node, key)
79
+ return if value_unused && key_unused
80
+
81
+ if value_unused
70
82
  message = message('each_key', node.method_name, value.source)
71
83
  unused_range = key.source_range.end.join(value.source_range.end)
72
84
 
73
85
  register_each_args_offense(node, message, 'each_key', unused_range)
74
- elsif unused_block_arg_exist?(node, key)
86
+ elsif key_unused
75
87
  message = message('each_value', node.method_name, key.source)
76
88
  unused_range = key.source_range.begin.join(value.source_range.begin)
77
89
 
@@ -80,8 +92,6 @@ module RuboCop
80
92
  end
81
93
  # rubocop:enable Metrics/AbcSize
82
94
 
83
- alias on_numblock on_block
84
-
85
95
  def on_block_pass(node)
86
96
  kv_each_with_block_pass(node.parent) do |target, method|
87
97
  register_kv_with_block_pass_offense(node, target, method)
@@ -91,6 +101,7 @@ module RuboCop
91
101
  private
92
102
 
93
103
  def handleable?(node)
104
+ return false if use_array_converter_method_as_preceding?(node)
94
105
  return false unless (root_receiver = root_receiver(node))
95
106
 
96
107
  !root_receiver.literal? || root_receiver.hash_type?
@@ -143,6 +154,16 @@ module RuboCop
143
154
  end
144
155
  end
145
156
 
157
+ def use_array_converter_method_as_preceding?(node)
158
+ return false unless (preceding_method = node.children.first.children.first)
159
+ unless preceding_method.call_type? ||
160
+ preceding_method.block_type? || preceding_method.numblock_type?
161
+ return false
162
+ end
163
+
164
+ ARRAY_CONVERTER_METHODS.include?(preceding_method.method_name)
165
+ end
166
+
146
167
  def root_receiver(node)
147
168
  receiver = node.receiver
148
169
  if receiver&.receiver
@@ -54,7 +54,7 @@ module RuboCop
54
54
  return false unless (parent = node.parent)
55
55
 
56
56
  parent.while_post_type? || parent.until_post_type? || parent.match_with_lvasgn_type? ||
57
- like_method_argument_parentheses?(parent)
57
+ like_method_argument_parentheses?(parent) || multiline_control_flow_statements?(node)
58
58
  end
59
59
 
60
60
  def allowed_expression?(node)
@@ -104,6 +104,13 @@ module RuboCop
104
104
  !node.arithmetic_operation? && node.first_argument.begin_type?
105
105
  end
106
106
 
107
+ def multiline_control_flow_statements?(node)
108
+ return false unless (parent = node.parent)
109
+ return false if parent.single_line?
110
+
111
+ parent.return_type? || parent.next_type? || parent.break_type?
112
+ end
113
+
107
114
  def empty_parentheses?(node)
108
115
  # Don't flag `()`
109
116
  node.children.empty?
@@ -116,7 +116,7 @@ module RuboCop
116
116
 
117
117
  def pid_running?
118
118
  Process.kill(0, pid_path.read.to_i) == 1
119
- rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES
119
+ rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS
120
120
  false
121
121
  end
122
122
 
@@ -17,7 +17,6 @@ module RuboCop
17
17
  class Exec < Base
18
18
  def run
19
19
  ensure_server!
20
- Cache.status_path.delete if Cache.status_path.file?
21
20
  read_stdin = ARGV.include?('-s') || ARGV.include?('--stdin')
22
21
  send_request(
23
22
  command: 'exec',
@@ -16,7 +16,6 @@ module RuboCop
16
16
  # @api private
17
17
  class Exec < Base
18
18
  def run
19
- Cache.status_path.delete if Cache.status_path.file?
20
19
  # RuboCop output is colorized by default where there is a TTY.
21
20
  # We must pass the --color option to preserve this behavior.
22
21
  @args.unshift('--color') unless %w[--color --no-color].any? { |f| @args.include?(f) }
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.60.0'
6
+ STRING = '1.60.2'
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.60.0
4
+ version: 1.60.2
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: 2024-01-15 00:00:00.000000000 Z
13
+ date: 2024-01-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -1028,7 +1028,7 @@ licenses:
1028
1028
  - MIT
1029
1029
  metadata:
1030
1030
  homepage_uri: https://rubocop.org/
1031
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.60.0
1031
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.60.2
1032
1032
  source_code_uri: https://github.com/rubocop/rubocop/
1033
1033
  documentation_uri: https://docs.rubocop.org/rubocop/1.60/
1034
1034
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues