From 3a26d3d34dcbcaee30dc700a385dd18b7427e3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 9 Sep 2020 15:16:44 +0900 Subject: [PATCH] Do not rename keywords in meta properties (#1053) --- ecmascript/transforms/Cargo.toml | 2 +- ecmascript/transforms/macros/Cargo.toml | 2 +- ecmascript/transforms/macros/src/fast.rs | 8 +- .../transforms/src/compat/reserved_words.rs | 80 +++++++++---------- tests/projects.rs | 8 ++ tests/projects/issue-1052/.swcrc | 8 ++ tests/projects/issue-1052/input.ts | 7 ++ 7 files changed, 70 insertions(+), 45 deletions(-) create mode 100644 tests/projects/issue-1052/.swcrc create mode 100644 tests/projects/issue-1052/input.ts diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml index 32da88d54284..e02fc04c65f4 100644 --- a/ecmascript/transforms/Cargo.toml +++ b/ecmascript/transforms/Cargo.toml @@ -36,7 +36,7 @@ swc_atoms = {version = "0.2.0", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} swc_ecma_ast = {version = "0.31.0", path = "../ast"} swc_ecma_parser = {version = "0.37.0", path = "../parser"} -swc_ecma_transforms_macros = {version = "0.1.0", path = "./macros"} +swc_ecma_transforms_macros = {version = "0.1.1", path = "./macros"} swc_ecma_utils = {version = "0.21.0", path = "../utils"} swc_ecma_visit = {version = "0.17.0", path = "../visit"} unicode-xid = "0.2" diff --git a/ecmascript/transforms/macros/Cargo.toml b/ecmascript/transforms/macros/Cargo.toml index 9d9553478ce5..d0c63eebdea2 100644 --- a/ecmascript/transforms/macros/Cargo.toml +++ b/ecmascript/transforms/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "swc_ecma_transforms_macros" -version = "0.1.0" +version = "0.1.1" authors = ["강동윤 "] license = "Apache-2.0/MIT" repository = "https://github.com/swc-project/swc.git" diff --git a/ecmascript/transforms/macros/src/fast.rs b/ecmascript/transforms/macros/src/fast.rs index 69357e2a3270..0b74a4a06268 100644 --- a/ecmascript/transforms/macros/src/fast.rs +++ b/ecmascript/transforms/macros/src/fast.rs @@ -95,7 +95,7 @@ impl Expander { }, { fn method(&mut self, node: &mut Type) { - node.visit_mut_with(self) + node.visit_mut_children_with(self) } } ), @@ -118,6 +118,12 @@ impl Expander { FnArg::Receiver(_) => unreachable!(), FnArg::Typed(ty) => ty, }; + if m.sig.ident == "visit_mut_ident" || m.sig.ident == "fold_ident" { + return m; + } + if m.block.stmts.is_empty() { + return m; + } let arg = match &*ty_arg.pat { Pat::Ident(i) => &i.ident, diff --git a/ecmascript/transforms/src/compat/reserved_words.rs b/ecmascript/transforms/src/compat/reserved_words.rs index ff4b5250fac3..2c2945961e4f 100644 --- a/ecmascript/transforms/src/compat/reserved_words.rs +++ b/ecmascript/transforms/src/compat/reserved_words.rs @@ -2,60 +2,55 @@ use crate::perf::Check; use swc_atoms::JsWord; use swc_ecma_ast::*; use swc_ecma_transforms_macros::fast_path; -use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit}; +use swc_ecma_visit::{ + as_folder, noop_visit_mut_type, noop_visit_type, Fold, Node, Visit, VisitMut, VisitMutWith, +}; pub fn reserved_words() -> impl 'static + Fold { - EsReservedWord {} + as_folder(EsReservedWord) } -struct EsReservedWord {} +struct EsReservedWord; #[fast_path(ShouldWork)] -impl Fold for EsReservedWord { - noop_fold_type!(); +impl VisitMut for EsReservedWord { + noop_visit_mut_type!(); - fn fold_export_specifier(&mut self, n: ExportSpecifier) -> ExportSpecifier { - n - } + fn visit_mut_export_specifier(&mut self, _n: &mut ExportSpecifier) {} - fn fold_ident(&mut self, i: Ident) -> Ident { - let sym = rename_ident(i.sym, true); + fn visit_mut_meta_prop_expr(&mut self, _n: &mut MetaPropExpr) {} - Ident { sym, ..i } + fn visit_mut_ident(&mut self, i: &mut Ident) { + rename_ident(&mut i.sym, true); } - fn fold_import_named_specifier(&mut self, s: ImportNamedSpecifier) -> ImportNamedSpecifier { - if s.imported.is_some() { - ImportNamedSpecifier { - local: s.local.fold_with(self), - ..s - } - } else { - ImportNamedSpecifier { - imported: s.imported.fold_with(self), - ..s - } - } + fn visit_mut_import_named_specifier(&mut self, s: &mut ImportNamedSpecifier) { + s.local.visit_mut_with(self); } - fn fold_member_expr(&mut self, e: MemberExpr) -> MemberExpr { + fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) { + match &e.obj { + ExprOrSuper::Super(_) => {} + ExprOrSuper::Expr(obj) => match &**obj { + Expr::Ident(Ident { + sym: js_word!("new"), + .. + }) + | Expr::Ident(Ident { + sym: js_word!("import"), + .. + }) => return, + _ => {} + }, + } + e.obj.visit_mut_with(self); + if e.computed { - MemberExpr { - obj: e.obj.fold_with(self), - prop: e.prop.fold_with(self), - ..e - } - } else { - MemberExpr { - obj: e.obj.fold_with(self), - ..e - } + e.prop.visit_mut_with(self); } } - fn fold_prop_name(&mut self, n: PropName) -> PropName { - n - } + fn visit_mut_prop_name(&mut self, _n: &mut PropName) {} } fn is_reserved(sym: &JsWord) -> bool { @@ -70,12 +65,11 @@ fn is_reserved(sym: &JsWord) -> bool { } } -fn rename_ident(sym: JsWord, _strict: bool) -> JsWord { +fn rename_ident(sym: &mut JsWord, _strict: bool) { // Es - if is_reserved(&sym) { - format!("_{}", sym).into() - } else { - sym + if is_reserved(&*sym) { + let s = format!("_{}", sym).into(); + *sym = s; } } #[derive(Default)] @@ -84,6 +78,8 @@ struct ShouldWork { } impl Visit for ShouldWork { + noop_visit_type!(); + fn visit_ident(&mut self, i: &Ident, _: &dyn Node) { if is_reserved(&i.sym) { self.found = true; diff --git a/tests/projects.rs b/tests/projects.rs index c6850ba21897..68d752d13f8b 100644 --- a/tests/projects.rs +++ b/tests/projects.rs @@ -557,3 +557,11 @@ fn issue_895() { assert!(!s.contains("_url.")); assert!(!s.contains("_url,")); } + +#[test] +fn issue_1052() { + let f = file("tests/projects/issue-1052/input.ts").unwrap(); + println!("{}", f); + + assert!(!f.contains("_new")) +} diff --git a/tests/projects/issue-1052/.swcrc b/tests/projects/issue-1052/.swcrc new file mode 100644 index 000000000000..ccea7488a8dd --- /dev/null +++ b/tests/projects/issue-1052/.swcrc @@ -0,0 +1,8 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript" + }, + "target": "es2018" + } +} diff --git a/tests/projects/issue-1052/input.ts b/tests/projects/issue-1052/input.ts new file mode 100644 index 000000000000..44b5193b02ec --- /dev/null +++ b/tests/projects/issue-1052/input.ts @@ -0,0 +1,7 @@ +class ArgumentValidationError extends Error { + constructor(public validationErrors: ValidationError[]) { + super("Argument Validation Error"); + + Object.setPrototypeOf(this, new.target.prototype); + } +} \ No newline at end of file