From 4b5322693f7a807c200e9047c601ca8284201bf6 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Sat, 21 Sep 2024 17:02:17 -0400 Subject: [PATCH] Remove character class checker --- .../src/rules/eslint/no_regex_spaces.rs | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs b/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs index e817f7c3c3c5a..b5b32548478ba 100644 --- a/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs +++ b/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs @@ -1,3 +1,5 @@ +use aho_corasick::AhoCorasick; +use lazy_static::lazy_static; use oxc_allocator::{Allocator, Vec}; use oxc_ast::{ ast::{Argument, CallExpression, NewExpression, RegExpLiteral}, @@ -45,6 +47,11 @@ declare_oxc_lint!( pending // TODO: This is somewhat autofixable, but the fixer does not exist yet. ); +lazy_static! { + static ref DOUBLE_SPACE: AhoCorasick = + AhoCorasick::new([" "]).expect("no-regex-spaces: Unable to build AhoCorasick"); +} + impl Rule for NoRegexSpaces { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { match node.kind() { @@ -75,7 +82,7 @@ impl NoRegexSpaces { fn find_literal_to_report(literal: &RegExpLiteral, ctx: &LintContext) -> Option { let pattern_text = literal.regex.pattern.source_text(ctx.source_text()); let pattern_text = pattern_text.as_ref(); - if Self::has_exempted_char_class(pattern_text) { + if !Self::has_double_space(pattern_text) { return None; } @@ -93,8 +100,8 @@ impl NoRegexSpaces { let Some(Argument::StringLiteral(pattern)) = args.first() else { return None; }; - if Self::has_exempted_char_class(&pattern.value) { - return None; // skip spaces inside char class, e.g. RegExp('[ ]') + if !Self::has_double_space(&pattern.value) { + return None; } let alloc = Allocator::default(); @@ -121,7 +128,7 @@ impl NoRegexSpaces { in_quantifier = false; return; } - if ch.value != b' ' as u32 { + if ch.value != u32::from(b' ') { return; } if let Some(ref mut space_span) = last_space_span { @@ -154,23 +161,10 @@ impl NoRegexSpaces { expr.callee.is_specific_id("RegExp") && expr.arguments.len() > 0 } - /// Whether the input has a character class but no consecutive spaces - /// outside the character class. - fn has_exempted_char_class(input: &str) -> bool { - let mut inside_class = false; - - for (i, c) in input.chars().enumerate() { - match c { - '[' => inside_class = true, - ']' => inside_class = false, - ' ' if input.chars().nth(i + 1) == Some(' ') && !inside_class => { - return false; - } - _ => {} - } - } - - true + // For skipping if there aren't any consecutive spaces in the source, to avoid reporting cases + // where the space is explicitly escaped, like: `RegExp(' \ ')``. + fn has_double_space(input: &str) -> bool { + DOUBLE_SPACE.is_match(input) } }