From fc929e962ba18afa98ae4523e50ff630527a218f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 23 Jan 2024 13:23:48 +0900 Subject: [PATCH] fix(es/compat): Support vars from `reserved_word` pass (#8543) **Related issue:** - Closes #8539 --- .../{issue-8475 => 8475}/input/.swcrc | 0 .../{issue-8475 => 8475}/input/1.js | 0 .../{issue-8475 => 8475}/output/1.js | 0 .../fixture/issues-8xxx/8539/input/.swcrc | 21 ++++ .../fixture/issues-8xxx/8539/input/input.js | 3 + .../fixture/issues-8xxx/8539/output/input.js | 4 + .../swc_ecma_compat_es3/src/reserved_word.rs | 95 ++++++++++++++----- 7 files changed, 98 insertions(+), 25 deletions(-) rename crates/swc/tests/fixture/issues-8xxx/{issue-8475 => 8475}/input/.swcrc (100%) rename crates/swc/tests/fixture/issues-8xxx/{issue-8475 => 8475}/input/1.js (100%) rename crates/swc/tests/fixture/issues-8xxx/{issue-8475 => 8475}/output/1.js (100%) create mode 100644 crates/swc/tests/fixture/issues-8xxx/8539/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-8xxx/8539/input/input.js create mode 100644 crates/swc/tests/fixture/issues-8xxx/8539/output/input.js diff --git a/crates/swc/tests/fixture/issues-8xxx/issue-8475/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8475/input/.swcrc similarity index 100% rename from crates/swc/tests/fixture/issues-8xxx/issue-8475/input/.swcrc rename to crates/swc/tests/fixture/issues-8xxx/8475/input/.swcrc diff --git a/crates/swc/tests/fixture/issues-8xxx/issue-8475/input/1.js b/crates/swc/tests/fixture/issues-8xxx/8475/input/1.js similarity index 100% rename from crates/swc/tests/fixture/issues-8xxx/issue-8475/input/1.js rename to crates/swc/tests/fixture/issues-8xxx/8475/input/1.js diff --git a/crates/swc/tests/fixture/issues-8xxx/issue-8475/output/1.js b/crates/swc/tests/fixture/issues-8xxx/8475/output/1.js similarity index 100% rename from crates/swc/tests/fixture/issues-8xxx/issue-8475/output/1.js rename to crates/swc/tests/fixture/issues-8xxx/8475/output/1.js diff --git a/crates/swc/tests/fixture/issues-8xxx/8539/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8539/input/.swcrc new file mode 100644 index 00000000000..f27ee21fde8 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8539/input/.swcrc @@ -0,0 +1,21 @@ +{ + "jsc": { + "parser": { + "syntax": "ecmascript", + "jsx": false + }, + "loose": false, + "minify": { + "compress": false, + "mangle": false + } + }, + "module": { + "type": "es6" + }, + "minify": false, + "isModule": true, + "env": { + "targets": "chrome >= 12" + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8539/input/input.js b/crates/swc/tests/fixture/issues-8xxx/8539/input/input.js new file mode 100644 index 00000000000..9e5ac82e3f3 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8539/input/input.js @@ -0,0 +1,3 @@ +export const goto = () => { + return null +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8539/output/input.js b/crates/swc/tests/fixture/issues-8xxx/8539/output/input.js new file mode 100644 index 00000000000..15fb1179e43 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8539/output/input.js @@ -0,0 +1,4 @@ +var _goto = function() { + return null; +}; +export { _goto as goto }; diff --git a/crates/swc_ecma_compat_es3/src/reserved_word.rs b/crates/swc_ecma_compat_es3/src/reserved_word.rs index 0918ed78c75..f4c6826d4db 100644 --- a/crates/swc_ecma_compat_es3/src/reserved_word.rs +++ b/crates/swc_ecma_compat_es3/src/reserved_word.rs @@ -1,7 +1,6 @@ use swc_common::{util::take::Take, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith}; -use swc_trace_macro::swc_trace; /// babel: `@babel/plugin-transform-reserved-words` /// @@ -27,7 +26,6 @@ struct ReservedWord { pub preserve_import: bool, } -#[swc_trace] impl VisitMut for ReservedWord { noop_visit_mut_type!(); @@ -35,31 +33,78 @@ impl VisitMut for ReservedWord { let mut extra_exports = vec![]; n.iter_mut().for_each(|module_item| { - if let Some((ident, decl)) = match module_item { - ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { decl, .. })) => { - let ident = decl - .as_fn_decl() - .filter(|fn_decl| fn_decl.ident.is_reserved_in_es3()) - .map(|fn_decl| fn_decl.ident.clone()); + match module_item { + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: decl @ Decl::Fn(..) | decl @ Decl::Class(..), + .. + })) => { + let ident = match decl { + Decl::Class(d) => d.ident.clone(), + Decl::Fn(d) => d.ident.clone(), + _ => { + unreachable!() + } + }; - ident.map(|ident| (ident, decl.take())) - } - _ => None, - } { - *module_item = ModuleItem::Stmt(decl.into()); - - let mut orig = ident.clone(); - orig.visit_mut_with(self); - - extra_exports.push( - ExportNamedSpecifier { - span: DUMMY_SP, - orig: orig.into(), - exported: Some(ident.into()), - is_type_only: false, + if !ident.is_reserved_in_es3() { + return; } - .into(), - ); + + *module_item = ModuleItem::Stmt(decl.take().into()); + + let mut orig = ident.clone(); + orig.visit_mut_with(self); + + extra_exports.push( + ExportNamedSpecifier { + span: DUMMY_SP, + orig: orig.into(), + exported: Some(ident.into()), + is_type_only: false, + } + .into(), + ); + } + + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Var(var), + .. + })) => { + if var.decls.iter().all(|var| { + if let Pat::Ident(i) = &var.name { + !i.id.sym.is_reserved_in_es3() + } else { + true + } + }) { + return; + } + + for var in &var.decls { + let ident = var.name.clone().expect_ident().id; + + if !ident.is_reserved_in_es3() { + return; + } + + let mut orig = ident.clone(); + orig.visit_mut_with(self); + + extra_exports.push( + ExportNamedSpecifier { + span: DUMMY_SP, + orig: orig.into(), + exported: Some(ident.into()), + is_type_only: false, + } + .into(), + ); + } + + *module_item = ModuleItem::Stmt(Decl::Var(var.take()).into()); + } + + _ => {} } module_item.visit_mut_with(self);