From 0c76696ed2d8cbf00a18fd9506b8c09f1be9cdd3 Mon Sep 17 00:00:00 2001 From: Austaras Date: Tue, 15 Mar 2022 20:21:17 +0800 Subject: [PATCH] fix(es/decorator): Insert initializer to constructor with body (#4028) --- .../swc_ecma_transforms/tests/decorators.rs | 37 ++++++++++++++ .../src/decorators/legacy/mod.rs | 48 ++++++------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/crates/swc_ecma_transforms/tests/decorators.rs b/crates/swc_ecma_transforms/tests/decorators.rs index 7ffe2454c86..433678e866c 100644 --- a/crates/swc_ecma_transforms/tests/decorators.rs +++ b/crates/swc_ecma_transforms/tests/decorators.rs @@ -6061,6 +6061,43 @@ test!( }), _class);" ); +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: false, + }), + issue_3979, + " +class A { + @foo x = 1; + constructor() + constructor() { + console.log(123) + } +} +", + r#" +var _class, _descriptor; +let A = ((_class = class A { + constructor(); + constructor(){ + _initializerDefineProperty(this, "x", _descriptor, this); + console.log(123); + } +}) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, "x", [ + foo +], { + configurable: true, + enumerable: true, + writable: true, + initializer: function() { + return 1; + } +}), _class); +"# +); + #[testing::fixture("tests/fixture/decorator/**/exec.ts")] fn fixture(input: PathBuf) { let code = fs::read_to_string(&input).expect("failed to read file"); 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 103d475b659..218e80b9483 100644 --- a/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs +++ b/crates/swc_ecma_transforms_proposal/src/decorators/legacy/mod.rs @@ -702,41 +702,23 @@ impl Legacy { }); if !constructor_stmts.is_empty() { - { - // Create constructors as required - - let has = c - .class + let constructor = if let Some(c) = c.class.body.iter_mut().find_map(|m| match m { + ClassMember::Constructor(c @ Constructor { body: Some(..), .. }) => Some(c), + _ => None, + }) { + c + } else { + c.class .body - .iter() - .any(|m| matches!(m, ClassMember::Constructor(..))); - - if !has { - c.class - .body - .push(ClassMember::Constructor(default_constructor( - c.class.super_class.is_some(), - ))) + .push(ClassMember::Constructor(default_constructor( + c.class.super_class.is_some(), + ))); + if let ClassMember::Constructor(c) = c.class.body.last_mut().unwrap() { + c + } else { + unreachable!() } - } - - let constructor = c - .class - .body - .iter_mut() - .filter_map(|m| match m { - ClassMember::Constructor(c) => Some(c), - _ => None, - }) - .next() - .unwrap(); - - if constructor.body.is_none() { - constructor.body = Some(BlockStmt { - span: DUMMY_SP, - stmts: vec![], - }); - } + }; let decorate_stmts_insert_position = constructor .body