From c474274e04b65d4ef5756c419974c2a7b7094a26 Mon Sep 17 00:00:00 2001 From: Owen Stephens Date: Mon, 31 Aug 2020 23:29:32 +0100 Subject: [PATCH] Use `regexp_parser` to improve `Style/RedundantRegexp...` cops As mentioned in #8593 by @marcandre --- CHANGELOG.md | 1 + .../style/redundant_regexp_character_class.rb | 62 ++++++++++++------- .../cop/style/redundant_regexp_escape.rb | 27 ++++---- .../redundant_regexp_character_class_spec.rb | 52 ++++++++++++++++ .../cop/style/redundant_regexp_escape_spec.rb | 23 ++++++- 5 files changed, 128 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4aab64bd0d..04f3c521472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ * [#8517](https://github.com/rubocop-hq/rubocop/pull/8517): Make `Style/HashTransformKeys` and `Style/HashTransformValues` aware of `to_h` with block. ([@eugeneius][]) * [#8529](https://github.com/rubocop-hq/rubocop/pull/8529): Mark `Lint/FrozenStringLiteralComment` as `Safe`, but with unsafe auto-correction. ([@marcandre][]) * [#8602](https://github.com/rubocop-hq/rubocop/pull/8602): Fix usage of `to_enum(:scan, regexp)` to work on TruffleRuby. ([@jaimerave][]) +* [#8625](https://github.com/rubocop-hq/rubocop/pull/8625): Improve `Style/RedundantRegexpCharacterClass` and `Style/RedundantRegexpEscape` by using `regexp_parser` gem. ([@owst][]) ## 0.89.1 (2020-08-10) diff --git a/lib/rubocop/cop/style/redundant_regexp_character_class.rb b/lib/rubocop/cop/style/redundant_regexp_character_class.rb index 4fc77e3309d..203b8d7601c 100644 --- a/lib/rubocop/cop/style/redundant_regexp_character_class.rb +++ b/lib/rubocop/cop/style/redundant_regexp_character_class.rb @@ -24,32 +24,15 @@ module Style # # @api private class RedundantRegexpCharacterClass < Base - include MatchRange include RegexpLiteralHelp extend AutoCorrector + REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS = '.*+?{}()|$'.chars.freeze MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \ '`%s` can be replaced with `%s`.' - PATTERN = / - ( - (? + expect_no_offenses('foo = /[a]\g/') + end + end + context 'with a character class containing an escaped ]' do it 'registers an offense and corrects' do expect_offense(<<~'RUBY') @@ -224,6 +263,19 @@ end end + context 'with a redundant character class after an interpolation' do + it 'registers an offense and corrects' do + expect_offense(<<~'RUBY') + foo = /#{x}[a]/ + ^^^ Redundant single-element character class, `[a]` can be replaced with `a`. + RUBY + + expect_correction(<<~'RUBY') + foo = /#{x}a/ + RUBY + end + end + context 'with a multi-line interpolation' do it 'ignores offenses in the interpolated expression' do expect_no_offenses(<<~'RUBY') diff --git a/spec/rubocop/cop/style/redundant_regexp_escape_spec.rb b/spec/rubocop/cop/style/redundant_regexp_escape_spec.rb index f56596ec2b0..a59cf26926e 100644 --- a/spec/rubocop/cop/style/redundant_regexp_escape_spec.rb +++ b/spec/rubocop/cop/style/redundant_regexp_escape_spec.rb @@ -29,7 +29,7 @@ end [ - ('a'..'z').to_a - %w[c n p u x], + ('a'..'z').to_a - %w[c g k n p u x], ('A'..'Z').to_a - %w[C M P], %w[n101 x41 u0041 u{0041} cc C-c p{alpha} P{alpha}] ].flatten.each do |escape| @@ -46,6 +46,14 @@ end end + context "with an invalid \g escape" do + it 'does not register an offense' do + # See https://ruby-doc.org/core-2.7.1/Regexp.html#class-Regexp-label-Subexpression+Calls + # \g should be \g + expect_no_offenses('foo = /\g/') + end + end + context "with an escaped 'M-a' outside a character class" do it 'does not register an offense' do expect_no_offenses('foo = /\\M-a/n') @@ -79,6 +87,19 @@ end end + context "with an escaped '+' inside a character class inside a group" do + it 'registers an offense and corrects' do + expect_offense(<<~'RUBY') + foo = /([\+])/ + ^^ Redundant escape inside regexp literal + RUBY + + expect_correction(<<~RUBY) + foo = /([+])/ + RUBY + end + end + context 'with an escaped . inside a character class beginning with :' do it 'registers an offense and corrects' do expect_offense(<<~'RUBY')