Skip to content

Commit

Permalink
fix(es/transforms): Fix decorator bugs (#1905)
Browse files Browse the repository at this point in the history
swc_ecma_transforms_proposal:
 - Initialze decorators lazily. (#1278)
  • Loading branch information
kdy1 authored Jul 8, 2021
1 parent 19bcb06 commit 03be315
Show file tree
Hide file tree
Showing 13 changed files with 459 additions and 258 deletions.
5 changes: 1 addition & 4 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_common"
repository = "https://github.com/swc-project/swc.git"
version = "0.10.22"

[package.metadata.docs.rs]
all-features = true
version = "0.10.23"

[features]
concurrent = ["parking_lot"]
Expand Down
2 changes: 1 addition & 1 deletion ecmascript/transforms/proposal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_proposal"
repository = "https://github.com/swc-project/swc.git"
version = "0.25.0"
version = "0.25.1"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
71 changes: 64 additions & 7 deletions ecmascript/transforms/proposal/src/decorators/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::DecoratorFinder;
use fxhash::FxHashMap;
use smallvec::SmallVec;
use std::mem::replace;
use std::mem::take;
use swc_common::{util::move_map::MoveMap, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::helper;
Expand All @@ -15,6 +16,9 @@ use swc_ecma_utils::{
ExprFactory, ModuleItemLike, StmtLike,
};
use swc_ecma_utils::{ident::IdentLike, Id};
use swc_ecma_visit::noop_visit_mut_type;
use swc_ecma_visit::VisitMut;
use swc_ecma_visit::VisitMutWith;
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};

mod metadata;
Expand Down Expand Up @@ -147,7 +151,7 @@ impl Fold for Legacy {
Stmt::Decl(Decl::Var(VarDecl {
span: DUMMY_SP,
kind: VarDeclKind::Var,
decls: replace(&mut self.uninitialized_vars, Default::default()),
decls: take(&mut self.uninitialized_vars),
declare: false,
}))
.into(),
Expand All @@ -157,7 +161,7 @@ impl Fold for Legacy {
if !self.exports.is_empty() {
let decl = ModuleDecl::ExportNamed(NamedExport {
span: DUMMY_SP,
specifiers: replace(&mut self.exports, Default::default()),
specifiers: take(&mut self.exports),
src: None,
type_only: false,
asserts: None,
Expand Down Expand Up @@ -291,6 +295,11 @@ impl Legacy {
definite: false,
});

// We initialize decorators lazily.
//
// See https://github.com/swc-project/swc/issues/1278
let mut dec_init_exprs = vec![];

// Injected to sequence expression which is wrapped with parenthesis.
let mut extra_exprs = vec![];
// Injected to constructor
Expand Down Expand Up @@ -367,10 +376,24 @@ impl Legacy {
PropName::Computed(e) => {
let (name, aliased) = alias_if_required(&e.expr, "key");
if aliased {
self.initialized_vars.push(VarDeclarator {
let mut init = e.expr.clone();
if let Some(name) = &cls_name {
init.visit_mut_with(&mut IdentReplacer {
from: name,
to: &cls_ident,
});
}

dec_init_exprs.push(Box::new(Expr::Assign(AssignExpr {
span: DUMMY_SP,
op: op!("="),
left: PatOrExpr::Pat(Box::new(Pat::Ident(name.clone().into()))),
right: init,
})));
self.uninitialized_vars.push(VarDeclarator {
span: DUMMY_SP,
name: Pat::Ident(name.clone().into()),
init: Some(e.expr.clone()),
init: None,
definite: Default::default(),
})
}
Expand Down Expand Up @@ -476,13 +499,26 @@ impl Legacy {
let mut value = Some(p.value);

let mut dec_exprs = vec![];
for dec in p.decorators.into_iter() {
for mut dec in p.decorators.into_iter() {
let (i, aliased) = alias_if_required(&dec.expr, "_dec");
if aliased {
self.initialized_vars.push(VarDeclarator {
if let Some(name) = &cls_name {
dec.expr.visit_mut_with(&mut IdentReplacer {
from: name,
to: &cls_ident,
});
}

dec_init_exprs.push(Box::new(Expr::Assign(AssignExpr {
span: DUMMY_SP,
op: op!("="),
left: PatOrExpr::Pat(Box::new(Pat::Ident(i.clone().into()))),
right: dec.expr,
})));
self.uninitialized_vars.push(VarDeclarator {
span: DUMMY_SP,
name: Pat::Ident(i.clone().into()),
init: Some(dec.expr),
init: None,
definite: false,
});
}
Expand Down Expand Up @@ -765,6 +801,12 @@ impl Legacy {
right: Box::new(Expr::Ident(cls_ident.clone())),
}));

let mut extra_exprs = {
let mut buf = dec_init_exprs;
buf.extend(extra_exprs);
buf
};

let expr = self.apply(
&cls_ident,
if extra_exprs.is_empty() {
Expand Down Expand Up @@ -862,3 +904,18 @@ impl Fold for ClassFieldAccessConverter {
}
}
}

struct IdentReplacer<'a> {
from: &'a Ident,
to: &'a Ident,
}

impl VisitMut for IdentReplacer<'_> {
noop_visit_mut_type!();

fn visit_mut_ident(&mut self, i: &mut Ident) {
if self.from.sym == i.sym && self.from.span.ctxt == i.span.ctxt {
*i = self.to.clone();
}
}
}
Loading

0 comments on commit 03be315

Please sign in to comment.