Skip to content

Commit

Permalink
Merge pull request #201 from koic/fix_incorrect_autocorrect_for_rever…
Browse files Browse the repository at this point in the history
…se_each

Fix an incorrect auto-correct for `Performance/ReverseEach`
  • Loading branch information
koic authored Dec 21, 2020
2 parents 0e59891 + 2ae0e2e commit 56147bc
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bug fixes

* [#201](https://github.com/rubocop-hq/rubocop-performance/pull/201): Fix an incorrect auto-correct for `Performance/ReverseEach` when using multi-line `reverse.each` with leading dot. ([@koic][])

## 1.9.1 (2020-11-28)

### Bug fixes
Expand Down
16 changes: 6 additions & 10 deletions lib/rubocop/cop/performance/reverse_each.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,25 @@ class ReverseEach < Base

MSG = 'Use `reverse_each` instead of `reverse.each`.'
RESTRICT_ON_SEND = %i[each].freeze
UNDERSCORE = '_'

def_node_matcher :reverse_each?, <<~MATCHER
(send $(send _ :reverse) :each)
(send (send _ :reverse) :each)
MATCHER

def on_send(node)
reverse_each?(node) do |receiver|
location_of_reverse = receiver.loc.selector.begin_pos
end_location = node.loc.selector.end_pos

range = range_between(location_of_reverse, end_location)
reverse_each?(node) do
range = offense_range(node)

add_offense(range) do |corrector|
corrector.replace(replacement_range(node), UNDERSCORE)
corrector.replace(range, 'reverse_each')
end
end
end

private

def replacement_range(node)
range_between(node.loc.dot.begin_pos, node.loc.selector.begin_pos)
def offense_range(node)
range_between(node.children.first.loc.selector.begin_pos, node.loc.selector.end_pos)
end
end
end
Expand Down
29 changes: 26 additions & 3 deletions spec/rubocop/cop/performance/reverse_each_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,19 @@ def arr
RUBY
end

it 'corrects a multi-line reverse_each' do
new_source = autocorrect_source(<<~RUBY)
it 'registers and corrects when using multi-line `reverse.each` with trailing dot' do
expect_offense(<<~RUBY)
def arr
[1, 2]
end
arr.
reverse.
^^^^^^^^ Use `reverse_each` instead of `reverse.each`.
each { |e| puts e }
RUBY

expect(new_source).to eq(<<~RUBY)
expect_correction(<<~RUBY)
def arr
[1, 2]
end
Expand All @@ -107,5 +108,27 @@ def arr
reverse_each { |e| puts e }
RUBY
end

it 'registers and corrects when using multi-line `reverse.each` with leading dot' do
expect_offense(<<~RUBY)
def arr
[1, 2]
end
arr
.reverse
^^^^^^^ Use `reverse_each` instead of `reverse.each`.
.each { |e| puts e }
RUBY

expect_correction(<<~RUBY)
def arr
[1, 2]
end
arr
.reverse_each { |e| puts e }
RUBY
end
end
end

0 comments on commit 56147bc

Please sign in to comment.