diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bfe1eea1b2..7d94a53ce04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * [#8917](https://github.com/rubocop-hq/rubocop/issues/8917): Fix rubocop comment directives handling of cops with multiple levels in department name. ([@fatkodima][]) * [#8918](https://github.com/rubocop-hq/rubocop/issues/8918): Fix a false positives for `Bundler/DuplicatedGem` when a gem conditionally duplicated within `if-elsif` or `case-when` statements. ([@fatkodima][]) * [#8933](https://github.com/rubocop-hq/rubocop/pull/8933): Fix an error for `Layout/EmptyLinesAroundAccessModifier` when the first line is a comment. ([@matthieugendreau][]) +* [#8954](https://github.com/rubocop-hq/rubocop/pull/8954): Fix autocorrection for Style/RedundantRegexpCharacterClass with %r. ([@ysakasin][]) ### Changes diff --git a/docs/modules/ROOT/pages/cops_style.adoc b/docs/modules/ROOT/pages/cops_style.adoc index 047668cbec6..c306191002e 100644 --- a/docs/modules/ROOT/pages/cops_style.adoc +++ b/docs/modules/ROOT/pages/cops_style.adoc @@ -8230,6 +8230,12 @@ r = /[\s]/ # good r = /\s/ +# bad +r = %r{/[b]} + +# good +r = %r{/b} + # good r = /[ab]/ ---- diff --git a/lib/rubocop/cop/style/redundant_regexp_character_class.rb b/lib/rubocop/cop/style/redundant_regexp_character_class.rb index c18076cea74..05ca06bcf09 100644 --- a/lib/rubocop/cop/style/redundant_regexp_character_class.rb +++ b/lib/rubocop/cop/style/redundant_regexp_character_class.rb @@ -19,6 +19,12 @@ module Style # # good # r = /\s/ # + # # bad + # r = %r{/[b]} + # + # # good + # r = %r{/b} + # # # good # r = /[ab]/ class RedundantRegexpCharacterClass < Base @@ -48,9 +54,7 @@ def each_redundant_character_class(node) each_single_element_character_class(node) do |char_class| next unless redundant_single_element_character_class?(node, char_class) - begin_pos = 1 + char_class.ts - end_pos = begin_pos + char_class.expressions.first.text.length + 1 - yield node.loc.begin.adjust(begin_pos: begin_pos, end_pos: end_pos) + yield char_class.loc.body end end diff --git a/spec/rubocop/cop/style/redundant_regexp_character_class_spec.rb b/spec/rubocop/cop/style/redundant_regexp_character_class_spec.rb index 18ffd68c95f..efd52178f44 100644 --- a/spec/rubocop/cop/style/redundant_regexp_character_class_spec.rb +++ b/spec/rubocop/cop/style/redundant_regexp_character_class_spec.rb @@ -69,6 +69,74 @@ end end + context 'with %r{} regexp' do + context 'with a character class containing a single character' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + foo = %r{[a]} + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + RUBY + + expect_correction(<<~RUBY) + foo = %r{a} + RUBY + end + end + + context 'with multiple character classes containing single characters' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + foo = %r{[a]b[c]d} + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + ^^^ Redundant single-element character class, `[c]` can be replaced with `c`. + RUBY + + expect_correction(<<~RUBY) + foo = %r{abcd} + RUBY + end + end + + context 'with a character class containing a single character inside a group' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + foo = %r{([a])} + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + RUBY + + expect_correction(<<~RUBY) + foo = %r{(a)} + RUBY + end + end + + context 'with a character class containing a single character before `+` quantifier' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + foo = %r{[a]+} + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + RUBY + + expect_correction(<<~RUBY) + foo = %r{a+} + RUBY + end + end + + context 'with a character class containing a single character before `{n,m}` quantifier' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + foo = %r{[a]{2,10}} + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + RUBY + + expect_correction(<<~RUBY) + foo = %r{a{2,10}} + RUBY + end + end + end + context 'with a character class containing a single range' do it 'does not register an offense' do expect_no_offenses('foo = /[a-z]/')