diff --git a/crates/oxc_cli/fixtures/astro/debugger.astro b/crates/oxc_cli/fixtures/astro/debugger.astro index 3c1754963..94a674706 100644 --- a/crates/oxc_cli/fixtures/astro/debugger.astro +++ b/crates/oxc_cli/fixtures/astro/debugger.astro @@ -1,3 +1,20 @@ --- debugger --- + + + + + + + + + + + diff --git a/crates/oxc_cli/src/lint/mod.rs b/crates/oxc_cli/src/lint/mod.rs index 0a7df1914..f76f89a20 100644 --- a/crates/oxc_cli/src/lint/mod.rs +++ b/crates/oxc_cli/src/lint/mod.rs @@ -370,7 +370,7 @@ mod test { let args = &["fixtures/astro/debugger.astro"]; let result = test(args); assert_eq!(result.number_of_files, 1); - assert_eq!(result.number_of_warnings, 1); + assert_eq!(result.number_of_warnings, 4); assert_eq!(result.number_of_errors, 0); } } diff --git a/crates/oxc_linter/src/partial_loader/astro_partial_loader.rs b/crates/oxc_linter/src/partial_loader/astro_partial_loader.rs index c5a1005c4..bed6b1030 100644 --- a/crates/oxc_linter/src/partial_loader/astro_partial_loader.rs +++ b/crates/oxc_linter/src/partial_loader/astro_partial_loader.rs @@ -1,9 +1,13 @@ -use memchr::memmem; +use memchr::memmem::Finder; use oxc_span::{SourceType, Span}; use super::JavaScriptSource; +const ASTRO_SPLIT: &str = "---"; +const SCRIPT_START: &str = " { source_text: &'a str, } @@ -15,28 +19,72 @@ impl<'a> AstroPartialLoader<'a> { pub fn parse(self) -> Vec> { let mut results = vec![]; - results.extend(self.parse_frontmatter()); + let frontmatter = self.parse_frontmatter(); + let start = frontmatter.as_ref().map_or(0, |r| r.source_text.len() + ASTRO_SPLIT.len() * 2); + results.extend(frontmatter); + results.extend(self.parse_scripts(start)); results } /// Parse `---` front matter block #[allow(clippy::cast_possible_truncation)] fn parse_frontmatter(&self) -> Option> { - let split = "---"; - let indexes = memmem::find_iter(self.source_text.as_bytes(), split).collect::>(); - if indexes.len() <= 1 { + let split_finder = Finder::new(ASTRO_SPLIT); + let offsets = split_finder.find_iter(self.source_text.as_bytes()).collect::>(); + if offsets.len() <= 1 { return None; } - let start = indexes.first()?; - let end = indexes.last()?; + let start = offsets.first()?; + let end = offsets.last()?; let Ok(start) = u32::try_from(*start) else { return None }; let Ok(end) = u32::try_from(*end) else { return None }; - let js_code = Span::new(start + split.len() as u32, end).source_text(self.source_text); + let js_code = + Span::new(start + ASTRO_SPLIT.len() as u32, end).source_text(self.source_text); Some(JavaScriptSource::new( js_code, SourceType::default().with_typescript(true).with_module(true), )) } + + /// In .astro files, you can add client-side JavaScript by adding one (or more) " + if let Some(offset) = script_end_finder.find(self.source_text[pointer..].as_bytes()) { + js_end = pointer + offset; + pointer += offset + SCRIPT_END.len(); + } else { + break; + }; + results.push(JavaScriptSource::new( + &self.source_text[js_start..js_end], + SourceType::default().with_typescript(true).with_module(true), + )); + } + results + } }