Skip to content

Commit

Permalink
fix(es/transforms/compat): handle arrow parameters in subclass constr…
Browse files Browse the repository at this point in the history
…uctor
  • Loading branch information
Austaras committed Dec 1, 2021
1 parent 9fb898d commit ab5d8de
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 54 deletions.
4 changes: 2 additions & 2 deletions crates/swc_ecma_transforms_compat/src/es2015/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ export var Foo = function() {
_createClass(Foo, [{
key: 'func',
value: function func(a, param) {
var b = param === void 0 ? Date.now() : param;
value: function func(a) {
var b = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : Date.now();
return {
a: a
};
Expand Down
129 changes: 80 additions & 49 deletions crates/swc_ecma_transforms_compat/src/es2015/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use serde::Deserialize;
use swc_atoms::js_word;
use swc_common::{util::take::Take, Mark, Spanned, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::perf::Parallel;
use swc_ecma_transforms_macros::parallel;
// use swc_ecma_transforms_base::perf::Parallel;
// use swc_ecma_transforms_macros::parallel;
use swc_ecma_utils::{
function::{FunctionWrapper, WrapperState},
function::{init_this, FunctionWrapper, WrapperState},
member_expr, prepend, prepend_stmts, private_ident, quote_ident, undefined, ExprFactory,
};
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
Expand All @@ -25,6 +25,7 @@ struct Params {
/// Used to store `this, in case if `arguments` is used and we should
/// transform an arrow expression to a function expression.
state: WrapperState,
in_subclass: bool,
c: Config,
}

Expand All @@ -35,32 +36,32 @@ pub struct Config {
pub ignore_function_length: bool,
}

impl Parallel for Params {
fn create(&self) -> Self {
Params {
state: Default::default(),
c: self.c,
}
}

fn merge(&mut self, other: Self) {
self.state.merge(other.state);
}

fn after_stmts(&mut self, stmts: &mut Vec<Stmt>) {
let decls = self.state.take().to_stmt();
if let Some(decls) = decls {
prepend(stmts, decls)
}
}

fn after_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
let decls = self.state.take().to_stmt();
if let Some(decls) = decls {
prepend(stmts, ModuleItem::Stmt(decls))
}
}
}
// impl Parallel for Params {
// fn create(&self) -> Self {
// Params {
// state: Default::default(),
// c: self.c,
// }
// }

// fn merge(&mut self, other: Self) {
// self.state.merge(other.state);
// }

// fn after_stmts(&mut self, stmts: &mut Vec<Stmt>) {
// let decls = self.state.take().to_stmt();
// if let Some(decls) = decls {
// prepend(stmts, decls)
// }
// }

// fn after_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
// let decls = self.state.take().to_stmt();
// if let Some(decls) = decls {
// prepend(stmts, ModuleItem::Stmt(decls))
// }
// }
// }

impl Params {
fn visit_mut_fn_like(&mut self, ps: &mut Vec<Param>, body: &mut BlockStmt, is_setter: bool) {
Expand Down Expand Up @@ -392,7 +393,6 @@ impl Params {
}
}

#[parallel]
impl VisitMut for Params {
noop_visit_mut_type!();

Expand Down Expand Up @@ -448,29 +448,30 @@ impl VisitMut for Params {
}

fn visit_mut_constructor(&mut self, f: &mut Constructor) {
if f.body.is_none() {
return;
}
f.params.visit_mut_with(self);

f.visit_mut_children_with(self);
if let Some(BlockStmt { span: _, stmts }) = &mut f.body {
let old_rep = self.state.take();

let mut params = f
.params
.take()
.into_iter()
.map(|pat| match pat {
ParamOrTsParamProp::Param(p) => p,
_ => {
unreachable!("TsParameterProperty should be removed by typescript::strip pass")
}
})
.collect();
stmts.visit_mut_children_with(self);

let mut body = f.body.take().unwrap();
self.visit_mut_fn_like(&mut params, &mut body, false);
if self.in_subclass {
let (decl, this_id) = mem::replace(&mut self.state, old_rep).to_stmt_in_subclass();

f.params = params.into_iter().map(ParamOrTsParamProp::Param).collect();
f.body = Some(body);
if let Some(stmt) = decl {
if let Some(this_id) = this_id {
init_this(stmts, &this_id)
}
prepend(stmts, stmt);
}
} else {
let decl = mem::replace(&mut self.state, old_rep).to_stmt();

if let Some(stmt) = decl {
prepend(stmts, stmt);
}
}
}
}

fn visit_mut_expr(&mut self, e: &mut Expr) {
Expand Down Expand Up @@ -622,6 +623,36 @@ impl VisitMut for Params {
f.param = params.pop().unwrap().pat;
f.body = Some(body);
}

fn visit_mut_class(&mut self, c: &mut Class) {
if c.super_class.is_some() {
self.in_subclass = true;
}
c.visit_mut_children_with(self);
self.in_subclass = false;
}

fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
stmts.visit_mut_children_with(self);

let decl = self.state.take().to_stmt();

if let Some(stmt) = decl {
prepend(stmts, ModuleItem::Stmt(stmt));
}
}

fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
let old_rep = self.state.take();

stmts.visit_mut_children_with(self);

let decl = mem::replace(&mut self.state, old_rep).to_stmt();

if let Some(stmt) = decl {
prepend(stmts, stmt);
}
}
}

fn make_arg_nth(n: usize) -> Expr {
Expand Down
5 changes: 2 additions & 3 deletions crates/swc_ecma_transforms_compat/tests/es2015_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1841,7 +1841,7 @@ class Foo extends function () {} {
constructor() {
var _this;
var foo = function foo() {
var foo = function() {
for (var _len = arguments.length, rest = new Array(_len), _key = 0; _key < _len; _key++) {
rest[_key] = arguments[_key];
}
Expand All @@ -1852,8 +1852,7 @@ constructor() {
if (true) {
console.log((super(), _this = this), foo());
} else {
super();
_this = this;
super(), _this = this;
console.log(foo());
}
}
Expand Down

0 comments on commit ab5d8de

Please sign in to comment.