mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
While looking into this, I knew vue would have similar problems. Which then led me to realize the generic case was handled already so I tried abstract out the function so both the vue and svelte partial loaders could reuse the code. Finally added some svelte test cases to prove this resolved the issue. I am a bit new to rust so if there was a better way to reuse the find_script_closing_angle function open to suggestions.
This commit is contained in:
parent
65f38dc0db
commit
1cd5e7511b
3 changed files with 61 additions and 25 deletions
|
|
@ -40,3 +40,24 @@ impl PartialLoader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Find closing angle for situations where there is another `>` in between.
|
||||
/// e.g. `<script generic="T extends Record<string, string>">`
|
||||
fn find_script_closing_angle(source_text: &str, pointer: usize) -> Option<usize> {
|
||||
let mut numbers_of_open_angle = 0;
|
||||
for (offset, c) in source_text[pointer..].char_indices() {
|
||||
match c {
|
||||
'>' => {
|
||||
if numbers_of_open_angle == 0 {
|
||||
return Some(offset);
|
||||
}
|
||||
numbers_of_open_angle -= 1;
|
||||
}
|
||||
'<' => {
|
||||
numbers_of_open_angle += 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use memchr::memmem::Finder;
|
|||
|
||||
use oxc_span::SourceType;
|
||||
|
||||
use super::{JavaScriptSource, SCRIPT_END, SCRIPT_START};
|
||||
use super::{find_script_closing_angle, JavaScriptSource, SCRIPT_END, SCRIPT_START};
|
||||
|
||||
pub struct SveltePartialLoader<'a> {
|
||||
source_text: &'a str,
|
||||
|
|
@ -28,7 +28,7 @@ impl<'a> SveltePartialLoader<'a> {
|
|||
pointer += offset + SCRIPT_START.len();
|
||||
|
||||
// find closing ">"
|
||||
let offset = self.source_text[pointer..].find('>')?;
|
||||
let offset = find_script_closing_angle(self.source_text, pointer)?;
|
||||
|
||||
// get lang="ts" attribute
|
||||
let content = &self.source_text[pointer..pointer + offset];
|
||||
|
|
@ -46,3 +46,39 @@ impl<'a> SveltePartialLoader<'a> {
|
|||
Some(JavaScriptSource::new(source_text, source_type, js_start))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{JavaScriptSource, SveltePartialLoader};
|
||||
|
||||
fn parse_svelte(source_text: &str) -> JavaScriptSource<'_> {
|
||||
let sources = SveltePartialLoader::new(source_text).parse();
|
||||
*sources.first().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_svelte() {
|
||||
let source_text = r#"
|
||||
<script>
|
||||
console.log("hi");
|
||||
</script>
|
||||
<h1>Hello World</h1>
|
||||
"#;
|
||||
|
||||
let result = parse_svelte(source_text);
|
||||
assert_eq!(result.source_text.trim(), r#"console.log("hi");"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_svelte_ts_with_generic() {
|
||||
let source_text = r#"
|
||||
<script lang="ts" generics="T extends Record<string, unknown>">
|
||||
console.log("hi");
|
||||
</script>
|
||||
<h1>Hello World</h1>
|
||||
"#;
|
||||
|
||||
let result = parse_svelte(source_text);
|
||||
assert_eq!(result.source_text.trim(), r#"console.log("hi");"#);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use memchr::memmem::Finder;
|
|||
|
||||
use oxc_span::SourceType;
|
||||
|
||||
use super::{JavaScriptSource, SCRIPT_END, SCRIPT_START};
|
||||
use super::{find_script_closing_angle, JavaScriptSource, SCRIPT_END, SCRIPT_START};
|
||||
|
||||
pub struct VuePartialLoader<'a> {
|
||||
source_text: &'a str,
|
||||
|
|
@ -37,7 +37,7 @@ impl<'a> VuePartialLoader<'a> {
|
|||
*pointer += offset + SCRIPT_START.len();
|
||||
|
||||
// find closing ">"
|
||||
let offset = self.find_script_closing_angle(*pointer)?;
|
||||
let offset = find_script_closing_angle(self.source_text, *pointer)?;
|
||||
|
||||
// get ts and jsx attribute
|
||||
let content = &self.source_text[*pointer..*pointer + offset];
|
||||
|
|
@ -57,27 +57,6 @@ impl<'a> VuePartialLoader<'a> {
|
|||
SourceType::default().with_module(true).with_typescript(is_ts).with_jsx(is_jsx);
|
||||
Some(JavaScriptSource::new(source_text, source_type, js_start))
|
||||
}
|
||||
|
||||
/// Find closing angle for situations where there is another `>` in between.
|
||||
/// e.g. `<script generic="T extends Record<string, string>">`
|
||||
fn find_script_closing_angle(&self, pointer: usize) -> Option<usize> {
|
||||
let mut numbers_of_open_angle = 0;
|
||||
for (offset, c) in self.source_text[pointer..].char_indices() {
|
||||
match c {
|
||||
'>' => {
|
||||
if numbers_of_open_angle == 0 {
|
||||
return Some(offset);
|
||||
}
|
||||
numbers_of_open_angle -= 1;
|
||||
}
|
||||
'<' => {
|
||||
numbers_of_open_angle += 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue