diff --git a/changelog/fix_an_incorrect_autocorrect_for_lint_regexp_as_condition.md b/changelog/fix_an_incorrect_autocorrect_for_lint_regexp_as_condition.md new file mode 100644 index 00000000000..597154b8f22 --- /dev/null +++ b/changelog/fix_an_incorrect_autocorrect_for_lint_regexp_as_condition.md @@ -0,0 +1 @@ +* [#11351](https://github.com/rubocop/rubocop/pull/11351): Fix an incorrect autocorrect for `Lint/RegexpAsCondition` when using regexp literal with bang. ([@koic][]) diff --git a/lib/rubocop/cop/lint/regexp_as_condition.rb b/lib/rubocop/cop/lint/regexp_as_condition.rb index 7736d18e022..211ef8dc96c 100644 --- a/lib/rubocop/cop/lint/regexp_as_condition.rb +++ b/lib/rubocop/cop/lint/regexp_as_condition.rb @@ -17,13 +17,19 @@ module Lint # do_something # end class RegexpAsCondition < Base + include IgnoredNode extend AutoCorrector MSG = 'Do not use regexp literal as a condition. ' \ 'The regexp literal matches `$_` implicitly.' def on_match_current_line(node) + return if node.ancestors.none?(&:conditional?) + return if part_of_ignored_node?(node) + add_offense(node) { |corrector| corrector.replace(node, "#{node.source} =~ $_") } + + ignore_node(node) end end end diff --git a/spec/rubocop/cop/lint/regexp_as_condition_spec.rb b/spec/rubocop/cop/lint/regexp_as_condition_spec.rb index 25530bc05d9..79853982fac 100644 --- a/spec/rubocop/cop/lint/regexp_as_condition_spec.rb +++ b/spec/rubocop/cop/lint/regexp_as_condition_spec.rb @@ -14,12 +14,31 @@ RUBY end + it 'registers an offense and corrects for a regexp literal with bang in `if` condition' do + expect_offense(<<~RUBY) + if !/foo/ + ^^^^^ Do not use regexp literal as a condition. The regexp literal matches `$_` implicitly. + end + RUBY + + expect_correction(<<~RUBY) + if !/foo/ =~ $_ + end + RUBY + end + it 'does not register an offense for a regexp literal outside conditions' do expect_no_offenses(<<~RUBY) /foo/ RUBY end + it 'does not register an offense for a regexp literal with bang outside conditions' do + expect_no_offenses(<<~RUBY) + !/foo/ + RUBY + end + it 'does not register an offense for a regexp literal with `=~` operator' do expect_no_offenses(<<~RUBY) if /foo/ =~ str