From d4be3833183b829bf39c0b53407b8892517256d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 8 May 2024 16:25:32 +0900 Subject: [PATCH] fix(es/minifier): Fix a bug about `Tpl` => `Str` (#8934) **Description:** I added the method to `swc_ecma_ast` to reuse it from plugins. **Related issue:** - Closes #8931 --- .../fixture/issues-8xxx/8931/input/.swcrc | 14 ++++++ .../tests/fixture/issues-8xxx/8931/input/1.js | 6 +++ .../tests/fixture/issues-8xxx/8931/input/2.js | 6 +++ .../fixture/issues-8xxx/8931/output/1.js | 1 + .../fixture/issues-8xxx/8931/output/2.js | 1 + crates/swc_ecma_ast/src/lit.rs | 48 +++++++++++++++++++ .../src/compress/pure/strings.rs | 13 +---- 7 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 crates/swc/tests/fixture/issues-8xxx/8931/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-8xxx/8931/input/1.js create mode 100644 crates/swc/tests/fixture/issues-8xxx/8931/input/2.js create mode 100644 crates/swc/tests/fixture/issues-8xxx/8931/output/1.js create mode 100644 crates/swc/tests/fixture/issues-8xxx/8931/output/2.js diff --git a/crates/swc/tests/fixture/issues-8xxx/8931/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8931/input/.swcrc new file mode 100644 index 000000000000..69928e405e0d --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8931/input/.swcrc @@ -0,0 +1,14 @@ +{ + // Enable minification + "minify": true, + // Optional, configure minification options + "jsc": { + "minify": { + "compress": { + "unused": true + }, + "mangle": true + }, + "target": "es2018" + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8931/input/1.js b/crates/swc/tests/fixture/issues-8xxx/8931/input/1.js new file mode 100644 index 000000000000..0052ec5a0841 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8931/input/1.js @@ -0,0 +1,6 @@ +export function _jsx(a, b) { + return b; +} + +export const a = _jsx("math", `P \\vdash q`) +export const b = _jsx("math", "P \\vdash q") \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8931/input/2.js b/crates/swc/tests/fixture/issues-8xxx/8931/input/2.js new file mode 100644 index 000000000000..05dd09faa3fa --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8931/input/2.js @@ -0,0 +1,6 @@ +export function _jsx(a, b) { + return b; +} + +export const a = _jsx("math", `\` \\vdash q`) +export const b = _jsx("math", "P \\vdash q") \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8931/output/1.js b/crates/swc/tests/fixture/issues-8xxx/8931/output/1.js new file mode 100644 index 000000000000..7954eba6a098 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8931/output/1.js @@ -0,0 +1 @@ +export function _jsx(t,s){return s}export const a=_jsx("math","P \\vdash q");export const b=_jsx("math","P \\vdash q"); diff --git a/crates/swc/tests/fixture/issues-8xxx/8931/output/2.js b/crates/swc/tests/fixture/issues-8xxx/8931/output/2.js new file mode 100644 index 000000000000..2d5a91a848e4 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8931/output/2.js @@ -0,0 +1 @@ +export function _jsx(t,s){return s}export const a=_jsx("math","` \\vdash q");export const b=_jsx("math","P \\vdash q"); diff --git a/crates/swc_ecma_ast/src/lit.rs b/crates/swc_ecma_ast/src/lit.rs index a682f8d9d62c..9c9249504c2e 100644 --- a/crates/swc_ecma_ast/src/lit.rs +++ b/crates/swc_ecma_ast/src/lit.rs @@ -196,6 +196,54 @@ impl Str { pub fn is_empty(&self) -> bool { self.value.is_empty() } + + pub fn from_tpl_raw(tpl_raw: &str) -> Atom { + let mut buf = String::with_capacity(tpl_raw.len()); + + let mut iter = tpl_raw.chars(); + + while let Some(c) = iter.next() { + match c { + '\\' => { + if let Some(next) = iter.next() { + match next { + '`' | '$' | '\\' => { + buf.push(next); + } + 'b' => { + buf.push('\u{0008}'); + } + 'f' => { + buf.push('\u{000C}'); + } + 'n' => { + buf.push('\n'); + } + 'r' => { + buf.push('\r'); + } + 't' => { + buf.push('\t'); + } + 'v' => { + buf.push('\u{000B}'); + } + _ => { + buf.push('\\'); + buf.push(next); + } + } + } + } + + c => { + buf.push(c); + } + } + } + + buf.into() + } } impl EqIgnoreSpan for Str { diff --git a/crates/swc_ecma_minifier/src/compress/pure/strings.rs b/crates/swc_ecma_minifier/src/compress/pure/strings.rs index 8e177d66fcaa..607de8011d00 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/strings.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/strings.rs @@ -220,23 +220,14 @@ impl Pure<'_> { && !c.contains("\\x") && !c.contains("\\u") { - let value = c - .replace("\\`", "`") - .replace("\\$", "$") - .replace("\\b", "\u{0008}") - .replace("\\f", "\u{000C}") - .replace("\\n", "\n") - .replace("\\r", "\r") - .replace("\\t", "\t") - .replace("\\v", "\u{000B}") - .replace("\\\\", "\\"); + let value = Str::from_tpl_raw(c); report_change!("converting a template literal to a string literal"); *e = Expr::Lit(Lit::Str(Str { span: t.span, raw: None, - value: value.into(), + value, })); } }