Skip to content

Commit

Permalink
[Fix rubocop#8708] Fix bad regexp recognition in `Lint/OutOfRangeRege…
Browse files Browse the repository at this point in the history
…xpRef` when there are multiple regexps.
  • Loading branch information
dvandersluis committed Oct 26, 2020
1 parent dc7260b commit d202e85
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog/fix_fix_8708_fix_bad_regexp_recognition_in.md
@@ -0,0 +1 @@
* [#8708](https://github.com/rubocop-hq/rubocop/pull/8708): Fix bad regexp recognition in `Lint/OutOfRangeRegexpRef` when there are multiple regexps. ([@dvandersluis][])
22 changes: 17 additions & 5 deletions lib/rubocop/cop/lint/out_of_range_regexp_ref.rb
Expand Up @@ -35,14 +35,13 @@ def on_match_with_lvasgn(node)
check_regexp(node.children.first)
end

def on_send(node)
def after_send(node)
@valid_ref = nil

if node.receiver&.regexp_type?
check_regexp(node.receiver)
elsif node.first_argument&.regexp_type? \
&& REGEXP_ARGUMENT_METHODS.include?(node.method_name)
if regexp_first_argument?(node)
check_regexp(node.first_argument)
elsif regexp_receiver?(node)
check_regexp(node.receiver)
end
end

Expand Down Expand Up @@ -80,6 +79,19 @@ def check_regexp(node)
node.each_capture(named: false).count
end
end

def regexp_first_argument?(send_node)
send_node.first_argument&.regexp_type? \
&& REGEXP_ARGUMENT_METHODS.include?(send_node.method_name)
end

def regexp_receiver?(send_node)
send_node.receiver&.regexp_type?
end

def nth_ref_receiver?(send_node)
send_node.receiver&.nth_ref_type?
end
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions spec/rubocop/cop/lint/out_of_range_regexp_ref_spec.rb
Expand Up @@ -234,6 +234,51 @@
end
end

context 'when both the LHS and RHS use regexp' do
it 'only considers the RHS regexp' do
expect_no_offenses(<<~RUBY)
if "foo bar".gsub(/\s+/, "") =~ /foo(bar)/
p $1
end
RUBY

expect_offense(<<~RUBY)
if "foo bar".gsub(/(\s+)/, "") =~ /foobar/
p $1
^^ $1 is out of range (no regexp capture groups detected).
end
RUBY
end
end

context 'when calling a regexp method on a nth-ref node' do
it 'does not register an offense when calling gsub on a valid nth-ref' do
expect_no_offenses(<<~RUBY)
if "some : line " =~ / : (.+)/
$1.gsub(/\s{2}/, " ")
end
RUBY
end

it 'registers an offense when calling gsub on an invalid nth-ref' do
expect_offense(<<~RUBY)
if "some : line " =~ / : (.+)/
$2.gsub(/\s{2}/, " ")
^^ $2 is out of range (1 regexp capture group detected).
end
RUBY
end

it 'registers an offense if the capturing groups have changed' do
expect_offense(<<~RUBY)
"some : line " =~ / : (.+)/
$1.gsub(/\s{2}/, " ")
puts $1
^^ $1 is out of range (no regexp capture groups detected).
RUBY
end
end

%i[gsub gsub! sub sub! scan].each do |method|
context "matching with #{method}" do
it 'does not register an offense when in range references are used' do
Expand Down

0 comments on commit d202e85

Please sign in to comment.