From f2ed83ca3bafe535574400fe7601e69ad1bc5f07 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sun, 7 Jan 2024 00:13:44 +0800 Subject: [PATCH] feat(linter): + +

Hello {name}!

diff --git a/crates/oxc_cli/src/lint/mod.rs b/crates/oxc_cli/src/lint/mod.rs index 4a75fb6ae..7e449478f 100644 --- a/crates/oxc_cli/src/lint/mod.rs +++ b/crates/oxc_cli/src/lint/mod.rs @@ -379,4 +379,13 @@ mod test { assert_eq!(result.number_of_warnings, 4); assert_eq!(result.number_of_errors, 0); } + + #[test] + fn lint_svelte_file() { + let args = &["fixtures/svelte/debugger.svelte"]; + let result = test(args); + assert_eq!(result.number_of_files, 1); + assert_eq!(result.number_of_warnings, 1); + assert_eq!(result.number_of_errors, 0); + } } diff --git a/crates/oxc_linter/src/partial_loader/astro.rs b/crates/oxc_linter/src/partial_loader/astro.rs index bed6b1030..8bc28c537 100644 --- a/crates/oxc_linter/src/partial_loader/astro.rs +++ b/crates/oxc_linter/src/partial_loader/astro.rs @@ -2,11 +2,9 @@ use memchr::memmem::Finder; use oxc_span::{SourceType, Span}; -use super::JavaScriptSource; +use super::{JavaScriptSource, SCRIPT_END, SCRIPT_START}; const ASTRO_SPLIT: &str = "---"; -const SCRIPT_START: &str = " { source_text: &'a str, diff --git a/crates/oxc_linter/src/partial_loader/mod.rs b/crates/oxc_linter/src/partial_loader/mod.rs index ff57579df..64c783c0f 100644 --- a/crates/oxc_linter/src/partial_loader/mod.rs +++ b/crates/oxc_linter/src/partial_loader/mod.rs @@ -1,16 +1,15 @@ mod astro; +mod svelte; mod vue; use oxc_span::SourceType; -pub use self::{astro::AstroPartialLoader, vue::VuePartialLoader}; +pub use self::{astro::AstroPartialLoader, svelte::SveltePartialLoader, vue::VuePartialLoader}; -pub const LINT_PARTIAL_LOADER_EXT: &[&str] = &["vue", "astro"]; +const SCRIPT_START: &str = " { @@ -24,11 +23,17 @@ impl<'a> JavaScriptSource<'a> { } } +pub struct PartialLoader; + impl PartialLoader { - pub fn build<'a>(&self, source_text: &'a str) -> Vec> { - match self { - Self::Vue => VuePartialLoader::new(source_text).parse(), - Self::Astro => AstroPartialLoader::new(source_text).parse(), + /// Extract js section of specifial files. + /// Returns `None` if the specifial file does not have a js section. + pub fn parse<'a>(ext: &str, source_text: &'a str) -> Option>> { + match ext { + "vue" => Some(VuePartialLoader::new(source_text).parse()), + "astro" => Some(AstroPartialLoader::new(source_text).parse()), + "svelte" => Some(SveltePartialLoader::new(source_text).parse()), + _ => None, } } } diff --git a/crates/oxc_linter/src/partial_loader/svelte.rs b/crates/oxc_linter/src/partial_loader/svelte.rs new file mode 100644 index 000000000..efb866f90 --- /dev/null +++ b/crates/oxc_linter/src/partial_loader/svelte.rs @@ -0,0 +1,48 @@ +use memchr::memmem::Finder; + +use oxc_span::SourceType; + +use super::{JavaScriptSource, SCRIPT_END, SCRIPT_START}; + +pub struct SveltePartialLoader<'a> { + source_text: &'a str, +} + +impl<'a> SveltePartialLoader<'a> { + pub fn new(source_text: &'a str) -> Self { + Self { source_text } + } + + pub fn parse(self) -> Vec> { + self.parse_script().map_or_else(Vec::new, |source| vec![source]) + } + + fn parse_script(&self) -> Option> { + let script_start_finder = Finder::new(SCRIPT_START); + let script_end_finder = Finder::new(SCRIPT_END); + + let mut pointer = 0; + + // find opening "" + let offset = self.source_text[pointer..].find('>')?; + + // get lang="ts" attribute + let content = &self.source_text[pointer..pointer + offset]; + let is_ts = content.contains("ts"); + + pointer += offset + 1; + let js_start = pointer; + + // find "" + let offset = script_end_finder.find(self.source_text[pointer..].as_bytes())?; + let js_end = pointer + offset; + + let source_text = &self.source_text[js_start..js_end]; + let source_type = SourceType::default().with_module(true).with_typescript(is_ts); + Some(JavaScriptSource::new(source_text, source_type)) + } +} diff --git a/crates/oxc_linter/src/partial_loader/vue.rs b/crates/oxc_linter/src/partial_loader/vue.rs index 8b21a2001..7aff48eb9 100644 --- a/crates/oxc_linter/src/partial_loader/vue.rs +++ b/crates/oxc_linter/src/partial_loader/vue.rs @@ -2,10 +2,7 @@ use memchr::memmem::Finder; use oxc_span::SourceType; -use super::JavaScriptSource; - -const SCRIPT_START: &str = " { source_text: &'a str, diff --git a/crates/oxc_linter/src/service.rs b/crates/oxc_linter/src/service.rs index b03fa2a09..17543f0d1 100644 --- a/crates/oxc_linter/src/service.rs +++ b/crates/oxc_linter/src/service.rs @@ -159,20 +159,6 @@ impl Runtime { Some(Ok((source_type, source_text))) } - /// Extract js section of specifial files. - /// Returns `None` if the specifial file does not have a js section. - fn extract_js<'a>( - source_text: &'a str, - source_type: SourceType, - ext: &str, - ) -> Vec> { - match ext { - "vue" => PartialLoader::Vue.build(source_text), - "astro" => PartialLoader::Astro.build(source_text), - _ => vec![JavaScriptSource::new(source_text, source_type)], - } - } - fn process_path(&self, path: &Path, tx_error: &DiagnosticSender) { if self.init_cache_state(path) { return; @@ -188,7 +174,9 @@ impl Runtime { return; } }; - let sources = Self::extract_js(&source_text, source_type, ext); + + let sources = PartialLoader::parse(ext, &source_text) + .unwrap_or_else(|| vec![JavaScriptSource::new(&source_text, source_type)]); if sources.is_empty() { return;