Skip to content

Commit

Permalink
fix(es/compat): Support vars from reserved_word pass (#8543)
Browse files Browse the repository at this point in the history
**Related issue:**

 - Closes #8539
  • Loading branch information
kdy1 authored Jan 23, 2024
1 parent ecd9403 commit fc929e9
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 25 deletions.
21 changes: 21 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8539/input/.swcrc
Original file line number Diff line number Diff line change
@@ -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"
}
}
3 changes: 3 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8539/input/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const goto = () => {
return null
}
4 changes: 4 additions & 0 deletions crates/swc/tests/fixture/issues-8xxx/8539/output/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
var _goto = function() {
return null;
};
export { _goto as goto };
95 changes: 70 additions & 25 deletions crates/swc_ecma_compat_es3/src/reserved_word.rs
Original file line number Diff line number Diff line change
@@ -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`
///
Expand All @@ -27,39 +26,85 @@ struct ReservedWord {
pub preserve_import: bool,
}

#[swc_trace]
impl VisitMut for ReservedWord {
noop_visit_mut_type!();

fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
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());

ident.map(|ident| (ident, decl.take()))
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!()
}
};

if !ident.is_reserved_in_es3() {
return;
}

*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(),
);
}
_ => 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,

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;
}
.into(),
);

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);
Expand Down

0 comments on commit fc929e9

Please sign in to comment.