rubocop-performance 1.19.1 → 1.21.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 +4 -4
- data/README.md +3 -1
- data/config/default.yml +18 -17
- data/lib/rubocop/cop/mixin/sort_block.rb +2 -2
- data/lib/rubocop/cop/performance/casecmp.rb +6 -0
- data/lib/rubocop/cop/performance/chain_array_allocation.rb +11 -4
- data/lib/rubocop/cop/performance/count.rb +5 -5
- data/lib/rubocop/cop/performance/end_with.rb +2 -1
- data/lib/rubocop/cop/performance/fixed_size.rb +2 -1
- data/lib/rubocop/cop/performance/flat_map.rb +4 -3
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +2 -2
- data/lib/rubocop/cop/performance/map_compact.rb +5 -4
- data/lib/rubocop/cop/performance/map_method_chain.rb +3 -1
- data/lib/rubocop/cop/performance/range_include.rb +2 -1
- data/lib/rubocop/cop/performance/redundant_block_call.rb +2 -0
- data/lib/rubocop/cop/performance/redundant_equality_comparison_block.rb +2 -2
- data/lib/rubocop/cop/performance/redundant_merge.rb +3 -1
- data/lib/rubocop/cop/performance/regexp_match.rb +1 -8
- data/lib/rubocop/cop/performance/reverse_each.rb +1 -1
- data/lib/rubocop/cop/performance/reverse_first.rb +5 -13
- data/lib/rubocop/cop/performance/select_map.rb +2 -6
- data/lib/rubocop/cop/performance/size.rb +4 -3
- data/lib/rubocop/cop/performance/sort_reverse.rb +5 -4
- data/lib/rubocop/cop/performance/start_with.rb +2 -1
- data/lib/rubocop/cop/performance/string_identifier_argument.rb +58 -10
- data/lib/rubocop/cop/performance/string_include.rb +5 -3
- data/lib/rubocop/cop/performance/sum.rb +11 -9
- data/lib/rubocop/cop/performance/times_map.rb +14 -2
- data/lib/rubocop/cop/performance/unfreeze_string.rb +3 -3
- data/lib/rubocop/performance/version.rb +1 -1
- metadata +14 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd286ebd5cb0d982f759a355a86281898577db559004bef9bfb53b8493a32934
|
|
4
|
+
data.tar.gz: f3e101a14918c3efa6dc657841471b22afec47d54ce70442567d54ffc3ee8ed5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1d6df8e36cbb224d892f14e7fb1eeccf34c887c9fd6e9ad302889ab71b64e48db3c3167291f210ad7e69a23f5e4720ae23ee767c4a569701d09e8fa771ede28c
|
|
7
|
+
data.tar.gz: 428da3a79195bcf8c715a1962c5bea38a08ee2973c0450b78fc24ceeb376a4f984b3d4f91efba93c799d28986dda22f711e90937738007abbd41b470a484a887
|
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# RuboCop Performance
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/rubocop-performance)
|
|
4
|
-
[](https://github.com/rubocop/rubocop-performance/actions/workflows/test.yml)
|
|
5
5
|
[](https://discord.gg/wJjWvGRDmm)
|
|
6
6
|
|
|
7
7
|
Performance optimization analysis for your projects, as an extension to [RuboCop](https://github.com/rubocop/rubocop).
|
|
@@ -53,6 +53,8 @@ $ rubocop --require rubocop-performance
|
|
|
53
53
|
### Rake task
|
|
54
54
|
|
|
55
55
|
```ruby
|
|
56
|
+
require 'rubocop/rake_task'
|
|
57
|
+
|
|
56
58
|
RuboCop::RakeTask.new do |task|
|
|
57
59
|
task.requires << 'rubocop-performance'
|
|
58
60
|
end
|
data/config/default.yml
CHANGED
|
@@ -6,7 +6,7 @@ Performance:
|
|
|
6
6
|
|
|
7
7
|
Performance/AncestorsInclude:
|
|
8
8
|
Description: 'Use `A <= B` instead of `A.ancestors.include?(B)`.'
|
|
9
|
-
Reference: 'https://github.com/
|
|
9
|
+
Reference: 'https://github.com/fastruby/fast-ruby#ancestorsinclude-vs--code'
|
|
10
10
|
Enabled: 'pending'
|
|
11
11
|
Safe: false
|
|
12
12
|
VersionAdded: '1.7'
|
|
@@ -54,10 +54,11 @@ Performance/CaseWhenSplat:
|
|
|
54
54
|
Performance/Casecmp:
|
|
55
55
|
Description: >-
|
|
56
56
|
Use `casecmp` rather than `downcase ==`, `upcase ==`, `== downcase`, or `== upcase`..
|
|
57
|
-
Reference: 'https://github.com/
|
|
58
|
-
Enabled:
|
|
57
|
+
Reference: 'https://github.com/fastruby/fast-ruby#stringcasecmp-vs--stringcasecmp-vs-stringdowncase---code'
|
|
58
|
+
Enabled: false
|
|
59
59
|
Safe: false
|
|
60
60
|
VersionAdded: '0.36'
|
|
61
|
+
VersionChanged: '1.21'
|
|
61
62
|
|
|
62
63
|
Performance/ChainArrayAllocation:
|
|
63
64
|
Description: >-
|
|
@@ -122,7 +123,7 @@ Performance/Detect:
|
|
|
122
123
|
Description: >-
|
|
123
124
|
Use `detect` instead of `select.first`, `find_all.first`, `filter.first`,
|
|
124
125
|
`select.last`, `find_all.last`, and `filter.last`.
|
|
125
|
-
Reference: 'https://github.com/
|
|
126
|
+
Reference: 'https://github.com/fastruby/fast-ruby#enumerabledetect-vs-enumerableselectfirst-code'
|
|
126
127
|
# This cop has known compatibility issues with `ActiveRecord` and other
|
|
127
128
|
# frameworks. `ActiveRecord` does not implement a `detect` method and `find`
|
|
128
129
|
# has its own meaning. Correcting `ActiveRecord` methods with this cop
|
|
@@ -145,7 +146,7 @@ Performance/DoubleStartEndWith:
|
|
|
145
146
|
|
|
146
147
|
Performance/EndWith:
|
|
147
148
|
Description: 'Use `end_with?` instead of a regex match anchored to the end of a string.'
|
|
148
|
-
Reference: 'https://github.com/
|
|
149
|
+
Reference: 'https://github.com/fastruby/fast-ruby#stringmatch-vs-stringmatch-vs-stringstart_withstringend_with-code-start-code-end'
|
|
149
150
|
# This will change to a new method call which isn't guaranteed to be on the
|
|
150
151
|
# object. Switching these methods has to be done with knowledge of the types
|
|
151
152
|
# of the variables which rubocop doesn't have.
|
|
@@ -165,7 +166,7 @@ Performance/FlatMap:
|
|
|
165
166
|
Use `Enumerable#flat_map`
|
|
166
167
|
instead of `Enumerable#map...Array#flatten(1)`
|
|
167
168
|
or `Enumerable#collect..Array#flatten(1)`.
|
|
168
|
-
Reference: 'https://github.com/
|
|
169
|
+
Reference: 'https://github.com/fastruby/fast-ruby#enumerablemaparrayflatten-vs-enumerableflat_map-code'
|
|
169
170
|
Enabled: true
|
|
170
171
|
VersionAdded: '0.30'
|
|
171
172
|
EnabledForFlattenWithoutParams: false
|
|
@@ -176,7 +177,7 @@ Performance/FlatMap:
|
|
|
176
177
|
|
|
177
178
|
Performance/InefficientHashSearch:
|
|
178
179
|
Description: 'Use `key?` or `value?` instead of `keys.include?` or `values.include?`.'
|
|
179
|
-
Reference: 'https://github.com/
|
|
180
|
+
Reference: 'https://github.com/fastruby/fast-ruby#hashkey-instead-of-hashkeysinclude-code'
|
|
180
181
|
Enabled: true
|
|
181
182
|
VersionAdded: '0.56'
|
|
182
183
|
Safe: false
|
|
@@ -201,7 +202,7 @@ Performance/MapMethodChain:
|
|
|
201
202
|
|
|
202
203
|
Performance/MethodObjectAsBlock:
|
|
203
204
|
Description: 'Use block explicitly instead of block-passing a method object.'
|
|
204
|
-
Reference: 'https://github.com/
|
|
205
|
+
Reference: 'https://github.com/fastruby/fast-ruby#normal-way-to-apply-method-vs-method-code'
|
|
205
206
|
Enabled: pending
|
|
206
207
|
VersionAdded: '1.9'
|
|
207
208
|
|
|
@@ -213,7 +214,7 @@ Performance/OpenStruct:
|
|
|
213
214
|
|
|
214
215
|
Performance/RangeInclude:
|
|
215
216
|
Description: 'Use `Range#cover?` instead of `Range#include?` (or `Range#member?`).'
|
|
216
|
-
Reference: 'https://github.com/
|
|
217
|
+
Reference: 'https://github.com/fastruby/fast-ruby#cover-vs-include-code'
|
|
217
218
|
Enabled: true
|
|
218
219
|
VersionAdded: '0.36'
|
|
219
220
|
VersionChanged: '1.7'
|
|
@@ -221,7 +222,7 @@ Performance/RangeInclude:
|
|
|
221
222
|
|
|
222
223
|
Performance/RedundantBlockCall:
|
|
223
224
|
Description: 'Use `yield` instead of `block.call`.'
|
|
224
|
-
Reference: 'https://github.com/
|
|
225
|
+
Reference: 'https://github.com/fastruby/fast-ruby#proccall-and-block-arguments-vs-yieldcode'
|
|
225
226
|
Enabled: true
|
|
226
227
|
VersionAdded: '0.36'
|
|
227
228
|
|
|
@@ -244,7 +245,7 @@ Performance/RedundantMatch:
|
|
|
244
245
|
|
|
245
246
|
Performance/RedundantMerge:
|
|
246
247
|
Description: 'Use Hash#[]=, rather than Hash#merge! with a single key-value pair.'
|
|
247
|
-
Reference: 'https://github.com/
|
|
248
|
+
Reference: 'https://github.com/fastruby/fast-ruby#hashmerge-vs-hash-code'
|
|
248
249
|
Enabled: true
|
|
249
250
|
Safe: false
|
|
250
251
|
VersionAdded: '0.36'
|
|
@@ -271,13 +272,13 @@ Performance/RegexpMatch:
|
|
|
271
272
|
Description: >-
|
|
272
273
|
Use `match?` instead of `Regexp#match`, `String#match`, `Symbol#match`,
|
|
273
274
|
`Regexp#===`, or `=~` when `MatchData` is not used.
|
|
274
|
-
Reference: 'https://github.com/
|
|
275
|
+
Reference: 'https://github.com/fastruby/fast-ruby#regexp-vs-regexpmatch-vs-regexpmatch-vs-stringmatch-vs-string-vs-stringmatch-code-'
|
|
275
276
|
Enabled: true
|
|
276
277
|
VersionAdded: '0.47'
|
|
277
278
|
|
|
278
279
|
Performance/ReverseEach:
|
|
279
280
|
Description: 'Use `reverse_each` instead of `reverse.each`.'
|
|
280
|
-
Reference: 'https://github.com/
|
|
281
|
+
Reference: 'https://github.com/fastruby/fast-ruby#enumerablereverseeach-vs-enumerablereverse_each-code'
|
|
281
282
|
Enabled: true
|
|
282
283
|
VersionAdded: '0.30'
|
|
283
284
|
|
|
@@ -295,7 +296,7 @@ Performance/Size:
|
|
|
295
296
|
Description: >-
|
|
296
297
|
Use `size` instead of `count` for counting
|
|
297
298
|
the number of elements in `Array` and `Hash`.
|
|
298
|
-
Reference: 'https://github.com/
|
|
299
|
+
Reference: 'https://github.com/fastruby/fast-ruby#arraylength-vs-arraysize-vs-arraycount-code'
|
|
299
300
|
Enabled: true
|
|
300
301
|
VersionAdded: '0.30'
|
|
301
302
|
|
|
@@ -306,13 +307,13 @@ Performance/SortReverse:
|
|
|
306
307
|
|
|
307
308
|
Performance/Squeeze:
|
|
308
309
|
Description: "Use `squeeze('a')` instead of `gsub(/a+/, 'a')`."
|
|
309
|
-
Reference: 'https://github.com/
|
|
310
|
+
Reference: 'https://github.com/fastruby/fast-ruby#remove-extra-spaces-or-other-contiguous-characters-code'
|
|
310
311
|
Enabled: 'pending'
|
|
311
312
|
VersionAdded: '1.7'
|
|
312
313
|
|
|
313
314
|
Performance/StartWith:
|
|
314
315
|
Description: 'Use `start_with?` instead of a regex match anchored to the beginning of a string.'
|
|
315
|
-
Reference: 'https://github.com/
|
|
316
|
+
Reference: 'https://github.com/fastruby/fast-ruby#stringmatch-vs-stringmatch-vs-stringstart_withstringend_with-code-start-code-end'
|
|
316
317
|
# This will change to a new method call which isn't guaranteed to be on the
|
|
317
318
|
# object. Switching these methods has to be done with knowledge of the types
|
|
318
319
|
# of the variables which rubocop doesn't have.
|
|
@@ -339,7 +340,7 @@ Performance/StringReplacement:
|
|
|
339
340
|
Use `tr` instead of `gsub` when you are replacing the same
|
|
340
341
|
number of characters. Use `delete` instead of `gsub` when
|
|
341
342
|
you are deleting characters.
|
|
342
|
-
Reference: 'https://github.com/
|
|
343
|
+
Reference: 'https://github.com/fastruby/fast-ruby#stringgsub-vs-stringtr-code'
|
|
343
344
|
Enabled: true
|
|
344
345
|
VersionAdded: '0.33'
|
|
345
346
|
|
|
@@ -9,14 +9,14 @@ module RuboCop
|
|
|
9
9
|
|
|
10
10
|
def_node_matcher :sort_with_block?, <<~PATTERN
|
|
11
11
|
(block
|
|
12
|
-
$(
|
|
12
|
+
$(call _ :sort)
|
|
13
13
|
(args (arg $_a) (arg $_b))
|
|
14
14
|
$send)
|
|
15
15
|
PATTERN
|
|
16
16
|
|
|
17
17
|
def_node_matcher :sort_with_numblock?, <<~PATTERN
|
|
18
18
|
(numblock
|
|
19
|
-
$(
|
|
19
|
+
$(call _ :sort)
|
|
20
20
|
$_arg_count
|
|
21
21
|
$send)
|
|
22
22
|
PATTERN
|
|
@@ -6,6 +6,12 @@ module RuboCop
|
|
|
6
6
|
# Identifies places where a case-insensitive string comparison
|
|
7
7
|
# can better be implemented using `casecmp`.
|
|
8
8
|
#
|
|
9
|
+
# This cop is disabled by default because `String#casecmp` only works with
|
|
10
|
+
# ASCII characters. See https://github.com/rubocop/rubocop/issues/9753.
|
|
11
|
+
#
|
|
12
|
+
# If you are working only with ASCII characters, then this cop can be
|
|
13
|
+
# safely enabled.
|
|
14
|
+
#
|
|
9
15
|
# @safety
|
|
10
16
|
# This cop is unsafe because `String#casecmp` and `String#casecmp?` behave
|
|
11
17
|
# differently when using Non-ASCII characters.
|
|
@@ -19,8 +19,6 @@ module RuboCop
|
|
|
19
19
|
# array.map! { |x| x.downcase }
|
|
20
20
|
# array
|
|
21
21
|
class ChainArrayAllocation < Base
|
|
22
|
-
include RangeHelp
|
|
23
|
-
|
|
24
22
|
# These methods return a new array but only sometimes. They must be
|
|
25
23
|
# called with an argument. For example:
|
|
26
24
|
#
|
|
@@ -54,7 +52,7 @@ module RuboCop
|
|
|
54
52
|
def_node_matcher :chain_array_allocation?, <<~PATTERN
|
|
55
53
|
(send {
|
|
56
54
|
(send _ $%RETURN_NEW_ARRAY_WHEN_ARGS {int lvar ivar cvar gvar send})
|
|
57
|
-
(block (send _ $%ALWAYS_RETURNS_NEW_ARRAY) ...)
|
|
55
|
+
({block numblock} (send _ $%ALWAYS_RETURNS_NEW_ARRAY) ...)
|
|
58
56
|
(send _ $%RETURNS_NEW_ARRAY ...)
|
|
59
57
|
} $%HAS_MUTATION_ALTERNATIVE ...)
|
|
60
58
|
PATTERN
|
|
@@ -62,12 +60,21 @@ module RuboCop
|
|
|
62
60
|
def on_send(node)
|
|
63
61
|
chain_array_allocation?(node) do |fm, sm|
|
|
64
62
|
return if node.each_descendant(:send).any? { |descendant| descendant.method?(:lazy) }
|
|
63
|
+
return if node.method?(:select) && !enumerable_select_method?(node.receiver)
|
|
65
64
|
|
|
66
|
-
range =
|
|
65
|
+
range = node.loc.selector.begin.join(node.source_range.end)
|
|
67
66
|
|
|
68
67
|
add_offense(range, message: format(MSG, method: fm, second_method: sm))
|
|
69
68
|
end
|
|
70
69
|
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def enumerable_select_method?(node)
|
|
74
|
+
# NOTE: `QueryMethods#select` in Rails accepts positional arguments, whereas `Enumerable#select` does not.
|
|
75
|
+
# This difference can be utilized to reduce the knowledge requirements related to `select`.
|
|
76
|
+
(node.block_type? || node.numblock_type?) && node.send_node.arguments.empty?
|
|
77
|
+
end
|
|
71
78
|
end
|
|
72
79
|
end
|
|
73
80
|
end
|
|
@@ -9,8 +9,7 @@ module RuboCop
|
|
|
9
9
|
#
|
|
10
10
|
# @safety
|
|
11
11
|
# This cop is unsafe because it has known compatibility issues with `ActiveRecord` and other
|
|
12
|
-
# frameworks.
|
|
13
|
-
# `ActiveRecord` will ignore the block that is passed to `count`.
|
|
12
|
+
# frameworks. Before Rails 5.1, `ActiveRecord` will ignore the block that is passed to `count`.
|
|
14
13
|
# Other methods, such as `select`, will convert the association to an
|
|
15
14
|
# array and then run the block on the array. A simple work around to
|
|
16
15
|
# make `count` work with a block is to call `to_a.count {...}`.
|
|
@@ -55,8 +54,8 @@ module RuboCop
|
|
|
55
54
|
|
|
56
55
|
def_node_matcher :count_candidate?, <<~PATTERN
|
|
57
56
|
{
|
|
58
|
-
(
|
|
59
|
-
(
|
|
57
|
+
(call (block $(call _ ${:select :filter :find_all :reject}) ...) ${:count :length :size})
|
|
58
|
+
(call $(call _ ${:select :filter :find_all :reject} (:block_pass _)) ${:count :length :size})
|
|
60
59
|
}
|
|
61
60
|
PATTERN
|
|
62
61
|
|
|
@@ -73,6 +72,7 @@ module RuboCop
|
|
|
73
72
|
end
|
|
74
73
|
end
|
|
75
74
|
end
|
|
75
|
+
alias on_csend on_send
|
|
76
76
|
|
|
77
77
|
private
|
|
78
78
|
|
|
@@ -101,7 +101,7 @@ module RuboCop
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
def negate_reject(corrector, node)
|
|
104
|
-
if node.receiver.
|
|
104
|
+
if node.receiver.call_type?
|
|
105
105
|
negate_block_pass_reject(corrector, node)
|
|
106
106
|
else
|
|
107
107
|
negate_block_reject(corrector, node)
|
|
@@ -56,7 +56,8 @@ module RuboCop
|
|
|
56
56
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
|
57
57
|
{(call $!nil? {:match :=~ :match?} (regexp (str $#literal_at_end?) (regopt)))
|
|
58
58
|
(send (regexp (str $#literal_at_end?) (regopt)) {:match :match?} $_)
|
|
59
|
-
(match-with-lvasgn (regexp (str $#literal_at_end?) (regopt)) $_)
|
|
59
|
+
({send match-with-lvasgn} (regexp (str $#literal_at_end?) (regopt)) $_)
|
|
60
|
+
(send (regexp (str $#literal_at_end?) (regopt)) :=~ $_)}
|
|
60
61
|
PATTERN
|
|
61
62
|
|
|
62
63
|
def on_send(node)
|
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
|
50
50
|
RESTRICT_ON_SEND = %i[count length size].freeze
|
|
51
51
|
|
|
52
52
|
def_node_matcher :counter, <<~MATCHER
|
|
53
|
-
(
|
|
53
|
+
(call ${array hash str sym} {:count :length :size} $...)
|
|
54
54
|
MATCHER
|
|
55
55
|
|
|
56
56
|
def on_send(node)
|
|
@@ -62,6 +62,7 @@ module RuboCop
|
|
|
62
62
|
add_offense(node)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
|
+
alias on_csend on_send
|
|
65
66
|
|
|
66
67
|
private
|
|
67
68
|
|
|
@@ -26,10 +26,10 @@ module RuboCop
|
|
|
26
26
|
'multiple levels.'
|
|
27
27
|
|
|
28
28
|
def_node_matcher :flat_map_candidate?, <<~PATTERN
|
|
29
|
-
(
|
|
29
|
+
(call
|
|
30
30
|
{
|
|
31
|
-
$(block (
|
|
32
|
-
$(
|
|
31
|
+
$(block (call _ ${:collect :map}) ...)
|
|
32
|
+
$(call _ ${:collect :map} (block_pass _))
|
|
33
33
|
}
|
|
34
34
|
${:flatten :flatten!}
|
|
35
35
|
$...
|
|
@@ -46,6 +46,7 @@ module RuboCop
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
+
alias on_csend on_send
|
|
49
50
|
|
|
50
51
|
private
|
|
51
52
|
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
|
45
45
|
RESTRICT_ON_SEND = %i[include?].freeze
|
|
46
46
|
|
|
47
47
|
def_node_matcher :inefficient_include?, <<~PATTERN
|
|
48
|
-
(
|
|
48
|
+
(call (call $_ {:keys :values}) :include? _)
|
|
49
49
|
PATTERN
|
|
50
50
|
|
|
51
51
|
def on_send(node)
|
|
@@ -89,7 +89,7 @@ module RuboCop
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def correct_argument(node)
|
|
92
|
-
node.
|
|
92
|
+
node.first_argument.source
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def correct_hash_expression(node)
|
|
@@ -8,8 +8,9 @@ module RuboCop
|
|
|
8
8
|
# This cop identifies places where `map { ... }.compact` can be replaced by `filter_map`.
|
|
9
9
|
#
|
|
10
10
|
# @safety
|
|
11
|
-
# This cop's autocorrection is unsafe because `map { ... }.compact`
|
|
12
|
-
#
|
|
11
|
+
# This cop's autocorrection is unsafe because `map { ... }.compact` might yield
|
|
12
|
+
# different results than `filter_map`. As illustrated in the example, `filter_map`
|
|
13
|
+
# also filters out falsy values, while `compact` only gets rid of `nil`.
|
|
13
14
|
#
|
|
14
15
|
# [source,ruby]
|
|
15
16
|
# ----
|
|
@@ -39,11 +40,11 @@ module RuboCop
|
|
|
39
40
|
|
|
40
41
|
def_node_matcher :map_compact, <<~PATTERN
|
|
41
42
|
{
|
|
42
|
-
(
|
|
43
|
+
(call
|
|
43
44
|
$(call _ {:map :collect}
|
|
44
45
|
(block_pass
|
|
45
46
|
(sym _))) _)
|
|
46
|
-
(
|
|
47
|
+
(call
|
|
47
48
|
(block
|
|
48
49
|
$(call _ {:map :collect})
|
|
49
50
|
(args ...) _) _)
|
|
@@ -68,6 +68,7 @@ module RuboCop
|
|
|
68
68
|
|
|
69
69
|
private
|
|
70
70
|
|
|
71
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
71
72
|
def find_begin_of_chained_map_method(node, map_args)
|
|
72
73
|
return unless (chained_map_method = node.receiver)
|
|
73
74
|
return if !chained_map_method.call_type? || !RESTRICT_ON_SEND.include?(chained_map_method.method_name)
|
|
@@ -77,10 +78,11 @@ module RuboCop
|
|
|
77
78
|
|
|
78
79
|
receiver = chained_map_method.receiver
|
|
79
80
|
|
|
80
|
-
return chained_map_method unless receiver
|
|
81
|
+
return chained_map_method unless receiver&.call_type? && block_pass_with_symbol_arg?(receiver.first_argument)
|
|
81
82
|
|
|
82
83
|
find_begin_of_chained_map_method(chained_map_method, map_args)
|
|
83
84
|
end
|
|
85
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
84
86
|
end
|
|
85
87
|
end
|
|
86
88
|
end
|
|
@@ -38,7 +38,7 @@ module RuboCop
|
|
|
38
38
|
# (We don't even catch it if the Range is in double parens)
|
|
39
39
|
|
|
40
40
|
def_node_matcher :range_include, <<~PATTERN
|
|
41
|
-
(
|
|
41
|
+
(call {irange erange (begin {irange erange})} ${:include? :member?} ...)
|
|
42
42
|
PATTERN
|
|
43
43
|
|
|
44
44
|
def on_send(node)
|
|
@@ -50,6 +50,7 @@ module RuboCop
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
|
+
alias on_csend on_send
|
|
53
54
|
end
|
|
54
55
|
end
|
|
55
56
|
end
|
|
@@ -63,8 +63,8 @@ module RuboCop
|
|
|
63
63
|
return unless TARGET_METHODS.include?(node.method_name)
|
|
64
64
|
return unless one_block_argument?(node.arguments)
|
|
65
65
|
|
|
66
|
-
block_argument = node.
|
|
67
|
-
block_body = node.body
|
|
66
|
+
block_argument = node.first_argument
|
|
67
|
+
return unless (block_body = node.body)
|
|
68
68
|
return unless use_equality_comparison_block?(block_body)
|
|
69
69
|
return if same_block_argument_and_is_a_argument?(block_body, block_argument)
|
|
70
70
|
return unless (new_argument = new_argument(block_argument, block_body))
|
|
@@ -130,7 +130,9 @@ module RuboCop
|
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
def rewrite_with_modifier(node, parent, new_source)
|
|
133
|
-
|
|
133
|
+
# FIXME: `|| 2` can be removed when support is limited to RuboCop 1.44 or higher.
|
|
134
|
+
# https://github.com/rubocop/rubocop/commit/02d1e5b
|
|
135
|
+
indent = ' ' * (configured_indentation_width || 2)
|
|
134
136
|
padding = "\n#{indent + leading_spaces(node)}"
|
|
135
137
|
new_source.gsub!("\n", padding)
|
|
136
138
|
|
|
@@ -248,7 +248,7 @@ module RuboCop
|
|
|
248
248
|
end
|
|
249
249
|
|
|
250
250
|
def correct_operator(corrector, recv, arg, oper = nil)
|
|
251
|
-
op_range =
|
|
251
|
+
op_range = recv.source_range.end.join(arg.source_range.begin)
|
|
252
252
|
|
|
253
253
|
replace_with_match_predicate_method(corrector, recv, arg, op_range)
|
|
254
254
|
|
|
@@ -271,13 +271,6 @@ module RuboCop
|
|
|
271
271
|
corrector.replace(recv, arg.source)
|
|
272
272
|
corrector.replace(arg, recv.source)
|
|
273
273
|
end
|
|
274
|
-
|
|
275
|
-
def correction_range(recv, arg)
|
|
276
|
-
buffer = processed_source.buffer
|
|
277
|
-
op_begin_pos = recv.source_range.end_pos
|
|
278
|
-
op_end_pos = arg.source_range.begin_pos
|
|
279
|
-
Parser::Source::Range.new(buffer, op_begin_pos, op_end_pos)
|
|
280
|
-
end
|
|
281
274
|
end
|
|
282
275
|
end
|
|
283
276
|
end
|
|
@@ -24,13 +24,13 @@ module RuboCop
|
|
|
24
24
|
RESTRICT_ON_SEND = %i[first].freeze
|
|
25
25
|
|
|
26
26
|
def_node_matcher :reverse_first_candidate?, <<~PATTERN
|
|
27
|
-
(
|
|
27
|
+
(call $(call _ :reverse) :first (int _)?)
|
|
28
28
|
PATTERN
|
|
29
29
|
|
|
30
30
|
def on_send(node)
|
|
31
31
|
reverse_first_candidate?(node) do |receiver|
|
|
32
32
|
range = correction_range(receiver, node)
|
|
33
|
-
message = build_message(node)
|
|
33
|
+
message = build_message(node, range)
|
|
34
34
|
|
|
35
35
|
add_offense(range, message: message) do |corrector|
|
|
36
36
|
replacement = build_good_method(node)
|
|
@@ -47,27 +47,19 @@ module RuboCop
|
|
|
47
47
|
range_between(receiver.loc.selector.begin_pos, node.source_range.end_pos)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
def build_message(node)
|
|
50
|
+
def build_message(node, range)
|
|
51
51
|
good_method = build_good_method(node)
|
|
52
|
-
bad_method =
|
|
52
|
+
bad_method = range.source
|
|
53
53
|
format(MSG, good_method: good_method, bad_method: bad_method)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def build_good_method(node)
|
|
57
57
|
if node.arguments?
|
|
58
|
-
"last(#{node.
|
|
58
|
+
"last(#{node.first_argument.source})#{node.loc.dot.source}reverse"
|
|
59
59
|
else
|
|
60
60
|
'last'
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
|
-
|
|
64
|
-
def build_bad_method(node)
|
|
65
|
-
if node.arguments?
|
|
66
|
-
"reverse.first(#{node.arguments.first.source})"
|
|
67
|
-
else
|
|
68
|
-
'reverse.first'
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
63
|
end
|
|
72
64
|
end
|
|
73
65
|
end
|
|
@@ -24,10 +24,6 @@ module RuboCop
|
|
|
24
24
|
MSG = 'Use `filter_map` instead of `%<method_name>s.map`.'
|
|
25
25
|
RESTRICT_ON_SEND = %i[select filter].freeze
|
|
26
26
|
|
|
27
|
-
def_node_matcher :bad_method?, <<~PATTERN
|
|
28
|
-
(send nil? :bad_method ...)
|
|
29
|
-
PATTERN
|
|
30
|
-
|
|
31
27
|
def on_send(node)
|
|
32
28
|
return if (first_argument = node.first_argument) && !first_argument.block_pass_type?
|
|
33
29
|
return unless (send_node = map_method_candidate(node))
|
|
@@ -45,9 +41,9 @@ module RuboCop
|
|
|
45
41
|
def map_method_candidate(node)
|
|
46
42
|
return unless (parent = node.parent)
|
|
47
43
|
|
|
48
|
-
if parent.block_type? && parent.parent&.
|
|
44
|
+
if parent.block_type? && parent.parent&.call_type?
|
|
49
45
|
parent.parent
|
|
50
|
-
elsif parent.
|
|
46
|
+
elsif parent.call_type?
|
|
51
47
|
parent
|
|
52
48
|
end
|
|
53
49
|
end
|
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
|
43
43
|
def_node_matcher :array?, <<~PATTERN
|
|
44
44
|
{
|
|
45
45
|
[!nil? array_type?]
|
|
46
|
-
(
|
|
46
|
+
(call _ :to_a)
|
|
47
47
|
(send (const nil? :Array) :[] _)
|
|
48
48
|
(send nil? :Array _)
|
|
49
49
|
}
|
|
@@ -52,14 +52,14 @@ module RuboCop
|
|
|
52
52
|
def_node_matcher :hash?, <<~PATTERN
|
|
53
53
|
{
|
|
54
54
|
[!nil? hash_type?]
|
|
55
|
-
(
|
|
55
|
+
(call _ :to_h)
|
|
56
56
|
(send (const nil? :Hash) :[] _)
|
|
57
57
|
(send nil? :Hash _)
|
|
58
58
|
}
|
|
59
59
|
PATTERN
|
|
60
60
|
|
|
61
61
|
def_node_matcher :count?, <<~PATTERN
|
|
62
|
-
(
|
|
62
|
+
(call {#array? #hash?} :count)
|
|
63
63
|
PATTERN
|
|
64
64
|
|
|
65
65
|
def on_send(node)
|
|
@@ -69,6 +69,7 @@ module RuboCop
|
|
|
69
69
|
corrector.replace(node.loc.selector, 'size')
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
|
+
alias on_csend on_send
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
75
|
end
|
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
|
17
17
|
include SortBlock
|
|
18
18
|
extend AutoCorrector
|
|
19
19
|
|
|
20
|
-
MSG = 'Use `
|
|
20
|
+
MSG = 'Use `%<prefer>s` instead.'
|
|
21
21
|
|
|
22
22
|
def on_block(node)
|
|
23
23
|
sort_with_block?(node) do |send, var_a, var_b, body|
|
|
@@ -41,11 +41,12 @@ module RuboCop
|
|
|
41
41
|
|
|
42
42
|
def register_offense(send, node)
|
|
43
43
|
range = sort_range(send, node)
|
|
44
|
+
prefer = "sort#{send.loc.dot.source}reverse"
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
replacement = 'sort.reverse'
|
|
46
|
+
message = format(MSG, prefer: prefer)
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
add_offense(range, message: message) do |corrector|
|
|
49
|
+
corrector.replace(range, prefer)
|
|
49
50
|
end
|
|
50
51
|
end
|
|
51
52
|
end
|
|
@@ -56,7 +56,8 @@ module RuboCop
|
|
|
56
56
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
|
57
57
|
{(call $!nil? {:match :=~ :match?} (regexp (str $#literal_at_start?) (regopt)))
|
|
58
58
|
(send (regexp (str $#literal_at_start?) (regopt)) {:match :match?} $_)
|
|
59
|
-
(match-with-lvasgn (regexp (str $#literal_at_start?) (regopt)) $_)
|
|
59
|
+
(match-with-lvasgn (regexp (str $#literal_at_start?) (regopt)) $_)
|
|
60
|
+
(send (regexp (str $#literal_at_start?) (regopt)) :=~ $_)}
|
|
60
61
|
PATTERN
|
|
61
62
|
|
|
62
63
|
def on_send(node)
|
|
@@ -16,11 +16,19 @@ module RuboCop
|
|
|
16
16
|
# send('do_something')
|
|
17
17
|
# attr_accessor 'do_something'
|
|
18
18
|
# instance_variable_get('@ivar')
|
|
19
|
+
# respond_to?("string_#{interpolation}")
|
|
19
20
|
#
|
|
20
21
|
# # good
|
|
21
22
|
# send(:do_something)
|
|
22
23
|
# attr_accessor :do_something
|
|
23
24
|
# instance_variable_get(:@ivar)
|
|
25
|
+
# respond_to?(:"string_#{interpolation}")
|
|
26
|
+
#
|
|
27
|
+
# # good - these methods don't support namespaced symbols
|
|
28
|
+
# const_get("#{module_path}::Base")
|
|
29
|
+
# const_source_location("#{module_path}::Base")
|
|
30
|
+
# const_defined?("#{module_path}::Base")
|
|
31
|
+
#
|
|
24
32
|
#
|
|
25
33
|
class StringIdentifierArgument < Base
|
|
26
34
|
extend AutoCorrector
|
|
@@ -32,33 +40,73 @@ module RuboCop
|
|
|
32
40
|
protected public public_constant module_function
|
|
33
41
|
].freeze
|
|
34
42
|
|
|
43
|
+
INTERPOLATION_IGNORE_METHODS = %i[const_get const_source_location const_defined?].freeze
|
|
44
|
+
|
|
45
|
+
TWO_ARGUMENTS_METHOD = :alias_method
|
|
46
|
+
MULTIPLE_ARGUMENTS_METHODS = %i[
|
|
47
|
+
attr_accessor attr_reader attr_writer private private_constant
|
|
48
|
+
protected public public_constant module_function
|
|
49
|
+
].freeze
|
|
50
|
+
|
|
35
51
|
# NOTE: `attr` method is not included in this list as it can cause false positives in Nokogiri API.
|
|
36
52
|
# And `attr` may not be used because `Style/Attr` registers an offense.
|
|
37
53
|
# https://github.com/rubocop/rubocop-performance/issues/278
|
|
38
54
|
RESTRICT_ON_SEND = (%i[
|
|
39
|
-
class_variable_defined?
|
|
55
|
+
class_variable_defined? const_set
|
|
40
56
|
define_method instance_method method_defined? private_class_method? private_method_defined?
|
|
41
57
|
protected_method_defined? public_class_method public_instance_method public_method_defined?
|
|
42
58
|
remove_class_variable remove_method undef_method class_variable_get class_variable_set
|
|
43
59
|
deprecate_constant remove_const ruby2_keywords define_singleton_method instance_variable_defined?
|
|
44
60
|
instance_variable_get instance_variable_set method public_method public_send remove_instance_variable
|
|
45
61
|
respond_to? send singleton_method __send__
|
|
46
|
-
] + COMMAND_METHODS).freeze
|
|
62
|
+
] + COMMAND_METHODS + INTERPOLATION_IGNORE_METHODS).freeze
|
|
47
63
|
|
|
48
64
|
def on_send(node)
|
|
49
65
|
return if COMMAND_METHODS.include?(node.method_name) && node.receiver
|
|
50
|
-
return unless (first_argument = node.first_argument)
|
|
51
|
-
return unless first_argument.str_type?
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
string_arguments(node).each do |string_argument|
|
|
68
|
+
string_argument_value = string_argument.value
|
|
69
|
+
next if string_argument_value.include?(' ') || string_argument_value.include?('::')
|
|
70
|
+
|
|
71
|
+
register_offense(string_argument, string_argument_value)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
55
76
|
|
|
56
|
-
|
|
77
|
+
def string_arguments(node)
|
|
78
|
+
arguments = if node.method?(TWO_ARGUMENTS_METHOD)
|
|
79
|
+
[node.first_argument, node.arguments[1]]
|
|
80
|
+
elsif MULTIPLE_ARGUMENTS_METHODS.include?(node.method_name)
|
|
81
|
+
node.arguments
|
|
82
|
+
else
|
|
83
|
+
[node.first_argument]
|
|
84
|
+
end
|
|
57
85
|
|
|
58
|
-
|
|
86
|
+
arguments.compact.filter { |argument| string_argument_compatible?(argument, node) }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def string_argument_compatible?(argument, node)
|
|
90
|
+
return true if argument.str_type?
|
|
91
|
+
|
|
92
|
+
argument.dstr_type? && INTERPOLATION_IGNORE_METHODS.none? { |method| node.method?(method) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def register_offense(argument, argument_value)
|
|
96
|
+
replacement = argument_replacement(argument, argument_value)
|
|
97
|
+
|
|
98
|
+
message = format(MSG, symbol_arg: replacement, string_arg: argument.source)
|
|
99
|
+
|
|
100
|
+
add_offense(argument, message: message) do |corrector|
|
|
101
|
+
corrector.replace(argument, replacement)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
59
104
|
|
|
60
|
-
|
|
61
|
-
|
|
105
|
+
def argument_replacement(node, value)
|
|
106
|
+
if node.str_type?
|
|
107
|
+
value.to_sym.inspect
|
|
108
|
+
else
|
|
109
|
+
":\"#{value.to_sym}\""
|
|
62
110
|
end
|
|
63
111
|
end
|
|
64
112
|
end
|
|
@@ -16,6 +16,7 @@ module RuboCop
|
|
|
16
16
|
# /ab/ =~ str
|
|
17
17
|
# str.match(/ab/)
|
|
18
18
|
# /ab/.match(str)
|
|
19
|
+
# /ab/ === str
|
|
19
20
|
#
|
|
20
21
|
# # good
|
|
21
22
|
# str.include?('ab')
|
|
@@ -23,12 +24,13 @@ module RuboCop
|
|
|
23
24
|
extend AutoCorrector
|
|
24
25
|
|
|
25
26
|
MSG = 'Use `%<negation>sString#include?` instead of a regex match with literal-only pattern.'
|
|
26
|
-
RESTRICT_ON_SEND = %i[match =~ !~ match?].freeze
|
|
27
|
+
RESTRICT_ON_SEND = %i[match =~ !~ match? ===].freeze
|
|
27
28
|
|
|
28
29
|
def_node_matcher :redundant_regex?, <<~PATTERN
|
|
29
30
|
{(call $!nil? {:match :=~ :!~ :match?} (regexp (str $#literal?) (regopt)))
|
|
30
|
-
(send (regexp (str $#literal?) (regopt)) {:match :match?} $_)
|
|
31
|
-
(match-with-lvasgn (regexp (str $#literal?) (regopt)) $_)
|
|
31
|
+
(send (regexp (str $#literal?) (regopt)) {:match :match? :===} $_)
|
|
32
|
+
(match-with-lvasgn (regexp (str $#literal?) (regopt)) $_)
|
|
33
|
+
(send (regexp (str $#literal?) (regopt)) :=~ $_)}
|
|
32
34
|
PATTERN
|
|
33
35
|
|
|
34
36
|
# rubocop:disable Metrics/AbcSize
|
|
@@ -80,21 +80,21 @@ module RuboCop
|
|
|
80
80
|
RESTRICT_ON_SEND = %i[inject reduce sum].freeze
|
|
81
81
|
|
|
82
82
|
def_node_matcher :sum_candidate?, <<~PATTERN
|
|
83
|
-
(
|
|
83
|
+
(call _ ${:inject :reduce} $_init ? ${(sym :+) (block_pass (sym :+))})
|
|
84
84
|
PATTERN
|
|
85
85
|
|
|
86
86
|
def_node_matcher :sum_map_candidate?, <<~PATTERN
|
|
87
|
-
(
|
|
87
|
+
(call
|
|
88
88
|
{
|
|
89
|
-
(block $(
|
|
90
|
-
$(
|
|
89
|
+
(block $(call _ {:map :collect}) ...)
|
|
90
|
+
$(call _ {:map :collect} (block_pass _))
|
|
91
91
|
}
|
|
92
92
|
:sum $_init ?)
|
|
93
93
|
PATTERN
|
|
94
94
|
|
|
95
95
|
def_node_matcher :sum_with_block_candidate?, <<~PATTERN
|
|
96
96
|
(block
|
|
97
|
-
$(
|
|
97
|
+
$(call _ {:inject :reduce} $_init ?)
|
|
98
98
|
(args (arg $_acc) (arg $_elem))
|
|
99
99
|
$send)
|
|
100
100
|
PATTERN
|
|
@@ -110,6 +110,7 @@ module RuboCop
|
|
|
110
110
|
handle_sum_candidate(node)
|
|
111
111
|
handle_sum_map_candidate(node)
|
|
112
112
|
end
|
|
113
|
+
alias on_csend on_send
|
|
113
114
|
|
|
114
115
|
def on_block(node)
|
|
115
116
|
sum_with_block_candidate?(node) do |send, init, var_acc, var_elem, body|
|
|
@@ -143,7 +144,7 @@ module RuboCop
|
|
|
143
144
|
sum_map_candidate?(node) do |map, init|
|
|
144
145
|
next if node.block_literal? || node.block_argument?
|
|
145
146
|
|
|
146
|
-
message = build_sum_map_message(map
|
|
147
|
+
message = build_sum_map_message(map, init)
|
|
147
148
|
|
|
148
149
|
add_offense(sum_map_range(map, node), message: message) do |corrector|
|
|
149
150
|
autocorrect_sum_map(corrector, node, map, init)
|
|
@@ -178,7 +179,7 @@ module RuboCop
|
|
|
178
179
|
|
|
179
180
|
corrector.remove(sum_range)
|
|
180
181
|
|
|
181
|
-
dot =
|
|
182
|
+
dot = map.loc.dot&.source || ''
|
|
182
183
|
corrector.replace(map_range, "#{dot}#{replacement}")
|
|
183
184
|
end
|
|
184
185
|
|
|
@@ -205,10 +206,11 @@ module RuboCop
|
|
|
205
206
|
format(msg, good_method: good_method, bad_method: bad_method)
|
|
206
207
|
end
|
|
207
208
|
|
|
208
|
-
def build_sum_map_message(
|
|
209
|
+
def build_sum_map_message(send_node, init)
|
|
209
210
|
sum_method = build_good_method(init)
|
|
210
211
|
good_method = "#{sum_method} { ... }"
|
|
211
|
-
|
|
212
|
+
dot = send_node.loc.dot&.source || '.'
|
|
213
|
+
bad_method = "#{send_node.method_name} { ... }#{dot}#{sum_method}"
|
|
212
214
|
format(MSG, good_method: good_method, bad_method: bad_method)
|
|
213
215
|
end
|
|
214
216
|
|
|
@@ -39,6 +39,7 @@ module RuboCop
|
|
|
39
39
|
def on_send(node)
|
|
40
40
|
check(node)
|
|
41
41
|
end
|
|
42
|
+
alias on_csend on_send
|
|
42
43
|
|
|
43
44
|
def on_block(node)
|
|
44
45
|
check(node)
|
|
@@ -49,6 +50,8 @@ module RuboCop
|
|
|
49
50
|
|
|
50
51
|
def check(node)
|
|
51
52
|
times_map_call(node) do |map_or_collect, count|
|
|
53
|
+
next unless handleable_receiver?(node)
|
|
54
|
+
|
|
52
55
|
add_offense(node, message: message(map_or_collect, count)) do |corrector|
|
|
53
56
|
replacement = "Array.new(#{count.source}#{map_or_collect.arguments.map { |arg| ", #{arg.source}" }.join})"
|
|
54
57
|
|
|
@@ -57,6 +60,13 @@ module RuboCop
|
|
|
57
60
|
end
|
|
58
61
|
end
|
|
59
62
|
|
|
63
|
+
def handleable_receiver?(node)
|
|
64
|
+
receiver = node.receiver.receiver
|
|
65
|
+
return true if receiver.literal? && (receiver.int_type? || receiver.float_type?)
|
|
66
|
+
|
|
67
|
+
node.receiver.dot?
|
|
68
|
+
end
|
|
69
|
+
|
|
60
70
|
def message(map_or_collect, count)
|
|
61
71
|
template = if count.literal?
|
|
62
72
|
"#{MESSAGE}."
|
|
@@ -67,8 +77,10 @@ module RuboCop
|
|
|
67
77
|
end
|
|
68
78
|
|
|
69
79
|
def_node_matcher :times_map_call, <<~PATTERN
|
|
70
|
-
{
|
|
71
|
-
|
|
80
|
+
{
|
|
81
|
+
({block numblock} $(call (call $!nil? :times) {:map :collect}) ...)
|
|
82
|
+
$(call (call $!nil? :times) {:map :collect} (block_pass ...))
|
|
83
|
+
}
|
|
72
84
|
PATTERN
|
|
73
85
|
end
|
|
74
86
|
end
|
|
@@ -15,8 +15,8 @@ module RuboCop
|
|
|
15
15
|
#
|
|
16
16
|
# @example
|
|
17
17
|
# # bad
|
|
18
|
-
# ''.dup
|
|
19
|
-
# "something".dup
|
|
18
|
+
# ''.dup # when Ruby 3.2 or lower
|
|
19
|
+
# "something".dup # when Ruby 3.2 or lower
|
|
20
20
|
# String.new
|
|
21
21
|
# String.new('')
|
|
22
22
|
# String.new('something')
|
|
@@ -45,7 +45,7 @@ module RuboCop
|
|
|
45
45
|
PATTERN
|
|
46
46
|
|
|
47
47
|
def on_send(node)
|
|
48
|
-
return unless dup_string?(node) || string_new?(node)
|
|
48
|
+
return unless (dup_string?(node) && target_ruby_version <= 3.2) || string_new?(node)
|
|
49
49
|
|
|
50
50
|
add_offense(node) do |corrector|
|
|
51
51
|
string_value = "+#{string_value(node)}"
|
metadata
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-performance
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.21.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bozhidar Batsov
|
|
8
8
|
- Jonas Arvidsson
|
|
9
9
|
- Yuji Nakayama
|
|
10
|
-
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date:
|
|
12
|
+
date: 2024-06-16 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
14
|
- !ruby/object:Gem::Dependency
|
|
16
15
|
name: rubocop
|
|
@@ -18,7 +17,7 @@ dependencies:
|
|
|
18
17
|
requirements:
|
|
19
18
|
- - ">="
|
|
20
19
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.
|
|
20
|
+
version: 1.48.1
|
|
22
21
|
- - "<"
|
|
23
22
|
- !ruby/object:Gem::Version
|
|
24
23
|
version: '2.0'
|
|
@@ -28,7 +27,7 @@ dependencies:
|
|
|
28
27
|
requirements:
|
|
29
28
|
- - ">="
|
|
30
29
|
- !ruby/object:Gem::Version
|
|
31
|
-
version: 1.
|
|
30
|
+
version: 1.48.1
|
|
32
31
|
- - "<"
|
|
33
32
|
- !ruby/object:Gem::Version
|
|
34
33
|
version: '2.0'
|
|
@@ -38,14 +37,20 @@ dependencies:
|
|
|
38
37
|
requirements:
|
|
39
38
|
- - ">="
|
|
40
39
|
- !ruby/object:Gem::Version
|
|
41
|
-
version:
|
|
40
|
+
version: 1.31.1
|
|
41
|
+
- - "<"
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '2.0'
|
|
42
44
|
type: :runtime
|
|
43
45
|
prerelease: false
|
|
44
46
|
version_requirements: !ruby/object:Gem::Requirement
|
|
45
47
|
requirements:
|
|
46
48
|
- - ">="
|
|
47
49
|
- !ruby/object:Gem::Version
|
|
48
|
-
version:
|
|
50
|
+
version: 1.31.1
|
|
51
|
+
- - "<"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '2.0'
|
|
49
54
|
description: |
|
|
50
55
|
A collection of RuboCop cops to check for performance optimizations
|
|
51
56
|
in Ruby code.
|
|
@@ -124,10 +129,9 @@ metadata:
|
|
|
124
129
|
homepage_uri: https://docs.rubocop.org/rubocop-performance/
|
|
125
130
|
changelog_uri: https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md
|
|
126
131
|
source_code_uri: https://github.com/rubocop/rubocop-performance/
|
|
127
|
-
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.
|
|
132
|
+
documentation_uri: https://docs.rubocop.org/rubocop-performance/1.21/
|
|
128
133
|
bug_tracker_uri: https://github.com/rubocop/rubocop-performance/issues
|
|
129
134
|
rubygems_mfa_required: 'true'
|
|
130
|
-
post_install_message:
|
|
131
135
|
rdoc_options: []
|
|
132
136
|
require_paths:
|
|
133
137
|
- lib
|
|
@@ -142,8 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
142
146
|
- !ruby/object:Gem::Version
|
|
143
147
|
version: '0'
|
|
144
148
|
requirements: []
|
|
145
|
-
rubygems_version: 3.
|
|
146
|
-
signing_key:
|
|
149
|
+
rubygems_version: 3.6.0.dev
|
|
147
150
|
specification_version: 4
|
|
148
151
|
summary: Automatic performance checking tool for Ruby code.
|
|
149
152
|
test_files: []
|