rubocop 1.59.0 → 1.60.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/config/default.yml +3 -1
- data/lib/rubocop/config.rb +0 -2
- data/lib/rubocop/config_loader.rb +0 -1
- data/lib/rubocop/config_validator.rb +0 -2
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +4 -4
- data/lib/rubocop/cop/layout/end_alignment.rb +5 -1
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +16 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +5 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +12 -5
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/naming/block_forwarding.rb +10 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/arguments_forwarding.rb +60 -12
- data/lib/rubocop/cop/style/collection_compact.rb +11 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/eval_with_location.rb +0 -11
- data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +39 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +9 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +13 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -3
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +8 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/symbol_proc.rb +36 -0
- data/lib/rubocop/cops_documentation_generator.rb +11 -1
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +1 -1
- data/lib/rubocop/options.rb +0 -8
- data/lib/rubocop/rspec/shared_contexts.rb +6 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/server/cache.rb +1 -2
- data/lib/rubocop/server/client_command/exec.rb +0 -1
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +11 -11
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5baa438e333ac7dbae0d7481f0a512e950f9ef11014f09d78f360d3bc64d528
|
4
|
+
data.tar.gz: bfba21f2555729c81554baad4910a35088fef9ba39538402e54841fdff1c8d8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 247eadb99d0c3d9f46067a707a0511433567fea2326ded958381c55cabe9a24ef6c2328e6d4ab901454a6af60cba185d5f87364fc9c1399684bbf3a657ef383b
|
7
|
+
data.tar.gz: 675be6aba0374927f8bf17df0d1dc51d4fc7a05431981d164ae62715fd9008b8ae6208b50f4b509afadb4622a0b19e0bf5d4c650aa203407ece15e9d88ebe031
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<p align="center">
|
2
|
-
<img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal.png" alt="RuboCop Logo"/>
|
2
|
+
<img src="https://raw.githubusercontent.com/rubocop/rubocop/master/logo/rubo-logo-horizontal-white.png" alt="RuboCop Logo"/>
|
3
3
|
</p>
|
4
4
|
|
5
5
|
----------
|
@@ -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.
|
56
|
+
gem 'rubocop', '~> 1.60', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -248,5 +248,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
248
248
|
|
249
249
|
## Copyright
|
250
250
|
|
251
|
-
Copyright (c) 2012-
|
251
|
+
Copyright (c) 2012-2024 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
252
252
|
further details.
|
data/config/default.yml
CHANGED
@@ -4712,6 +4712,7 @@ Style/OperatorMethodCall:
|
|
4712
4712
|
|
4713
4713
|
Style/OptionHash:
|
4714
4714
|
Description: "Don't use option hashes when you can use keyword arguments."
|
4715
|
+
StyleGuide: '#keyword-arguments-vs-option-hashes'
|
4715
4716
|
Enabled: false
|
4716
4717
|
VersionAdded: '0.33'
|
4717
4718
|
VersionChanged: '0.34'
|
@@ -5237,7 +5238,8 @@ Style/SingleLineMethods:
|
|
5237
5238
|
AllowIfMethodIsEmpty: true
|
5238
5239
|
|
5239
5240
|
Style/SlicingWithRange:
|
5240
|
-
Description: 'Checks array slicing is done with endless ranges when suitable.'
|
5241
|
+
Description: 'Checks array slicing is done with redundant, endless, and beginless ranges when suitable.'
|
5242
|
+
StyleGuide: '#slicing-with-ranges'
|
5241
5243
|
Enabled: true
|
5242
5244
|
VersionAdded: '0.83'
|
5243
5245
|
Safe: false
|
data/lib/rubocop/config.rb
CHANGED
data/lib/rubocop/cop/base.rb
CHANGED
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
# The parameter name given is transformed into a method name (eg. `Max`
|
9
9
|
# becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
|
10
10
|
def exclude_limit(parameter_name, method_name: transform(parameter_name))
|
11
|
-
define_method("#{method_name}=") do |value|
|
11
|
+
define_method(:"#{method_name}=") do |value|
|
12
12
|
cfg = config_to_allow_offenses
|
13
13
|
cfg[:exclude_limit] ||= {}
|
14
14
|
current_max = cfg[:exclude_limit][parameter_name]
|
@@ -63,10 +63,10 @@ module RuboCop
|
|
63
63
|
expect_correction: EXPECT_CORRECTION_DESCRIPTION_MAPPING
|
64
64
|
}.freeze
|
65
65
|
|
66
|
-
# @!method offense_example
|
67
|
-
def_node_matcher :offense_example
|
66
|
+
# @!method offense_example(node)
|
67
|
+
def_node_matcher :offense_example, <<~PATTERN
|
68
68
|
(block
|
69
|
-
(send _ {:it :specify}
|
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
|
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)
|
@@ -5,7 +5,10 @@ module RuboCop
|
|
5
5
|
module Layout
|
6
6
|
# Checks the indentation of the first element in an array literal
|
7
7
|
# where the opening bracket and the first element are on separate lines.
|
8
|
-
# The other elements' indentations are handled by
|
8
|
+
# The other elements' indentations are handled by `Layout/ArrayAlignment` cop.
|
9
|
+
#
|
10
|
+
# This cop will respect `Layout/ArrayAlignment` and will not work when
|
11
|
+
# `EnforcedStyle: with_fixed_indentation` is specified for `Layout/ArrayAlignment`.
|
9
12
|
#
|
10
13
|
# By default, array literals that are arguments in a method call with
|
11
14
|
# parentheses, and where the opening square bracket of the array is on the
|
@@ -93,6 +96,8 @@ module RuboCop
|
|
93
96
|
end
|
94
97
|
|
95
98
|
def on_send(node)
|
99
|
+
return if style != :consistent && enforce_first_argument_with_fixed_indentation?
|
100
|
+
|
96
101
|
each_argument_node(node, :array) do |array_node, left_parenthesis|
|
97
102
|
check(array_node, left_parenthesis)
|
98
103
|
end
|
@@ -174,6 +179,16 @@ module RuboCop
|
|
174
179
|
'where the left bracket is.'
|
175
180
|
end
|
176
181
|
end
|
182
|
+
|
183
|
+
def enforce_first_argument_with_fixed_indentation?
|
184
|
+
return false unless array_alignment_config['Enabled']
|
185
|
+
|
186
|
+
array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
187
|
+
end
|
188
|
+
|
189
|
+
def array_alignment_config
|
190
|
+
config.for_cop('Layout/ArrayAlignment')
|
191
|
+
end
|
177
192
|
end
|
178
193
|
end
|
179
194
|
end
|
@@ -107,7 +107,7 @@ module RuboCop
|
|
107
107
|
return false unless line.end_with?("\\\n")
|
108
108
|
|
109
109
|
# Ensure backslash isn't part of a token spanning to the next line.
|
110
|
-
node.children.none? { |c| c.first_line
|
110
|
+
node.children.none? { |c| (c.first_line...c.last_line).cover?(line_num) && c.multiline? }
|
111
111
|
end
|
112
112
|
|
113
113
|
def autocorrect(corrector, offense_range, insert_pos, spaces)
|
@@ -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)
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
next unless asgn_node.loc.operator
|
42
42
|
|
43
43
|
rhs = asgn_node.to_a.last
|
44
|
-
next if !
|
44
|
+
next if !all_literals?(rhs) || parallel_assignment_with_splat_operator?(rhs)
|
45
45
|
|
46
46
|
range = offense_range(asgn_node, rhs)
|
47
47
|
|
@@ -59,10 +59,17 @@ module RuboCop
|
|
59
59
|
node.each_child_node { |child| traverse_node(child, &block) }
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
def all_literals?(node)
|
63
|
+
case node.type
|
64
|
+
when :dstr, :xstr
|
65
|
+
false
|
66
|
+
when :array
|
67
|
+
node.values.all? { |value| all_literals?(value) }
|
68
|
+
when :hash
|
69
|
+
(node.values + node.keys).all? { |item| all_literals?(item) }
|
70
|
+
else
|
71
|
+
node.respond_to?(:literal?) && node.literal?
|
72
|
+
end
|
66
73
|
end
|
67
74
|
|
68
75
|
def parallel_assignment_with_splat_operator?(node)
|
@@ -123,6 +123,7 @@ module RuboCop
|
|
123
123
|
|
124
124
|
# Shorthand assignments always use their arguments
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
126
|
+
next false unless assignment_node.parent
|
126
127
|
|
127
128
|
node_within_block_or_conditional =
|
128
129
|
node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
|
@@ -17,9 +17,12 @@ module RuboCop
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def add_offense_from_diagnostic(diagnostic, ruby_version)
|
20
|
-
message =
|
21
|
-
|
22
|
-
|
20
|
+
message = if lsp_mode?
|
21
|
+
diagnostic.message
|
22
|
+
else
|
23
|
+
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
24
|
+
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
25
|
+
end
|
23
26
|
add_offense(diagnostic.location, message: message, severity: diagnostic.level)
|
24
27
|
end
|
25
28
|
|
@@ -51,21 +51,29 @@ module RuboCop
|
|
51
51
|
[Lint::AmbiguousOperator, Style::ArgumentsForwarding]
|
52
52
|
end
|
53
53
|
|
54
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
54
55
|
def on_def(node)
|
55
56
|
return if node.arguments.empty?
|
56
57
|
|
57
58
|
last_argument = node.last_argument
|
58
59
|
return if expected_block_forwarding_style?(node, last_argument)
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
invalid_syntax = false
|
62
62
|
node.each_descendant(:block_pass) do |block_pass_node|
|
63
63
|
next if block_pass_node.children.first&.sym_type? ||
|
64
64
|
last_argument.source != block_pass_node.source
|
65
65
|
|
66
|
+
if block_pass_node.each_ancestor(:block, :numblock).any?
|
67
|
+
invalid_syntax = true
|
68
|
+
next
|
69
|
+
end
|
70
|
+
|
66
71
|
register_offense(block_pass_node, node)
|
67
72
|
end
|
73
|
+
|
74
|
+
register_offense(last_argument, node) unless invalid_syntax
|
68
75
|
end
|
76
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
69
77
|
alias on_defs on_def
|
70
78
|
|
71
79
|
private
|
@@ -23,6 +23,7 @@ module RuboCop
|
|
23
23
|
# # bad
|
24
24
|
# open(something)
|
25
25
|
# open("| #{something}")
|
26
|
+
# open("| foo")
|
26
27
|
# URI.open(something)
|
27
28
|
#
|
28
29
|
# # good
|
@@ -32,7 +33,6 @@ module RuboCop
|
|
32
33
|
#
|
33
34
|
# # good (literal strings)
|
34
35
|
# open("foo.text")
|
35
|
-
# open("| foo")
|
36
36
|
# URI.open("http://example.com")
|
37
37
|
class Open < Base
|
38
38
|
MSG = 'The use of `%<receiver>sopen` is a serious security risk.'
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
|
41
41
|
# @!method open?(node)
|
42
42
|
def_node_matcher :open?, <<~PATTERN
|
43
|
-
(send ${nil? (const {nil? cbase} :URI)} :open
|
43
|
+
(send ${nil? (const {nil? cbase} :URI)} :open $_ ...)
|
44
44
|
PATTERN
|
45
45
|
|
46
46
|
def on_send(node)
|
@@ -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,27 +172,42 @@ 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
|
-
|
176
|
-
|
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|
|
189
|
-
if forward_rest
|
204
|
+
send_classifications.each do |send_node, _c, forward_rest, forward_kwrest, _forward_block_arg| # rubocop:disable Layout/LineLength
|
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)
|
192
208
|
end
|
193
209
|
|
194
|
-
if forward_kwrest
|
210
|
+
if outside_block?(forward_kwrest)
|
195
211
|
register_forward_kwargs_offense(!forward_rest, def_node.arguments, kwrest_arg)
|
196
212
|
register_forward_kwargs_offense(!forward_rest, send_node, forward_kwrest)
|
197
213
|
end
|
@@ -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
|
-
[
|
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)
|
@@ -250,6 +268,12 @@ module RuboCop
|
|
250
268
|
redundant_arg_names.include?(arg.source) ? arg : nil
|
251
269
|
end
|
252
270
|
|
271
|
+
def outside_block?(node)
|
272
|
+
return false unless node
|
273
|
+
|
274
|
+
node.each_ancestor(:block, :numblock).none?
|
275
|
+
end
|
276
|
+
|
253
277
|
def register_forward_args_offense(def_arguments_or_send, rest_arg_or_splat)
|
254
278
|
add_offense(rest_arg_or_splat, message: ARGS_MSG) do |corrector|
|
255
279
|
add_parens_if_missing(def_arguments_or_send, corrector)
|
@@ -266,6 +290,16 @@ module RuboCop
|
|
266
290
|
end
|
267
291
|
end
|
268
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
|
+
|
269
303
|
def register_forward_all_offense(def_or_send, send_or_arguments, rest_or_splat)
|
270
304
|
arg_range = arguments_range(def_or_send, rest_or_splat)
|
271
305
|
|
@@ -340,7 +374,7 @@ module RuboCop
|
|
340
374
|
end
|
341
375
|
|
342
376
|
def classification
|
343
|
-
return nil unless forwarded_rest_arg || forwarded_kwrest_arg
|
377
|
+
return nil unless forwarded_rest_arg || forwarded_kwrest_arg || forwarded_block_arg
|
344
378
|
|
345
379
|
if can_forward_all?
|
346
380
|
:all
|
@@ -424,9 +458,23 @@ module RuboCop
|
|
424
458
|
def no_additional_args?
|
425
459
|
forwardable_count = [@rest_arg, @kwrest_arg, @block_arg].compact.size
|
426
460
|
|
461
|
+
return false if missing_rest_arg_or_kwrest_arg?
|
462
|
+
|
427
463
|
@def_node.arguments.size == forwardable_count &&
|
428
464
|
@send_node.arguments.size == forwardable_count
|
429
465
|
end
|
466
|
+
|
467
|
+
def missing_rest_arg_or_kwrest_arg?
|
468
|
+
(@rest_arg_name && !forwarded_rest_arg) ||
|
469
|
+
(@kwrest_arg_name && !forwarded_kwrest_arg)
|
470
|
+
end
|
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'
|
430
478
|
end
|
431
479
|
end
|
432
480
|
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?
|
@@ -32,27 +32,27 @@ module RuboCop
|
|
32
32
|
|
33
33
|
send_node = node.send_node
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
add_offense(range) do |corrector|
|
35
|
+
add_offense(send_node) do |corrector|
|
38
36
|
range_type, min, max = each_range(node)
|
39
37
|
|
40
38
|
max += 1 if range_type == :irange
|
41
39
|
|
42
|
-
corrector.replace(
|
40
|
+
corrector.replace(send_node, "#{max - min}.times")
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
44
|
private
|
47
45
|
|
48
46
|
def offending?(node)
|
47
|
+
return false unless node.arguments.empty?
|
48
|
+
|
49
49
|
each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
|
50
50
|
end
|
51
51
|
|
52
52
|
# @!method each_range(node)
|
53
53
|
def_node_matcher :each_range, <<~PATTERN
|
54
54
|
(block
|
55
|
-
(
|
55
|
+
(call
|
56
56
|
(begin
|
57
57
|
(${irange erange}
|
58
58
|
(int $_) (int $_)))
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
64
64
|
# @!method each_range_with_zero_origin?(node)
|
65
65
|
def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
|
66
66
|
(block
|
67
|
-
(
|
67
|
+
(call
|
68
68
|
(begin
|
69
69
|
({irange erange}
|
70
70
|
(int 0) (int _)))
|
@@ -76,7 +76,7 @@ module RuboCop
|
|
76
76
|
# @!method each_range_without_block_argument?(node)
|
77
77
|
def_node_matcher :each_range_without_block_argument?, <<~PATTERN
|
78
78
|
(block
|
79
|
-
(
|
79
|
+
(call
|
80
80
|
(begin
|
81
81
|
({irange erange}
|
82
82
|
(int _) (int _)))
|
@@ -128,17 +128,6 @@ module RuboCop
|
|
128
128
|
node.method?(:eval) ? node.arguments.size >= 2 : true
|
129
129
|
end
|
130
130
|
|
131
|
-
# FIXME: It's a Style/ConditionalAssignment's false positive.
|
132
|
-
# rubocop:disable Style/ConditionalAssignment
|
133
|
-
def with_lineno?(node)
|
134
|
-
if node.method?(:eval)
|
135
|
-
node.arguments.size == 4
|
136
|
-
else
|
137
|
-
node.arguments.size == 3
|
138
|
-
end
|
139
|
-
end
|
140
|
-
# rubocop:enable Style/ConditionalAssignment
|
141
|
-
|
142
131
|
def add_offense_for_incorrect_line(method_name, line_node, sign, line_diff)
|
143
132
|
expected = expected_line(sign, line_diff)
|
144
133
|
message = format(MSG_INCORRECT_LINE,
|