mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(codegen): move string test to codegen (#2150)
This commit is contained in:
parent
2406e94c0d
commit
1ee6d8cea9
3 changed files with 174 additions and 91 deletions
|
|
@ -1075,10 +1075,79 @@ impl<const MINIFY: bool> Gen<MINIFY> for RegExpLiteral {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_str<const MINIFY: bool>(s: &str, p: &mut Codegen<{ MINIFY }>) {
|
||||
p.print(b'\'');
|
||||
fn choose_quote(s: &str) -> char {
|
||||
let mut single_cost = 0;
|
||||
let mut double_cost = 0;
|
||||
for c in s.chars() {
|
||||
match c {
|
||||
'\'' => single_cost += 1,
|
||||
'"' => double_cost += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if single_cost > double_cost {
|
||||
'"'
|
||||
} else {
|
||||
'\''
|
||||
}
|
||||
}
|
||||
|
||||
fn print_str<const MINIFY: bool>(s: &str, p: &mut Codegen<{ MINIFY }>) {
|
||||
let quote = choose_quote(s);
|
||||
p.print(quote as u8);
|
||||
let mut chars = s.chars();
|
||||
|
||||
while let Some(c) = chars.next() {
|
||||
match c {
|
||||
'\x00' => {
|
||||
if chars.clone().next().is_some_and(|next| next.is_ascii_digit()) {
|
||||
p.print_str(b"\\x00");
|
||||
} else {
|
||||
p.print_str(b"\\0");
|
||||
}
|
||||
}
|
||||
'\x07' => {
|
||||
p.print_str(b"\\x07");
|
||||
}
|
||||
// \b
|
||||
'\u{8}' => {
|
||||
p.print_str(b"\\b");
|
||||
}
|
||||
// \v
|
||||
'\u{b}' => {
|
||||
p.print_str(b"\\v");
|
||||
}
|
||||
// \f
|
||||
'\u{c}' => {
|
||||
p.print_str(b"\\f");
|
||||
}
|
||||
'\n' => {
|
||||
p.print_str(b"\\n");
|
||||
}
|
||||
'\r' => {
|
||||
p.print_str(b"\\r");
|
||||
}
|
||||
'\x1B' => {
|
||||
p.print_str(b"\\x1B");
|
||||
}
|
||||
'\\' => {
|
||||
p.print_str(b"\\\\");
|
||||
}
|
||||
'\'' => {
|
||||
if quote == '\'' {
|
||||
p.print_str(b"\\'");
|
||||
} else {
|
||||
p.print_str(b"'");
|
||||
}
|
||||
}
|
||||
'\"' => {
|
||||
if quote == '"' {
|
||||
p.print_str(b"\\\"");
|
||||
} else {
|
||||
p.print_str(b"\"");
|
||||
}
|
||||
}
|
||||
// Allow `U+2028` and `U+2029` in string literals
|
||||
// <https://tc39.es/proposal-json-superset>
|
||||
// <https://github.com/tc39/proposal-json-superset>
|
||||
|
|
@ -1090,7 +1159,7 @@ fn print_str<const MINIFY: bool>(s: &str, p: &mut Codegen<{ MINIFY }>) {
|
|||
_ => p.print_str(c.escape_default().to_string().as_bytes()),
|
||||
}
|
||||
}
|
||||
p.print(b'\'');
|
||||
p.print(quote as u8);
|
||||
}
|
||||
|
||||
impl<const MINIFY: bool> Gen<MINIFY> for StringLiteral {
|
||||
|
|
|
|||
102
crates/oxc_codegen/tests/mod.rs
Normal file
102
crates/oxc_codegen/tests/mod.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
use oxc_allocator::Allocator;
|
||||
use oxc_codegen::{Codegen, CodegenOptions};
|
||||
use oxc_parser::Parser;
|
||||
use oxc_span::SourceType;
|
||||
|
||||
fn test(source_text: &str, expected: &str) {
|
||||
let allocator = Allocator::default();
|
||||
let program = Parser::new(&allocator, source_text, SourceType::default()).parse().program;
|
||||
let program = allocator.alloc(program);
|
||||
let result = Codegen::<false>::new(source_text.len(), CodegenOptions).build(program);
|
||||
assert_eq!(expected, result, "for source {source_text}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string() {
|
||||
test("let x = ''", "let x = '';\n");
|
||||
test(r"let x = '\b'", "let x = '\\b';\n");
|
||||
test(r"let x = '\f'", "let x = '\\f';\n");
|
||||
test("let x = '\t'", "let x = '\\t';\n");
|
||||
test(r"let x = '\v'", "let x = '\\v';\n");
|
||||
test("let x = '\\n'", "let x = '\\n';\n");
|
||||
test("let x = '\\''", "let x = \"'\";\n");
|
||||
test("let x = '\\\"'", "let x = '\"';\n");
|
||||
// test( "let x = '\\'''", "let x = `''`;\n");
|
||||
test("let x = '\\\\'", "let x = '\\\\';\n");
|
||||
test("let x = '\x00'", "let x = '\\0';\n");
|
||||
test("let x = '\x00!'", "let x = '\\0!';\n");
|
||||
test("let x = '\x001'", "let x = '\\x001';\n");
|
||||
test("let x = '\\0'", "let x = '\\0';\n");
|
||||
test("let x = '\\0!'", "let x = '\\0!';\n");
|
||||
test("let x = '\x07'", "let x = '\\x07';\n");
|
||||
test("let x = '\x07!'", "let x = '\\x07!';\n");
|
||||
test("let x = '\x071'", "let x = '\\x071';\n");
|
||||
test("let x = '\\7'", "let x = '\\x07';\n");
|
||||
test("let x = '\\7!'", "let x = '\\x07!';\n");
|
||||
// test( "let x = '\\01'", "let x = '\x01';\n");
|
||||
// test( "let x = '\x10'", "let x = '\x10';\n");
|
||||
// test( "let x = '\\x10'", "let x = '\x10';\n");
|
||||
test("let x = '\x1B'", "let x = '\\x1B';\n");
|
||||
test("let x = '\\x1B'", "let x = '\\x1B';\n");
|
||||
// test( r#"let x = '\uABCD'"#, r#"let x = "\uABCD";"#);
|
||||
// test( "let x = '\\uABCD'", r#"let x = '\uABCD';\n"#);
|
||||
// test( r#"let x = '\U000123AB'"#, r#"let x = '\U000123AB';\n"#);
|
||||
// test( "let x = '\\u{123AB}'", r#"let x = '\U000123AB';\n"#);
|
||||
// test( "let x = '\\uD808\\uDFAB'", r#"let x = '\U000123AB';\n"#);
|
||||
test("let x = '\\uD808'", "let x = '\\\\ud808';\n");
|
||||
test("let x = '\\uD808X'", "let x = '\\\\ud808X';\n");
|
||||
test("let x = '\\uDFAB'", "let x = '\\\\udfab';\n");
|
||||
test("let x = '\\uDFABX'", "let x = '\\\\udfabX';\n");
|
||||
|
||||
// test( "let x = '\\x80'", r#"let x = '\U00000080';\n"#);
|
||||
// test( "let x = '\\xFF'", r#"let x = '\U000000FF';\n"#);
|
||||
// test( "let x = '\\xF0\\x9F\\x8D\\x95'", r#"let x = '\U000000F0\U0000009F\U0000008D\U00000095';\n"#);
|
||||
// test("let x = '\\uD801\\uDC02\\uDC03\\uD804'", r#"let x = '\U00010402\\uDC03\\uD804';\n"#)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn template() {
|
||||
test("let x = `\\0`", "let x = `\\0`;\n");
|
||||
test("let x = `\\x01`", "let x = `\x01`;\n");
|
||||
test("let x = `\\0${0}`", "let x = `\\0${0}`;\n");
|
||||
test("let x = `\\x01${0}`", "let x = `\x01${0}`;\n");
|
||||
test("let x = `${0}\\0`", "let x = `${0}\\0`;\n");
|
||||
test("let x = `${0}\\x01`", "let x = `${0}\x01`;\n");
|
||||
test("let x = `${0}\\0${1}`", "let x = `${0}\\0${1}`;\n");
|
||||
test("let x = `${0}\\x01${1}`", "let x = `${0}\x01${1}`;\n");
|
||||
|
||||
test("let x = String.raw`\\1`", "let x = String.raw`\\1`;\n");
|
||||
test("let x = String.raw`\\x01`", "let x = String.raw`\\x01`;\n");
|
||||
test("let x = String.raw`\\1${0}`", "let x = String.raw`\\1${0}`;\n");
|
||||
test("let x = String.raw`\\x01${0}`", "let x = String.raw`\\x01${0}`;\n");
|
||||
test("let x = String.raw`${0}\\1`", "let x = String.raw`${0}\\1`;\n");
|
||||
test("let x = String.raw`${0}\\x01`", "let x = String.raw`${0}\\x01`;\n");
|
||||
test("let x = String.raw`${0}\\1${1}`", "let x = String.raw`${0}\\1${1}`;\n");
|
||||
test("let x = String.raw`${0}\\x01${1}`", "let x = String.raw`${0}\\x01${1}`;\n");
|
||||
|
||||
test("let x = `${y}`", "let x = `${y}`;\n");
|
||||
test("let x = `$(y)`", "let x = `$(y)`;\n");
|
||||
test("let x = `{y}$`", "let x = `{y}$`;\n");
|
||||
test("let x = `$}y{`", "let x = `$}y{`;\n");
|
||||
test("let x = `\\${y}`", "let x = `\\${y}`;\n");
|
||||
test("let x = `$\\{y}`", "let x = `\\${y}`;\n");
|
||||
|
||||
test("await tag`x`", "await tag`x`;\n");
|
||||
test("await (tag`x`)", "await tag`x`;\n");
|
||||
test("(await tag)`x`", "(await tag)`x`;\n");
|
||||
|
||||
test("await tag`${x}`", "await tag`${x}`;\n");
|
||||
test("await (tag`${x}`)", "await tag`${x}`;\n");
|
||||
test("(await tag)`${x}`", "(await tag)`${x}`;\n");
|
||||
|
||||
test("new tag`x`", "new tag`x`();\n");
|
||||
test("new (tag`x`)", "new tag`x`();\n");
|
||||
test("new tag()`x`", "new tag()`x`;\n");
|
||||
test("(new tag)`x`", "new tag()`x`;\n");
|
||||
|
||||
test("new tag`${x}`", "new tag`${x}`();\n");
|
||||
test("new (tag`${x}`)", "new tag`${x}`();\n");
|
||||
test("new tag()`${x}`", "new tag()`${x}`;\n");
|
||||
test("(new tag)`${x}`", "new tag()`${x}`;\n");
|
||||
}
|
||||
|
|
@ -171,102 +171,14 @@ fn nullish() {
|
|||
test("(a ?? b) || c", "(a??b)||c;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn string() {
|
||||
test("let x = ''", "let x = \"\";");
|
||||
test("let x = '\\b'", "let x = \"\\b\";");
|
||||
test("let x = '\\f'", "let x = \"\\f\";");
|
||||
test("let x = '\t'", "let x = \"\t\";");
|
||||
test("let x = '\\v'", "let x = \"\\v\";");
|
||||
test("let x = '\\n'", "let x = \"\\n\";");
|
||||
test("let x = '\\''", "let x = \"'\";");
|
||||
test("let x = '\\\"'", "let x = '\"';");
|
||||
test("let x = '\\'\"'", "let x = `'\"`;");
|
||||
test("let x = '\\\\'", "let x = \"\\\\\";");
|
||||
test("let x = '\x00'", "let x = \"\\0\";");
|
||||
test("let x = '\x00!'", "let x = \"\\0!\";");
|
||||
test("let x = '\x001'", "let x = \"\\x001\";");
|
||||
test("let x = '\\0'", "let x = \"\\0\";");
|
||||
test("let x = '\\0!'", "let x = \"\\0!\";");
|
||||
test("let x = '\x07'", "let x = \"\\x07\";");
|
||||
test("let x = '\x07!'", "let x = \"\\x07!\";");
|
||||
test("let x = '\x071'", "let x = \"\\x071\";");
|
||||
test("let x = '\\7'", "let x = \"\\x07\";");
|
||||
test("let x = '\\7!'", "let x = \"\\x07!\";");
|
||||
test("let x = '\\01'", "let x = \"\x01\";");
|
||||
test("let x = '\x10'", "let x = \"\x10\";");
|
||||
test("let x = '\\x10'", "let x = \"\x10\";");
|
||||
test("let x = '\x1B'", "let x = \"\\x1B\";");
|
||||
test("let x = '\\x1B'", "let x = \"\\x1B\";");
|
||||
test("let x = '\\uABCD'", "let x = \"\\uABCD\";");
|
||||
test("let x = '\\uABCD'", "let x = \"\\uABCD\";");
|
||||
test("let x = '\\U000123AB'", "let x = \"\\U000123AB\";");
|
||||
test("let x = '\\u{123AB}'", "let x = \"\\U000123AB\";");
|
||||
test("let x = '\\uD808\\uDFAB'", "let x = \"\\U000123AB\";");
|
||||
test("let x = '\\uD808'", "let x = \"\\uD808\";");
|
||||
test("let x = '\\uD808X'", "let x = \"\\uD808X\";");
|
||||
test("let x = '\\uDFAB'", "let x = \"\\uDFAB\";");
|
||||
test("let x = '\\uDFABX'", "let x = \"\\uDFABX\";");
|
||||
|
||||
test("let x = '\\x80'", "let x = \"\\U00000080\";");
|
||||
test("let x = '\\xFF'", "let x = \"\\U000000FF\";");
|
||||
test(
|
||||
"let x = '\\xF0\\x9F\\x8D\\x95'",
|
||||
"let x = \"\\U000000F0\\U0000009F\\U0000008D\\U00000095\"",
|
||||
);
|
||||
test("let x = '\\uD801\\uDC02\\uDC03\\uD804'", "let x = \"\\U00010402\\uDC03\\uD804\";");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn template() {
|
||||
test("let x = `\\0`", "let x = `\\0`;");
|
||||
test("let x = `\\x01`", "let x = `\x01`;");
|
||||
test("let x = `\\0${0}`", "let x = `\\0${0}`;");
|
||||
test("let x = `\\x01${0}`", "let x = `\x01${0}`;");
|
||||
test("let x = `${0}\\0`", "let x = `${0}\\0`;");
|
||||
test("let x = `${0}\\x01`", "let x = `${0}\x01`;");
|
||||
test("let x = `${0}\\0${1}`", "let x = `${0}\\0${1}`;");
|
||||
test("let x = `${0}\\x01${1}`", "let x = `${0}\x01${1}`;");
|
||||
|
||||
test("let x = String.raw`\\1`", "let x = String.raw`\\1`;");
|
||||
test("let x = String.raw`\\x01`", "let x = String.raw`\\x01`;");
|
||||
test("let x = String.raw`\\1${0}`", "let x = String.raw`\\1${0}`;");
|
||||
test("let x = String.raw`\\x01${0}`", "let x = String.raw`\\x01${0}`;");
|
||||
test("let x = String.raw`${0}\\1`", "let x = String.raw`${0}\\1`;");
|
||||
test("let x = String.raw`${0}\\x01`", "let x = String.raw`${0}\\x01`;");
|
||||
test("let x = String.raw`${0}\\1${1}`", "let x = String.raw`${0}\\1${1}`;");
|
||||
test("let x = String.raw`${0}\\x01${1}`", "let x = String.raw`${0}\\x01${1}`;");
|
||||
|
||||
test("let x = `${y}`", "let x = `${y}`;");
|
||||
test("let x = `$(y)`", "let x = `$(y)`;");
|
||||
test("let x = `{y}$`", "let x = `{y}$`;");
|
||||
test("let x = `$}y{`", "let x = `$}y{`;");
|
||||
test("let x = `\\${y}`", "let x = `\\${y}`;");
|
||||
test("let x = `$\\{y}`", "let x = `\\${y}`;");
|
||||
|
||||
test("await tag`x`", "await tag`x`;");
|
||||
test("await (tag`x`)", "await tag`x`;");
|
||||
test("(await tag)`x`", "(await tag)`x`;");
|
||||
|
||||
test("await tag`${x}`", "await tag`${x}`;");
|
||||
test("await (tag`${x}`)", "await tag`${x}`;");
|
||||
test("(await tag)`${x}`", "(await tag)`${x}`;");
|
||||
|
||||
test("new tag`x`", "new tag`x`();");
|
||||
test("new (tag`x`)", "new tag`x`();");
|
||||
test("new tag()`x`", "new tag()`x`;");
|
||||
test("(new tag)`x`", "new tag()`x`;");
|
||||
test("new tag`x`", "new tag`x`;;");
|
||||
test("new (tag`x`)", "new tag`x`;;");
|
||||
test("new tag()`x`", "new tag()`x`;;");
|
||||
test("(new tag)`x`", "new tag()`x`;;");
|
||||
|
||||
test("new tag`${x}`", "new tag`${x}`();");
|
||||
test("new (tag`${x}`)", "new tag`${x}`();");
|
||||
test("new tag()`${x}`", "new tag()`${x}`;");
|
||||
test("(new tag)`${x}`", "new tag()`${x}`;");
|
||||
test("new tag`${x}`", "new tag`${x}`;;");
|
||||
test("new (tag`${x}`)", "new tag`${x}`;;");
|
||||
test("new tag()`${x}`", "new tag()`${x}`;;");
|
||||
|
|
|
|||
Loading…
Reference in a new issue