Skip to content

Commit 272e23a

Browse files
author
5hun-s
committed
[Fix #509] Fix a false positive for Performance/RedundantMatch
1 parent ae0059a commit 272e23a

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*[#509](https://github.com/rubocop/rubocop-performance/issues/509): Fix a false positive
2+
for `Performance/RedundantMatch` when global variable is used after match ([@5hun-s][])

lib/rubocop/cop/performance/redundant_match.rb

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ class RedundantMatch < Base
3737
PATTERN
3838

3939
def on_send(node)
40-
return unless match_call?(node) &&
41-
(!node.value_used? || only_truthiness_matters?(node)) &&
42-
!(node.parent && node.parent.block_type?)
40+
return unless should_register_offense?(node)
4341

4442
add_offense(node) do |corrector|
4543
autocorrect(corrector, node) if autocorrectable?(node)
@@ -48,6 +46,32 @@ def on_send(node)
4846

4947
private
5048

49+
def should_register_offense?(node)
50+
match_call?(node) &&
51+
used_only_for_truthiness?(node) &&
52+
!inside_block_argument?(node) &&
53+
!special_global_variable_used_after_match?(node)
54+
end
55+
56+
def used_only_for_truthiness?(node)
57+
!node.value_used? || only_truthiness_matters?(node)
58+
end
59+
60+
def inside_block_argument?(node)
61+
node.parent&.block_type?
62+
end
63+
64+
def special_global_variable_used_after_match?(node)
65+
scope = scope_root(node) || node.ancestors.last
66+
scope.each_node(:gvar, :back_ref, :nth_ref).any?
67+
end
68+
69+
def scope_root(node)
70+
node.each_ancestor.find do |ancestor|
71+
ancestor.type?(:any_def, :class, :module)
72+
end
73+
end
74+
5175
def autocorrect(corrector, node)
5276
new_source = "#{node.receiver.source} =~ #{replacement(node)}"
5377

spec/rubocop/cop/performance/redundant_match_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,38 @@ def method(str)
103103
expect_no_offenses('match("bar")')
104104
end
105105

106+
it 'does not register an error when numbered global variable is used after match' do
107+
expect_no_offenses(<<~RUBY)
108+
def method(str)
109+
puts $1 if str.match(/regex/)
110+
end
111+
RUBY
112+
end
113+
114+
it 'does not register an error when numbered capture variable is used after match' do
115+
expect_no_offenses(<<~RUBY)
116+
def method(str)
117+
str.match(/regex/)
118+
puts $1
119+
end
120+
RUBY
121+
end
122+
123+
it 'does not register an error when numbered capture variable is used after a match in a conditional expression' do
124+
expect_no_offenses(<<~RUBY)
125+
def method(str)
126+
puts str.match(/regex/) ? $1 : ''
127+
end
128+
RUBY
129+
end
130+
131+
it 'does not register an error when numbered capture variable is used in a subsequent statement after match' do
132+
expect_no_offenses(<<~RUBY)
133+
exit unless str.match(/regex/)
134+
puts $1
135+
RUBY
136+
end
137+
106138
it 'formats error message correctly for something if str.match(/regex/)' do
107139
expect_offense(<<~RUBY)
108140
something if str.match(/regex/)

0 commit comments

Comments
 (0)