From 13b2f38cdd9b11b5a4e021ef3340458071d4a926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 22 Mar 2022 19:03:58 +0900 Subject: [PATCH] fix(es/typescript): Collect all bindings in `strip` (#4118) --- .../tests/fixture/issue-3686/1/input/.swcrc | 19 +++++++ .../tests/fixture/issue-3686/1/input/index.ts | 36 ++++++++++++++ .../fixture/issue-3686/1/output/index.ts | 49 +++++++++++++++++++ crates/swc_ecma_minifier/tests/eval.rs | 2 +- .../src/strip.rs | 13 +++++ 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 crates/swc/tests/fixture/issue-3686/1/input/.swcrc create mode 100644 crates/swc/tests/fixture/issue-3686/1/input/index.ts create mode 100644 crates/swc/tests/fixture/issue-3686/1/output/index.ts diff --git a/crates/swc/tests/fixture/issue-3686/1/input/.swcrc b/crates/swc/tests/fixture/issue-3686/1/input/.swcrc new file mode 100644 index 00000000000..a3abafb7f82 --- /dev/null +++ b/crates/swc/tests/fixture/issue-3686/1/input/.swcrc @@ -0,0 +1,19 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true, + "tsx": false + }, + "target": "es2022", + "loose": false, + "minify": { + "compress": false, + "mangle": false + } + }, + "module": { + "type": "commonjs" + }, + "minify": false +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issue-3686/1/input/index.ts b/crates/swc/tests/fixture/issue-3686/1/input/index.ts new file mode 100644 index 00000000000..38f0d2e191f --- /dev/null +++ b/crates/swc/tests/fixture/issue-3686/1/input/index.ts @@ -0,0 +1,36 @@ +const CD: ClassDecorator = () => { } +const PD: PropertyDecorator = () => { } + +// Commenting out the decorators creates valid ouput. +@CD +export class ServiceError extends Error { + @PD + readonly code: ServiceError.Code = ServiceError.Code.badResponse + readonly name: string = "ServiceError.BadResponse" +} + +export namespace ServiceError { + export const enum Code { + serviceNotFound = 404, + serviceNotCompatible = 426, + serviceGone = 410, + implementation = 500, + timedOut = 504, + badRequest = 400, + badResponse = 422, + } + + export class ServiceNotFound extends ServiceError { + // Service was probably not registered, or using the wrong channel + readonly code = Code.serviceNotFound + readonly name = "ServiceError.ServiceNotFound" + } + + export function toMessageBody(error: unknown): { + code: number + message?: string + stack?: string + } { + return { code: ServiceError.Code.implementation } + } +} diff --git a/crates/swc/tests/fixture/issue-3686/1/output/index.ts b/crates/swc/tests/fixture/issue-3686/1/output/index.ts new file mode 100644 index 00000000000..c6ac640d9dd --- /dev/null +++ b/crates/swc/tests/fixture/issue-3686/1/output/index.ts @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ServiceError = void 0; +var swcHelpers = require("@swc/helpers"); +var _class, _descriptor; +const CD = ()=>{}; +const PD = ()=>{}; +let ServiceError = _class = CD(((_class = class ServiceError extends Error { + name = "ServiceError.BadResponse"; + constructor(...args){ + super(...args); + swcHelpers.initializerDefineProperty(this, "code", _descriptor, this); + } +}) || _class, _descriptor = swcHelpers.applyDecoratedDescriptor(_class.prototype, "code", [ + PD +], { + configurable: true, + enumerable: true, + writable: true, + initializer: function() { + return ServiceError.Code.badResponse; + } +}), _class)) || _class; +exports.ServiceError = ServiceError; +(function(ServiceError1) { + let Code; + (function(Code) { + Code[Code["serviceNotFound"] = 404] = "serviceNotFound"; + Code[Code["serviceNotCompatible"] = 426] = "serviceNotCompatible"; + Code[Code["serviceGone"] = 410] = "serviceGone"; + Code[Code["implementation"] = 500] = "implementation"; + Code[Code["timedOut"] = 504] = "timedOut"; + Code[Code["badRequest"] = 400] = "badRequest"; + Code[Code["badResponse"] = 422] = "badResponse"; + })(Code = ServiceError1.Code || (ServiceError1.Code = {})); + class ServiceNotFound extends ServiceError { + code = 404; + name = "ServiceError.ServiceNotFound"; + } + ServiceError1.ServiceNotFound = ServiceNotFound; + function toMessageBody(error) { + return { + code: ServiceError.Code.implementation + }; + } + ServiceError1.toMessageBody = toMessageBody; +})(ServiceError || (exports.ServiceError = ServiceError = {})); diff --git a/crates/swc_ecma_minifier/tests/eval.rs b/crates/swc_ecma_minifier/tests/eval.rs index e329f12a0ed..5ca3c74ae73 100644 --- a/crates/swc_ecma_minifier/tests/eval.rs +++ b/crates/swc_ecma_minifier/tests/eval.rs @@ -185,7 +185,7 @@ impl VisitMut for PartialInliner { span: s.span, tail: true, // TODO possible bug for quotes - raw: s.value.clone().into(), + raw: s.value.clone(), cooked: Some(s.value), }; tt.tpl = Tpl { diff --git a/crates/swc_ecma_transforms_typescript/src/strip.rs b/crates/swc_ecma_transforms_typescript/src/strip.rs index 34538623e6b..009ce0f4065 100644 --- a/crates/swc_ecma_transforms_typescript/src/strip.rs +++ b/crates/swc_ecma_transforms_typescript/src/strip.rs @@ -1489,6 +1489,8 @@ where fn visit_assign_pat_prop(&mut self, n: &AssignPatProp) { if !self.in_var_pat { n.key.visit_with(self); + } else { + self.decl_names.insert(n.key.to_id()); } n.value.visit_with(self); } @@ -1500,6 +1502,8 @@ where fn visit_binding_ident(&mut self, n: &BindingIdent) { if !self.in_var_pat { n.visit_children_with(self) + } else { + self.decl_names.insert(n.to_id()); } } @@ -1521,12 +1525,14 @@ where f.function.visit_with(self) } Decl::Var(ref var) => { + let old = self.in_var_pat; for decl in &var.decls { self.in_var_pat = true; decl.name.visit_with(self); self.in_var_pat = false; decl.init.visit_with(self); } + self.in_var_pat = old; } Decl::TsEnum(e) => { e.members.visit_with(self); @@ -1609,6 +1615,13 @@ where self.non_top_level = old; } + fn visit_expr(&mut self, n: &Expr) { + let old = self.in_var_pat; + self.in_var_pat = false; + n.visit_children_with(self); + self.in_var_pat = old; + } + fn visit_ts_entity_name(&mut self, _: &TsEntityName) {} // these may contain expr