From e41010263379fc9a7676925f089aa9913c8f0f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 27 Sep 2022 20:48:42 +0900 Subject: [PATCH] fix(es/compat): Fix the order of initialization for decorators on computed keys (#5964) --- .../fixture/issues-5xxx/5189/1/input/.swcrc | 12 ++++++++++++ .../fixture/issues-5xxx/5189/1/input/index.ts | 6 ++++++ .../issues-5xxx/5189/1/output/index.ts | 14 ++++++++++++++ .../legacy-only/issues/swc-node-210/output.ts | 2 +- .../src/decorators/legacy/mod.rs | 19 ++++++++++++++++++- 5 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 crates/swc/tests/fixture/issues-5xxx/5189/1/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-5xxx/5189/1/input/index.ts create mode 100644 crates/swc/tests/fixture/issues-5xxx/5189/1/output/index.ts diff --git a/crates/swc/tests/fixture/issues-5xxx/5189/1/input/.swcrc b/crates/swc/tests/fixture/issues-5xxx/5189/1/input/.swcrc new file mode 100644 index 00000000000..08bf530be84 --- /dev/null +++ b/crates/swc/tests/fixture/issues-5xxx/5189/1/input/.swcrc @@ -0,0 +1,12 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true + }, + "target": "es2020" + }, + "module": { + "type": "commonjs" + } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-5xxx/5189/1/input/index.ts b/crates/swc/tests/fixture/issues-5xxx/5189/1/input/index.ts new file mode 100644 index 00000000000..9ef48f9a87a --- /dev/null +++ b/crates/swc/tests/fixture/issues-5xxx/5189/1/input/index.ts @@ -0,0 +1,6 @@ +const sym = Symbol("sym"); + +class Cls { + @Memoize() + [sym]() { } +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-5xxx/5189/1/output/index.ts b/crates/swc/tests/fixture/issues-5xxx/5189/1/output/index.ts new file mode 100644 index 00000000000..0462f5e4ae8 --- /dev/null +++ b/crates/swc/tests/fixture/issues-5xxx/5189/1/output/index.ts @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +const _tsDecorate = require("@swc/helpers/lib/_ts_decorate.js").default; +const sym = Symbol("sym"); +var _key; +_key = sym; +class Cls { + [_key]() {} +} +_tsDecorate([ + Memoize() +], Cls.prototype, _key, null); diff --git a/crates/swc_ecma_transforms/tests/fixture/legacy-only/issues/swc-node-210/output.ts b/crates/swc_ecma_transforms/tests/fixture/legacy-only/issues/swc-node-210/output.ts index 25dc9cc6efb..e08ec679808 100644 --- a/crates/swc_ecma_transforms/tests/fixture/legacy-only/issues/swc-node-210/output.ts +++ b/crates/swc_ecma_transforms/tests/fixture/legacy-only/issues/swc-node-210/output.ts @@ -1,8 +1,8 @@ var _key; +_key = foo; class Foo { [_key]() {} } -_key = foo; __decorate([ dec ], Foo.prototype, _key, null); diff --git a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs index e3b985e870c..b02153fe753 100644 --- a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs +++ b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs @@ -27,6 +27,7 @@ pub(super) fn new(metadata: bool, use_define_for_class_fields: bool) -> TscDecor enums: Default::default(), vars: Default::default(), appended_exprs: Default::default(), + prepended_exprs: Default::default(), class_name: Default::default(), constructor_exprs: Default::default(), exports: Default::default(), @@ -42,6 +43,7 @@ pub(super) struct TscDecorator { /// Used for computed keys, and this variables are not initialized. vars: Vec, appended_exprs: Vec>, + prepended_exprs: Vec>, class_name: Option, @@ -58,6 +60,7 @@ impl TscDecorator { { let old_vars = self.vars.take(); let old_appended_exprs = self.appended_exprs.take(); + let old_prepended_exprs = self.prepended_exprs.take(); let mut new = vec![]; @@ -78,6 +81,19 @@ impl TscDecorator { )); } + new.extend( + self.prepended_exprs + .drain(..) + .into_iter() + .map(|expr| { + Stmt::Expr(ExprStmt { + span: DUMMY_SP, + expr, + }) + }) + .map(T::from_stmt), + ); + new.push(s); new.extend( @@ -96,6 +112,7 @@ impl TscDecorator { *stmts = new; + self.prepended_exprs = old_prepended_exprs; self.appended_exprs = old_appended_exprs; self.vars = old_vars; } @@ -114,7 +131,7 @@ impl TscDecorator { }); // Initialize var - self.appended_exprs.push(Box::new(Expr::Assign(AssignExpr { + self.prepended_exprs.push(Box::new(Expr::Assign(AssignExpr { span: DUMMY_SP, op: op!("="), left: PatOrExpr::Pat(var_name.clone().into()),