Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a0a632e

Browse files
committedSep 10, 2022
Support numbered parameter for RedundantSortBlock, SortReverse, and TimesMap.
This PR support numbered parameter for `Performance/RedundantSortBlock`, `Performance/SortReverse`, and `Performance/TimesMap` cops.
1 parent 5898a1b commit a0a632e

File tree

8 files changed

+109
-20
lines changed

8 files changed

+109
-20
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#305](https://github.com/rubocop/rubocop-performance/pull/305): Support numbered parameter for `Performance/RedundantSortBlock`, `Performance/SortReverse`, and `Performance/TimesMap` cops. ([@koic][])

‎lib/rubocop/cop/mixin/sort_block.rb

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ module SortBlock
1414
$send)
1515
PATTERN
1616

17+
def_node_matcher :sort_with_numblock?, <<~PATTERN
18+
(numblock
19+
$(send _ :sort)
20+
$_arg_count
21+
$send)
22+
PATTERN
23+
1724
def_node_matcher :replaceable_body?, <<~PATTERN
1825
(send (lvar %1) :<=> (lvar %2))
1926
PATTERN

‎lib/rubocop/cop/performance/redundant_sort_block.rb

+16-8
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,33 @@ class RedundantSortBlock < Base
1616
include SortBlock
1717
extend AutoCorrector
1818

19-
MSG = 'Use `sort` instead of `%<bad_method>s`.'
19+
MSG = 'Use `sort` without block.'
2020

2121
def on_block(node)
2222
return unless (send, var_a, var_b, body = sort_with_block?(node))
2323

2424
replaceable_body?(body, var_a, var_b) do
25-
range = sort_range(send, node)
25+
register_offense(send, node)
26+
end
27+
end
28+
29+
def on_numblock(node)
30+
return unless (send, arg_count, body = sort_with_numblock?(node))
31+
return unless arg_count == 2
2632

27-
add_offense(range, message: message(var_a, var_b)) do |corrector|
28-
corrector.replace(range, 'sort')
29-
end
33+
replaceable_body?(body, :_1, :_2) do
34+
register_offense(send, node)
3035
end
3136
end
3237

3338
private
3439

35-
def message(var_a, var_b)
36-
bad_method = "sort { |#{var_a}, #{var_b}| #{var_a} <=> #{var_b} }"
37-
format(MSG, bad_method: bad_method)
40+
def register_offense(send, node)
41+
range = sort_range(send, node)
42+
43+
add_offense(range) do |corrector|
44+
corrector.replace(range, 'sort')
45+
end
3846
end
3947
end
4048
end

‎lib/rubocop/cop/performance/sort_reverse.rb

+18-9
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,36 @@ class SortReverse < Base
1717
include SortBlock
1818
extend AutoCorrector
1919

20-
MSG = 'Use `sort.reverse` instead of `%<bad_method>s`.'
20+
MSG = 'Use `sort.reverse` instead.'
2121

2222
def on_block(node)
2323
sort_with_block?(node) do |send, var_a, var_b, body|
2424
replaceable_body?(body, var_b, var_a) do
25-
range = sort_range(send, node)
25+
register_offense(send, node)
26+
end
27+
end
28+
end
2629

27-
add_offense(range, message: message(var_a, var_b)) do |corrector|
28-
replacement = 'sort.reverse'
30+
def on_numblock(node)
31+
sort_with_numblock?(node) do |send, arg_count, body|
32+
next unless arg_count == 2
2933

30-
corrector.replace(range, replacement)
31-
end
34+
replaceable_body?(body, :_2, :_1) do
35+
register_offense(send, node)
3236
end
3337
end
3438
end
3539

3640
private
3741

38-
def message(var_a, var_b)
39-
bad_method = "sort { |#{var_a}, #{var_b}| #{var_b} <=> #{var_a} }"
40-
format(MSG, bad_method: bad_method)
42+
def register_offense(send, node)
43+
range = sort_range(send, node)
44+
45+
add_offense(range) do |corrector|
46+
replacement = 'sort.reverse'
47+
48+
corrector.replace(range, replacement)
49+
end
4150
end
4251
end
4352
end

‎lib/rubocop/cop/performance/times_map.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def on_send(node)
4343
def on_block(node)
4444
check(node)
4545
end
46+
alias on_numblock on_block
4647

4748
private
4849

@@ -66,7 +67,7 @@ def message(map_or_collect, count)
6667
end
6768

6869
def_node_matcher :times_map_call, <<~PATTERN
69-
{(block $(send (send $!nil? :times) {:map :collect}) ...)
70+
{({block numblock} $(send (send $!nil? :times) {:map :collect}) ...)
7071
$(send (send $!nil? :times) {:map :collect} (block_pass ...))}
7172
PATTERN
7273
end

‎spec/rubocop/cop/performance/redundant_sort_block_spec.rb

+26-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
it 'registers an offense and corrects when sorting in direct order' do
55
expect_offense(<<~RUBY)
66
array.sort { |a, b| a <=> b }
7-
^^^^^^^^^^^^^^^^^^^^^^^ Use `sort` instead of `sort { |a, b| a <=> b }`.
7+
^^^^^^^^^^^^^^^^^^^^^^^ Use `sort` without block.
88
RUBY
99

1010
expect_correction(<<~RUBY)
@@ -29,4 +29,29 @@
2929
array.sort
3030
RUBY
3131
end
32+
33+
context 'when using numbered parameter', :ruby27 do
34+
it 'registers an offense and corrects when sorting in direct order' do
35+
expect_offense(<<~RUBY)
36+
array.sort { _1 <=> _2 }
37+
^^^^^^^^^^^^^^^^^^ Use `sort` without block.
38+
RUBY
39+
40+
expect_correction(<<~RUBY)
41+
array.sort
42+
RUBY
43+
end
44+
45+
it 'does not register an offense when sorting in reverse order' do
46+
expect_no_offenses(<<~RUBY)
47+
array.sort { _2 <=> _1 }
48+
RUBY
49+
end
50+
51+
it 'does not register an offense when sorting in direct order by some property' do
52+
expect_no_offenses(<<~RUBY)
53+
array.sort { _1.x <=> _2.x }
54+
RUBY
55+
end
56+
end
3257
end

‎spec/rubocop/cop/performance/sort_reverse_spec.rb

+26-1
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,39 @@
99
it 'registers an offense and corrects when sorting in reverse order' do
1010
expect_offense(<<~RUBY)
1111
array.sort { |a, b| b <=> a }
12-
^^^^^^^^^^^^^^^^^^^^^^^ Use `sort.reverse` instead of `sort { |a, b| b <=> a }`.
12+
^^^^^^^^^^^^^^^^^^^^^^^ Use `sort.reverse` instead.
1313
RUBY
1414

1515
expect_correction(<<~RUBY)
1616
array.sort.reverse
1717
RUBY
1818
end
1919

20+
context 'when using numbered parameter', :ruby27 do
21+
it 'registers an offense and corrects when sorting in reverse order' do
22+
expect_offense(<<~RUBY)
23+
array.sort { _2 <=> _1 }
24+
^^^^^^^^^^^^^^^^^^ Use `sort.reverse` instead.
25+
RUBY
26+
27+
expect_correction(<<~RUBY)
28+
array.sort.reverse
29+
RUBY
30+
end
31+
32+
it 'does not register an offense when sorting in direct order' do
33+
expect_no_offenses(<<~RUBY)
34+
array.sort { _1 <=> _2 }
35+
RUBY
36+
end
37+
38+
it 'does not register an offense when sorting in reverse order by some property' do
39+
expect_no_offenses(<<~RUBY)
40+
array.sort { _2.x <=> _1.x }
41+
RUBY
42+
end
43+
end
44+
2045
it 'does not register an offense when sorting in direct order' do
2146
expect_no_offenses(<<~RUBY)
2247
array.sort { |a, b| a <=> b }

‎spec/rubocop/cop/performance/times_map_spec.rb

+13
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@
5757
RUBY
5858
end
5959
end
60+
61+
context 'when using numbered parameter', :ruby27 do
62+
it 'registers an offense and corrects' do
63+
expect_offense(<<~RUBY, method: method)
64+
4.times.#{method} { _1.to_s }
65+
^^^^^^^^^{method}^^^^^^^^^^^^ Use `Array.new(4)` with a block instead of `.times.#{method}`.
66+
RUBY
67+
68+
expect_correction(<<~RUBY)
69+
Array.new(4) { _1.to_s }
70+
RUBY
71+
end
72+
end
6073
end
6174
end
6275

0 commit comments

Comments
 (0)
Please sign in to comment.