diff --git a/Cargo.lock b/Cargo.lock index dfbcb10c03fe3..7f3b1dc279f39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1672,7 +1672,6 @@ dependencies = [ name = "oxc_linter" version = "0.14.1" dependencies = [ - "aho-corasick", "bitflags 2.6.0", "convert_case", "cow-utils", diff --git a/Cargo.toml b/Cargo.toml index 8aee27568f722..6a7ad404b44b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,12 +118,13 @@ quote = "1" syn = { version = "2", default-features = false } unicode-id-start = "1" +# oxc-browserslist = "1.1.0" oxc_index = "1.0.1" oxc_resolver = "2.1.1" oxc_sourcemap = "1.0.3" -aho-corasick = "1.1.3" +# allocator-api2 = "0.2.21" assert-unchecked = "0.1.2" base64 = "0.22.1" diff --git a/crates/oxc_linter/Cargo.toml b/crates/oxc_linter/Cargo.toml index 69c25f713d720..b1ff7150e3444 100644 --- a/crates/oxc_linter/Cargo.toml +++ b/crates/oxc_linter/Cargo.toml @@ -35,7 +35,7 @@ oxc_semantic = { workspace = true } oxc_span = { workspace = true, features = ["schemars", "serialize"] } oxc_syntax = { workspace = true, features = ["serialize"] } -aho-corasick = { workspace = true } +# bitflags = { workspace = true } convert_case = { workspace = true } cow-utils = { workspace = true } 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 14f1f980d3c0c..0e58d0d6fcc07 100644 --- a/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs +++ b/crates/oxc_linter/src/rules/eslint/no_regex_spaces.rs @@ -1,5 +1,3 @@ -use aho_corasick::AhoCorasick; -use lazy_static::lazy_static; use oxc_allocator::{Allocator, Vec}; use oxc_ast::{ ast::{Argument, CallExpression, NewExpression, RegExpLiteral}, @@ -48,11 +46,6 @@ 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() { @@ -127,7 +120,7 @@ impl NoRegexSpaces { // 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) + input.contains(" ") } } diff --git a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs index 55b5cf68fbc33..ef502c5a66cc1 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs @@ -1,4 +1,6 @@ -use aho_corasick::AhoCorasick; +use std::borrow::Cow; + +use cow_utils::CowUtils; use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeName, JSXAttributeValue, JSXExpression}, AstKind, @@ -28,7 +30,7 @@ pub struct ImgRedundantAlt(Box); #[derive(Debug, Clone)] pub struct ImgRedundantAltConfig { types_to_validate: Vec, - redundant_words: AhoCorasick, + redundant_words: Vec>, } impl std::ops::Deref for ImgRedundantAlt { @@ -45,24 +47,19 @@ impl Default for ImgRedundantAltConfig { fn default() -> Self { Self { types_to_validate: vec![CompactStr::new("img")], - redundant_words: AhoCorasick::builder() - .ascii_case_insensitive(true) - .build(REDUNDANT_WORDS) - .expect("Could not build AhoCorasick"), + redundant_words: vec!["image".into(), "photo".into(), "picture".into()], } } } impl ImgRedundantAltConfig { - fn new( - types_to_validate: Vec<&str>, - redundant_words: &[&str], - ) -> Result { - Ok(Self { + fn new(types_to_validate: Vec<&str>, redundant_words: &[&str]) -> Self { + Self { types_to_validate: types_to_validate.into_iter().map(Into::into).collect(), - redundant_words: AhoCorasick::builder() - .ascii_case_insensitive(true) - .build(redundant_words)?, - }) + redundant_words: redundant_words + .iter() + .map(|w| Cow::Owned(w.cow_to_ascii_lowercase().to_string())) + .collect::>(), + } } } @@ -121,7 +118,7 @@ impl Rule for ImgRedundantAlt { v.iter().filter_map(Value::as_str).chain(REDUNDANT_WORDS).collect::>() }); - Self(Box::new(ImgRedundantAltConfig::new(components, words.as_slice()).unwrap())) + Self(Box::new(ImgRedundantAltConfig::new(components, words.as_slice()))) } fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { @@ -195,10 +192,15 @@ impl Rule for ImgRedundantAlt { impl ImgRedundantAlt { #[inline] fn is_redundant_alt_text(&self, alt_text: &str) -> bool { - for mat in self.redundant_words.find_iter(alt_text) { - // check if followed by space or is whole text - if mat.end() == alt_text.len() || alt_text.as_bytes()[mat.end()] == b' ' { - return true; + let alt_text = alt_text.cow_to_ascii_lowercase(); + for word in &self.redundant_words { + if let Some(index) = alt_text.find(word.as_ref()) { + // check if followed by space or is whole text + if index + word.len() == alt_text.len() + || alt_text.as_bytes().get(index + word.len()) == Some(&b' ') + { + return true; + } } } false