mirror of
https://github.com/swc-project/swc.git
synced 2024-12-26 07:02:28 +03:00
refactor(es): Use into
for AST construction (#9197)
**Description:** This PR changes the AST node construction code to use `.into()` or `::from()` to make changing the boxed-ness of the AST node easier. I used `ast-grep` to make large changes across codebase.
This commit is contained in:
parent
a7d236c162
commit
e7358e0f81
@ -108,7 +108,7 @@ fn wrap_module(
|
||||
}
|
||||
|
||||
// ... body of foo
|
||||
let module_fn = Expr::Fn(FnExpr {
|
||||
let module_fn: Expr = FnExpr {
|
||||
ident: None,
|
||||
function: Box::new(Function {
|
||||
params: vec![
|
||||
@ -145,7 +145,8 @@ fn wrap_module(
|
||||
is_async: false,
|
||||
..Default::default()
|
||||
}),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
// var load = __swcpack_require__.bind(void 0, moduleDecl)
|
||||
|
||||
@ -355,15 +356,12 @@ impl VisitMut for DefaultHandler {
|
||||
|
||||
if let Expr::Ident(i) = e {
|
||||
if i.sym == "default" {
|
||||
*e = Expr::Member(MemberExpr {
|
||||
*e = MemberExpr {
|
||||
span: i.span,
|
||||
obj: Box::new(Expr::Ident(Ident::new(
|
||||
"module".into(),
|
||||
DUMMY_SP,
|
||||
self.local_ctxt,
|
||||
))),
|
||||
obj: Ident::new("module".into(), DUMMY_SP, self.local_ctxt).into(),
|
||||
prop: MemberProp::Ident(quote_ident!("exports")),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,10 +114,13 @@ where
|
||||
|
||||
let return_stmt = Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Object(ObjectLit {
|
||||
arg: Some(
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: take(&mut export_visitor.return_props),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
|
||||
module.iter().for_each(|(_, v)| {
|
||||
@ -131,7 +134,7 @@ where
|
||||
}
|
||||
});
|
||||
|
||||
let module_fn = Expr::Fn(FnExpr {
|
||||
let module_fn: Expr = FnExpr {
|
||||
function: Box::new(Function {
|
||||
params: Default::default(),
|
||||
body: Some(BlockStmt {
|
||||
@ -144,20 +147,23 @@ where
|
||||
..Default::default()
|
||||
}),
|
||||
ident: None,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
let mut module_expr = Expr::Call(CallExpr {
|
||||
let mut module_expr = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: module_fn.as_callee(),
|
||||
args: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
if is_async {
|
||||
module_expr = Expr::Await(AwaitExpr {
|
||||
module_expr = AwaitExpr {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(module_expr),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
let var_decl = VarDecl {
|
||||
@ -208,7 +214,7 @@ impl ExportToReturn {
|
||||
self.return_props
|
||||
.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(key.into()),
|
||||
value: Box::new(Expr::Ident(value)),
|
||||
value: value.into(),
|
||||
}))));
|
||||
}
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ where
|
||||
))
|
||||
}
|
||||
None => {
|
||||
let init = Expr::Class(c);
|
||||
let init = c;
|
||||
new.push(init.assign_to(local.clone()).into_module_item(
|
||||
injected_ctxt,
|
||||
"prepare -> export default decl -> class -> without \
|
||||
@ -974,8 +974,9 @@ where
|
||||
|
||||
vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(mod_var.clone().into()),
|
||||
init: Some(Box::new(Expr::Call(CallExpr {
|
||||
name: mod_var.clone().into(),
|
||||
init: Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Ident::new(
|
||||
"load".into(),
|
||||
@ -984,7 +985,9 @@ where
|
||||
)
|
||||
.as_callee(),
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: Default::default(),
|
||||
});
|
||||
for s in specifiers {
|
||||
@ -994,10 +997,8 @@ where
|
||||
ModuleExportName::Ident(name) => {
|
||||
vars.push(VarDeclarator {
|
||||
span: s.span,
|
||||
name: Pat::Ident(name.clone().into()),
|
||||
init: Some(Box::new(Expr::Ident(
|
||||
mod_var.clone(),
|
||||
))),
|
||||
name: name.clone().into(),
|
||||
init: Some(mod_var.clone().into()),
|
||||
definite: Default::default(),
|
||||
});
|
||||
}
|
||||
@ -1011,7 +1012,7 @@ where
|
||||
ExportSpecifier::Default(s) => {
|
||||
vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(s.exported.clone().into()),
|
||||
name: s.exported.clone().into(),
|
||||
init: Some(
|
||||
mod_var
|
||||
.clone()
|
||||
@ -1042,9 +1043,7 @@ where
|
||||
};
|
||||
vars.push(VarDeclarator {
|
||||
span: s.span,
|
||||
name: Pat::Ident(
|
||||
exported.clone().unwrap().into(),
|
||||
),
|
||||
name: exported.clone().unwrap().into(),
|
||||
init: Some(
|
||||
mod_var
|
||||
.clone()
|
||||
@ -1339,7 +1338,7 @@ impl VisitMut for ImportMetaHandler<'_, '_> {
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
*e = Expr::Ident(self.inline_ident.clone());
|
||||
*e = self.inline_ident.clone().into();
|
||||
self.occurred = true;
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ where
|
||||
"default".into(),
|
||||
DUMMY_SP,
|
||||
)),
|
||||
value: Box::new(Expr::Ident(s.exported)),
|
||||
value: s.exported.into(),
|
||||
},
|
||||
))));
|
||||
}
|
||||
@ -225,7 +225,7 @@ where
|
||||
props.push(PropOrSpread::Prop(Box::new(
|
||||
Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(exported.into()),
|
||||
value: Box::new(Expr::Ident(orig)),
|
||||
value: orig.into(),
|
||||
}),
|
||||
)));
|
||||
}
|
||||
@ -262,7 +262,7 @@ where
|
||||
"default".into(),
|
||||
export.span,
|
||||
)),
|
||||
value: Box::new(Expr::Ident(ident.clone())),
|
||||
value: ident.clone().into(),
|
||||
},
|
||||
))));
|
||||
|
||||
@ -283,7 +283,7 @@ where
|
||||
"default".into(),
|
||||
export.span,
|
||||
)),
|
||||
value: Box::new(Expr::Ident(ident.clone())),
|
||||
value: ident.clone().into(),
|
||||
},
|
||||
))));
|
||||
|
||||
@ -302,7 +302,7 @@ where
|
||||
))));
|
||||
let var = VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(default_var.into()),
|
||||
name: default_var.into(),
|
||||
init: Some(export.expr),
|
||||
definite: false,
|
||||
};
|
||||
@ -323,10 +323,13 @@ where
|
||||
};
|
||||
body.stmts.push(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Object(ObjectLit {
|
||||
arg: Some(
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props,
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}));
|
||||
|
||||
let f = Function {
|
||||
@ -342,12 +345,13 @@ where
|
||||
function: Box::new(f),
|
||||
};
|
||||
|
||||
let iife = Box::new(Expr::Call(CallExpr {
|
||||
let iife = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: invoked_fn_expr.as_callee(),
|
||||
args: Default::default(),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
Module {
|
||||
span: DUMMY_SP,
|
||||
|
@ -356,7 +356,7 @@ where
|
||||
};
|
||||
prop.ctxt = self.imported_idents.get(&obj.to_id()).copied().unwrap();
|
||||
|
||||
*e = Expr::Ident(prop);
|
||||
*e = prop.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,17 +91,18 @@ impl VisitMut for KeywordRenamer {
|
||||
Some(default) => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take().into()),
|
||||
value: Box::new(Pat::Assign(AssignPat {
|
||||
value: AssignPat {
|
||||
span: pat.span,
|
||||
left: Box::new(Pat::Ident(renamed.into())),
|
||||
left: Box::new(renamed.into()),
|
||||
right: default.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take().into()),
|
||||
value: Box::new(Pat::Ident(renamed.into())),
|
||||
value: renamed.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -134,7 +135,7 @@ impl VisitMut for KeywordRenamer {
|
||||
if let Some(renamed) = self.renamed(i) {
|
||||
*n = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(i.clone().into()),
|
||||
value: Box::new(Expr::Ident(renamed)),
|
||||
value: renamed.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +127,6 @@ impl From<Id> for Ident {
|
||||
impl From<Id> for Expr {
|
||||
#[inline]
|
||||
fn from(id: Id) -> Self {
|
||||
Expr::Ident(id.into_ident())
|
||||
id.into_ident().into()
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ impl VisitMut for Inliner {
|
||||
if i.sym != orig.sym {
|
||||
*n = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(orig.into()),
|
||||
value: Box::new(Expr::Ident(i.clone())),
|
||||
value: i.clone().into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ pub(crate) trait ExprExt: Into<Expr> {
|
||||
|
||||
VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(Ident::new(lhs.0, DUMMY_SP, lhs.1).into()),
|
||||
name: Ident::new(lhs.0, DUMMY_SP, lhs.1).into(),
|
||||
init: Some(Box::new(init)),
|
||||
definite: false,
|
||||
}
|
||||
@ -184,11 +184,12 @@ impl<T> IntoParallelIterator for T where T: IntoIterator {}
|
||||
fn metadata(key: &str, value: &str) -> PropOrSpread {
|
||||
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(IdentName::new(key.into(), DUMMY_SP)),
|
||||
value: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
value: Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: value.into(),
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -302,10 +302,11 @@ impl Expr {
|
||||
if exprs.len() == 1 {
|
||||
exprs.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -418,7 +419,7 @@ impl Clone for Expr {
|
||||
|
||||
impl Take for Expr {
|
||||
fn dummy() -> Self {
|
||||
Expr::Invalid(Invalid { span: DUMMY_SP })
|
||||
Invalid { span: DUMMY_SP }.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,12 +470,14 @@ boxed_expr!(JSXEmptyExpr);
|
||||
boxed_expr!(Box<JSXElement>);
|
||||
boxed_expr!(JSXFragment);
|
||||
boxed_expr!(TsTypeAssertion);
|
||||
boxed_expr!(TsSatisfiesExpr);
|
||||
boxed_expr!(TsConstAssertion);
|
||||
boxed_expr!(TsNonNullExpr);
|
||||
boxed_expr!(TsAsExpr);
|
||||
boxed_expr!(TsInstantiation);
|
||||
boxed_expr!(PrivateName);
|
||||
boxed_expr!(OptChainExpr);
|
||||
boxed_expr!(Invalid);
|
||||
|
||||
#[ast_node("ThisExpression")]
|
||||
#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
|
||||
@ -567,7 +570,7 @@ impl From<ImportWith> for ObjectLit {
|
||||
.map(|item| {
|
||||
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(item.key),
|
||||
value: Box::new(Expr::Lit(Lit::Str(item.value))),
|
||||
value: Lit::Str(item.value).into(),
|
||||
})))
|
||||
})
|
||||
.collect(),
|
||||
@ -1387,7 +1390,7 @@ impl TryFrom<Pat> for AssignTarget {
|
||||
|
||||
Pat::Expr(e) => match Self::try_from(e) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(Pat::Expr(e)),
|
||||
Err(e) => return Err(e.into()),
|
||||
},
|
||||
|
||||
_ => return Err(p),
|
||||
@ -1437,9 +1440,9 @@ impl Default for AssignTargetPat {
|
||||
impl From<AssignTargetPat> for Pat {
|
||||
fn from(pat: AssignTargetPat) -> Self {
|
||||
match pat {
|
||||
AssignTargetPat::Array(a) => Pat::Array(a),
|
||||
AssignTargetPat::Object(o) => Pat::Object(o),
|
||||
AssignTargetPat::Invalid(i) => Pat::Invalid(i),
|
||||
AssignTargetPat::Array(a) => a.into(),
|
||||
AssignTargetPat::Object(o) => o.into(),
|
||||
AssignTargetPat::Invalid(i) => i.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1551,17 +1554,17 @@ bridge_from!(AssignTarget, AssignTargetPat, ObjectPat);
|
||||
impl From<SimpleAssignTarget> for Box<Expr> {
|
||||
fn from(s: SimpleAssignTarget) -> Self {
|
||||
match s {
|
||||
SimpleAssignTarget::Ident(i) => Box::new(Expr::Ident(i.into())),
|
||||
SimpleAssignTarget::Member(m) => Box::new(Expr::Member(m)),
|
||||
SimpleAssignTarget::SuperProp(s) => Box::new(Expr::SuperProp(s)),
|
||||
SimpleAssignTarget::Paren(s) => Box::new(Expr::Paren(s)),
|
||||
SimpleAssignTarget::OptChain(s) => Box::new(Expr::OptChain(s)),
|
||||
SimpleAssignTarget::TsAs(a) => Box::new(Expr::TsAs(a)),
|
||||
SimpleAssignTarget::TsSatisfies(s) => Box::new(Expr::TsSatisfies(s)),
|
||||
SimpleAssignTarget::TsNonNull(n) => Box::new(Expr::TsNonNull(n)),
|
||||
SimpleAssignTarget::TsTypeAssertion(a) => Box::new(Expr::TsTypeAssertion(a)),
|
||||
SimpleAssignTarget::TsInstantiation(a) => Box::new(Expr::TsInstantiation(a)),
|
||||
SimpleAssignTarget::Invalid(i) => Box::new(Expr::Invalid(i)),
|
||||
SimpleAssignTarget::Ident(i) => i.into(),
|
||||
SimpleAssignTarget::Member(m) => m.into(),
|
||||
SimpleAssignTarget::SuperProp(s) => s.into(),
|
||||
SimpleAssignTarget::Paren(s) => s.into(),
|
||||
SimpleAssignTarget::OptChain(s) => s.into(),
|
||||
SimpleAssignTarget::TsAs(a) => a.into(),
|
||||
SimpleAssignTarget::TsSatisfies(s) => s.into(),
|
||||
SimpleAssignTarget::TsNonNull(n) => n.into(),
|
||||
SimpleAssignTarget::TsTypeAssertion(a) => a.into(),
|
||||
SimpleAssignTarget::TsInstantiation(a) => a.into(),
|
||||
SimpleAssignTarget::Invalid(i) => i.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl Clone for Pat {
|
||||
|
||||
impl Default for Pat {
|
||||
fn default() -> Self {
|
||||
Pat::Invalid(Invalid { span: DUMMY_SP })
|
||||
Invalid { span: DUMMY_SP }.into()
|
||||
}
|
||||
}
|
||||
impl Take for Pat {
|
||||
@ -80,6 +80,7 @@ pat_to_other!(ArrayPat);
|
||||
pat_to_other!(ObjectPat);
|
||||
pat_to_other!(AssignPat);
|
||||
pat_to_other!(RestPat);
|
||||
pat_to_other!(Box<Expr>);
|
||||
|
||||
#[ast_node("ArrayPattern")]
|
||||
#[derive(Eq, Hash, EqIgnoreSpan)]
|
||||
|
@ -44,11 +44,12 @@ impl VisitMut for EdgeDefaultParam {
|
||||
{
|
||||
let prop = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(key.clone().into()),
|
||||
value: Box::new(Pat::Assign(AssignPat {
|
||||
value: AssignPat {
|
||||
span: *span,
|
||||
left: key.clone().into(),
|
||||
right: value.clone(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
|
||||
n.props[idx] = prop;
|
||||
|
@ -70,14 +70,17 @@ impl Fold for TemplateLiteralCaching {
|
||||
self.helper_ident = Some(helper_ident.clone());
|
||||
self.create_binding(
|
||||
helper_ident,
|
||||
Some(Expr::Arrow(ArrowExpr {
|
||||
Some(
|
||||
ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
params: vec![t.clone().into()],
|
||||
body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Ident(t)))),
|
||||
body: Box::new(BlockStmtOrExpr::Expr(t.into())),
|
||||
is_async: false,
|
||||
is_generator: false,
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@ -88,7 +91,7 @@ impl Fold for TemplateLiteralCaching {
|
||||
// the same shape. identity`a${0}`
|
||||
let template = TaggedTpl {
|
||||
span: DUMMY_SP,
|
||||
tag: Box::new(Expr::Ident(helper_ident.clone())),
|
||||
tag: helper_ident.clone().into(),
|
||||
tpl: Box::new(Tpl {
|
||||
span: DUMMY_SP,
|
||||
quasis: n.tpl.quasis,
|
||||
@ -101,23 +104,25 @@ impl Fold for TemplateLiteralCaching {
|
||||
// _t || (_t = identity`a${0}`)
|
||||
let t = private_ident!("t");
|
||||
self.create_binding(t.clone(), None);
|
||||
let inline_cache = Expr::Bin(BinExpr {
|
||||
let inline_cache: Expr = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("||"),
|
||||
left: Box::new(Expr::Ident(t.clone())),
|
||||
right: Box::new(Expr::Assign(AssignExpr {
|
||||
left: t.clone().into(),
|
||||
right: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: t.into(),
|
||||
right: Box::new(Expr::TaggedTpl(template)),
|
||||
})),
|
||||
});
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
|
||||
// The original tag function becomes a plain function call.
|
||||
// The expressions omitted from the cached Strings tag are
|
||||
// directly applied as arguments.
|
||||
// tag(_t || (_t = Object`a${0}`), 'hello')
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: n.tag.as_callee(),
|
||||
args: vec![inline_cache.as_arg()]
|
||||
@ -125,7 +130,8 @@ impl Fold for TemplateLiteralCaching {
|
||||
.chain(n.tpl.exprs.into_iter().map(|expr| expr.as_arg()))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
_ => n,
|
||||
}
|
||||
|
@ -267,10 +267,11 @@ impl BlockScoping {
|
||||
}
|
||||
|
||||
if !inits.is_empty() {
|
||||
call = Expr::Seq(SeqExpr {
|
||||
call = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: inits.into_iter().chain(once(Box::new(call))).collect(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
if flow_helper.has_return || flow_helper.has_break || !flow_helper.label.is_empty() {
|
||||
@ -297,7 +298,7 @@ impl BlockScoping {
|
||||
stmts.push(
|
||||
IfStmt {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("==="),
|
||||
left: {
|
||||
@ -314,7 +315,8 @@ impl BlockScoping {
|
||||
},
|
||||
//"object"
|
||||
right: "object".into(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: Box::new(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(ret.clone().make_member(quote_ident!("v")).into()),
|
||||
@ -792,11 +794,14 @@ impl VisitMut for FlowHelper<'_> {
|
||||
};
|
||||
*node = Stmt::Return(ReturnStmt {
|
||||
span,
|
||||
arg: Some(Box::new(Expr::Lit(Lit::Str(Str {
|
||||
arg: Some(
|
||||
Lit::Str(Str {
|
||||
span,
|
||||
value,
|
||||
raw: None,
|
||||
})))),
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
}
|
||||
Stmt::Return(s) => {
|
||||
@ -805,9 +810,11 @@ impl VisitMut for FlowHelper<'_> {
|
||||
|
||||
*node = Stmt::Return(ReturnStmt {
|
||||
span,
|
||||
arg: Some(Box::new(Expr::Object(ObjectLit {
|
||||
arg: Some(
|
||||
ObjectLit {
|
||||
span,
|
||||
props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(
|
||||
KeyValueProp {
|
||||
key: PropName::Ident(IdentName::new("v".into(), DUMMY_SP)),
|
||||
value: s.arg.take().unwrap_or_else(|| {
|
||||
Box::new(Expr::Unary(UnaryExpr {
|
||||
@ -816,8 +823,11 @@ impl VisitMut for FlowHelper<'_> {
|
||||
arg: Expr::undefined(DUMMY_SP),
|
||||
}))
|
||||
}),
|
||||
})))],
|
||||
}))),
|
||||
},
|
||||
)))],
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
}
|
||||
_ => node.visit_mut_children_with(self),
|
||||
@ -869,19 +879,23 @@ impl MutationHandler<'_> {
|
||||
let mut exprs = Vec::with_capacity(self.map.len() + 1);
|
||||
|
||||
for (id, ctxt) in &*self.map {
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Ident::new(id.0.clone(), DUMMY_SP, id.1).into(),
|
||||
op: op!("="),
|
||||
right: Box::new(Expr::Ident(Ident::new(id.0.clone(), DUMMY_SP, *ctxt))),
|
||||
})));
|
||||
right: Box::new(Ident::new(id.0.clone(), DUMMY_SP, *ctxt).into()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
exprs.push(orig.unwrap_or_else(|| Expr::undefined(DUMMY_SP)));
|
||||
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ impl VisitMut for ConstructorFolder<'_> {
|
||||
{
|
||||
let right = match self.super_var.clone() {
|
||||
Some(super_var) => {
|
||||
let call = Box::new(Expr::Call(CallExpr {
|
||||
let call = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: if self.is_constructor_default {
|
||||
super_var.make_member(quote_ident!("apply")).as_callee()
|
||||
@ -228,15 +228,17 @@ impl VisitMut for ConstructorFolder<'_> {
|
||||
call_args
|
||||
},
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
if self.super_is_callable_constructor {
|
||||
Box::new(Expr::Bin(BinExpr {
|
||||
BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: call,
|
||||
op: op!("||"),
|
||||
right: Box::new(Expr::This(ThisExpr { span: DUMMY_SP })),
|
||||
}))
|
||||
right: Box::new(ThisExpr { span: DUMMY_SP }.into()),
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
call
|
||||
}
|
||||
@ -249,12 +251,13 @@ impl VisitMut for ConstructorFolder<'_> {
|
||||
})),
|
||||
};
|
||||
|
||||
*expr = Expr::Assign(AssignExpr {
|
||||
*expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: quote_ident!(SyntaxContext::empty().apply_mark(self.mark), "_this").into(),
|
||||
op: op!("="),
|
||||
right,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
};
|
||||
}
|
||||
|
||||
@ -284,7 +287,7 @@ impl VisitMut for ConstructorFolder<'_> {
|
||||
}) = &mut **expr
|
||||
{
|
||||
let expr = match self.super_var.clone() {
|
||||
Some(super_var) => Box::new(Expr::Call(CallExpr {
|
||||
Some(super_var) => CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: if self.is_constructor_default {
|
||||
super_var.make_member(quote_ident!("apply")).as_callee()
|
||||
@ -303,7 +306,8 @@ impl VisitMut for ConstructorFolder<'_> {
|
||||
call_args
|
||||
},
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None => Box::new(make_possible_return_value(ReturningMode::Prototype {
|
||||
is_constructor_default: self.is_constructor_default,
|
||||
class_name: self.class_name.clone(),
|
||||
@ -378,7 +382,7 @@ pub(super) enum ReturningMode {
|
||||
pub(super) fn make_possible_return_value(mode: ReturningMode) -> Expr {
|
||||
let callee = helper!(possible_constructor_return);
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee,
|
||||
args: match mode {
|
||||
@ -455,7 +459,8 @@ pub(super) fn make_possible_return_value(mode: ReturningMode) -> Expr {
|
||||
}
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// `mark`: Mark for `_this`
|
||||
@ -481,14 +486,15 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: &mut Constructor) -> bo
|
||||
let this = quote_ident!(SyntaxContext::empty().apply_mark(self.mark), "_this");
|
||||
|
||||
if self.wrap_with_assertion {
|
||||
*expr = Expr::Call(CallExpr {
|
||||
*expr = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(assert_this_initialized),
|
||||
args: vec![this.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
*expr = Expr::Ident(this);
|
||||
*expr = this.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,10 +489,11 @@ where
|
||||
prepend_stmt(&mut function.body.as_mut().unwrap().stmts, use_strict);
|
||||
}
|
||||
function.span = span;
|
||||
return Expr::Fn(FnExpr {
|
||||
return FnExpr {
|
||||
ident: Some(ident),
|
||||
function,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -519,7 +520,7 @@ where
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Expr::Call(call)
|
||||
call.into()
|
||||
}
|
||||
|
||||
/// Returned `stmts` contains `return Foo`
|
||||
@ -714,7 +715,7 @@ where
|
||||
if is_always_initialized {
|
||||
body.push(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Ident(this))),
|
||||
arg: Some(this.into()),
|
||||
}));
|
||||
} else {
|
||||
let possible_return_value =
|
||||
@ -805,7 +806,7 @@ where
|
||||
// `return Foo`
|
||||
stmts.push(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Ident(class_name_sym))),
|
||||
arg: Some(class_name_sym.into()),
|
||||
}));
|
||||
|
||||
stmts
|
||||
@ -890,17 +891,15 @@ where
|
||||
Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(quote_ident!(Default::default(), key.span(), "key").into()),
|
||||
value: match key {
|
||||
PropName::Ident(i) => Box::new(Expr::Lit(Lit::Str(quote_str!(i.span, i.sym)))),
|
||||
PropName::Str(s) => Box::new(Expr::from(s)),
|
||||
PropName::Num(n) => Box::new(Expr::from(n)),
|
||||
PropName::BigInt(b) => Box::new(Expr::Lit(
|
||||
Str {
|
||||
PropName::Ident(i) => Lit::Str(quote_str!(i.span, i.sym)).into(),
|
||||
PropName::Str(s) => s.into(),
|
||||
PropName::Num(n) => n.into(),
|
||||
PropName::BigInt(b) => Str {
|
||||
span: b.span,
|
||||
raw: None,
|
||||
value: b.value.to_string().into(),
|
||||
}
|
||||
.into(),
|
||||
)),
|
||||
PropName::Computed(c) => c.expr,
|
||||
},
|
||||
}))
|
||||
@ -911,22 +910,20 @@ where
|
||||
PropName::Ident(i) => MemberProp::Ident(i),
|
||||
PropName::Str(s) => MemberProp::Computed(ComputedPropName {
|
||||
span: s.span,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(s))),
|
||||
expr: Lit::Str(s).into(),
|
||||
}),
|
||||
PropName::Num(n) => MemberProp::Computed(ComputedPropName {
|
||||
span: n.span,
|
||||
expr: Box::new(Expr::Lit(Lit::Num(n))),
|
||||
expr: Lit::Num(n).into(),
|
||||
}),
|
||||
PropName::BigInt(b) => MemberProp::Computed(ComputedPropName {
|
||||
span: b.span,
|
||||
expr: Box::new(Expr::Lit(
|
||||
Str {
|
||||
expr: Str {
|
||||
span: b.span,
|
||||
raw: None,
|
||||
value: b.value.to_string().into(),
|
||||
}
|
||||
.into(),
|
||||
)),
|
||||
}),
|
||||
PropName::Computed(c) => MemberProp::Computed(c),
|
||||
}
|
||||
@ -936,7 +933,7 @@ where
|
||||
if props.is_empty() {
|
||||
return quote_expr!(DUMMY_SP, null).as_arg();
|
||||
}
|
||||
Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: props
|
||||
.into_iter()
|
||||
@ -969,7 +966,7 @@ where
|
||||
})
|
||||
.map(Some)
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
.as_arg()
|
||||
}
|
||||
|
||||
@ -1078,7 +1075,7 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
let value = Box::new(Expr::Fn(FnExpr {
|
||||
let value = FnExpr {
|
||||
ident: if m.kind == MethodKind::Method && !computed {
|
||||
match prop_name {
|
||||
Expr::Ident(ident) => Some(private_ident!(ident.span, ident.sym)),
|
||||
@ -1095,7 +1092,8 @@ where
|
||||
None
|
||||
},
|
||||
function: m.function,
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let data = append_to.entry(key).or_insert_with(|| Data {
|
||||
key_prop,
|
||||
@ -1153,7 +1151,7 @@ where
|
||||
let prop = *v.key_prop.clone();
|
||||
res.push(Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span,
|
||||
op: op!("="),
|
||||
left: MemberExpr {
|
||||
@ -1163,7 +1161,8 @@ where
|
||||
}
|
||||
.into(),
|
||||
right: escape_keywords(method),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}));
|
||||
!(v.get.is_none() && v.set.is_none())
|
||||
} else {
|
||||
@ -1177,7 +1176,7 @@ where
|
||||
let prop = *v.key_prop.clone();
|
||||
res.push(Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span,
|
||||
op: op!("="),
|
||||
left: MemberExpr {
|
||||
@ -1187,7 +1186,8 @@ where
|
||||
}
|
||||
.into(),
|
||||
right: escape_keywords(method),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}));
|
||||
!(v.get.is_none() && v.set.is_none())
|
||||
} else {
|
||||
|
@ -76,7 +76,7 @@ impl VisitMut for ComputedProps {
|
||||
let mark = Mark::fresh(Mark::root());
|
||||
let obj_ident = quote_ident!(SyntaxContext::empty().apply_mark(mark), *span, "_obj");
|
||||
|
||||
let mut exprs = Vec::with_capacity(props.len() + 2);
|
||||
let mut exprs: Vec<Box<Expr>> = Vec::with_capacity(props.len() + 2);
|
||||
let mutator_map = quote_ident!(
|
||||
SyntaxContext::empty().apply_mark(mark),
|
||||
*span,
|
||||
@ -98,20 +98,25 @@ impl VisitMut for ComputedProps {
|
||||
|
||||
exprs.push(
|
||||
if !self.c.loose && props_cnt == 1 && !self.used_define_enum_props {
|
||||
Box::new(Expr::Object(ObjectLit {
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: obj_props,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Box::new(Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: obj_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: Box::new(Expr::Object(ObjectLit {
|
||||
right: Box::new(
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: obj_props,
|
||||
})),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into()
|
||||
},
|
||||
);
|
||||
|
||||
@ -125,17 +130,18 @@ impl VisitMut for ComputedProps {
|
||||
Prop::Shorthand(ident) => (
|
||||
(
|
||||
if self.c.loose {
|
||||
Expr::Ident(ident.clone())
|
||||
ident.clone().into()
|
||||
} else {
|
||||
Expr::Lit(Lit::Str(Str {
|
||||
Lit::Str(Str {
|
||||
span: ident.span,
|
||||
raw: None,
|
||||
value: ident.sym.clone(),
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
},
|
||||
false,
|
||||
),
|
||||
Expr::Ident(ident),
|
||||
ident.into(),
|
||||
),
|
||||
Prop::KeyValue(KeyValueProp { key, value }) => {
|
||||
(prop_name_to_expr(key, self.c.loose), *value)
|
||||
@ -193,11 +199,13 @@ impl VisitMut for ComputedProps {
|
||||
.computed_member(prop_name_to_expr(key, false).0);
|
||||
|
||||
// mutator[f] = mutator[f] || {}
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span,
|
||||
left: mutator_elem.clone().into(),
|
||||
op: op!("="),
|
||||
right: Box::new(Expr::Bin(BinExpr {
|
||||
right: Box::new(
|
||||
BinExpr {
|
||||
span,
|
||||
left: mutator_elem.clone().into(),
|
||||
op: op!("||"),
|
||||
@ -205,43 +213,57 @@ impl VisitMut for ComputedProps {
|
||||
span,
|
||||
props: vec![],
|
||||
})),
|
||||
})),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
// mutator[f].get = function(){}
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span,
|
||||
left: mutator_elem
|
||||
.make_member(quote_ident!(gs_prop_name.unwrap()))
|
||||
.into(),
|
||||
op: op!("="),
|
||||
right: Box::new(Expr::Fn(FnExpr {
|
||||
right: Box::new(
|
||||
FnExpr {
|
||||
ident: None,
|
||||
function,
|
||||
})),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
continue;
|
||||
// unimplemented!("getter /setter property")
|
||||
}
|
||||
Prop::Method(MethodProp { key, function }) => (
|
||||
prop_name_to_expr(key, self.c.loose),
|
||||
Expr::Fn(FnExpr {
|
||||
FnExpr {
|
||||
ident: None,
|
||||
function,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
},
|
||||
PropOrSpread::Spread(..) => unimplemented!("computed spread property"),
|
||||
};
|
||||
|
||||
if !self.c.loose && props_cnt == 1 {
|
||||
single_cnt_prop = Some(Expr::Call(CallExpr {
|
||||
single_cnt_prop = Some(
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(define_property),
|
||||
args: vec![exprs.pop().unwrap().as_arg(), key.as_arg(), value.as_arg()],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
break;
|
||||
}
|
||||
exprs.push(if self.c.loose {
|
||||
@ -250,19 +272,21 @@ impl VisitMut for ComputedProps {
|
||||
} else {
|
||||
obj_ident.clone().make_member(key.ident().unwrap().into())
|
||||
};
|
||||
Box::new(Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span,
|
||||
op: op!("="),
|
||||
left: left.into(),
|
||||
right: value.into(),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(define_property),
|
||||
args: vec![obj_ident.clone().as_arg(), key.as_arg(), value.as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
});
|
||||
}
|
||||
|
||||
@ -281,26 +305,33 @@ impl VisitMut for ComputedProps {
|
||||
self.vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: mutator_map.clone().into(),
|
||||
init: Some(Box::new(Expr::Object(ObjectLit {
|
||||
init: Some(
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: vec![],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: false,
|
||||
});
|
||||
exprs.push(Box::new(Expr::Call(CallExpr {
|
||||
exprs.push(
|
||||
CallExpr {
|
||||
span: *span,
|
||||
callee: helper!(define_enumerable_properties),
|
||||
args: vec![obj_ident.clone().as_arg(), mutator_map.as_arg()],
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Last value
|
||||
exprs.push(Box::new(Expr::Ident(obj_ident)));
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
exprs.push(obj_ident.into());
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
};
|
||||
}
|
||||
|
||||
@ -380,19 +411,20 @@ fn prop_name_to_expr(p: PropName, loose: bool) -> (Expr, bool) {
|
||||
match p {
|
||||
PropName::Ident(i) => (
|
||||
if loose {
|
||||
Expr::Ident(i.into())
|
||||
i.into()
|
||||
} else {
|
||||
Expr::Lit(Lit::Str(Str {
|
||||
Lit::Str(Str {
|
||||
raw: None,
|
||||
value: i.sym,
|
||||
span: i.span,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
},
|
||||
false,
|
||||
),
|
||||
PropName::Str(s) => (Expr::Lit(Lit::Str(s)), true),
|
||||
PropName::Num(n) => (Expr::Lit(Lit::Num(n)), true),
|
||||
PropName::BigInt(b) => (Expr::Lit(Lit::BigInt(b)), true),
|
||||
PropName::Str(s) => (Lit::Str(s).into(), true),
|
||||
PropName::Num(n) => (Lit::Num(n).into(), true),
|
||||
PropName::BigInt(b) => (Lit::BigInt(b).into(), true),
|
||||
PropName::Computed(c) => (*c.expr, true),
|
||||
}
|
||||
}
|
||||
|
@ -178,13 +178,16 @@ impl AssignFolder {
|
||||
VarDeclarator {
|
||||
span: p.span(),
|
||||
name: *p.arg,
|
||||
init: Some(Box::new(Expr::Array(ArrayLit {
|
||||
init: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: arr_elems
|
||||
.take()
|
||||
.expect("two rest element?")
|
||||
.collect(),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: false,
|
||||
},
|
||||
);
|
||||
@ -249,7 +252,8 @@ impl AssignFolder {
|
||||
}) => VarDeclarator {
|
||||
span: dot3_token,
|
||||
name: *arg,
|
||||
init: Some(Box::new(Expr::Call(CallExpr {
|
||||
init: Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ref_ident
|
||||
.clone()
|
||||
@ -262,7 +266,9 @@ impl AssignFolder {
|
||||
}
|
||||
.as_arg()],
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: false,
|
||||
},
|
||||
_ => VarDeclarator {
|
||||
@ -339,7 +345,7 @@ impl AssignFolder {
|
||||
let ref_ident = make_ref_ident(self.c, ref_decls, decl.init);
|
||||
|
||||
let ref_ident = if can_be_null {
|
||||
let init = Box::new(Expr::Ident(ref_ident));
|
||||
let init = ref_ident.into();
|
||||
make_ref_ident(self.c, ref_decls, Some(init))
|
||||
} else {
|
||||
ref_ident
|
||||
@ -507,7 +513,7 @@ impl Destructuring {
|
||||
decls.push(VarDeclarator {
|
||||
span,
|
||||
name: param.pat,
|
||||
init: Some(Box::new(Expr::Ident(ref_ident))),
|
||||
init: Some(ref_ident.into()),
|
||||
definite: false,
|
||||
})
|
||||
}
|
||||
@ -570,20 +576,22 @@ impl AssignFolder {
|
||||
.into(),
|
||||
)];
|
||||
|
||||
let mut assign_cond_expr = Expr::Assign(AssignExpr {
|
||||
let mut assign_cond_expr: Expr = AssignExpr {
|
||||
span,
|
||||
left: pat.left.take().try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right: Box::new(make_cond_expr(ref_ident, pat.right.take())),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
assign_cond_expr.visit_mut_with(self);
|
||||
exprs.push(Box::new(assign_cond_expr));
|
||||
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,18 +670,24 @@ impl VisitMut for AssignFolder {
|
||||
let mut arr_elems = Some(arr.elems.take().into_iter());
|
||||
elems.iter_mut().for_each(|p| match p {
|
||||
Some(Pat::Rest(p)) => {
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: p.span(),
|
||||
left: p.arg.take().try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right: Box::new(Expr::Array(ArrayLit {
|
||||
right: Box::new(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: arr_elems
|
||||
.take()
|
||||
.expect("two rest element?")
|
||||
.collect(),
|
||||
})),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
Some(p) => {
|
||||
let e = arr_elems
|
||||
@ -692,12 +706,13 @@ impl VisitMut for AssignFolder {
|
||||
let mut expr = if let Pat::Assign(pat) = p {
|
||||
self.handle_assign_pat(*span, pat, &mut right)
|
||||
} else {
|
||||
Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span: p.span(),
|
||||
left: p.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
self.visit_mut_expr(&mut expr);
|
||||
@ -730,7 +745,8 @@ impl VisitMut for AssignFolder {
|
||||
elems.len()
|
||||
}),
|
||||
);
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: ref_ident.clone().into(),
|
||||
@ -739,7 +755,8 @@ impl VisitMut for AssignFolder {
|
||||
} else {
|
||||
match &mut **right {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "arguments" => {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
Box::new(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: member_expr!(
|
||||
Default::default(),
|
||||
@ -749,20 +766,27 @@ impl VisitMut for AssignFolder {
|
||||
.as_callee(),
|
||||
args: vec![right.take().as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
Expr::Array(..) => right.take(),
|
||||
_ => {
|
||||
// if left has rest then need `_to_array`
|
||||
// else `_sliced_to_array`
|
||||
if elems.iter().any(|elem| matches!(elem, Some(Pat::Rest(..))))
|
||||
if elems
|
||||
.iter()
|
||||
.any(|elem| matches!(elem, Some(Pat::Rest(..))))
|
||||
{
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
Box::new(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(to_array),
|
||||
args: vec![right.take().as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
Box::new(
|
||||
CallExpr {
|
||||
@ -780,7 +804,9 @@ impl VisitMut for AssignFolder {
|
||||
}
|
||||
}
|
||||
},
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
for (i, elem) in elems.iter_mut().enumerate() {
|
||||
let elem = match elem {
|
||||
@ -795,29 +821,33 @@ impl VisitMut for AssignFolder {
|
||||
}) => {
|
||||
// initialized by sequence expression.
|
||||
let assign_ref_ident = make_ref_ident(self.c, &mut self.vars, None);
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: assign_ref_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: ref_ident.clone().computed_member(i as f64).into(),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
let mut assign_expr = Expr::Assign(AssignExpr {
|
||||
let mut assign_expr: Expr = AssignExpr {
|
||||
span: *span,
|
||||
left: left.take().try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right: Box::new(make_cond_expr(assign_ref_ident, right.take())),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
assign_expr.visit_mut_with(self);
|
||||
|
||||
exprs.push(Box::new(assign_expr));
|
||||
}
|
||||
Pat::Rest(RestPat { arg, .. }) => {
|
||||
let mut assign_expr = Expr::Assign(AssignExpr {
|
||||
let mut assign_expr: Expr = AssignExpr {
|
||||
span: elem_span,
|
||||
op: op!("="),
|
||||
left: arg.take().try_into().unwrap(),
|
||||
right: Box::new(Expr::Call(CallExpr {
|
||||
right: CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ref_ident
|
||||
.clone()
|
||||
@ -825,19 +855,22 @@ impl VisitMut for AssignFolder {
|
||||
.as_callee(),
|
||||
args: vec![(i as f64).as_arg()],
|
||||
..Default::default()
|
||||
})),
|
||||
});
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
|
||||
assign_expr.visit_mut_with(self);
|
||||
exprs.push(Box::new(assign_expr));
|
||||
}
|
||||
_ => {
|
||||
let mut assign_expr = Expr::Assign(AssignExpr {
|
||||
let mut assign_expr: Expr = AssignExpr {
|
||||
span: elem_span,
|
||||
op: op!("="),
|
||||
left: elem.take().try_into().unwrap(),
|
||||
right: make_ref_idx_expr(&ref_ident, i).into(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
assign_expr.visit_mut_with(self);
|
||||
exprs.push(Box::new(assign_expr))
|
||||
@ -846,12 +879,13 @@ impl VisitMut for AssignFolder {
|
||||
}
|
||||
|
||||
// last one should be `ref`
|
||||
exprs.push(Box::new(Expr::Ident(ref_ident)));
|
||||
exprs.push(ref_ident.into());
|
||||
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
AssignTargetPat::Object(ObjectPat { props, .. }) if props.is_empty() => {
|
||||
let mut right = right.take();
|
||||
@ -865,12 +899,13 @@ impl VisitMut for AssignFolder {
|
||||
if let ObjectPatProp::Assign(p @ AssignPatProp { value: None, .. }) =
|
||||
&props[0]
|
||||
{
|
||||
*expr = Expr::Assign(AssignExpr {
|
||||
*expr = AssignExpr {
|
||||
span: *span,
|
||||
op: op!("="),
|
||||
left: p.key.clone().into(),
|
||||
right: right.take().make_member(p.key.clone().into()).into(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -900,12 +935,13 @@ impl VisitMut for AssignFolder {
|
||||
let mut expr = if let Pat::Assign(pat) = *value {
|
||||
self.handle_assign_pat(span, pat, &mut right)
|
||||
} else {
|
||||
Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span,
|
||||
left: value.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
expr.visit_mut_with(self);
|
||||
@ -919,7 +955,8 @@ impl VisitMut for AssignFolder {
|
||||
let prop_ident =
|
||||
make_ref_ident(self.c, &mut self.vars, None);
|
||||
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span,
|
||||
left: prop_ident.clone().into(),
|
||||
op: op!("="),
|
||||
@ -928,9 +965,12 @@ impl VisitMut for AssignFolder {
|
||||
key.clone().into(),
|
||||
computed,
|
||||
)),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span,
|
||||
left: key.clone().into(),
|
||||
op: op!("="),
|
||||
@ -938,10 +978,13 @@ impl VisitMut for AssignFolder {
|
||||
prop_ident,
|
||||
value.take(),
|
||||
)),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span,
|
||||
left: key.clone().into(),
|
||||
op: op!("="),
|
||||
@ -950,7 +993,9 @@ impl VisitMut for AssignFolder {
|
||||
key.clone().into(),
|
||||
computed,
|
||||
)),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -962,12 +1007,13 @@ impl VisitMut for AssignFolder {
|
||||
}
|
||||
|
||||
// Last one should be object itself.
|
||||
exprs.push(Box::new(Expr::Ident(ref_ident)));
|
||||
exprs.push(ref_ident.into());
|
||||
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
AssignTargetPat::Invalid(..) => unreachable!(),
|
||||
@ -1161,7 +1207,7 @@ fn make_ref_ident_for_array(
|
||||
fn make_ref_prop_expr(ref_ident: &Ident, prop: Box<Expr>, mut computed: bool) -> Expr {
|
||||
computed |= matches!(*prop, Expr::Lit(Lit::Num(..)) | Expr::Lit(Lit::Str(..)));
|
||||
|
||||
Expr::Member(MemberExpr {
|
||||
MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: Box::new(ref_ident.clone().into()),
|
||||
prop: if computed {
|
||||
@ -1172,14 +1218,15 @@ fn make_ref_prop_expr(ref_ident: &Ident, prop: Box<Expr>, mut computed: bool) ->
|
||||
} else {
|
||||
MemberProp::Ident(prop.ident().unwrap().into())
|
||||
},
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Creates `tmp === void 0 ? def_value : tmp`
|
||||
fn make_cond_expr(tmp: Ident, def_value: Box<Expr>) -> Expr {
|
||||
Expr::Cond(CondExpr {
|
||||
CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(Expr::Ident(tmp.clone())),
|
||||
op: op!("==="),
|
||||
@ -1188,10 +1235,12 @@ fn make_cond_expr(tmp: Ident, def_value: Box<Expr>) -> Expr {
|
||||
op: op!("void"),
|
||||
arg: 0.0.into(),
|
||||
})),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: def_value,
|
||||
alt: Box::new(Expr::Ident(tmp)),
|
||||
})
|
||||
alt: tmp.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn can_be_null(e: &Expr) -> bool {
|
||||
|
@ -59,7 +59,7 @@ impl VisitMut for PropFolder {
|
||||
span: ident.span,
|
||||
expr: quote_str!(ident.sym.clone()).into(),
|
||||
}),
|
||||
value: Box::new(Expr::Ident(ident.clone())),
|
||||
value: ident.clone().into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -102,11 +102,12 @@ impl<'a> VisitMut for PropNameFolder<'a> {
|
||||
if !self.props.insert(ident.sym.clone()) {
|
||||
*name = PropName::Computed(ComputedPropName {
|
||||
span,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value: ident.sym.clone(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -100,18 +100,24 @@ impl ForOf {
|
||||
|
||||
let i = private_ident!("_i");
|
||||
|
||||
let test = Some(Box::new(Expr::Bin(BinExpr {
|
||||
let test = Some(
|
||||
BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(Expr::Ident(i.clone())),
|
||||
left: Box::new(i.clone().into()),
|
||||
op: op!("<"),
|
||||
right: arr.clone().make_member(quote_ident!("length")).into(),
|
||||
})));
|
||||
let update = Some(Box::new(Expr::Update(UpdateExpr {
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
let update = Some(
|
||||
UpdateExpr {
|
||||
span: DUMMY_SP,
|
||||
prefix: false,
|
||||
op: op!("++"),
|
||||
arg: Box::new(Expr::Ident(i.clone())),
|
||||
})));
|
||||
arg: Box::new(i.clone().into()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
let mut decls = Vec::with_capacity(2);
|
||||
decls.push(VarDeclarator {
|
||||
@ -281,7 +287,7 @@ impl ForOf {
|
||||
}
|
||||
|
||||
// !(_step = _iterator()).done;
|
||||
let test = Box::new(Expr::Unary(UnaryExpr {
|
||||
let test = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: AssignExpr {
|
||||
@ -298,7 +304,8 @@ impl ForOf {
|
||||
}
|
||||
.make_member(quote_ident!("done"))
|
||||
.into(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let stmt = Stmt::For(ForStmt {
|
||||
span,
|
||||
@ -393,10 +400,7 @@ impl ForOf {
|
||||
self.top_level_vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: error_ident.clone().into(),
|
||||
init: Some(Box::new(Expr::Ident(Ident::new_no_ctxt(
|
||||
"undefined".into(),
|
||||
DUMMY_SP,
|
||||
)))),
|
||||
init: Some(Ident::new_no_ctxt("undefined".into(), DUMMY_SP).into()),
|
||||
definite: false,
|
||||
});
|
||||
|
||||
@ -437,11 +441,12 @@ impl ForOf {
|
||||
.into(),
|
||||
),
|
||||
// !(_iteratorNormalCompletion = (_step = _iterator.next()).done)
|
||||
test: Some(Box::new(Expr::Unary(UnaryExpr {
|
||||
test: Some(
|
||||
UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: {
|
||||
let step_expr = Box::new(Expr::Assign(AssignExpr {
|
||||
let step_expr: Expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: step.into(),
|
||||
op: op!("="),
|
||||
@ -453,24 +458,33 @@ impl ForOf {
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
})),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
Box::new(Expr::Assign(AssignExpr {
|
||||
Box::new(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: normal_completion_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: step_expr.make_member(quote_ident!("done")).into(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
||||
// `_iteratorNormalCompletion = true`
|
||||
update: Some(Box::new(Expr::Assign(AssignExpr {
|
||||
update: Some(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: normal_completion_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: true.into(),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
body: Box::new(Stmt::Block(body)),
|
||||
}
|
||||
.into();
|
||||
|
@ -76,12 +76,13 @@ impl VisitMut for FnName {
|
||||
if let Expr::Fn(expr @ FnExpr { ident: None, .. }) = &mut *p.value {
|
||||
//
|
||||
p.value = if let PropName::Ident(ref i) = p.key {
|
||||
Box::new(Expr::Fn(FnExpr {
|
||||
FnExpr {
|
||||
ident: Some(prepare(i.clone().into())),
|
||||
..expr.take()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Box::new(Expr::Fn(expr.take()))
|
||||
expr.take().into()
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl VisitMut for Wrapper {
|
||||
is_async: false,
|
||||
..Default::default()
|
||||
});
|
||||
let generator_object = Box::new(Expr::Call(CallExpr {
|
||||
let generator_object = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(ts, ts_generator),
|
||||
args: vec![
|
||||
@ -97,7 +97,8 @@ impl VisitMut for Wrapper {
|
||||
.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
let mut stmts = vec![];
|
||||
if !v.hoisted_vars.is_empty() {
|
||||
stmts.push(
|
||||
@ -494,7 +495,7 @@ impl VisitMut for Generator {
|
||||
|
||||
self.mark_label(result_label);
|
||||
|
||||
*e = Expr::Ident(result_local);
|
||||
*e = result_local.into();
|
||||
} else {
|
||||
node.visit_mut_with(self);
|
||||
}
|
||||
@ -528,10 +529,11 @@ impl VisitMut for Generator {
|
||||
expr: if pending_expressions.len() == 1 {
|
||||
pending_expressions.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: pending_expressions.take(),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
})))),
|
||||
None,
|
||||
@ -565,7 +567,7 @@ impl VisitMut for Generator {
|
||||
// .mark resumeLabel
|
||||
// a = _a[%sent%]
|
||||
|
||||
*obj = Box::new(Expr::Ident(self.cache_expression(obj.take())));
|
||||
*obj = self.cache_expression(obj.take()).into();
|
||||
prop.visit_mut_with(self);
|
||||
return;
|
||||
}
|
||||
@ -590,7 +592,7 @@ impl VisitMut for Generator {
|
||||
left.obj.visit_mut_with(self);
|
||||
let obj = self.cache_expression(left.obj.take());
|
||||
|
||||
left.obj = Box::new(Expr::Ident(obj));
|
||||
left.obj = obj.into();
|
||||
}
|
||||
MemberProp::Computed(prop) => {
|
||||
// [source]
|
||||
@ -611,10 +613,10 @@ impl VisitMut for Generator {
|
||||
prop.visit_mut_with(self);
|
||||
let prop = self.cache_expression(prop.expr.take());
|
||||
|
||||
left.obj = Box::new(Expr::Ident(obj));
|
||||
left.obj = obj.into();
|
||||
left.prop = MemberProp::Computed(ComputedPropName {
|
||||
span: prop_span,
|
||||
expr: Box::new(Expr::Ident(prop)),
|
||||
expr: prop.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -630,12 +632,13 @@ impl VisitMut for Generator {
|
||||
|
||||
node.right.visit_mut_with(self);
|
||||
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
*e = AssignExpr {
|
||||
span: node.right.span(),
|
||||
op: node.op,
|
||||
left: left_of_right.into(),
|
||||
right: node.right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
node.right.visit_mut_with(self);
|
||||
}
|
||||
@ -672,7 +675,7 @@ impl VisitMut for Generator {
|
||||
|
||||
self.emit_assignment(
|
||||
temp.clone().into(),
|
||||
Box::new(Expr::Object(ObjectLit {
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: node
|
||||
.props
|
||||
@ -680,7 +683,8 @@ impl VisitMut for Generator {
|
||||
.take(num_initial_properties)
|
||||
.map(|v| v.take())
|
||||
.collect(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -736,7 +740,7 @@ impl VisitMut for Generator {
|
||||
self.reduce_property(exprs, property, &mut temp)
|
||||
});
|
||||
|
||||
expressions.push(Box::new(Expr::Ident(temp)));
|
||||
expressions.push(temp.into());
|
||||
|
||||
*e = *Expr::from_exprs(expressions);
|
||||
}
|
||||
@ -821,7 +825,7 @@ impl VisitMut for Generator {
|
||||
None
|
||||
};
|
||||
|
||||
let apply = Expr::Ident(callee).apply(
|
||||
let apply = callee.apply(
|
||||
node.span,
|
||||
this_arg,
|
||||
arg.take().map(|v| v.as_arg()).into_iter().collect(),
|
||||
@ -863,10 +867,11 @@ impl VisitMut for Generator {
|
||||
Some(VarDeclOrExpr::Expr(if exprs.len() == 1 {
|
||||
exprs.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}))
|
||||
};
|
||||
node.test.visit_mut_with(self);
|
||||
@ -1030,10 +1035,11 @@ impl VisitMut for Generator {
|
||||
expr: if exprs.len() == 1 {
|
||||
exprs.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -1082,7 +1088,7 @@ impl Generator {
|
||||
|
||||
self.emit_assignment(
|
||||
temp.clone().unwrap().into(),
|
||||
Box::new(Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: leading_element
|
||||
.take()
|
||||
@ -1095,7 +1101,8 @@ impl Generator {
|
||||
.map(|e| e.take()),
|
||||
)
|
||||
.collect(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None,
|
||||
);
|
||||
}
|
||||
@ -1109,7 +1116,7 @@ impl Generator {
|
||||
});
|
||||
|
||||
if let Some(temp) = temp {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: temp.make_member(quote_ident!("concat")).as_callee(),
|
||||
args: vec![ExprOrSpread {
|
||||
@ -1120,9 +1127,10 @@ impl Generator {
|
||||
})),
|
||||
}],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: leading_element
|
||||
.take()
|
||||
@ -1130,7 +1138,8 @@ impl Generator {
|
||||
.map(Some)
|
||||
.chain(expressions)
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1150,7 +1159,7 @@ impl Generator {
|
||||
self.emit_assignment(
|
||||
temp.clone().unwrap().into(),
|
||||
if has_assigned_temp {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: temp
|
||||
.clone()
|
||||
@ -1163,7 +1172,8 @@ impl Generator {
|
||||
}))
|
||||
.as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Box::new(
|
||||
ArrayLit {
|
||||
@ -1209,47 +1219,50 @@ impl Generator {
|
||||
}));
|
||||
}
|
||||
|
||||
let mut expression = match property {
|
||||
let mut expression: Expr = match property {
|
||||
CompiledProp::Prop(p) => match p {
|
||||
Prop::Shorthand(p) => Expr::Assign(AssignExpr {
|
||||
Prop::Shorthand(p) => AssignExpr {
|
||||
span: p.span,
|
||||
op: op!("="),
|
||||
left: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: Box::new(Expr::Ident(temp.clone())),
|
||||
obj: temp.clone().into(),
|
||||
prop: MemberProp::Ident(p.clone().into()),
|
||||
}
|
||||
.into(),
|
||||
right: Box::new(Expr::Ident(p)),
|
||||
}),
|
||||
Prop::KeyValue(p) => Expr::Assign(AssignExpr {
|
||||
right: p.into(),
|
||||
}
|
||||
.into(),
|
||||
Prop::KeyValue(p) => AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: Box::new(Expr::Ident(temp.clone())),
|
||||
obj: temp.clone().into(),
|
||||
prop: p.key.into(),
|
||||
}
|
||||
.into(),
|
||||
right: p.value,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
Prop::Assign(_) => {
|
||||
unreachable!("assignment property be removed before generator pass")
|
||||
}
|
||||
Prop::Getter(_) | Prop::Setter(_) => {
|
||||
unreachable!("getter/setter property be compiled as CompiledProp::Accessor")
|
||||
}
|
||||
Prop::Method(p) => Expr::Assign(AssignExpr {
|
||||
Prop::Method(p) => AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: Box::new(Expr::Ident(temp.clone())),
|
||||
obj: temp.clone().into(),
|
||||
prop: p.key.into(),
|
||||
}
|
||||
.into(),
|
||||
right: p.function.into(),
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
},
|
||||
CompiledProp::Accessor(getter, setter) => {
|
||||
let key = getter
|
||||
@ -1293,7 +1306,7 @@ impl Generator {
|
||||
.collect(),
|
||||
};
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(define_property),
|
||||
args: vec![
|
||||
@ -1302,7 +1315,8 @@ impl Generator {
|
||||
desc.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
@ -1329,7 +1343,7 @@ impl Generator {
|
||||
// _a + %sent% + c()
|
||||
|
||||
node.left.visit_mut_with(self);
|
||||
node.left = Box::new(Expr::Ident(self.cache_expression(node.left.take())));
|
||||
node.left = self.cache_expression(node.left.take()).into();
|
||||
node.right.visit_mut_with(self);
|
||||
return None;
|
||||
}
|
||||
@ -1404,7 +1418,7 @@ impl Generator {
|
||||
);
|
||||
self.mark_label(result_label);
|
||||
|
||||
Expr::Ident(result_local)
|
||||
result_local.into()
|
||||
}
|
||||
|
||||
fn transform_and_emit_stmts(&mut self, stmts: Vec<Stmt>, start: usize) {
|
||||
@ -1509,10 +1523,11 @@ impl Generator {
|
||||
expr: if pending_expressions.len() == 1 {
|
||||
pending_expressions.pop().unwrap()
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: take(&mut pending_expressions),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
}))
|
||||
}
|
||||
@ -1748,7 +1763,7 @@ impl Generator {
|
||||
right: node.right.take(),
|
||||
body: Box::new(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Call(CallExpr {
|
||||
expr: CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: keys_array
|
||||
.clone()
|
||||
@ -1756,7 +1771,8 @@ impl Generator {
|
||||
.as_callee(),
|
||||
args: vec![key.as_arg()],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})),
|
||||
}));
|
||||
|
||||
@ -1797,14 +1813,15 @@ impl Generator {
|
||||
};
|
||||
self.emit_assignment(
|
||||
variable.try_into().unwrap(),
|
||||
Box::new(Expr::Member(MemberExpr {
|
||||
MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: Box::new(keys_array.into()),
|
||||
prop: MemberProp::Computed(ComputedPropName {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(keys_index.clone().into()),
|
||||
}),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None,
|
||||
);
|
||||
self.transform_and_emit_embedded_stmt(*node.body);
|
||||
@ -1812,12 +1829,13 @@ impl Generator {
|
||||
self.mark_label(increment_label);
|
||||
self.emit_stmt(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Update(UpdateExpr {
|
||||
expr: UpdateExpr {
|
||||
span: DUMMY_SP,
|
||||
prefix: false,
|
||||
op: op!("++"),
|
||||
arg: Box::new(keys_index.clone().into()),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}));
|
||||
|
||||
self.emit_break(condition_label, None);
|
||||
@ -1966,7 +1984,7 @@ impl Generator {
|
||||
clauses_written += pending_clauses.len();
|
||||
self.emit_stmt(Stmt::Switch(SwitchStmt {
|
||||
span: DUMMY_SP,
|
||||
discriminant: Box::new(Expr::Ident(expression.clone())),
|
||||
discriminant: expression.clone().into(),
|
||||
cases: take(&mut pending_clauses),
|
||||
}));
|
||||
}
|
||||
@ -2302,7 +2320,7 @@ impl Generator {
|
||||
|
||||
self.emit_assignment(
|
||||
name.clone().into(),
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: self
|
||||
.state
|
||||
@ -2311,7 +2329,8 @@ impl Generator {
|
||||
.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -2594,9 +2613,10 @@ impl Generator {
|
||||
.unwrap()
|
||||
.push(expr);
|
||||
}
|
||||
return Box::new(Expr::Invalid(Invalid {
|
||||
return Invalid {
|
||||
span: Span::new(BytePos(label.0 as _), BytePos(label.0 as _)),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2631,10 +2651,13 @@ impl Generator {
|
||||
];
|
||||
ReturnStmt {
|
||||
span: span.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: args,
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -2645,7 +2668,8 @@ impl Generator {
|
||||
fn create_inline_return(&mut self, expr: Option<Box<Expr>>, loc: Option<Span>) -> ReturnStmt {
|
||||
ReturnStmt {
|
||||
span: loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: match expr {
|
||||
Some(expr) => vec![
|
||||
@ -2654,13 +2678,15 @@ impl Generator {
|
||||
],
|
||||
None => vec![Some(self.create_instruction(Instruction::Return).as_arg())],
|
||||
},
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an expression that can be used to resume from a Yield operation.
|
||||
fn create_generator_resume(&mut self, loc: Option<Span>) -> Box<Expr> {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: loc.unwrap_or(DUMMY_SP),
|
||||
callee: self
|
||||
.state
|
||||
@ -2669,7 +2695,8 @@ impl Generator {
|
||||
.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Emits an empty instruction.
|
||||
@ -2976,7 +3003,7 @@ impl Generator {
|
||||
0,
|
||||
Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Call(CallExpr {
|
||||
expr: CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: self
|
||||
.state
|
||||
@ -2995,7 +3022,8 @@ impl Generator {
|
||||
}
|
||||
.as_arg()],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@ -3007,12 +3035,13 @@ impl Generator {
|
||||
|
||||
stmts.push(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: self.state.clone().make_member(quote_ident!("label")).into(),
|
||||
right: (self.label_number + 1).into(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -3241,12 +3270,13 @@ impl Generator {
|
||||
fn write_assign(&mut self, left: AssignTarget, right: Box<Expr>, op_loc: Option<Span>) {
|
||||
self.write_stmt(Stmt::Expr(ExprStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left,
|
||||
right,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -3276,7 +3306,8 @@ impl Generator {
|
||||
let inst = self.create_instruction(Instruction::Return);
|
||||
self.write_stmt(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: match expr {
|
||||
Some(expr) => {
|
||||
@ -3286,7 +3317,9 @@ impl Generator {
|
||||
vec![Some(inst.as_arg())]
|
||||
}
|
||||
},
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -3301,10 +3334,13 @@ impl Generator {
|
||||
let label = self.create_label(Some(label));
|
||||
self.write_stmt(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: vec![Some(inst.as_arg()), Some(label.as_arg())],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -3321,10 +3357,13 @@ impl Generator {
|
||||
test: cond,
|
||||
cons: Box::new(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: vec![Some(inst.as_arg()), Some(label.as_arg())],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
})),
|
||||
alt: None,
|
||||
}))
|
||||
@ -3340,17 +3379,21 @@ impl Generator {
|
||||
let label = self.create_label(Some(label));
|
||||
self.write_stmt(Stmt::If(IfStmt {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Unary(UnaryExpr {
|
||||
test: UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: cond,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: Box::new(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: vec![Some(inst.as_arg()), Some(label.as_arg())],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
})),
|
||||
alt: None,
|
||||
}))
|
||||
@ -3374,10 +3417,13 @@ impl Generator {
|
||||
};
|
||||
self.write_stmt(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems,
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -3391,10 +3437,13 @@ impl Generator {
|
||||
let arg1 = self.create_instruction(Instruction::YieldStar);
|
||||
self.write_stmt(Stmt::Return(ReturnStmt {
|
||||
span: op_loc.unwrap_or(DUMMY_SP),
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: vec![Some(arg1.as_arg()), Some(expr.as_arg())],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -3405,10 +3454,13 @@ impl Generator {
|
||||
let arg = self.create_instruction(Instruction::Endfinally);
|
||||
self.write_stmt(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Array(ArrayLit {
|
||||
arg: Some(
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems: vec![Some(arg.as_arg())],
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
@ -3472,7 +3524,7 @@ impl Generator {
|
||||
let this_arg = self.create_temp_variable();
|
||||
*obj = Box::new(obj.take().make_assign_to(op!("="), this_arg.clone().into()));
|
||||
|
||||
(callee, Box::new(Expr::Ident(this_arg)))
|
||||
(callee, this_arg.into())
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -3481,7 +3533,7 @@ impl Generator {
|
||||
} else {
|
||||
let this_arg = self.create_temp_variable();
|
||||
let target = callee.make_assign_to(op!("="), this_arg.clone().into());
|
||||
(Box::new(target), Box::new(Expr::Ident(this_arg)))
|
||||
(Box::new(target), this_arg.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,12 +62,13 @@ impl VisitMut for InstanceOf {
|
||||
hi: right.span_lo(),
|
||||
};
|
||||
|
||||
*expr = Expr::Call(CallExpr {
|
||||
*expr = CallExpr {
|
||||
span: *span,
|
||||
callee: helper!(instanceof_span, instanceof),
|
||||
args: vec![left.take().as_arg(), right.take().as_arg()],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,19 +70,21 @@ impl VisitMut for NewTarget {
|
||||
Ctx::Constructor => *e = this_ctor(*span),
|
||||
Ctx::Method => *e = *Expr::undefined(DUMMY_SP),
|
||||
Ctx::Function(i) => {
|
||||
*e = Expr::Cond(CondExpr {
|
||||
*e = CondExpr {
|
||||
span: *span,
|
||||
// this instanceof Foo
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("instanceof"),
|
||||
left: Box::new(Expr::This(ThisExpr { span: DUMMY_SP })),
|
||||
right: Box::new(Expr::Ident(i.clone())),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: Box::new(this_ctor(DUMMY_SP)),
|
||||
// void 0
|
||||
alt: Expr::undefined(DUMMY_SP),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,12 +114,13 @@ impl VisitMut for ObjectSuper {
|
||||
}
|
||||
}
|
||||
if let Some(obj) = replacer.obj {
|
||||
*expr = Expr::Assign(AssignExpr {
|
||||
*expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: obj.clone().into(),
|
||||
right: Box::new(expr.take()),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
self.extra_vars.push(obj);
|
||||
}
|
||||
}
|
||||
@ -176,13 +177,13 @@ impl SuperReplacer {
|
||||
}
|
||||
|
||||
fn get_proto(&mut self) -> ExprOrSpread {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(get_prototype_of),
|
||||
args: vec![self.get_obj_ref().as_arg()],
|
||||
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.as_arg()
|
||||
}
|
||||
|
||||
@ -191,11 +192,12 @@ impl SuperReplacer {
|
||||
match prop.take() {
|
||||
SuperProp::Ident(IdentName {
|
||||
sym: value, span, ..
|
||||
}) => Box::new(Expr::Lit(Lit::Str(Str {
|
||||
}) => Lit::Str(Str {
|
||||
raw: None,
|
||||
value,
|
||||
span,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
|
||||
SuperProp::Computed(ComputedPropName { expr, .. }) => expr,
|
||||
}
|
||||
@ -227,7 +229,7 @@ impl SuperReplacer {
|
||||
SuperReplacer::super_to_get_call(self.get_proto(), *super_token, prop.as_arg());
|
||||
let this = ThisExpr { span: DUMMY_SP }.as_arg();
|
||||
if args.len() == 1 && is_rest_arguments(&args[0]) {
|
||||
*n = Expr::Call(CallExpr {
|
||||
*n = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -243,11 +245,12 @@ impl SuperReplacer {
|
||||
}))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
*n = Expr::Call(CallExpr {
|
||||
*n = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -257,7 +260,8 @@ impl SuperReplacer {
|
||||
.as_callee(),
|
||||
args: iter::once(this).chain(args.take()).collect(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,12 +309,13 @@ impl SuperReplacer {
|
||||
return;
|
||||
}
|
||||
left.visit_mut_children_with(self);
|
||||
*n = Expr::Assign(AssignExpr {
|
||||
*n = AssignExpr {
|
||||
span: *span,
|
||||
left: left.take(),
|
||||
op: *op,
|
||||
right: right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -339,12 +344,13 @@ impl SuperReplacer {
|
||||
}
|
||||
|
||||
fn super_to_get_call(proto: ExprOrSpread, super_token: Span, prop: ExprOrSpread) -> Expr {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: super_token,
|
||||
callee: helper!(get),
|
||||
args: vec![proto, prop, ThisExpr { span: super_token }.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn to_bin_expr(left: Box<Expr>, op: AssignOp, rhs: Box<Expr>) -> BinExpr {
|
||||
@ -362,7 +368,7 @@ impl SuperReplacer {
|
||||
prop: ExprOrSpread,
|
||||
rhs: ExprOrSpread,
|
||||
) -> Expr {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: super_token,
|
||||
callee: helper!(set),
|
||||
args: vec![
|
||||
@ -374,7 +380,8 @@ impl SuperReplacer {
|
||||
true.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn super_to_set_call(
|
||||
@ -400,12 +407,13 @@ impl SuperReplacer {
|
||||
if computed {
|
||||
let ref_ident = alias_ident_for(&rhs, "_ref").into_private();
|
||||
self.vars.push(ref_ident.clone());
|
||||
*prop = Expr::Assign(AssignExpr {
|
||||
*prop = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: ref_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: prop.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
ref_ident.as_arg()
|
||||
} else {
|
||||
prop.clone().as_arg()
|
||||
@ -417,11 +425,12 @@ impl SuperReplacer {
|
||||
super_token,
|
||||
prop.as_arg(),
|
||||
SuperReplacer::to_bin_expr(
|
||||
Box::new(Expr::Unary(UnaryExpr {
|
||||
UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!(unary, "+"),
|
||||
arg: left,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
op,
|
||||
rhs,
|
||||
)
|
||||
@ -430,7 +439,7 @@ impl SuperReplacer {
|
||||
} else {
|
||||
let update_ident = alias_ident_for(&rhs, "_super").into_private();
|
||||
self.vars.push(update_ident.clone());
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![
|
||||
Box::new(
|
||||
@ -459,7 +468,8 @@ impl SuperReplacer {
|
||||
),
|
||||
Box::new(Expr::Ident(update_ident)),
|
||||
],
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
} else {
|
||||
self.call_set_helper(
|
||||
|
@ -114,7 +114,7 @@ impl Params {
|
||||
let decl = VarDeclarator {
|
||||
span,
|
||||
name: param.pat,
|
||||
init: Some(Box::new(Expr::Ident(binding))),
|
||||
init: Some(binding.into()),
|
||||
definite: false,
|
||||
};
|
||||
if self.c.ignore_function_length {
|
||||
@ -141,9 +141,11 @@ impl Params {
|
||||
decls.push(VarDeclarator {
|
||||
span,
|
||||
name: *left,
|
||||
init: Some(Box::new(Expr::Cond(CondExpr {
|
||||
init: Some(
|
||||
CondExpr {
|
||||
span,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: Box::new(
|
||||
BinExpr {
|
||||
left: Box::new(check_arg_len(i)),
|
||||
op: op!("&&"),
|
||||
right: Box::new(Expr::Bin(BinExpr {
|
||||
@ -153,10 +155,14 @@ impl Params {
|
||||
span: DUMMY_SP,
|
||||
})),
|
||||
span,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
cons: make_arg_nth(i).into(),
|
||||
alt: right,
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: false,
|
||||
})
|
||||
} else if let Pat::Ident(ident) = left.as_ref() {
|
||||
@ -167,20 +173,22 @@ impl Params {
|
||||
});
|
||||
loose_stmt.push(Stmt::If(IfStmt {
|
||||
span,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(Expr::Ident(Ident::from(ident))),
|
||||
left: Box::new(Ident::from(ident).into()),
|
||||
op: op!("==="),
|
||||
right: Expr::undefined(DUMMY_SP),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: Box::new(Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span,
|
||||
left: left.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})),
|
||||
alt: None,
|
||||
}))
|
||||
@ -258,37 +266,40 @@ impl Params {
|
||||
// `len - $i`
|
||||
let bin: Expr = BinExpr {
|
||||
span,
|
||||
left: Box::new(Expr::Ident(ident.clone())),
|
||||
left: ident.clone().into(),
|
||||
op: op!(bin, "-"),
|
||||
right: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
right: Lit::Num(Number {
|
||||
span,
|
||||
value: i as f64,
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
if !min_zero {
|
||||
return bin;
|
||||
}
|
||||
|
||||
Expr::Cond(CondExpr {
|
||||
CondExpr {
|
||||
span,
|
||||
test: Box::new(
|
||||
BinExpr {
|
||||
span,
|
||||
left: Box::new(len_ident.clone().into()),
|
||||
op: op!(">"),
|
||||
right: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
right: Lit::Num(Number {
|
||||
span,
|
||||
value: i as _,
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
cons: Box::new(bin),
|
||||
alt: 0.into(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
@ -348,19 +359,25 @@ impl Params {
|
||||
.into(),
|
||||
),
|
||||
// `_key < _len`
|
||||
test: Some(Box::new(Expr::Bin(BinExpr {
|
||||
test: Some(
|
||||
BinExpr {
|
||||
span,
|
||||
left: Box::new(idx_ident.clone().into()),
|
||||
op: op!("<"),
|
||||
right: Box::new(len_ident.clone().into()),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
// _key++
|
||||
update: Some(Box::new(Expr::Update(UpdateExpr {
|
||||
update: Some(
|
||||
UpdateExpr {
|
||||
span,
|
||||
op: op!("++"),
|
||||
prefix: false,
|
||||
arg: Box::new(idx_ident.clone().into()),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
body: Box::new(Stmt::Block(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
stmts: vec![{
|
||||
@ -634,7 +651,7 @@ impl VisitMut for Params {
|
||||
}
|
||||
.into();
|
||||
*e = match (self.in_prop, local_vars) {
|
||||
(true, Some(var_decl)) => Expr::Arrow(ArrowExpr {
|
||||
(true, Some(var_decl)) => ArrowExpr {
|
||||
span: f.span,
|
||||
params: Vec::new(),
|
||||
is_async: false,
|
||||
@ -651,7 +668,7 @@ impl VisitMut for Params {
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.as_iife()
|
||||
.into(),
|
||||
_ => func,
|
||||
@ -675,7 +692,7 @@ impl VisitMut for Params {
|
||||
Box::new(BlockStmtOrExpr::BlockStmt(body))
|
||||
};
|
||||
|
||||
*e = Expr::Arrow(ArrowExpr {
|
||||
*e = ArrowExpr {
|
||||
params: params.into_iter().map(|param| param.pat).collect(),
|
||||
body,
|
||||
span: f.span,
|
||||
@ -684,7 +701,8 @@ impl VisitMut for Params {
|
||||
type_params: f.type_params.take(),
|
||||
return_type: f.return_type.take(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => e.visit_mut_children_with(self),
|
||||
}
|
||||
@ -784,25 +802,27 @@ impl VisitMut for Params {
|
||||
}
|
||||
|
||||
fn make_arg_nth(n: usize) -> MemberExpr {
|
||||
Expr::Ident(Ident::new_no_ctxt("arguments".into(), DUMMY_SP)).computed_member(n)
|
||||
Ident::new_no_ctxt("arguments".into(), DUMMY_SP).computed_member(n)
|
||||
}
|
||||
|
||||
fn check_arg_len(n: usize) -> Expr {
|
||||
Expr::Bin(BinExpr {
|
||||
BinExpr {
|
||||
left: Expr::Ident(Ident::new_no_ctxt("arguments".into(), DUMMY_SP))
|
||||
.make_member(IdentName::new("length".into(), DUMMY_SP))
|
||||
.into(),
|
||||
op: op!(">"),
|
||||
right: n.into(),
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn check_arg_len_or_undef(n: usize) -> Expr {
|
||||
Expr::Cond(CondExpr {
|
||||
CondExpr {
|
||||
test: Box::new(check_arg_len(n)),
|
||||
cons: make_arg_nth(n).into(),
|
||||
alt: Expr::undefined(DUMMY_SP),
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -96,10 +96,11 @@ impl VisitMut for Shorthand {
|
||||
};
|
||||
*prop = Prop::KeyValue(KeyValueProp {
|
||||
key,
|
||||
value: Box::new(Expr::Fn(FnExpr {
|
||||
value: FnExpr {
|
||||
ident: None,
|
||||
function: function.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
|
@ -85,7 +85,7 @@ impl VisitMut for Spread {
|
||||
Expr::SuperProp(SuperPropExpr {
|
||||
obj: Super { span, .. },
|
||||
..
|
||||
}) => (Box::new(Expr::This(ThisExpr { span: *span })), None),
|
||||
}) => (ThisExpr { span: *span }.into(), None),
|
||||
|
||||
Expr::Member(MemberExpr { obj, .. }) if obj.is_this() => (obj.clone(), None),
|
||||
|
||||
@ -93,7 +93,7 @@ impl VisitMut for Spread {
|
||||
Expr::Member(MemberExpr { obj, .. })
|
||||
if obj.as_ident().is_some() && obj.as_ident().unwrap().span.is_dummy() =>
|
||||
{
|
||||
(Box::new(Expr::Ident(obj.as_ident().unwrap().clone())), None)
|
||||
(obj.as_ident().unwrap().clone().into(), None)
|
||||
}
|
||||
|
||||
Expr::Ident(Ident { span, .. }) => (Expr::undefined(*span), None),
|
||||
@ -109,29 +109,34 @@ impl VisitMut for Spread {
|
||||
init: None,
|
||||
});
|
||||
|
||||
let this = Box::new(Expr::Ident(ident.clone()));
|
||||
let callee = Expr::Assign(AssignExpr {
|
||||
let this = ident.clone().into();
|
||||
let callee: Expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: ident.into(),
|
||||
op: op!("="),
|
||||
right: obj.clone(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
(
|
||||
this,
|
||||
Some(Box::new(Expr::Member(MemberExpr {
|
||||
Some(
|
||||
MemberExpr {
|
||||
span: *span,
|
||||
obj: callee.into(),
|
||||
prop: prop.clone(),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// https://github.com/swc-project/swc/issues/400
|
||||
// _ => (undefined(callee.span()), callee),
|
||||
_ => (
|
||||
Box::new(Expr::This(ThisExpr {
|
||||
ThisExpr {
|
||||
span: callee.span(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None,
|
||||
),
|
||||
};
|
||||
@ -140,10 +145,11 @@ impl VisitMut for Spread {
|
||||
matches!(e, ExprOrSpread { spread: None, .. })
|
||||
|| matches!(e, ExprOrSpread { expr, .. } if expr.is_array())
|
||||
}) {
|
||||
Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: *span,
|
||||
elems: expand_literal_args(args.take().into_iter().map(Some)),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
self.concat_args(*span, args.take().into_iter().map(Some), false)
|
||||
};
|
||||
@ -154,12 +160,13 @@ impl VisitMut for Spread {
|
||||
prop: MemberProp::Ident(IdentName::new("apply".into(), *span)),
|
||||
};
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: apply.as_callee(),
|
||||
args: vec![this.as_arg(), args_array.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Expr::New(NewExpr {
|
||||
callee,
|
||||
@ -176,12 +183,13 @@ impl VisitMut for Spread {
|
||||
|
||||
let args = self.concat_args(*span, args.take().into_iter().map(Some), true);
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: helper!(construct),
|
||||
args: vec![callee.take().as_arg(), args.as_arg()],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
@ -291,7 +299,7 @@ impl Spread {
|
||||
);
|
||||
}
|
||||
|
||||
return Expr::Call(CallExpr {
|
||||
return CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
@ -301,7 +309,8 @@ impl Spread {
|
||||
.as_callee(),
|
||||
args: arg_list,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
for arg in args {
|
||||
@ -338,7 +347,7 @@ impl Spread {
|
||||
Expr::Ident(Ident { ref sym, .. }) if &**sym == "arguments" => {
|
||||
if args_len == 1 {
|
||||
if need_array {
|
||||
return Expr::Call(CallExpr {
|
||||
return CallExpr {
|
||||
span,
|
||||
callee: member_expr!(
|
||||
Default::default(),
|
||||
@ -348,7 +357,8 @@ impl Spread {
|
||||
.as_callee(),
|
||||
args: vec![expr.as_arg()],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
return *expr;
|
||||
}
|
||||
@ -372,13 +382,13 @@ impl Spread {
|
||||
return if self.c.loose {
|
||||
*expr
|
||||
} else {
|
||||
Expr::Call(to_consumable_array(expr, span))
|
||||
to_consumable_array(expr, span).into()
|
||||
};
|
||||
}
|
||||
// [].concat(arr) is shorter than _to_consumable_array(arr)
|
||||
if args_len == 1 {
|
||||
return if self.c.loose {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
@ -388,9 +398,10 @@ impl Spread {
|
||||
.as_callee(),
|
||||
args: vec![expr.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::Call(to_consumable_array(expr, span))
|
||||
to_consumable_array(expr, span).into()
|
||||
};
|
||||
}
|
||||
to_consumable_array(expr, span).as_arg()
|
||||
@ -418,15 +429,16 @@ impl Spread {
|
||||
.make_member(IdentName::new("concat".into(), DUMMY_SP))
|
||||
.as_callee();
|
||||
|
||||
return Expr::Call(CallExpr {
|
||||
return CallExpr {
|
||||
span,
|
||||
callee,
|
||||
args: buf,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
// TODO
|
||||
span,
|
||||
|
||||
@ -446,7 +458,8 @@ impl Spread {
|
||||
|
||||
args: buf,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,12 +41,13 @@ impl VisitMut for StickyRegex {
|
||||
|
||||
if let Expr::Lit(Lit::Regex(Regex { exp, flags, span })) = e {
|
||||
if flags.contains('y') {
|
||||
*e = Expr::New(NewExpr {
|
||||
*e = NewExpr {
|
||||
span: *span,
|
||||
callee: Box::new(quote_ident!(Default::default(), *span, "RegExp").into()),
|
||||
args: Some(vec![exp.clone().as_arg(), flags.clone().as_arg()]),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,16 +132,16 @@ impl VisitMut for TemplateLiteral {
|
||||
value: r_value,
|
||||
..
|
||||
})) => {
|
||||
obj = Box::new(Expr::Lit(Lit::Str(Str {
|
||||
obj = Lit::Str(Str {
|
||||
span: span.with_hi(r_span.hi()),
|
||||
raw: None,
|
||||
value: format!("{}{}", value, r_value).into(),
|
||||
})));
|
||||
})
|
||||
.into();
|
||||
continue;
|
||||
}
|
||||
_ => {
|
||||
obj =
|
||||
Box::new(Expr::Lit(Lit::Str(Str { span, raw, value })));
|
||||
obj = Lit::Str(Str { span, raw, value }).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,16 +155,17 @@ impl VisitMut for TemplateLiteral {
|
||||
obj = if self.c.ignore_to_primitive {
|
||||
let args = mem::take(&mut args);
|
||||
for arg in args {
|
||||
obj = Box::new(Expr::Bin(BinExpr {
|
||||
obj = BinExpr {
|
||||
span: span.with_hi(expr_span.hi() + BytePos(1)),
|
||||
op: op!(bin, "+"),
|
||||
left: obj,
|
||||
right: arg,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
obj
|
||||
} else {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: span.with_hi(expr_span.hi() + BytePos(1)),
|
||||
callee: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -180,7 +181,8 @@ impl VisitMut for TemplateLiteral {
|
||||
.map(|expr| expr.as_arg())
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -196,16 +198,17 @@ impl VisitMut for TemplateLiteral {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
obj = Box::new(Expr::Bin(BinExpr {
|
||||
obj = BinExpr {
|
||||
span: span.with_hi(expr_span.hi() + BytePos(1)),
|
||||
op: op!(bin, "+"),
|
||||
left: obj,
|
||||
right: arg,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
obj
|
||||
} else {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: span.with_hi(expr_span.hi() + BytePos(1)),
|
||||
callee: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -221,7 +224,8 @@ impl VisitMut for TemplateLiteral {
|
||||
.map(|expr| expr.as_arg())
|
||||
.collect(),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
};
|
||||
}
|
||||
debug_assert!(args.is_empty());
|
||||
@ -310,8 +314,8 @@ impl VisitMut for TemplateLiteral {
|
||||
// _templateObject2 = function () {
|
||||
// return data;
|
||||
// };
|
||||
let assign_expr = {
|
||||
Expr::Assign(AssignExpr {
|
||||
let assign_expr: Expr = {
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: fn_ident.clone().into(),
|
||||
op: op!("="),
|
||||
@ -331,7 +335,8 @@ impl VisitMut for TemplateLiteral {
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
Some(BlockStmt {
|
||||
@ -357,7 +362,7 @@ impl VisitMut for TemplateLiteral {
|
||||
function: f.into(),
|
||||
})));
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: tag.take().as_callee(),
|
||||
args: iter::once(
|
||||
@ -372,7 +377,8 @@ impl VisitMut for TemplateLiteral {
|
||||
.chain(tpl.exprs.take().into_iter().map(|e| e.as_arg()))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -67,39 +67,46 @@ impl VisitMut for TypeOfSymbol {
|
||||
Expr::Ident(..) => {
|
||||
let undefined_str: Box<Expr> = quote_str!("undefined").into();
|
||||
|
||||
let test = Box::new(Expr::Bin(BinExpr {
|
||||
let test = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("==="),
|
||||
left: Box::new(Expr::Unary(UnaryExpr {
|
||||
left: Box::new(
|
||||
UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("typeof"),
|
||||
arg: arg.clone(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
right: undefined_str.clone(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let call = Expr::Call(CallExpr {
|
||||
let call = CallExpr {
|
||||
span: *span,
|
||||
callee: helper!(*span, type_of),
|
||||
args: vec![arg.take().as_arg()],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
*expr = Expr::Cond(CondExpr {
|
||||
*expr = CondExpr {
|
||||
span: *span,
|
||||
test,
|
||||
cons: undefined_str,
|
||||
alt: Box::new(call),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => {
|
||||
let call = Expr::Call(CallExpr {
|
||||
let call = CallExpr {
|
||||
span: *span,
|
||||
callee: helper!(*span, type_of),
|
||||
args: vec![arg.take().as_arg()],
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
*expr = call;
|
||||
}
|
||||
|
@ -109,12 +109,13 @@ impl VisitMut for Exponentiation {
|
||||
}
|
||||
|
||||
left => {
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
*e = AssignExpr {
|
||||
span: *span,
|
||||
left: left.take(),
|
||||
op: op!("="),
|
||||
right: right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -138,13 +139,14 @@ impl VisitMut for Exponentiation {
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
fn mk_call(span: Span, left: Box<Expr>, right: Box<Expr>) -> Expr {
|
||||
// Math.pow()
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: member_expr!(Default::default(), span, Math.pow).as_callee(),
|
||||
|
||||
args: vec![left.as_arg(), right.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -156,12 +156,15 @@ impl<C: Comments> VisitMut for Actual<C> {
|
||||
.into_iter()
|
||||
.chain(iter::once(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Call(CallExpr {
|
||||
arg: Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: expr.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
})))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
@ -267,18 +270,15 @@ impl<C: Comments> VisitMut for Actual<C> {
|
||||
);
|
||||
|
||||
let fn_ref = if is_this_used {
|
||||
fn_ref.apply(
|
||||
DUMMY_SP,
|
||||
Box::new(Expr::This(ThisExpr { span: DUMMY_SP })),
|
||||
vec![],
|
||||
)
|
||||
fn_ref.apply(DUMMY_SP, ThisExpr { span: DUMMY_SP }.into(), vec![])
|
||||
} else {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: fn_ref.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
prop.function = Function {
|
||||
@ -427,14 +427,13 @@ fn make_fn_ref(mut expr: FnExpr) -> Expr {
|
||||
|
||||
let span = expr.span();
|
||||
|
||||
let expr = Expr::Fn(expr);
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper,
|
||||
args: vec![expr.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
struct AsyncFnBodyHandler {
|
||||
@ -470,7 +469,7 @@ impl VisitMut for AsyncFnBodyHandler {
|
||||
delegate: true,
|
||||
}) => {
|
||||
let callee = helper!(async_generator_delegate);
|
||||
let arg = Box::new(Expr::Call(CallExpr {
|
||||
let arg = CallExpr {
|
||||
span: *span,
|
||||
callee,
|
||||
args: vec![
|
||||
@ -484,34 +483,39 @@ impl VisitMut for AsyncFnBodyHandler {
|
||||
helper_expr!(await_async_generator).as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
}));
|
||||
*expr = Expr::Yield(YieldExpr {
|
||||
}
|
||||
.into();
|
||||
*expr = YieldExpr {
|
||||
span: *span,
|
||||
delegate: true,
|
||||
arg: Some(arg),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
Expr::Await(AwaitExpr { span, arg }) => {
|
||||
if self.is_async_generator {
|
||||
let callee = helper!(await_async_generator);
|
||||
let arg = Box::new(Expr::Call(CallExpr {
|
||||
let arg = CallExpr {
|
||||
span: *span,
|
||||
callee,
|
||||
args: vec![arg.take().as_arg()],
|
||||
..Default::default()
|
||||
}));
|
||||
*expr = Expr::Yield(YieldExpr {
|
||||
}
|
||||
.into();
|
||||
*expr = YieldExpr {
|
||||
span: *span,
|
||||
delegate: false,
|
||||
arg: Some(arg),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
*expr = Expr::Yield(YieldExpr {
|
||||
*expr = YieldExpr {
|
||||
span: *span,
|
||||
delegate: false,
|
||||
arg: Some(arg.take()),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -606,7 +610,7 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
let var_decl = VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: var.name,
|
||||
init: Some(Box::new(Expr::Ident(value))),
|
||||
init: Some(value.into()),
|
||||
definite: false,
|
||||
};
|
||||
for_loop_body.push(
|
||||
@ -623,12 +627,13 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
ForHead::Pat(p) => {
|
||||
for_loop_body.push(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: p.try_into().unwrap(),
|
||||
right: Box::new(Expr::Ident(value)),
|
||||
})),
|
||||
right: Box::new(value.into()),
|
||||
}
|
||||
.into(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -653,12 +658,15 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
init: {
|
||||
let callee = helper!(async_iterator);
|
||||
|
||||
Some(Box::new(Expr::Call(CallExpr {
|
||||
Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee,
|
||||
args: vec![s.right.as_arg()],
|
||||
..Default::default()
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
definite: false,
|
||||
});
|
||||
@ -693,49 +701,59 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
};
|
||||
|
||||
let yield_arg = if is_async_generator {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(await_async_generator),
|
||||
args: vec![iter_next.as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Box::new(Expr::Call(iter_next))
|
||||
iter_next.into()
|
||||
};
|
||||
|
||||
let assign_to_step = Expr::Assign(AssignExpr {
|
||||
let assign_to_step: Expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: step.into(),
|
||||
right: Box::new(Expr::Yield(YieldExpr {
|
||||
right: YieldExpr {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(yield_arg),
|
||||
delegate: false,
|
||||
})),
|
||||
});
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
|
||||
let right = Box::new(Expr::Unary(UnaryExpr {
|
||||
let right = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: assign_to_step.make_member(quote_ident!("done")).into(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let left = iterator_abrupt_completion.clone().into();
|
||||
|
||||
Some(Box::new(Expr::Assign(AssignExpr {
|
||||
Some(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left,
|
||||
right,
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
// _iteratorNormalCompletion = true
|
||||
update: Some(Box::new(Expr::Assign(AssignExpr {
|
||||
update: Some(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: iterator_abrupt_completion.clone().into(),
|
||||
right: false.into(),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
body: Box::new(Stmt::Block(for_loop_body)),
|
||||
});
|
||||
|
||||
@ -750,22 +768,24 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
// _didIteratorError = true;
|
||||
let mark_as_errorred = Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: did_iteration_error.clone().into(),
|
||||
right: true.into(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
// _iteratorError = err;
|
||||
let store_error = Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
expr: AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: iterator_error.clone().into(),
|
||||
right: Box::new(Expr::Ident(err_param.clone())),
|
||||
})),
|
||||
right: Box::new(err_param.clone().into()),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
|
||||
CatchClause {
|
||||
@ -781,11 +801,11 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
let finally_block = {
|
||||
let throw_iterator_error = Stmt::Throw(ThrowStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Box::new(Expr::Ident(iterator_error.clone())),
|
||||
arg: iterator_error.clone().into(),
|
||||
});
|
||||
let throw_iterator_error = Stmt::If(IfStmt {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Ident(did_iteration_error.clone())),
|
||||
test: did_iteration_error.clone().into(),
|
||||
cons: Box::new(Stmt::Block(BlockStmt {
|
||||
span: DUMMY_SP,
|
||||
stmts: vec![throw_iterator_error],
|
||||
@ -794,7 +814,7 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
alt: None,
|
||||
});
|
||||
|
||||
let iterator_return = Box::new(Expr::Call(CallExpr {
|
||||
let iterator_return: Expr = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: iterator
|
||||
.clone()
|
||||
@ -802,45 +822,52 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
// yield _iterator.return();
|
||||
// or
|
||||
// yield _awaitAsyncGenerator(_iterator.return());
|
||||
let yield_stmt = Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Yield(YieldExpr {
|
||||
expr: YieldExpr {
|
||||
span: DUMMY_SP,
|
||||
delegate: false,
|
||||
arg: Some(if is_async_generator {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(await_async_generator),
|
||||
args: vec![iterator_return.as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
iterator_return
|
||||
iterator_return.into()
|
||||
}),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
|
||||
let conditional_yield = Stmt::If(IfStmt {
|
||||
span: DUMMY_SP,
|
||||
// _iteratorAbruptCompletion && _iterator.return != null
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("&&"),
|
||||
// _iteratorAbruptCompletion
|
||||
left: Box::new(Expr::Ident(iterator_abrupt_completion.clone())),
|
||||
left: Box::new(iterator_abrupt_completion.clone().into()),
|
||||
// _iterator.return != null
|
||||
right: Box::new(Expr::Bin(BinExpr {
|
||||
right: Box::new(
|
||||
BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!="),
|
||||
left: iterator.make_member(quote_ident!("return")).into(),
|
||||
right: Null { span: DUMMY_SP }.into(),
|
||||
})),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
cons: Box::new(Stmt::Block(BlockStmt {
|
||||
stmts: vec![yield_stmt],
|
||||
..Default::default()
|
||||
|
@ -229,34 +229,41 @@ impl VisitMut for ObjectRest {
|
||||
definite: false,
|
||||
});
|
||||
// println!("Expr: var_ident = right");
|
||||
self.exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
self.exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: var_ident.clone().into(),
|
||||
op: op!("="),
|
||||
right: right.take(),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
let pat = self.fold_rest(
|
||||
&mut 0,
|
||||
pat.take().into(),
|
||||
Box::new(Expr::Ident(var_ident.clone())),
|
||||
var_ident.clone().into(),
|
||||
true,
|
||||
true,
|
||||
);
|
||||
|
||||
match pat {
|
||||
Pat::Object(ObjectPat { ref props, .. }) if props.is_empty() => {}
|
||||
_ => self.exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
_ => self.exprs.push(
|
||||
AssignExpr {
|
||||
span: *span,
|
||||
left: pat.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right: Box::new(var_ident.clone().into()),
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
self.exprs.push(Box::new(var_ident.into()));
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: mem::take(&mut self.exprs),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
};
|
||||
}
|
||||
|
||||
@ -362,7 +369,8 @@ impl VisitMut for ObjectRest {
|
||||
self.vars.push(VarDeclarator {
|
||||
span: prop.span(),
|
||||
name: *prop.arg,
|
||||
init: Some(Box::new(Expr::Call(CallExpr {
|
||||
init: Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(extends),
|
||||
args: vec![
|
||||
@ -376,7 +384,9 @@ impl VisitMut for ObjectRest {
|
||||
.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
definite: false,
|
||||
});
|
||||
continue;
|
||||
@ -400,13 +410,8 @@ impl VisitMut for ObjectRest {
|
||||
}
|
||||
|
||||
let mut index = self.vars.len();
|
||||
let mut pat = self.fold_rest(
|
||||
&mut index,
|
||||
decl.name,
|
||||
Box::new(Expr::Ident(var_ident.clone())),
|
||||
false,
|
||||
true,
|
||||
);
|
||||
let mut pat =
|
||||
self.fold_rest(&mut index, decl.name, var_ident.clone().into(), false, true);
|
||||
match pat {
|
||||
// skip `{} = z`
|
||||
Pat::Object(ObjectPat { ref props, .. }) if props.is_empty() => {}
|
||||
@ -426,7 +431,7 @@ impl VisitMut for ObjectRest {
|
||||
name: pat,
|
||||
// preserve
|
||||
init: if has_init {
|
||||
Some(Box::new(Expr::Ident(var_ident.clone())))
|
||||
Some(var_ident.clone().into())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
@ -567,13 +572,8 @@ impl ObjectRest {
|
||||
.map(|mut param| {
|
||||
let var_ident = private_ident!(param.span(), "_param");
|
||||
let mut index = self.vars.len();
|
||||
param.pat = self.fold_rest(
|
||||
&mut index,
|
||||
param.pat,
|
||||
Box::new(Expr::Ident(var_ident.clone())),
|
||||
false,
|
||||
true,
|
||||
);
|
||||
param.pat =
|
||||
self.fold_rest(&mut index, param.pat, var_ident.clone().into(), false, true);
|
||||
|
||||
match param.pat {
|
||||
Pat::Rest(..) | Pat::Ident(..) => param,
|
||||
@ -591,18 +591,19 @@ impl ObjectRest {
|
||||
VarDeclarator {
|
||||
span,
|
||||
name: *left,
|
||||
init: Some(Box::new(Expr::Ident(var_ident.clone()))),
|
||||
init: Some(var_ident.clone().into()),
|
||||
definite: false,
|
||||
},
|
||||
);
|
||||
Param {
|
||||
span: DUMMY_SP,
|
||||
decorators: Default::default(),
|
||||
pat: Pat::Assign(AssignPat {
|
||||
pat: AssignPat {
|
||||
span,
|
||||
left: var_ident.into(),
|
||||
right,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -612,7 +613,7 @@ impl ObjectRest {
|
||||
VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: param.pat,
|
||||
init: Some(Box::new(Expr::Ident(var_ident.clone()))),
|
||||
init: Some(var_ident.clone().into()),
|
||||
definite: false,
|
||||
},
|
||||
);
|
||||
@ -693,7 +694,7 @@ impl ObjectRest {
|
||||
use_expr_for_assign,
|
||||
use_member_for_array,
|
||||
));
|
||||
return Pat::Assign(AssignPat { span, left, right });
|
||||
return AssignPat { span, left, right }.into();
|
||||
}
|
||||
Pat::Array(n) => {
|
||||
let ArrayPat { span, elems, .. } = n;
|
||||
@ -717,7 +718,7 @@ impl ObjectRest {
|
||||
})
|
||||
.collect();
|
||||
|
||||
return Pat::Array(ArrayPat { span, elems, ..n });
|
||||
return ArrayPat { span, elems, ..n }.into();
|
||||
}
|
||||
_ => return pat,
|
||||
};
|
||||
@ -760,11 +761,12 @@ impl ObjectRest {
|
||||
key,
|
||||
MemberProp::Computed(ComputedPropName {
|
||||
span,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value: format!("{}", value).into(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}),
|
||||
),
|
||||
PropName::BigInt(BigInt {
|
||||
@ -775,11 +777,12 @@ impl ObjectRest {
|
||||
key,
|
||||
MemberProp::Computed(ComputedPropName {
|
||||
span,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value: format!("{}", value).into(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@ -802,7 +805,7 @@ impl ObjectRest {
|
||||
(
|
||||
PropName::Computed(ComputedPropName {
|
||||
span: c.span,
|
||||
expr: Box::new(Expr::Ident(ident.clone())),
|
||||
expr: ident.clone().into(),
|
||||
}),
|
||||
MemberProp::Computed(ComputedPropName {
|
||||
span: c.span,
|
||||
@ -837,12 +840,13 @@ impl ObjectRest {
|
||||
match props.last() {
|
||||
Some(ObjectPatProp::Rest(..)) => {}
|
||||
_ => {
|
||||
return Pat::Object(ObjectPat {
|
||||
return ObjectPat {
|
||||
span,
|
||||
props,
|
||||
optional: false,
|
||||
type_ann,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
let last = match props.pop() {
|
||||
@ -854,7 +858,8 @@ impl ObjectRest {
|
||||
|
||||
if use_expr_for_assign {
|
||||
// println!("Expr: last.arg = objectWithoutProperties()",);
|
||||
self.exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
self.exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: last.arg.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
@ -863,7 +868,9 @@ impl ObjectRest {
|
||||
excluded_props,
|
||||
self.config.no_symbol,
|
||||
)),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
} else {
|
||||
// println!("Var: rest = objectWithoutProperties()",);
|
||||
self.push_var_if_not_empty(VarDeclarator {
|
||||
@ -878,12 +885,13 @@ impl ObjectRest {
|
||||
});
|
||||
}
|
||||
|
||||
Pat::Object(ObjectPat {
|
||||
ObjectPat {
|
||||
props,
|
||||
span,
|
||||
type_ann,
|
||||
optional: false,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -894,7 +902,7 @@ fn object_without_properties(
|
||||
no_symbol: bool,
|
||||
) -> Expr {
|
||||
if excluded_props.is_empty() {
|
||||
return Expr::Call(CallExpr {
|
||||
return CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(extends),
|
||||
args: vec![
|
||||
@ -908,7 +916,8 @@ fn object_without_properties(
|
||||
.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
let excluded_props = excluded_props
|
||||
@ -916,11 +925,12 @@ fn object_without_properties(
|
||||
.map(|v| {
|
||||
v.map(|v| match *v.expr {
|
||||
Expr::Lit(Lit::Num(Number { span, value, .. })) => ExprOrSpread {
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value: value.to_string().into(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
..v
|
||||
},
|
||||
_ => v,
|
||||
@ -928,7 +938,7 @@ fn object_without_properties(
|
||||
})
|
||||
.collect();
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: if no_symbol {
|
||||
helper!(object_without_properties_loose)
|
||||
@ -959,7 +969,8 @@ fn object_without_properties(
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
|
@ -95,12 +95,13 @@ impl VisitMut for ObjectSpread {
|
||||
buf
|
||||
};
|
||||
|
||||
*expr = Expr::Call(CallExpr {
|
||||
*expr = CallExpr {
|
||||
span: *span,
|
||||
callee,
|
||||
args,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,14 +109,15 @@ impl VisitMut for NullishCoalescing {
|
||||
}
|
||||
|
||||
let var_expr = if aliased {
|
||||
Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: l.clone().into(),
|
||||
right: left.take(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::Ident(l.clone())
|
||||
l.clone().into()
|
||||
};
|
||||
|
||||
*e = make_cond(self.c, *span, &l, var_expr, right.take());
|
||||
@ -125,7 +126,7 @@ impl VisitMut for NullishCoalescing {
|
||||
Expr::Assign(ref mut assign @ AssignExpr { op: op!("??="), .. }) => {
|
||||
match &mut assign.left {
|
||||
AssignTarget::Simple(SimpleAssignTarget::Ident(i)) => {
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
*e = AssignExpr {
|
||||
span: assign.span,
|
||||
op: op!("="),
|
||||
left: i.clone().into(),
|
||||
@ -136,7 +137,8 @@ impl VisitMut for NullishCoalescing {
|
||||
Expr::Ident(Ident::from(&*i)),
|
||||
assign.right.take(),
|
||||
)),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
AssignTarget::Simple(left) => {
|
||||
@ -149,21 +151,23 @@ impl VisitMut for NullishCoalescing {
|
||||
});
|
||||
|
||||
// TODO: Check for computed.
|
||||
let right_expr = Box::new(Expr::Assign(AssignExpr {
|
||||
let right_expr = AssignExpr {
|
||||
span: assign.span,
|
||||
left: left.clone().into(),
|
||||
op: op!("="),
|
||||
right: assign.right.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let var_expr = Expr::Assign(AssignExpr {
|
||||
let var_expr = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: alias.clone().into(),
|
||||
right: left.take().into(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
*e = AssignExpr {
|
||||
span: assign.span,
|
||||
op: op!("="),
|
||||
left: alias.clone().into(),
|
||||
@ -174,7 +178,8 @@ impl VisitMut for NullishCoalescing {
|
||||
var_expr,
|
||||
right_expr,
|
||||
)),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -221,22 +226,23 @@ impl VisitMut for NullishCoalescing {
|
||||
|
||||
#[tracing::instrument(level = "info", skip_all)]
|
||||
fn make_cond(c: Config, span: Span, alias: &Ident, var_expr: Expr, init: Box<Expr>) -> Expr {
|
||||
Expr::Cond(if c.no_document_all {
|
||||
if c.no_document_all {
|
||||
CondExpr {
|
||||
span,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(var_expr),
|
||||
op: op!("!="),
|
||||
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
})),
|
||||
cons: Box::new(Expr::Ident(alias.clone())),
|
||||
}
|
||||
.into(),
|
||||
cons: alias.clone().into(),
|
||||
alt: init,
|
||||
}
|
||||
} else {
|
||||
CondExpr {
|
||||
span,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(Expr::Bin(BinExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -251,9 +257,11 @@ fn make_cond(c: Config, span: Span, alias: &Ident, var_expr: Expr, init: Box<Exp
|
||||
op: op!("!=="),
|
||||
right: Expr::undefined(DUMMY_SP),
|
||||
})),
|
||||
})),
|
||||
cons: Box::new(Expr::Ident(alias.clone())),
|
||||
}
|
||||
.into(),
|
||||
cons: alias.clone().into(),
|
||||
alt: init,
|
||||
}
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -111,13 +111,14 @@ impl VisitMut for Operators {
|
||||
});
|
||||
|
||||
(
|
||||
Box::new(Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: alias.clone().into(),
|
||||
right: obj.into(),
|
||||
})),
|
||||
Box::new(Expr::Ident(alias)),
|
||||
}
|
||||
.into(),
|
||||
alias.into(),
|
||||
)
|
||||
}
|
||||
};
|
||||
@ -131,16 +132,18 @@ impl VisitMut for Operators {
|
||||
};
|
||||
|
||||
(
|
||||
Box::new(Expr::Member(MemberExpr {
|
||||
MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: left_obj,
|
||||
prop: left_prop,
|
||||
})),
|
||||
Box::new(Expr::Member(MemberExpr {
|
||||
}
|
||||
.into(),
|
||||
MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: right_obj,
|
||||
prop: right_prop,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
@ -149,12 +152,13 @@ impl VisitMut for Operators {
|
||||
}
|
||||
};
|
||||
|
||||
let right = Box::new(Expr::Assign(AssignExpr {
|
||||
let right = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: r_assign_target.try_into().unwrap(),
|
||||
right: right.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let op = match *op {
|
||||
op!("??=") => op!("??"),
|
||||
@ -163,12 +167,13 @@ impl VisitMut for Operators {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op,
|
||||
left: left_expr,
|
||||
right,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ impl<'a> VisitMut for ClassNameTdzFolder<'a> {
|
||||
//
|
||||
|
||||
if i.sym == self.class_name.sym {
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
@ -36,7 +36,8 @@ impl<'a> VisitMut for ClassNameTdzFolder<'a> {
|
||||
})),
|
||||
Box::new(Expr::Ident(i.clone())),
|
||||
],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ impl MemberInitRecord {
|
||||
MemberInit::PubProp(PubProp { span, name, value }) => value_init.push(
|
||||
if self.c.set_public_fields {
|
||||
let this = ThisExpr { span: DUMMY_SP };
|
||||
Expr::Assign(AssignExpr {
|
||||
Expr::from(AssignExpr {
|
||||
span,
|
||||
left: match name {
|
||||
PropName::Ident(id) => this.make_member(id).into(),
|
||||
@ -160,7 +160,7 @@ impl MemberInitRecord {
|
||||
right: value,
|
||||
})
|
||||
} else {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(define_property),
|
||||
args: vec![
|
||||
@ -169,7 +169,8 @@ impl MemberInitRecord {
|
||||
value.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
@ -193,7 +194,7 @@ impl MemberInitRecord {
|
||||
span,
|
||||
expr: (if self.c.set_public_fields {
|
||||
let class = class_ident.clone();
|
||||
Expr::Assign(AssignExpr {
|
||||
Expr::from(AssignExpr {
|
||||
span,
|
||||
left: match name {
|
||||
PropName::Ident(id) => class.make_member(id).into(),
|
||||
@ -203,7 +204,7 @@ impl MemberInitRecord {
|
||||
right: value,
|
||||
})
|
||||
} else {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(define_property),
|
||||
args: vec![
|
||||
@ -212,7 +213,8 @@ impl MemberInitRecord {
|
||||
value.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.into(),
|
||||
}))
|
||||
@ -221,7 +223,7 @@ impl MemberInitRecord {
|
||||
value_init.push(if self.c.private_as_properties {
|
||||
Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Call(CallExpr {
|
||||
expr: CallExpr {
|
||||
span,
|
||||
callee: obj_def_prop(),
|
||||
args: vec![
|
||||
@ -230,7 +232,8 @@ impl MemberInitRecord {
|
||||
get_value_desc(value).as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
} else {
|
||||
VarDecl {
|
||||
@ -255,7 +258,7 @@ impl MemberInitRecord {
|
||||
}) => normal_init.push(if self.c.private_as_properties {
|
||||
Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Call(CallExpr {
|
||||
expr: CallExpr {
|
||||
span,
|
||||
callee: obj_def_prop(),
|
||||
args: vec![
|
||||
@ -264,7 +267,8 @@ impl MemberInitRecord {
|
||||
get_accessor_desc(getter, setter).as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
} else {
|
||||
VarDecl {
|
||||
|
@ -195,7 +195,7 @@ impl<C: Comments> VisitMut for ClassProperties<C> {
|
||||
|
||||
stmts.push(Stmt::Return(ReturnStmt {
|
||||
span: DUMMY_SP,
|
||||
arg: Some(Box::new(Expr::Ident(ident))),
|
||||
arg: Some(ident.into()),
|
||||
}));
|
||||
|
||||
*body = BlockStmtOrExpr::BlockStmt(BlockStmt {
|
||||
@ -221,10 +221,11 @@ impl<C: Comments> VisitMut for ClassProperties<C> {
|
||||
let (decl, ClassExtra { lets, vars, stmts }) =
|
||||
self.visit_mut_class_as_decl(ident.clone(), class.take());
|
||||
|
||||
let class = Expr::Class(ClassExpr {
|
||||
let class = ClassExpr {
|
||||
ident: orig_ident.clone(),
|
||||
class: decl.class,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
if vars.is_empty() && lets.is_empty() && stmts.is_empty() {
|
||||
*expr = class;
|
||||
return;
|
||||
@ -319,10 +320,11 @@ impl<C: Comments> VisitMut for ClassProperties<C> {
|
||||
exprs.push(Box::new(ident.into()))
|
||||
}
|
||||
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
expr.visit_mut_children_with(self);
|
||||
};
|
||||
@ -579,7 +581,7 @@ impl<C: Comments> ClassProperties<C> {
|
||||
// string.
|
||||
PropName::Computed(ComputedPropName {
|
||||
span: c_span,
|
||||
expr: Box::new(Expr::Ident(ident)),
|
||||
expr: ident.into(),
|
||||
})
|
||||
}
|
||||
_ => method.key,
|
||||
@ -629,7 +631,7 @@ impl<C: Comments> ClassProperties<C> {
|
||||
definite: false,
|
||||
});
|
||||
}
|
||||
*key.expr = Expr::from(ident);
|
||||
*key.expr = ident.into();
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
@ -658,12 +660,13 @@ impl<C: Comments> ClassProperties<C> {
|
||||
definite: false,
|
||||
});
|
||||
let span = super_class.span();
|
||||
**super_class = Expr::Assign(AssignExpr {
|
||||
**super_class = AssignExpr {
|
||||
span,
|
||||
op: op!("="),
|
||||
left: ident.into(),
|
||||
right: super_class.take(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -766,24 +769,30 @@ impl<C: Comments> ClassProperties<C> {
|
||||
span: DUMMY_SP,
|
||||
definite: false,
|
||||
name: ident.clone().into(),
|
||||
init: Some(Box::new(Expr::from(CallExpr {
|
||||
init: Some(
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(class_private_field_loose_key),
|
||||
args: vec![ident.sym.as_arg()],
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
} else if !prop.is_static {
|
||||
vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
definite: false,
|
||||
name: ident.into(),
|
||||
init: Some(Box::new(Expr::from(NewExpr {
|
||||
init: Some(
|
||||
NewExpr {
|
||||
span,
|
||||
callee: Box::new(Expr::Ident(quote_ident!("WeakMap").into())),
|
||||
callee: Box::new(quote_ident!("WeakMap").into()),
|
||||
args: Some(Default::default()),
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
};
|
||||
if prop.is_static {
|
||||
@ -915,19 +924,21 @@ impl<C: Comments> ClassProperties<C> {
|
||||
definite: false,
|
||||
name: weak_coll_var.clone().into(),
|
||||
init: Some(Box::new(if self.c.private_as_properties {
|
||||
Expr::from(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee: helper!(class_private_field_loose_key),
|
||||
args: vec![weak_coll_var.sym.as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::New(NewExpr {
|
||||
NewExpr {
|
||||
span,
|
||||
callee: Box::new(Expr::Ident(extra.into())),
|
||||
callee: extra.into(),
|
||||
args: Some(Default::default()),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
})),
|
||||
})
|
||||
};
|
||||
|
@ -102,12 +102,13 @@ impl VisitMut for BrandCheckHandler<'_> {
|
||||
if let Expr::Ident(right) = &**right {
|
||||
let curr_class = self.private.curr_class();
|
||||
if curr_class.sym == right.sym && curr_class.ctxt == right.ctxt {
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("==="),
|
||||
left: Box::new(Expr::Ident(curr_class.clone())),
|
||||
right: Box::new(Expr::Ident(right.clone())),
|
||||
});
|
||||
left: curr_class.clone().into(),
|
||||
right: right.clone().into(),
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -119,12 +120,13 @@ impl VisitMut for BrandCheckHandler<'_> {
|
||||
}
|
||||
|
||||
if kind.is_static {
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("==="),
|
||||
left: right.take(),
|
||||
right: Box::new(Expr::Ident(class_name.clone())),
|
||||
});
|
||||
right: class_name.clone().into(),
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -134,13 +136,14 @@ impl VisitMut for BrandCheckHandler<'_> {
|
||||
SyntaxContext::empty().apply_mark(mark),
|
||||
);
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: weak_coll_ident.make_member(quote_ident!("has")).as_callee(),
|
||||
args: vec![right.take().as_arg()],
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -254,12 +257,12 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
SyntaxContext::empty().apply_mark(mark),
|
||||
);
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
callee: helper!(class_private_field_loose_base),
|
||||
span: *span,
|
||||
args: vec![obj.take().as_arg(), ident.clone().as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.computed_member(ident)
|
||||
.into();
|
||||
} else {
|
||||
@ -290,12 +293,13 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
let n = match &left.prop {
|
||||
MemberProp::PrivateName(n) => n.clone(),
|
||||
_ => {
|
||||
*e = Expr::Assign(AssignExpr {
|
||||
*e = AssignExpr {
|
||||
span: *span,
|
||||
left: left.into(),
|
||||
op: *op,
|
||||
right: right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -355,7 +359,7 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
};
|
||||
|
||||
if kind.is_static {
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(class_static_private_field_spec_set),
|
||||
args: vec![
|
||||
@ -366,7 +370,8 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
],
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else if kind.is_readonly() {
|
||||
let err = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -375,20 +380,22 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
..Default::default()
|
||||
}
|
||||
.into();
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: *span,
|
||||
exprs: vec![this, value, err],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
let set = helper!(class_private_field_set);
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: set,
|
||||
args: vec![this.as_arg(), ident.as_arg(), value.as_arg()],
|
||||
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,24 +422,27 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
let (expr, this) = self.visit_mut_private_get(&mut tag, None);
|
||||
|
||||
if let Some(this) = this {
|
||||
*e = Expr::TaggedTpl(TaggedTpl {
|
||||
*e = TaggedTpl {
|
||||
span: *span,
|
||||
tag: Box::new(Expr::Call(CallExpr {
|
||||
tag: CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: expr.make_member(quote_ident!("bind")).as_callee(),
|
||||
args: vec![this.as_arg()],
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
tpl: tpl.take(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
*e = Expr::TaggedTpl(TaggedTpl {
|
||||
*e = TaggedTpl {
|
||||
span: *span,
|
||||
tag: Box::new(expr),
|
||||
tpl: tpl.take(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,19 +458,21 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
|
||||
let (expr, this) = self.visit_mut_private_get(&mut callee, None);
|
||||
if let Some(this) = this {
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: expr.make_member(quote_ident!("call")).as_callee(),
|
||||
args: iter::once(this.as_arg()).chain(args.take()).collect(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: expr.as_callee(),
|
||||
args: args.take(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,12 +531,12 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
|
||||
SyntaxContext::empty().apply_mark(mark),
|
||||
);
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
callee: helper!(class_private_field_loose_base),
|
||||
span: *span,
|
||||
args: vec![obj.take().as_arg(), ident.clone().as_arg()],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.computed_member(ident)
|
||||
.into();
|
||||
} else {
|
||||
@ -662,7 +674,7 @@ impl<'a> PrivateAccessVisitor<'a> {
|
||||
let h = helper!(class_static_private_method_get);
|
||||
|
||||
return (
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: h,
|
||||
args: vec![
|
||||
@ -671,21 +683,23 @@ impl<'a> PrivateAccessVisitor<'a> {
|
||||
method_name.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
}),
|
||||
Some(Expr::Ident(class_name.clone())),
|
||||
}
|
||||
.into(),
|
||||
Some(class_name.clone().into()),
|
||||
);
|
||||
}
|
||||
|
||||
let get = helper!(class_static_private_field_spec_get);
|
||||
|
||||
(
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: get,
|
||||
args: vec![obj.as_arg(), class_name.clone().as_arg(), ident.as_arg()],
|
||||
..Default::default()
|
||||
}),
|
||||
Some(Expr::Ident(class_name.clone())),
|
||||
}
|
||||
.into(),
|
||||
Some(class_name.clone().into()),
|
||||
)
|
||||
} else {
|
||||
match self.private_access_type {
|
||||
@ -821,7 +835,7 @@ impl<'a> PrivateAccessVisitor<'a> {
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
Some(Expr::Ident(var)),
|
||||
Some(var.into()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ impl VisitMut for ThisInStaticFolder {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
if let Expr::This(..) = e {
|
||||
*e = Expr::Ident(self.ident.clone())
|
||||
*e = self.ident.clone().into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,9 +116,9 @@ impl VisitMut for OptionalChaining {
|
||||
arg: Some(a.right.take()),
|
||||
}),
|
||||
];
|
||||
a.right = Box::new(Expr::Call(CallExpr {
|
||||
a.right = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Expr::Arrow(ArrowExpr {
|
||||
callee: ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
params: vec![],
|
||||
body: Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt {
|
||||
@ -129,11 +129,12 @@ impl VisitMut for OptionalChaining {
|
||||
is_async: false,
|
||||
is_generator: false,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
self.vars = uninit;
|
||||
@ -158,7 +159,7 @@ enum Memo {
|
||||
impl Memo {
|
||||
fn into_expr(self) -> Expr {
|
||||
match self {
|
||||
Memo::Cache(i) => Expr::Ident(i),
|
||||
Memo::Cache(i) => i.into(),
|
||||
Memo::Raw(e) => *e,
|
||||
}
|
||||
}
|
||||
@ -259,12 +260,12 @@ impl OptionalChaining {
|
||||
Gathering::Call(mut c) => {
|
||||
c.callee = current.as_callee();
|
||||
ctx = None;
|
||||
Expr::Call(c)
|
||||
c.into()
|
||||
}
|
||||
Gathering::Member(mut m) => {
|
||||
m.obj = Box::new(current);
|
||||
ctx = None;
|
||||
Expr::Member(m)
|
||||
m.into()
|
||||
}
|
||||
Gathering::OptCall(mut c, memo) => {
|
||||
let mut call = false;
|
||||
@ -278,12 +279,13 @@ impl OptionalChaining {
|
||||
|
||||
match &this {
|
||||
Memo::Cache(i) => {
|
||||
m.obj = Box::new(Expr::Assign(AssignExpr {
|
||||
m.obj = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: i.clone().into(),
|
||||
right: m.obj.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
this
|
||||
}
|
||||
Memo::Raw(_) => this,
|
||||
@ -316,7 +318,7 @@ impl OptionalChaining {
|
||||
memo.into_expr().as_callee()
|
||||
};
|
||||
ctx = None;
|
||||
Expr::Call(c)
|
||||
c.into()
|
||||
}
|
||||
Gathering::OptMember(mut m, memo) => {
|
||||
committed_cond.push(CondExpr {
|
||||
@ -331,24 +333,25 @@ impl OptionalChaining {
|
||||
});
|
||||
ctx = Some(memo.clone());
|
||||
m.obj = memo.into_expr().into();
|
||||
Expr::Member(m)
|
||||
m.into()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// At this point, `current` is the right-most expression `_a_b.c` in `a?.b?.c`
|
||||
if is_delete {
|
||||
current = Expr::Unary(UnaryExpr {
|
||||
current = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("delete"),
|
||||
arg: Box::new(current),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
// We now need to reverse iterate the conditionals to construct out tree.
|
||||
for mut cond in committed_cond.into_iter().rev() {
|
||||
cond.alt = Box::new(current);
|
||||
current = Expr::Cond(cond)
|
||||
current = cond.into()
|
||||
}
|
||||
current
|
||||
}
|
||||
@ -423,47 +426,52 @@ impl OptionalChaining {
|
||||
|
||||
fn init_and_eq_null_or_undefined(i: &Memo, init: Expr, no_document_all: bool) -> Box<Expr> {
|
||||
let lhs = match i {
|
||||
Memo::Cache(i) => Box::new(Expr::Assign(AssignExpr {
|
||||
Memo::Cache(i) => AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: i.clone().into(),
|
||||
right: Box::new(init),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
Memo::Raw(e) => e.to_owned(),
|
||||
};
|
||||
|
||||
if no_document_all {
|
||||
return Box::new(Expr::Bin(BinExpr {
|
||||
return BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: lhs,
|
||||
op: op!("=="),
|
||||
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
}));
|
||||
right: Box::new(Lit::Null(Null { span: DUMMY_SP }).into()),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
let null_cmp = Box::new(Expr::Bin(BinExpr {
|
||||
let null_cmp = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: lhs,
|
||||
op: op!("==="),
|
||||
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
}));
|
||||
right: Box::new(Lit::Null(Null { span: DUMMY_SP }).into()),
|
||||
}
|
||||
.into();
|
||||
|
||||
let left_expr = match i {
|
||||
Memo::Cache(i) => Box::new(i.clone().into()),
|
||||
Memo::Raw(e) => e.to_owned(),
|
||||
};
|
||||
|
||||
let void_cmp = Box::new(Expr::Bin(BinExpr {
|
||||
let void_cmp = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: left_expr,
|
||||
op: op!("==="),
|
||||
right: Expr::undefined(DUMMY_SP),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
Box::new(Expr::Bin(BinExpr {
|
||||
BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: null_cmp,
|
||||
op: op!("||"),
|
||||
right: void_cmp,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -51,12 +51,15 @@ impl Mode {
|
||||
definite: Default::default(),
|
||||
});
|
||||
if let Some(init) = init {
|
||||
init_exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
init_exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: n.into(),
|
||||
right: init,
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Mode::ClassDecl { vars } => {
|
||||
@ -265,7 +268,7 @@ impl VisitMut for PrivateInObject {
|
||||
}));
|
||||
bs.visit_mut_with(self);
|
||||
|
||||
p.right = Box::new(Expr::Call(CallExpr {
|
||||
p.right = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -278,7 +281,8 @@ impl VisitMut for PrivateInObject {
|
||||
.as_callee(),
|
||||
args: Default::default(),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,10 +301,11 @@ impl VisitMut for PrivateInObject {
|
||||
}
|
||||
_ => {
|
||||
prepend_exprs.push(Box::new(e.take()));
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: prepend_exprs,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -320,12 +325,13 @@ impl VisitMut for PrivateInObject {
|
||||
|
||||
if let Some(cls_ident) = self.cls.ident.clone() {
|
||||
if is_static && is_method {
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("==="),
|
||||
left: Box::new(Expr::Ident(cls_ident)),
|
||||
left: cls_ident.into(),
|
||||
right: right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -337,18 +343,20 @@ impl VisitMut for PrivateInObject {
|
||||
{
|
||||
self.cls.vars.push_var(
|
||||
var_name.clone(),
|
||||
Some(Box::new(Expr::New(NewExpr {
|
||||
Some(
|
||||
NewExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Box::new(Expr::Ident(quote_ident!("WeakSet").into())),
|
||||
callee: Box::new(quote_ident!("WeakSet").into()),
|
||||
args: Some(Default::default()),
|
||||
..Default::default()
|
||||
}))),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
|
||||
if is_method {
|
||||
self.cls
|
||||
.constructor_exprs
|
||||
.push(Box::new(Expr::Call(CallExpr {
|
||||
self.cls.constructor_exprs.push(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: var_name
|
||||
.clone()
|
||||
@ -356,16 +364,19 @@ impl VisitMut for PrivateInObject {
|
||||
.as_callee(),
|
||||
args: vec![ThisExpr { span: DUMMY_SP }.as_arg()],
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
callee: var_name.make_member(quote_ident!("has")).as_callee(),
|
||||
args: vec![right.take().as_arg()],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -404,36 +415,45 @@ impl VisitMut for PrivateInObject {
|
||||
|
||||
self.cls.vars.push_var(tmp.clone(), None);
|
||||
|
||||
let assign = Box::new(Expr::Assign(AssignExpr {
|
||||
let assign = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: tmp.clone().into(),
|
||||
right: init.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let add_to_checker = Box::new(Expr::Call(CallExpr {
|
||||
let add_to_checker = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: var_name.make_member(quote_ident!("add")).as_callee(),
|
||||
args: vec![ThisExpr { span: DUMMY_SP }.as_arg()],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
*init = Box::new(Expr::Seq(SeqExpr {
|
||||
*init = SeqExpr {
|
||||
span: init_span,
|
||||
exprs: vec![assign, add_to_checker, Box::new(tmp.into())],
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
None => {
|
||||
n.value = Some(Box::new(Expr::Unary(UnaryExpr {
|
||||
n.value = Some(
|
||||
UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("void"),
|
||||
arg: Box::new(Expr::Call(CallExpr {
|
||||
arg: Box::new(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: var_name.make_member(quote_ident!("add")).as_callee(),
|
||||
args: vec![ThisExpr { span: DUMMY_SP }.as_arg()],
|
||||
..Default::default()
|
||||
})),
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ impl ClassStaticBlock {
|
||||
} else {
|
||||
static_block.body.stmts = stmts;
|
||||
|
||||
let expr = Expr::Call(CallExpr {
|
||||
let expr = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -43,7 +43,8 @@ impl ClassStaticBlock {
|
||||
.as_callee(),
|
||||
args: Vec::new(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
Some(Box::new(expr))
|
||||
};
|
||||
|
@ -42,11 +42,12 @@ impl Fold for MemberExprLit {
|
||||
return MemberExpr {
|
||||
prop: MemberProp::Computed(ComputedPropName {
|
||||
span: i.span,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span: i.span,
|
||||
raw: None,
|
||||
value: i.sym,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}),
|
||||
..e
|
||||
};
|
||||
|
@ -148,7 +148,7 @@ impl Hoister<'_> {
|
||||
|
||||
var_decls.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(id.into()),
|
||||
name: id.into(),
|
||||
init: None,
|
||||
definite: false,
|
||||
})
|
||||
@ -157,12 +157,15 @@ impl Hoister<'_> {
|
||||
|
||||
if let Some(init) = decl.init {
|
||||
//
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: decl.span,
|
||||
left: decl.name.try_into().unwrap(),
|
||||
op: op!("="),
|
||||
right: init,
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,10 +177,11 @@ impl Hoister<'_> {
|
||||
expr: if exprs.len() == 1 {
|
||||
exprs.into_iter().next().unwrap()
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
})))
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ impl ArgReplacer<'_> {
|
||||
let p = Param {
|
||||
span: DUMMY_SP,
|
||||
decorators: Default::default(),
|
||||
pat: Pat::Ident(private_ident!(format!("argument_{}", start)).into()),
|
||||
pat: private_ident!(format!("argument_{}", start)).into(),
|
||||
};
|
||||
start += 1;
|
||||
p
|
||||
@ -191,7 +191,7 @@ impl VisitMut for ArgReplacer<'_> {
|
||||
"arguments: Replacing access to arguments to normal \
|
||||
reference"
|
||||
);
|
||||
*n = Expr::Ident(i.id.clone());
|
||||
*n = i.id.clone().into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,7 +213,7 @@ impl VisitMut for ArgReplacer<'_> {
|
||||
reference"
|
||||
);
|
||||
self.changed = true;
|
||||
*n = Expr::Ident(i.id.clone());
|
||||
*n = i.id.clone().into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,12 +99,13 @@ impl Optimizer<'_> {
|
||||
report_change!("conditionals: `if (foo) bar;` => `foo && bar`");
|
||||
*s = Stmt::Expr(ExprStmt {
|
||||
span: stmt.span,
|
||||
expr: Box::new(Expr::Bin(BinExpr {
|
||||
expr: BinExpr {
|
||||
span: stmt.test.span(),
|
||||
op: op!("&&"),
|
||||
left: stmt.test.take(),
|
||||
right: cons.expr.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -194,7 +195,7 @@ impl Optimizer<'_> {
|
||||
span: e.span,
|
||||
op: e.op,
|
||||
left: left.left.take(),
|
||||
right: Box::new(Expr::Bin(res)),
|
||||
right: res.into(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -283,7 +284,7 @@ impl Optimizer<'_> {
|
||||
span,
|
||||
op: op!("=="),
|
||||
left: cmp.take(),
|
||||
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
right: Lit::Null(Null { span: DUMMY_SP }).into(),
|
||||
});
|
||||
} else {
|
||||
report_change!(
|
||||
@ -293,7 +294,7 @@ impl Optimizer<'_> {
|
||||
span,
|
||||
op: op!("!="),
|
||||
left: cmp.take(),
|
||||
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
right: Lit::Null(Null { span: DUMMY_SP }).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -66,24 +66,26 @@ impl Optimizer<'_> {
|
||||
if !cond.cons.may_have_side_effects(&self.expr_ctx) {
|
||||
self.changed = true;
|
||||
report_change!("conditionals: `cond ? useless : alt` => `cond || alt`");
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("||"),
|
||||
left: cond.test.take(),
|
||||
right: cond.alt.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
if !cond.alt.may_have_side_effects(&self.expr_ctx) {
|
||||
self.changed = true;
|
||||
report_change!("conditionals: `cond ? cons : useless` => `cond && cons`");
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("&&"),
|
||||
left: cond.test.take(),
|
||||
right: cond.cons.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,12 +146,13 @@ impl Optimizer<'_> {
|
||||
if SyntaxContext::within_ignored_ctxt(|| {
|
||||
cur_if.cons.eq_ignore_span(&stmt.cons)
|
||||
}) {
|
||||
cur_if.test = Box::new(Expr::Bin(BinExpr {
|
||||
cur_if.test = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: cur_if.test.take(),
|
||||
op: op!("||"),
|
||||
right: stmt.test.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
new.extend(cur.take().map(Stmt::If).map(T::from_stmt));
|
||||
|
||||
@ -244,31 +247,33 @@ impl Optimizer<'_> {
|
||||
}) => {
|
||||
report_change!("Optimizing `if (!foo); else bar();` as `foo && bar();`");
|
||||
|
||||
let mut expr = Box::new(Expr::Bin(BinExpr {
|
||||
let mut expr = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: arg.take(),
|
||||
op: op!("&&"),
|
||||
right: Box::new(alt.take()),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
self.compress_logical_exprs_as_bang_bang(&mut expr, true);
|
||||
*s = Stmt::Expr(ExprStmt {
|
||||
span: stmt.span,
|
||||
expr,
|
||||
expr: expr.into(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
report_change!("Optimizing `if (foo); else bar();` as `foo || bar();`");
|
||||
|
||||
let mut expr = Box::new(Expr::Bin(BinExpr {
|
||||
let mut expr = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: stmt.test.take(),
|
||||
op: op!("||"),
|
||||
right: Box::new(alt.take()),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
self.compress_logical_exprs_as_bang_bang(&mut expr, false);
|
||||
*s = Stmt::Expr(ExprStmt {
|
||||
span: stmt.span,
|
||||
expr,
|
||||
expr: expr.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -303,12 +308,13 @@ impl Optimizer<'_> {
|
||||
self.changed = true;
|
||||
*s = Stmt::Expr(ExprStmt {
|
||||
span: stmt.span,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
expr: CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: stmt.test.take(),
|
||||
cons: Box::new(cons.take()),
|
||||
alt: Box::new(alt.take()),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -337,12 +343,13 @@ impl Optimizer<'_> {
|
||||
if cond.test.is_ident() && cond.test.eq_ignore_span(&cond.cons) {
|
||||
report_change!("Compressing `x ? x : y` as `x || y`");
|
||||
self.changed = true;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("||"),
|
||||
left: cond.test.take(),
|
||||
right: cond.alt.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,10 +365,13 @@ impl Optimizer<'_> {
|
||||
|
||||
if cons.eq_ignore_span(alt) && !matches!(&*cons, Expr::Yield(..) | Expr::Fn(..)) {
|
||||
report_change!("conditionals: cons is same as alt");
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![test.take(), Box::new(cons.take())],
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
match (cons, alt) {
|
||||
@ -418,12 +428,13 @@ impl Optimizer<'_> {
|
||||
// Inject conditional.
|
||||
new_args.push(ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
expr: CondExpr {
|
||||
span: arg.expr.span(),
|
||||
test: test.take(),
|
||||
cons: arg.expr,
|
||||
alt: alt.args[idx].expr.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
} else {
|
||||
//
|
||||
@ -431,12 +442,15 @@ impl Optimizer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
return Some(Expr::Call(CallExpr {
|
||||
return Some(
|
||||
CallExpr {
|
||||
span: test.span(),
|
||||
callee: cons_callee.clone().as_callee(),
|
||||
args: new_args,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,22 +480,28 @@ impl Optimizer<'_> {
|
||||
"Compressing if into cond as there's no side effect and the number of \
|
||||
arguments is 1"
|
||||
);
|
||||
return Some(Expr::Call(CallExpr {
|
||||
return Some(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: cons.callee.take(),
|
||||
args,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
if !side_effect_free && is_for_if_stmt {
|
||||
report_change!("Compressing if into cond while preserving side effects");
|
||||
return Some(Expr::Cond(CondExpr {
|
||||
return Some(
|
||||
CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: test.take(),
|
||||
cons: Box::new(Expr::Call(cons.take())),
|
||||
alt: Box::new(Expr::Call(alt.take())),
|
||||
}));
|
||||
cons: cons.take().into(),
|
||||
alt: alt.take().into(),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
None
|
||||
@ -532,12 +552,15 @@ impl Optimizer<'_> {
|
||||
"Compressing if statement into a conditional expression of `new` as \
|
||||
there's no side effect and the number of arguments is 1"
|
||||
);
|
||||
return Some(Expr::New(NewExpr {
|
||||
return Some(
|
||||
NewExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: cons.callee.take(),
|
||||
args: Some(args),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
None
|
||||
@ -552,33 +575,41 @@ impl Optimizer<'_> {
|
||||
}
|
||||
|
||||
report_change!("Merging assignments in cons and alt of if statement");
|
||||
Some(Expr::Assign(AssignExpr {
|
||||
Some(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: cons.op,
|
||||
left: cons.left.take(),
|
||||
right: Box::new(Expr::Cond(CondExpr {
|
||||
right: CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: test.take(),
|
||||
cons: cons.right.take(),
|
||||
alt: alt.right.take(),
|
||||
})),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
// a ? b ? c() : d() : d() => a && b ? c() : d()
|
||||
(Expr::Cond(cons), alt) if (*cons.alt).eq_ignore_span(&*alt) => {
|
||||
report_change!("conditionals: a ? b ? c() : d() : d() => a && b ? c() : d()");
|
||||
Some(Expr::Cond(CondExpr {
|
||||
Some(
|
||||
CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
test: BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: test.take(),
|
||||
op: op!("&&"),
|
||||
right: cons.test.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons: cons.cons.take(),
|
||||
alt: cons.alt.take(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
// z ? "fuji" : (condition(), "fuji");
|
||||
@ -589,16 +620,20 @@ impl Optimizer<'_> {
|
||||
report_change!("conditionals: Reducing seq expr in alt");
|
||||
//
|
||||
alt.exprs.pop();
|
||||
let first = Box::new(Expr::Bin(BinExpr {
|
||||
let first = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: test.take(),
|
||||
op: op!("||"),
|
||||
right: Expr::from_exprs(alt.exprs.take()),
|
||||
}));
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
}
|
||||
.into();
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![first, Box::new(cons.take())],
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
// z ? (condition(), "fuji") : "fuji"
|
||||
@ -609,16 +644,20 @@ impl Optimizer<'_> {
|
||||
report_change!("conditionals: Reducing seq expr in cons");
|
||||
//
|
||||
cons.exprs.pop();
|
||||
let first = Box::new(Expr::Bin(BinExpr {
|
||||
let first = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: test.take(),
|
||||
op: op!("&&"),
|
||||
right: Expr::from_exprs(cons.exprs.take()),
|
||||
}));
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
}
|
||||
.into();
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![first, Box::new(alt.take())],
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
(Expr::Seq(left), Expr::Seq(right)) => {
|
||||
@ -657,10 +696,13 @@ impl Optimizer<'_> {
|
||||
}))];
|
||||
seq.append(&mut left.exprs);
|
||||
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: seq,
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else if idx == right_len {
|
||||
self.changed = true;
|
||||
report_change!("conditionals: Reducing similar seq expr in alt");
|
||||
@ -677,10 +719,13 @@ impl Optimizer<'_> {
|
||||
}))];
|
||||
seq.append(&mut right.exprs);
|
||||
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: seq,
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
self.changed = true;
|
||||
report_change!("conditionals: Reducing similar seq expr");
|
||||
@ -695,10 +740,13 @@ impl Optimizer<'_> {
|
||||
}))];
|
||||
seq.append(&mut common);
|
||||
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: seq,
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,12 +87,13 @@ impl Optimizer<'_> {
|
||||
);
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: assign.span,
|
||||
op,
|
||||
left: Box::new(Expr::Ident(lhs.clone().into())),
|
||||
left: lhs.clone().into(),
|
||||
right: assign.right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -49,22 +49,24 @@ impl Optimizer<'_> {
|
||||
"length" => {
|
||||
report_change!("evaluate: function.length");
|
||||
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: *span,
|
||||
value: metadata.len as _,
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
self.changed = true;
|
||||
}
|
||||
|
||||
"name" => {
|
||||
report_change!("evaluate: function.name");
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: *span,
|
||||
value: obj.sym.clone(),
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
self.changed = true;
|
||||
}
|
||||
|
||||
@ -113,20 +115,23 @@ impl Optimizer<'_> {
|
||||
Expr::Ident(Ident { span, sym, .. }) if &**sym == "Infinity" => {
|
||||
report_change!("evaluate: `Infinity` -> `1 / 0`");
|
||||
self.changed = true;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("/"),
|
||||
left: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
left: Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: 1.0,
|
||||
raw: None,
|
||||
}))),
|
||||
right: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
})
|
||||
.into(),
|
||||
right: Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: 0.0,
|
||||
raw: None,
|
||||
}))),
|
||||
});
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -187,11 +192,12 @@ impl Optimizer<'_> {
|
||||
exp.value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Regex(Regex {
|
||||
*e = Lit::Regex(Regex {
|
||||
span,
|
||||
exp: exp.value.as_ref().into(),
|
||||
flags: atom!(""),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -205,11 +211,12 @@ impl Optimizer<'_> {
|
||||
flags.value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Regex(Regex {
|
||||
*e = Lit::Regex(Regex {
|
||||
span,
|
||||
exp: exp.value.as_ref().into(),
|
||||
flags: flags.value.as_ref().into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,11 +249,12 @@ impl Optimizer<'_> {
|
||||
|
||||
let value = v.to_string();
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -272,28 +280,30 @@ impl Optimizer<'_> {
|
||||
Prop::Shorthand(p) => {
|
||||
keys.push(Some(ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span: p.span,
|
||||
raw: None,
|
||||
value: p.sym.clone(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}));
|
||||
}
|
||||
Prop::KeyValue(p) => match &p.key {
|
||||
PropName::Ident(key) => {
|
||||
keys.push(Some(ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
expr: Lit::Str(Str {
|
||||
span: key.span,
|
||||
raw: None,
|
||||
value: key.sym.clone(),
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}));
|
||||
}
|
||||
PropName::Str(key) => {
|
||||
keys.push(Some(ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Lit(Lit::Str(key.clone()))),
|
||||
expr: Lit::Str(key.clone()).into(),
|
||||
}));
|
||||
}
|
||||
_ => return,
|
||||
@ -303,7 +313,7 @@ impl Optimizer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
*e = Expr::Array(ArrayLit { span, elems: keys })
|
||||
*e = ArrayLit { span, elems: keys }.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,11 +345,12 @@ impl Optimizer<'_> {
|
||||
self.changed = true;
|
||||
report_change!("evaluate: Evaluated an expression as `{}`", value);
|
||||
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: e.span(),
|
||||
value,
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -355,17 +366,19 @@ impl Optimizer<'_> {
|
||||
report_change!("evaluate: Evaluated `{:?} ** {:?}`", l, r);
|
||||
|
||||
if l.is_nan() || r.is_nan() {
|
||||
*e = Expr::Ident(Ident::new(
|
||||
*e = Ident::new(
|
||||
"NaN".into(),
|
||||
bin.span,
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
));
|
||||
)
|
||||
.into();
|
||||
} else {
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: bin.span,
|
||||
value: l.powf(r),
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -401,11 +414,12 @@ impl Optimizer<'_> {
|
||||
report_change!("evaluate: `0 / 0` => `NaN`");
|
||||
|
||||
// Sign does not matter for NaN
|
||||
*e = Expr::Ident(Ident::new(
|
||||
*e = Ident::new(
|
||||
"NaN".into(),
|
||||
bin.span,
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
));
|
||||
)
|
||||
.into();
|
||||
}
|
||||
(FpCategory::Normal, FpCategory::Zero) => {
|
||||
self.changed = true;
|
||||
@ -413,16 +427,14 @@ impl Optimizer<'_> {
|
||||
|
||||
// Sign does not matter for NaN
|
||||
*e = if ln.is_sign_positive() == rn.is_sign_positive() {
|
||||
Expr::Ident(Ident::new_no_ctxt("Infinity".into(), bin.span))
|
||||
Ident::new_no_ctxt("Infinity".into(), bin.span).into()
|
||||
} else {
|
||||
Expr::Unary(UnaryExpr {
|
||||
UnaryExpr {
|
||||
span: bin.span,
|
||||
op: op!(unary, "-"),
|
||||
arg: Box::new(Expr::Ident(Ident::new_no_ctxt(
|
||||
"Infinity".into(),
|
||||
bin.span,
|
||||
))),
|
||||
})
|
||||
arg: Ident::new_no_ctxt("Infinity".into(), bin.span).into(),
|
||||
}
|
||||
.into()
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
|
@ -31,12 +31,13 @@ impl Optimizer<'_> {
|
||||
self.changed = true;
|
||||
report_change!("if_return: Merging nested if statements");
|
||||
|
||||
s.test = Box::new(Expr::Bin(BinExpr {
|
||||
s.test = BinExpr {
|
||||
span: s.test.span(),
|
||||
op: op!("&&"),
|
||||
left: s.test.take(),
|
||||
right: test.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
s.cons = cons.take();
|
||||
}
|
||||
}
|
||||
@ -313,7 +314,7 @@ impl Optimizer<'_> {
|
||||
)
|
||||
}
|
||||
},
|
||||
None => cur = Some(Box::new(Expr::Seq(v))),
|
||||
None => cur = Some(v.into()),
|
||||
},
|
||||
Expr::Cond(v) => match &mut cur {
|
||||
Some(cur) => match &mut **cur {
|
||||
@ -328,26 +329,31 @@ impl Optimizer<'_> {
|
||||
(prev_seq.span, exprs)
|
||||
};
|
||||
|
||||
*alt = Expr::Cond(CondExpr {
|
||||
*alt = CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Seq(SeqExpr { span, exprs })),
|
||||
test: SeqExpr { span, exprs }.into(),
|
||||
cons: v.cons,
|
||||
alt: v.alt,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
Expr::Seq(prev_seq) => {
|
||||
prev_seq.exprs.push(v.test);
|
||||
let exprs = prev_seq.exprs.take();
|
||||
|
||||
*cur = Box::new(Expr::Cond(CondExpr {
|
||||
*cur = CondExpr {
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Seq(SeqExpr {
|
||||
test: Box::new(
|
||||
SeqExpr {
|
||||
span: prev_seq.span,
|
||||
exprs,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
cons: v.cons,
|
||||
alt: v.alt,
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => {
|
||||
unreachable!(
|
||||
@ -356,7 +362,7 @@ impl Optimizer<'_> {
|
||||
)
|
||||
}
|
||||
},
|
||||
None => cur = Some(Box::new(Expr::Cond(v))),
|
||||
None => cur = Some(v.into()),
|
||||
},
|
||||
_ => {
|
||||
unreachable!(
|
||||
@ -432,34 +438,41 @@ impl Optimizer<'_> {
|
||||
|
||||
exprs.push(test);
|
||||
|
||||
Expr::Cond(CondExpr {
|
||||
CondExpr {
|
||||
span,
|
||||
test: Box::new(Expr::Seq(SeqExpr {
|
||||
test: SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
cons,
|
||||
alt,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Stmt::Expr(stmt) => {
|
||||
exprs.push(Box::new(Expr::Unary(UnaryExpr {
|
||||
exprs.push(
|
||||
UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("void"),
|
||||
arg: stmt.expr,
|
||||
})));
|
||||
Expr::Seq(SeqExpr {
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Stmt::Return(stmt) => {
|
||||
let span = stmt.span;
|
||||
exprs.push(stmt.arg.unwrap_or_else(|| Expr::undefined(span)));
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -35,11 +35,12 @@ impl Optimizer<'_> {
|
||||
|
||||
if let Expr::Fn(..) = callee {
|
||||
report_change!("negate_iife: Negating iife");
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: Box::new(e.take()),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,11 +67,12 @@ impl Optimizer<'_> {
|
||||
match callee {
|
||||
Expr::Fn(..) => {
|
||||
report_change!("negate_iife: Swapping cons and alt");
|
||||
cond.test = Box::new(Expr::Unary(UnaryExpr {
|
||||
cond.test = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg: cond.test.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
swap(&mut cond.cons, &mut cond.alt);
|
||||
true
|
||||
}
|
||||
@ -95,12 +97,13 @@ impl Optimizer<'_> {
|
||||
}) = &mut **arg
|
||||
{
|
||||
if let Expr::Fn(..) = &**callee {
|
||||
cond.test = Box::new(Expr::Call(CallExpr {
|
||||
cond.test = CallExpr {
|
||||
span: *call_span,
|
||||
callee: callee.take().as_callee(),
|
||||
args: args.take(),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
swap(&mut cond.cons, &mut cond.alt);
|
||||
}
|
||||
}
|
||||
@ -263,7 +266,7 @@ impl Optimizer<'_> {
|
||||
|
||||
vars.insert(
|
||||
param_id.to_id(),
|
||||
Box::new(Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: param_id.span,
|
||||
elems: e
|
||||
.args
|
||||
@ -271,7 +274,8 @@ impl Optimizer<'_> {
|
||||
.skip(idx)
|
||||
.map(|arg| Some(arg.clone()))
|
||||
.collect(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
param.take();
|
||||
}
|
||||
@ -899,7 +903,7 @@ impl Optimizer<'_> {
|
||||
|
||||
vars.push(VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(param.clone().into()),
|
||||
name: param.clone().into(),
|
||||
init: if self.ctx.executed_multiple_time && no_arg {
|
||||
Some(Expr::undefined(DUMMY_SP))
|
||||
} else {
|
||||
@ -970,12 +974,15 @@ impl Optimizer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
exprs.push(Box::new(Expr::Assign(AssignExpr {
|
||||
exprs.push(
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("="),
|
||||
left: decl.name.clone().try_into().unwrap(),
|
||||
right: decl.init.take().unwrap(),
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,7 +1004,7 @@ impl Optimizer<'_> {
|
||||
};
|
||||
self.merge_sequences_in_seq_expr(&mut e);
|
||||
|
||||
let mut e = Expr::Seq(e);
|
||||
let mut e = e.into();
|
||||
self.normalize_expr(&mut e);
|
||||
return Some(e);
|
||||
}
|
||||
@ -1006,11 +1013,12 @@ impl Optimizer<'_> {
|
||||
}
|
||||
|
||||
if let Some(last) = exprs.last_mut() {
|
||||
*last = Box::new(Expr::Unary(UnaryExpr {
|
||||
*last = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("void"),
|
||||
arg: last.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
return Some(*Expr::undefined(body.span));
|
||||
}
|
||||
@ -1021,7 +1029,7 @@ impl Optimizer<'_> {
|
||||
};
|
||||
self.merge_sequences_in_seq_expr(&mut e);
|
||||
|
||||
let mut e = Expr::Seq(e);
|
||||
let mut e = e.into();
|
||||
self.normalize_expr(&mut e);
|
||||
Some(e)
|
||||
}
|
||||
|
@ -688,10 +688,11 @@ impl Optimizer<'_> {
|
||||
|
||||
self.vars.simple_functions.insert(
|
||||
i.to_id(),
|
||||
Box::new(Expr::Fn(FnExpr {
|
||||
FnExpr {
|
||||
ident: None,
|
||||
function: f.function.clone(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
return;
|
||||
@ -764,18 +765,20 @@ impl Optimizer<'_> {
|
||||
}
|
||||
|
||||
let e = match decl.take() {
|
||||
Decl::Class(c) => Box::new(Expr::Class(ClassExpr {
|
||||
Decl::Class(c) => ClassExpr {
|
||||
ident: Some(c.ident),
|
||||
class: c.class,
|
||||
})),
|
||||
Decl::Fn(f) => Box::new(Expr::Fn(FnExpr {
|
||||
}
|
||||
.into(),
|
||||
Decl::Fn(f) => FnExpr {
|
||||
ident: if usage.used_recursively {
|
||||
Some(f.ident)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
function: f.function,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
|
@ -641,15 +641,17 @@ impl Optimizer<'_> {
|
||||
if let Lit::Bool(v) = lit {
|
||||
self.changed = true;
|
||||
report_change!("Compressing boolean literal");
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: v.span,
|
||||
op: op!("!"),
|
||||
arg: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
arg: Lit::Num(Number {
|
||||
span: v.span,
|
||||
value: if v.value { 0.0 } else { 1.0 },
|
||||
raw: None,
|
||||
}))),
|
||||
});
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -716,7 +718,7 @@ impl Optimizer<'_> {
|
||||
.any(|m| m.as_static_block().iter().any(|s| !s.body.is_empty()))
|
||||
{
|
||||
// there's nothing we can do about it
|
||||
return Some(Expr::Class(cls.take()));
|
||||
return Some(cls.take().into());
|
||||
}
|
||||
|
||||
let exprs: Vec<Box<Expr>> =
|
||||
@ -730,10 +732,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: cls.class.span,
|
||||
exprs,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
Expr::Paren(e) => return self.ignore_return_value(&mut e.expr),
|
||||
@ -807,10 +812,13 @@ impl Optimizer<'_> {
|
||||
|
||||
self.changed = true;
|
||||
report_change!("ignore_return_value: Compressing binary as seq");
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span,
|
||||
exprs: vec![Box::new(left.unwrap()), Box::new(right.unwrap())],
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Pure calls can be removed
|
||||
@ -890,10 +898,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Array(ArrayLit {
|
||||
return Some(
|
||||
ArrayLit {
|
||||
span: callee.span,
|
||||
elems,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
let args = args
|
||||
@ -907,10 +918,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: callee.span,
|
||||
exprs: args,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1022,7 +1036,8 @@ impl Optimizer<'_> {
|
||||
}) => true,
|
||||
_ => false,
|
||||
}) {
|
||||
return Some(Expr::Array(ArrayLit {
|
||||
return Some(
|
||||
ArrayLit {
|
||||
elems: arr
|
||||
.elems
|
||||
.take()
|
||||
@ -1040,7 +1055,9 @@ impl Optimizer<'_> {
|
||||
.map(Some)
|
||||
.collect(),
|
||||
..*arr
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut exprs = vec![];
|
||||
@ -1060,10 +1077,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: arr.span,
|
||||
exprs,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
Expr::Object(obj) => {
|
||||
@ -1120,10 +1140,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: obj.span,
|
||||
exprs,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
// Preserves negated iife
|
||||
@ -1174,10 +1197,11 @@ impl Optimizer<'_> {
|
||||
let left = self.ignore_return_value(left).map(Box::new);
|
||||
let right = self.ignore_return_value(right).map(Box::new);
|
||||
|
||||
let mut seq = Expr::Seq(SeqExpr {
|
||||
let mut seq = SeqExpr {
|
||||
span: *span,
|
||||
exprs: left.into_iter().chain(right).collect(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return self.ignore_return_value(&mut seq);
|
||||
}
|
||||
|
||||
@ -1205,7 +1229,8 @@ impl Optimizer<'_> {
|
||||
|
||||
// TODO: Remove if test is side effect free.
|
||||
|
||||
return Some(Expr::Cond(CondExpr {
|
||||
return Some(
|
||||
CondExpr {
|
||||
span: cond.span,
|
||||
test: cond.test.take(),
|
||||
cons: cons.unwrap_or_else(|| {
|
||||
@ -1218,7 +1243,9 @@ impl Optimizer<'_> {
|
||||
self.changed = true;
|
||||
Expr::undefined(alt_span)
|
||||
}),
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
Expr::Seq(seq) => {
|
||||
@ -1263,11 +1290,12 @@ impl Optimizer<'_> {
|
||||
if let Some(last) = exprs.last_mut() {
|
||||
report_change!("ignore_return_value: Shifting void");
|
||||
self.changed = true;
|
||||
*last = Box::new(Expr::Unary(UnaryExpr {
|
||||
*last = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("void"),
|
||||
arg: last.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1276,10 +1304,13 @@ impl Optimizer<'_> {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Expr::Seq(SeqExpr {
|
||||
return Some(
|
||||
SeqExpr {
|
||||
span: seq.span,
|
||||
exprs,
|
||||
}));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1626,18 +1657,20 @@ impl VisitMut for Optimizer<'_> {
|
||||
if is_this_undefined {
|
||||
if let Callee::Expr(callee) = &mut e.callee {
|
||||
if let Expr::Member(..) = &mut **callee {
|
||||
let zero = Box::new(Expr::Lit(Lit::Num(Number {
|
||||
let zero = Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: 0.0,
|
||||
raw: None,
|
||||
})));
|
||||
})
|
||||
.into();
|
||||
self.changed = true;
|
||||
report_change!("injecting zero to preserve `this` in call");
|
||||
|
||||
*callee = Box::new(Expr::Seq(SeqExpr {
|
||||
*callee = SeqExpr {
|
||||
span: callee.span(),
|
||||
exprs: vec![zero, callee.take()],
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2393,12 +2426,12 @@ impl VisitMut for Optimizer<'_> {
|
||||
|
||||
if let Prop::Shorthand(i) = n {
|
||||
if self.vars.has_pending_inline_for(&i.to_id()) {
|
||||
let mut e = Box::new(Expr::Ident(i.clone()));
|
||||
let mut e: Expr = i.clone().into();
|
||||
e.visit_mut_with(self);
|
||||
|
||||
*n = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(i.clone().into()),
|
||||
value: e,
|
||||
value: Box::new(e),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -3036,10 +3069,11 @@ impl VisitMut for Optimizer<'_> {
|
||||
expr: if side_effects.len() == 1 {
|
||||
side_effects.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: side_effects.take(),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
}));
|
||||
} else {
|
||||
@ -3061,10 +3095,11 @@ impl VisitMut for Optimizer<'_> {
|
||||
expr: if side_effects.len() == 1 {
|
||||
side_effects.remove(0)
|
||||
} else {
|
||||
Box::new(Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: side_effects,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
@ -119,10 +119,13 @@ impl Optimizer<'_> {
|
||||
let flag = n.op == op!("!=");
|
||||
let mut make_lit_bool = |value: bool| {
|
||||
self.changed = true;
|
||||
Some(Expr::Lit(Lit::Bool(Bool {
|
||||
Some(
|
||||
Lit::Bool(Bool {
|
||||
span: n.span,
|
||||
value: flag ^ value,
|
||||
})))
|
||||
})
|
||||
.into(),
|
||||
)
|
||||
};
|
||||
match (n.left.get_type().opt()?, n.right.get_type().opt()?) {
|
||||
// Abort if types differ, or one of them is unknown.
|
||||
@ -358,32 +361,35 @@ impl Optimizer<'_> {
|
||||
"Converting typeof of variable to literal as we know the value"
|
||||
);
|
||||
self.changed = true;
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: *span,
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Arrow(..) | Expr::Fn(..) => {
|
||||
report_change!("Converting typeof to 'function' as we know the value");
|
||||
self.changed = true;
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: *span,
|
||||
raw: None,
|
||||
value: "function".into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
|
||||
Expr::Array(..) | Expr::Object(..) => {
|
||||
report_change!("Converting typeof to 'object' as we know the value");
|
||||
self.changed = true;
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: *span,
|
||||
raw: None,
|
||||
value: "object".into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -458,12 +458,13 @@ impl Optimizer<'_> {
|
||||
report_change!("sequences: Lifting Assign");
|
||||
self.changed = true;
|
||||
if let Some(last) = seq.exprs.last_mut() {
|
||||
**last = Expr::Assign(AssignExpr {
|
||||
**last = AssignExpr {
|
||||
span: *span,
|
||||
op: op!("="),
|
||||
left: left.take(),
|
||||
right: last.take(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
*e = *right.take()
|
||||
@ -541,11 +542,12 @@ impl Optimizer<'_> {
|
||||
e.exprs.pop();
|
||||
let last = e.exprs.last_mut().unwrap();
|
||||
|
||||
*last = Box::new(Expr::Unary(UnaryExpr {
|
||||
*last = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("void"),
|
||||
arg: last.take(),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1279,7 +1281,7 @@ impl Optimizer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
if !self.is_skippable_for_seq(a, &Expr::Ident(left_id.id.clone())) {
|
||||
if !self.is_skippable_for_seq(a, &left_id.id.clone().into()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1315,7 +1317,7 @@ impl Optimizer<'_> {
|
||||
PropOrSpread::Spread(_) => return false,
|
||||
PropOrSpread::Prop(p) => match &**p {
|
||||
Prop::Shorthand(i) => {
|
||||
if !self.is_skippable_for_seq(a, &Expr::Ident(i.clone())) {
|
||||
if !self.is_skippable_for_seq(a, &i.clone().into()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1785,7 +1787,7 @@ impl Optimizer<'_> {
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
if !self.is_skippable_for_seq(Some(a), &Expr::Ident(b_left.id.clone())) {
|
||||
if !self.is_skippable_for_seq(Some(a), &b_left.id.clone().into()) {
|
||||
// Let's be safe
|
||||
if IdentUsageFinder::find(&b_left.to_id(), &b_assign.right) {
|
||||
return Ok(false);
|
||||
@ -1871,17 +1873,19 @@ impl Optimizer<'_> {
|
||||
if self.merge_sequential_expr(a, b_callee)? {
|
||||
if is_this_undefined {
|
||||
if let Expr::Member(..) = &**b_callee {
|
||||
let zero = Box::new(Expr::Lit(Lit::Num(Number {
|
||||
let zero = Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: 0.0,
|
||||
raw: None,
|
||||
})));
|
||||
})
|
||||
.into();
|
||||
report_change!("injecting zero to preserve `this` in call");
|
||||
|
||||
*b_callee = Box::new(Expr::Seq(SeqExpr {
|
||||
*b_callee = SeqExpr {
|
||||
span: b_callee.span(),
|
||||
exprs: vec![zero, b_callee.take()],
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1988,7 +1992,7 @@ impl Optimizer<'_> {
|
||||
// We can't ignore shorthand properties
|
||||
//
|
||||
// https://github.com/swc-project/swc/issues/6914
|
||||
let mut new_b = Box::new(Expr::Ident(shorthand.clone()));
|
||||
let mut new_b = shorthand.clone().into();
|
||||
if self.merge_sequential_expr(a, &mut new_b)? {
|
||||
*prop = Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: Ident::new_no_ctxt(
|
||||
@ -1996,7 +2000,7 @@ impl Optimizer<'_> {
|
||||
shorthand.span,
|
||||
)
|
||||
.into(),
|
||||
value: new_b.clone(),
|
||||
value: new_b.clone().into(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -2123,12 +2127,13 @@ impl Optimizer<'_> {
|
||||
if let Expr::Ident(orig_expr) = &*e {
|
||||
if orig_expr.to_id() == a_id.to_id() {
|
||||
replaced = true;
|
||||
*e = Expr::Update(UpdateExpr {
|
||||
*e = UpdateExpr {
|
||||
span: DUMMY_SP,
|
||||
op: *op,
|
||||
prefix: true,
|
||||
arg: Box::new(Expr::Ident(orig_expr.clone())),
|
||||
});
|
||||
arg: orig_expr.clone().into(),
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2197,12 +2202,13 @@ impl Optimizer<'_> {
|
||||
if let Expr::Ident(orig_expr) = &*e {
|
||||
if orig_expr.to_id() == a_id.to_id() {
|
||||
replaced = true;
|
||||
*e = Expr::Update(UpdateExpr {
|
||||
*e = UpdateExpr {
|
||||
span: DUMMY_SP,
|
||||
op: *op,
|
||||
prefix: true,
|
||||
arg: Box::new(Expr::Ident(orig_expr.clone())),
|
||||
});
|
||||
arg: orig_expr.clone().into(),
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2421,10 +2427,11 @@ impl Optimizer<'_> {
|
||||
Mergable::FnDecl(a) => {
|
||||
// We can inline a function declaration as a function expression.
|
||||
|
||||
Box::new(Expr::Fn(FnExpr {
|
||||
FnExpr {
|
||||
ident: Some(a.ident.take()),
|
||||
function: a.function.take(),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
Mergable::Drop => {
|
||||
@ -2445,10 +2452,11 @@ impl Optimizer<'_> {
|
||||
let a_expr = self.ignore_return_value(&mut a_expr);
|
||||
|
||||
if let Some(a) = a_expr {
|
||||
b.right = Box::new(Expr::Seq(SeqExpr {
|
||||
b.right = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![Box::new(a), b.right.take()],
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
@ -2476,12 +2484,13 @@ impl Optimizer<'_> {
|
||||
|
||||
let to = take_a(a, true, true);
|
||||
|
||||
b.right = Box::new(Expr::Bin(BinExpr {
|
||||
b.right = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
op: bin_op,
|
||||
left: to,
|
||||
right: b.right.take(),
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
@ -65,11 +65,12 @@ impl Optimizer<'_> {
|
||||
report_change!(
|
||||
"strings: Converted an expression into a string literal (in string context)"
|
||||
);
|
||||
*n = Expr::Lit(Lit::Str(Str {
|
||||
*n = Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -84,11 +85,12 @@ impl Optimizer<'_> {
|
||||
|
||||
let value = format!("{:?}", v.value);
|
||||
|
||||
*n = Expr::Lit(Lit::Str(Str {
|
||||
*n = Lit::Str(Str {
|
||||
span: v.span,
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
|
||||
Expr::Lit(Lit::Regex(v)) => {
|
||||
@ -104,11 +106,12 @@ impl Optimizer<'_> {
|
||||
|
||||
let value = format!("/{}/{}", v.exp, v.flags);
|
||||
|
||||
*n = Expr::Lit(Lit::Str(Str {
|
||||
*n = Lit::Str(Str {
|
||||
span: v.span,
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
|
||||
Expr::Bin(BinExpr {
|
||||
@ -119,11 +122,12 @@ impl Optimizer<'_> {
|
||||
}) => {
|
||||
if let (Expr::Lit(Lit::Num(l)), Expr::Lit(Lit::Num(r))) = (&**left, &**right) {
|
||||
if l.value == 0.0 && r.value == 0.0 {
|
||||
*n = Expr::Ident(Ident::new(
|
||||
*n = Ident::new(
|
||||
"NaN".into(),
|
||||
*span,
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
));
|
||||
)
|
||||
.into();
|
||||
self.changed = true;
|
||||
report_change!("strings: Evaluated 0 / 0 => NaN in string context");
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ impl Optimizer<'_> {
|
||||
.into_iter()
|
||||
.map(|name| VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(name.into()),
|
||||
name: name.into(),
|
||||
init: None,
|
||||
definite: Default::default(),
|
||||
})
|
||||
@ -369,12 +369,13 @@ impl Optimizer<'_> {
|
||||
let discriminant = sw.discriminant.take();
|
||||
|
||||
if let Some(test) = case.test {
|
||||
let test = Box::new(Expr::Bin(BinExpr {
|
||||
let test = BinExpr {
|
||||
left: discriminant,
|
||||
right: test,
|
||||
op: op!("==="),
|
||||
span: DUMMY_SP,
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
*s = Stmt::If(IfStmt {
|
||||
span: sw.span,
|
||||
|
@ -206,7 +206,7 @@ impl Optimizer<'_> {
|
||||
if let Some(VarDeclKind::Const | VarDeclKind::Let) = self.ctx.var_kind {
|
||||
*e = Null { span: DUMMY_SP }.into();
|
||||
} else {
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -677,10 +677,11 @@ impl Optimizer<'_> {
|
||||
);
|
||||
self.changed = true;
|
||||
if self.ctx.is_this_aware_callee {
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![0.into(), assign.right.take()],
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
*e = *assign.right.take();
|
||||
}
|
||||
|
@ -276,12 +276,13 @@ impl<'a> Finalizer<'a> {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match &*e {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => {
|
||||
Some(Box::new(Expr::Seq(SeqExpr {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![0.into(), e],
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => Some(e),
|
||||
}
|
||||
}
|
||||
@ -469,12 +470,13 @@ impl<'a> NormalMultiReplacer<'a> {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match &*e {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => {
|
||||
Some(Box::new(Expr::Seq(SeqExpr {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![0.into(), e],
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => Some(e),
|
||||
}
|
||||
}
|
||||
@ -553,12 +555,13 @@ impl ExprReplacer {
|
||||
let e = self.to.take()?;
|
||||
|
||||
match &*e {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => {
|
||||
Some(Box::new(Expr::Seq(SeqExpr {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![0.into(), e],
|
||||
})))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => Some(e),
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,15 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("unsafe_arrows: Fn expr => arrow");
|
||||
|
||||
*e = Expr::Arrow(ArrowExpr {
|
||||
*e = ArrowExpr {
|
||||
span: function.span,
|
||||
params: function.params.take().into_iter().map(|p| p.pat).collect(),
|
||||
body: Box::new(BlockStmtOrExpr::BlockStmt(function.body.take().unwrap())),
|
||||
is_async: function.is_async,
|
||||
is_generator: function.is_generator,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +95,7 @@ impl Pure<'_> {
|
||||
|
||||
*p = Prop::KeyValue(KeyValueProp {
|
||||
key: m.key.take(),
|
||||
value: Box::new(Expr::Arrow(ArrowExpr {
|
||||
value: ArrowExpr {
|
||||
span: m_span,
|
||||
params: m
|
||||
.function
|
||||
@ -107,7 +108,8 @@ impl Pure<'_> {
|
||||
is_async: m.function.is_async,
|
||||
is_generator: m.function.is_generator,
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -233,10 +233,11 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
let span = delete.arg.span();
|
||||
report_change!("booleans: Compressing `delete` as sequence expression");
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span,
|
||||
exprs: vec![delete.arg.take(), Box::new(make_bool(span, true))],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -321,11 +322,12 @@ impl Pure<'_> {
|
||||
report_change!("Optimizing: number => number (in bool context)");
|
||||
|
||||
self.changed = true;
|
||||
*n = Expr::Lit(Lit::Num(Number {
|
||||
*n = Lit::Num(Number {
|
||||
span: *span,
|
||||
value: if *value == 0.0 { 1.0 } else { 0.0 },
|
||||
raw: None,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
Expr::Unary(UnaryExpr {
|
||||
@ -348,23 +350,26 @@ impl Pure<'_> {
|
||||
|
||||
match &**arg {
|
||||
Expr::Ident(..) => {
|
||||
*n = Expr::Lit(Lit::Num(Number {
|
||||
*n = Lit::Num(Number {
|
||||
span: *span,
|
||||
value: 1.0,
|
||||
raw: None,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
_ => {
|
||||
// Return value of typeof is always truthy
|
||||
let true_expr = Box::new(Expr::Lit(Lit::Num(Number {
|
||||
let true_expr = Lit::Num(Number {
|
||||
span: *span,
|
||||
value: 1.0,
|
||||
raw: None,
|
||||
})));
|
||||
*n = Expr::Seq(SeqExpr {
|
||||
})
|
||||
.into();
|
||||
*n = SeqExpr {
|
||||
span: *span,
|
||||
exprs: vec![arg.take(), true_expr],
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,11 +378,12 @@ impl Pure<'_> {
|
||||
if !is_ignore {
|
||||
report_change!("Converting string as boolean expressions");
|
||||
self.changed = true;
|
||||
*n = Expr::Lit(Lit::Num(Number {
|
||||
*n = Lit::Num(Number {
|
||||
span: s.span,
|
||||
value: if s.value.is_empty() { 0.0 } else { 1.0 },
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,11 +394,12 @@ impl Pure<'_> {
|
||||
if self.options.bools {
|
||||
report_change!("booleans: Converting number as boolean expressions");
|
||||
self.changed = true;
|
||||
*n = Expr::Lit(Lit::Num(Number {
|
||||
*n = Lit::Num(Number {
|
||||
span: num.span,
|
||||
value: if num.value == 0.0 { 0.0 } else { 1.0 },
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,12 +30,13 @@ impl Pure<'_> {
|
||||
self.negate_twice(&mut cond.test, false);
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("||"),
|
||||
left: cond.test.take(),
|
||||
right: cond.alt.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -46,12 +47,13 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
self.negate(&mut cond.test, false, false);
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("&&"),
|
||||
left: cond.test.take(),
|
||||
right: cond.alt.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -66,12 +68,13 @@ impl Pure<'_> {
|
||||
// Negate twice to convert `test` to boolean.
|
||||
self.negate_twice(&mut cond.test, false);
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("&&"),
|
||||
left: cond.test.take(),
|
||||
right: cond.cons.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -81,12 +84,13 @@ impl Pure<'_> {
|
||||
|
||||
self.negate(&mut cond.test, false, false);
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("||"),
|
||||
left: cond.test.take(),
|
||||
right: cond.cons.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,17 +114,19 @@ impl Pure<'_> {
|
||||
report_change!("conditionals: `x ? y || z : z` => `x || y && z`");
|
||||
self.changed = true;
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: cond.span,
|
||||
op: op!("||"),
|
||||
left: Box::new(Expr::Bin(BinExpr {
|
||||
left: BinExpr {
|
||||
span: cons_span,
|
||||
op: op!("&&"),
|
||||
left: cond.test.take(),
|
||||
right: cons.left.take(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
right: cons.right.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ impl Pure<'_> {
|
||||
.into_iter()
|
||||
.map(|name| VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(name.into()),
|
||||
name: name.into(),
|
||||
init: None,
|
||||
definite: Default::default(),
|
||||
})
|
||||
@ -551,7 +551,7 @@ impl Pure<'_> {
|
||||
.into_iter()
|
||||
.map(|name| VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(name.into()),
|
||||
name: name.into(),
|
||||
init: None,
|
||||
definite: Default::default(),
|
||||
})
|
||||
|
@ -88,16 +88,17 @@ impl Pure<'_> {
|
||||
report_change!("evaluate: Reducing array.slice({}) call", start);
|
||||
|
||||
if start >= arr.elems.len() {
|
||||
*e = Expr::Array(ArrayLit {
|
||||
*e = ArrayLit {
|
||||
span: *span,
|
||||
elems: Default::default(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
let elems = arr.elems.drain(start..).collect();
|
||||
|
||||
*e = Expr::Array(ArrayLit { span: *span, elems });
|
||||
*e = ArrayLit { span: *span, elems }.into();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -129,16 +130,17 @@ impl Pure<'_> {
|
||||
end
|
||||
);
|
||||
if start >= arr.elems.len() {
|
||||
*e = Expr::Array(ArrayLit {
|
||||
*e = ArrayLit {
|
||||
span: *span,
|
||||
elems: Default::default(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
let elems = arr.elems.drain(start..end).collect();
|
||||
|
||||
*e = Expr::Array(ArrayLit { span: *span, elems });
|
||||
*e = ArrayLit { span: *span, elems }.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,11 +284,12 @@ impl Pure<'_> {
|
||||
"evaluate: Reducing a call to `Number` into an unary operation"
|
||||
);
|
||||
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: *span,
|
||||
op: op!(unary, "+"),
|
||||
arg: args.take().into_iter().next().unwrap().expr,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,11 +372,12 @@ impl Pure<'_> {
|
||||
value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
|
||||
return;
|
||||
@ -393,11 +397,12 @@ impl Pure<'_> {
|
||||
value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -418,11 +423,12 @@ impl Pure<'_> {
|
||||
num,
|
||||
value
|
||||
);
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value: value.into(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -439,11 +445,12 @@ impl Pure<'_> {
|
||||
value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
} else if let Some(precision) = args
|
||||
.first()
|
||||
@ -465,11 +472,12 @@ impl Pure<'_> {
|
||||
value
|
||||
);
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -481,11 +489,12 @@ impl Pure<'_> {
|
||||
{
|
||||
if base.trunc() == 10. {
|
||||
let value = num.value.to_js_string().into();
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -505,11 +514,12 @@ impl Pure<'_> {
|
||||
}
|
||||
.into();
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: e.span(),
|
||||
raw: None,
|
||||
value,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -570,10 +580,11 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("evaluate: `foo || true` => `foo, 1`");
|
||||
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: bin_expr.span,
|
||||
exprs: vec![bin_expr.left.clone(), bin_expr.right.clone()],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
} else {
|
||||
self.changed = true;
|
||||
report_change!("evaluate: `foo || false` => `foo` (bool ctx)");
|
||||
@ -603,10 +614,11 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("evaluate: `foo && false` => `foo, false`");
|
||||
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: bin_expr.span,
|
||||
exprs: vec![bin_expr.left.clone(), bin_expr.right.clone()],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -749,22 +761,19 @@ impl Pure<'_> {
|
||||
"evaluate: Evaluated `charCodeAt` of a string literal as `{}`",
|
||||
v
|
||||
);
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: call.span,
|
||||
value: v as usize as f64,
|
||||
raw: None,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
None => {
|
||||
self.changed = true;
|
||||
report_change!(
|
||||
"evaluate: Evaluated `charCodeAt` of a string literal as `NaN`",
|
||||
);
|
||||
*e = Expr::Ident(Ident::new(
|
||||
"NaN".into(),
|
||||
e.span(),
|
||||
SyntaxContext::empty(),
|
||||
))
|
||||
*e = Ident::new("NaN".into(), e.span(), SyntaxContext::empty()).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -788,22 +797,24 @@ impl Pure<'_> {
|
||||
"evaluate: Evaluated `codePointAt` of a string literal as `{}`",
|
||||
v
|
||||
);
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: call.span,
|
||||
value: v as usize as f64,
|
||||
raw: None,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
None => {
|
||||
self.changed = true;
|
||||
report_change!(
|
||||
"evaluate: Evaluated `codePointAt` of a string literal as `NaN`",
|
||||
);
|
||||
*e = Expr::Ident(Ident::new(
|
||||
*e = Ident::new(
|
||||
"NaN".into(),
|
||||
e.span(),
|
||||
SyntaxContext::empty().apply_mark(self.marks.unresolved_mark),
|
||||
))
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -814,11 +825,12 @@ impl Pure<'_> {
|
||||
|
||||
self.changed = true;
|
||||
report_change!("evaluate: Evaluated `{method}` of a string literal");
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
value: new_val.into(),
|
||||
raw: None,
|
||||
..s
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,12 +79,13 @@ impl Pure<'_> {
|
||||
match s.test.as_deref_mut() {
|
||||
Some(e) => {
|
||||
let orig_test = e.take();
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("&&"),
|
||||
left: Box::new(orig_test),
|
||||
right: test.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
None => {
|
||||
s.test = Some(test.take());
|
||||
@ -110,12 +111,13 @@ impl Pure<'_> {
|
||||
match s.test.as_deref_mut() {
|
||||
Some(e) => {
|
||||
let orig_test = e.take();
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: *span,
|
||||
op: op!("&&"),
|
||||
left: Box::new(orig_test),
|
||||
right: test.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
None => {
|
||||
s.test = Some(test.take());
|
||||
@ -173,12 +175,15 @@ impl Pure<'_> {
|
||||
|
||||
match s.test.take() {
|
||||
Some(left) => {
|
||||
s.test = Some(Box::new(Expr::Bin(BinExpr {
|
||||
s.test = Some(
|
||||
BinExpr {
|
||||
span: s.test.span(),
|
||||
op: op!("&&"),
|
||||
left,
|
||||
right: test.take(),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
s.test = Some(test.take());
|
||||
|
@ -322,7 +322,7 @@ impl Pure<'_> {
|
||||
let mut exprs: Vec<Box<Expr>> = exprs.drain(..(exprs.len() - 1)).collect();
|
||||
exprs.push(Box::new(replacement));
|
||||
|
||||
Some(Expr::Seq(SeqExpr { span: *span, exprs }))
|
||||
Some(SeqExpr { span: *span, exprs }.into())
|
||||
}
|
||||
|
||||
Expr::Lit(Lit::Str(Str { value, span, .. })) => {
|
||||
@ -381,20 +381,20 @@ impl Pure<'_> {
|
||||
Some(if exprs.is_empty() {
|
||||
// No side effects, replacement is:
|
||||
// (0, void 0)
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: *span,
|
||||
exprs: vec![0.into(), Expr::undefined(*span)]
|
||||
})
|
||||
}.into()
|
||||
} else {
|
||||
// Side effects exist, replacement is:
|
||||
// (x(), y(), void 0)
|
||||
// Where `x()` and `y()` are side effects.
|
||||
exprs.push(Expr::undefined(*span));
|
||||
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: *span,
|
||||
exprs
|
||||
})
|
||||
}.into()
|
||||
})
|
||||
}
|
||||
|
||||
@ -429,9 +429,9 @@ impl Pure<'_> {
|
||||
|
||||
Some(if is_known_symbol {
|
||||
// [x(), y()].push
|
||||
Expr::Member(MemberExpr {
|
||||
MemberExpr {
|
||||
span: *span,
|
||||
obj: Box::new(Expr::Array(ArrayLit {
|
||||
obj: ArrayLit {
|
||||
span: *span,
|
||||
elems: exprs
|
||||
.into_iter()
|
||||
@ -440,29 +440,30 @@ impl Pure<'_> {
|
||||
expr: elem,
|
||||
}))
|
||||
.collect()
|
||||
})),
|
||||
}.into(),
|
||||
prop: prop.clone(),
|
||||
})
|
||||
}.into()
|
||||
} else {
|
||||
let val = Expr::undefined(*span);
|
||||
let val = Expr::undefined(
|
||||
*span);
|
||||
|
||||
if exprs.is_empty() {
|
||||
// No side effects, replacement is:
|
||||
// (0, void 0)
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: val.span(),
|
||||
exprs: vec![0.into(), val]
|
||||
})
|
||||
}.into()
|
||||
} else {
|
||||
// Side effects exist, replacement is:
|
||||
// (x(), y(), void 0)
|
||||
// Where `x()` and `y()` are side effects.
|
||||
exprs.push(val);
|
||||
|
||||
Expr::Seq(SeqExpr {
|
||||
SeqExpr {
|
||||
span: *span,
|
||||
exprs
|
||||
})
|
||||
}.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -522,22 +523,24 @@ impl Pure<'_> {
|
||||
}
|
||||
|
||||
// Can be optimized fully or partially
|
||||
Some(self.expr_ctx.preserve_effects(
|
||||
Some(*self.expr_ctx.preserve_effects(
|
||||
*span,
|
||||
if is_known_symbol {
|
||||
// Valid key, e.g. "hasOwnProperty". Replacement:
|
||||
// (foo(), bar(), {}.hasOwnProperty)
|
||||
Expr::Member(MemberExpr {
|
||||
MemberExpr {
|
||||
span: *span,
|
||||
obj: Box::new(Expr::Object(ObjectLit {
|
||||
obj: ObjectLit {
|
||||
span: *span,
|
||||
props: vec![],
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
prop: MemberProp::Ident(IdentName::new(key, *span)),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
// Invalid key. Replace with side effects plus `undefined`.
|
||||
*Expr::undefined(*span)
|
||||
Expr::undefined(*span)
|
||||
},
|
||||
props.drain(..).map(|x| match x {
|
||||
PropOrSpread::Prop(prop) => match *prop {
|
||||
|
@ -232,25 +232,28 @@ impl Pure<'_> {
|
||||
return;
|
||||
}
|
||||
|
||||
let sep = Box::new(Expr::Lit(Lit::Str(Str {
|
||||
let sep: Box<Expr> = Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
raw: None,
|
||||
value: separator,
|
||||
})));
|
||||
let mut res = Expr::Lit(Lit::Str(Str {
|
||||
})
|
||||
.into();
|
||||
let mut res = Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
raw: None,
|
||||
value: js_word!(""),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
|
||||
fn add(to: &mut Expr, right: Box<Expr>) {
|
||||
let lhs = to.take();
|
||||
*to = Expr::Bin(BinExpr {
|
||||
*to = BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: Box::new(lhs),
|
||||
op: op!(bin, "+"),
|
||||
right,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
for (last, elem) in arr.elems.take().into_iter().identify_last() {
|
||||
@ -305,11 +308,12 @@ impl Pure<'_> {
|
||||
report_change!("Compressing array.join()");
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: call.span,
|
||||
raw: None,
|
||||
value: res.into(),
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
pub(super) fn drop_undefined_from_return_arg(&mut self, s: &mut ReturnStmt) {
|
||||
@ -398,7 +402,8 @@ impl Pure<'_> {
|
||||
|
||||
report_change!("Optimized regex");
|
||||
|
||||
Some(Expr::Lit(Lit::Regex(Regex {
|
||||
Some(
|
||||
Lit::Regex(Regex {
|
||||
span: *span,
|
||||
exp: pattern,
|
||||
flags: {
|
||||
@ -408,7 +413,9 @@ impl Pure<'_> {
|
||||
|
||||
String::from_utf8(bytes).unwrap().into()
|
||||
},
|
||||
})))
|
||||
})
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Array() -> []
|
||||
@ -418,38 +425,50 @@ impl Pure<'_> {
|
||||
match &**expr {
|
||||
Expr::Lit(Lit::Num(num)) => {
|
||||
if num.value <= 5_f64 && num.value >= 0_f64 {
|
||||
Some(Expr::Array(ArrayLit {
|
||||
Some(
|
||||
ArrayLit {
|
||||
span: *span,
|
||||
elems: vec![None; num.value as usize],
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Expr::Lit(_) => Some(Expr::Array(ArrayLit {
|
||||
Expr::Lit(_) => Some(
|
||||
ArrayLit {
|
||||
span: *span,
|
||||
elems: vec![args.take().into_iter().next()],
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some(Expr::Array(ArrayLit {
|
||||
Some(
|
||||
ArrayLit {
|
||||
span: *span,
|
||||
elems: args.take().into_iter().map(Some).collect(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Object -> {}
|
||||
fn optimize_object(&mut self, args: &mut Vec<ExprOrSpread>, span: &mut Span) -> Option<Expr> {
|
||||
if args.is_empty() {
|
||||
Some(Expr::Object(ObjectLit {
|
||||
Some(
|
||||
ObjectLit {
|
||||
span: *span,
|
||||
props: Vec::new(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -470,11 +489,12 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("Optimized optional chaining expression where object is not null");
|
||||
|
||||
*e = Expr::Member(MemberExpr {
|
||||
*e = MemberExpr {
|
||||
span: opt.span,
|
||||
obj: base.obj.take(),
|
||||
prop: base.prop.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -534,11 +554,15 @@ impl Pure<'_> {
|
||||
{
|
||||
let new_expr = match &**callee {
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "Boolean" => match &mut args[..] {
|
||||
[] => Some(Expr::Lit(Lit::Bool(Bool {
|
||||
[] => Some(
|
||||
Lit::Bool(Bool {
|
||||
span: *span,
|
||||
value: false,
|
||||
}))),
|
||||
[ExprOrSpread { spread: None, expr }] => Some(Expr::Unary(UnaryExpr {
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
[ExprOrSpread { spread: None, expr }] => Some(
|
||||
UnaryExpr {
|
||||
span: *span,
|
||||
op: op!("!"),
|
||||
arg: UnaryExpr {
|
||||
@ -547,34 +571,44 @@ impl Pure<'_> {
|
||||
arg: expr.take(),
|
||||
}
|
||||
.into(),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => None,
|
||||
},
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "Number" => match &mut args[..] {
|
||||
[] => Some(Expr::Lit(Lit::Num(Number {
|
||||
[] => Some(
|
||||
Lit::Num(Number {
|
||||
span: *span,
|
||||
value: 0.0,
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
// this is indeed very unsafe in case of BigInt
|
||||
[ExprOrSpread { spread: None, expr }] if self.options.unsafe_math => {
|
||||
Some(Expr::Unary(UnaryExpr {
|
||||
[ExprOrSpread { spread: None, expr }] if self.options.unsafe_math => Some(
|
||||
UnaryExpr {
|
||||
span: *span,
|
||||
op: op!(unary, "+"),
|
||||
arg: expr.take(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => None,
|
||||
},
|
||||
Expr::Ident(Ident { sym, .. }) if &**sym == "String" => match &mut args[..] {
|
||||
[] => Some(Expr::Lit(Lit::Str(Str {
|
||||
[] => Some(
|
||||
Lit::Str(Str {
|
||||
span: *span,
|
||||
value: "".into(),
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
// this is also very unsafe in case of Symbol
|
||||
[ExprOrSpread { spread: None, expr }] if self.options.unsafe_passes => {
|
||||
Some(Expr::Bin(BinExpr {
|
||||
Some(
|
||||
BinExpr {
|
||||
span: *span,
|
||||
left: expr.take(),
|
||||
op: op!(bin, "+"),
|
||||
@ -584,7 +618,9 @@ impl Pure<'_> {
|
||||
raw: None,
|
||||
})
|
||||
.into(),
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
@ -648,13 +684,14 @@ impl Pure<'_> {
|
||||
report_change!(
|
||||
"new operator: Compressing `new Array/RegExp/..` => `Array()/RegExp()/..`"
|
||||
);
|
||||
*e = Expr::Call(CallExpr {
|
||||
*e = CallExpr {
|
||||
span: *span,
|
||||
ctxt: *ctxt,
|
||||
callee: callee.take().as_callee(),
|
||||
args: args.take().unwrap_or_default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -777,7 +814,7 @@ impl Pure<'_> {
|
||||
raw: cur_raw.into(),
|
||||
});
|
||||
|
||||
Some(Expr::Tpl(new_tpl))
|
||||
Some(new_tpl.into())
|
||||
}
|
||||
|
||||
/// Returns true if something is modified.
|
||||
@ -860,10 +897,13 @@ impl Pure<'_> {
|
||||
return Some(*exprs.remove(0));
|
||||
}
|
||||
|
||||
Some(Expr::Seq(SeqExpr {
|
||||
Some(
|
||||
SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
}))
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Calls [`Self::ignore_return_value`] on the arguments of return
|
||||
@ -936,7 +976,7 @@ impl Pure<'_> {
|
||||
|
||||
let new = self.make_ignored_expr(args.take().into_iter().map(|arg| arg.expr));
|
||||
|
||||
*e = new.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
*e = new.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -946,7 +986,7 @@ impl Pure<'_> {
|
||||
|
||||
let new = self.make_ignored_expr(tpl.exprs.take().into_iter());
|
||||
|
||||
*e = new.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
*e = new.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -957,7 +997,7 @@ impl Pure<'_> {
|
||||
let new =
|
||||
self.make_ignored_expr(args.take().into_iter().flatten().map(|arg| arg.expr));
|
||||
|
||||
*e = new.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
*e = new.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -975,7 +1015,7 @@ impl Pure<'_> {
|
||||
report_change!("Dropping pure call as callee is pure");
|
||||
*e = self
|
||||
.make_ignored_expr(args.take().into_iter().map(|arg| arg.expr))
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -988,7 +1028,7 @@ impl Pure<'_> {
|
||||
report_change!("Dropping pure tag tpl as callee is pure");
|
||||
*e = self
|
||||
.make_ignored_expr(tpl.exprs.take().into_iter())
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1000,7 +1040,7 @@ impl Pure<'_> {
|
||||
// Skip 0
|
||||
if n.value != 0.0 && n.value.classify() == FpCategory::Normal {
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1014,13 +1054,13 @@ impl Pure<'_> {
|
||||
{
|
||||
if is_global_var_with_pure_property_access(&i.sym) {
|
||||
report_change!("Dropping a reference to a global variable");
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
report_change!("Dropping an identifier as it's declared");
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1044,7 +1084,7 @@ impl Pure<'_> {
|
||||
|
||||
if arg.is_invalid() {
|
||||
report_change!("Dropping an unary expression");
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1078,10 +1118,11 @@ impl Pure<'_> {
|
||||
if tpl.exprs.len() == 1 {
|
||||
*e = *tpl.exprs.remove(0);
|
||||
} else {
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: tpl.span,
|
||||
exprs: tpl.exprs.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,7 +1152,7 @@ impl Pure<'_> {
|
||||
Expr::Lit(Lit::Num(n)) => {
|
||||
if n.value == 0.0 && opts.drop_zero {
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1121,7 +1162,7 @@ impl Pure<'_> {
|
||||
report_change!("Dropping an identifier as it's declared");
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1130,7 +1171,7 @@ impl Pure<'_> {
|
||||
report_change!("Dropping literals");
|
||||
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1180,7 +1221,7 @@ impl Pure<'_> {
|
||||
let span = bin.span;
|
||||
|
||||
if bin.left.is_invalid() && bin.right.is_invalid() {
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
} else if bin.right.is_invalid() {
|
||||
*e = *bin.left.take();
|
||||
@ -1193,10 +1234,11 @@ impl Pure<'_> {
|
||||
if matches!(*bin.left, Expr::Await(..) | Expr::Update(..)) {
|
||||
self.changed = true;
|
||||
report_change!("ignore_return_value: Compressing binary as seq");
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span,
|
||||
exprs: vec![bin.left.take(), bin.right.take()],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1225,7 +1267,7 @@ impl Pure<'_> {
|
||||
|| s.value.starts_with("@babel/helpers"))
|
||||
{
|
||||
self.changed = true;
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1328,7 +1370,7 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
*e = self
|
||||
.make_ignored_expr(args.iter_mut().flatten().map(|arg| arg.expr.take()))
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1346,7 +1388,7 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
*e = self
|
||||
.make_ignored_expr(args.iter_mut().map(|arg| arg.expr.take()))
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1364,7 +1406,7 @@ impl Pure<'_> {
|
||||
if let PropOrSpread::Prop(p) = prop {
|
||||
match *p {
|
||||
Prop::Shorthand(p) => {
|
||||
exprs.push(Box::new(Expr::Ident(p)));
|
||||
exprs.push(p.into());
|
||||
}
|
||||
Prop::KeyValue(p) => {
|
||||
if let PropName::Computed(e) = p.key {
|
||||
@ -1386,7 +1428,7 @@ impl Pure<'_> {
|
||||
|
||||
*e = self
|
||||
.make_ignored_expr(exprs.into_iter())
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
report_change!("Ignored an object literal");
|
||||
self.changed = true;
|
||||
return;
|
||||
@ -1400,7 +1442,7 @@ impl Pure<'_> {
|
||||
}) => true,
|
||||
_ => false,
|
||||
}) {
|
||||
*e = Expr::Array(ArrayLit {
|
||||
*e = ArrayLit {
|
||||
elems: arr
|
||||
.elems
|
||||
.take()
|
||||
@ -1432,7 +1474,8 @@ impl Pure<'_> {
|
||||
.map(Some)
|
||||
.collect(),
|
||||
..*arr
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1457,7 +1500,7 @@ impl Pure<'_> {
|
||||
|
||||
*e = self
|
||||
.make_ignored_expr(exprs.into_iter())
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
report_change!("Ignored an array literal");
|
||||
self.changed = true;
|
||||
return;
|
||||
@ -1485,7 +1528,7 @@ impl Pure<'_> {
|
||||
.make_ignored_expr(
|
||||
vec![obj.take(), prop.expr.take()].into_iter(),
|
||||
)
|
||||
.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP }));
|
||||
.unwrap_or(Invalid { span: DUMMY_SP }.into());
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -1504,7 +1547,7 @@ impl Pure<'_> {
|
||||
if is_pure_member_access(obj, prop) {
|
||||
self.changed = true;
|
||||
report_change!("Remving pure member access to global var");
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1534,7 +1577,7 @@ impl Pure<'_> {
|
||||
right,
|
||||
..
|
||||
}) => {
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: unary.span,
|
||||
op: if *op == op!("==") {
|
||||
op!("!=")
|
||||
@ -1543,7 +1586,8 @@ impl Pure<'_> {
|
||||
},
|
||||
left: left.take(),
|
||||
right: right.take(),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ impl VisitMut for Pure<'_> {
|
||||
|
||||
if let Expr::Seq(seq) = e {
|
||||
if seq.exprs.is_empty() {
|
||||
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
|
||||
*e = Invalid { span: DUMMY_SP }.into();
|
||||
return;
|
||||
}
|
||||
if seq.exprs.len() == 1 {
|
||||
|
@ -18,11 +18,12 @@ impl Pure<'_> {
|
||||
|
||||
self.changed = true;
|
||||
report_change!("numbers: Converting a string literal to {:?}", value);
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
*e = Lit::Num(Number {
|
||||
span: *span,
|
||||
value,
|
||||
raw: None,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,16 +48,18 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("numbers: Lifting `-`");
|
||||
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: arg.span,
|
||||
op: op!(unary, "-"),
|
||||
arg: Box::new(Expr::Bin(BinExpr {
|
||||
arg: BinExpr {
|
||||
span: arg.span,
|
||||
op: arg.op,
|
||||
left: arg.left.take(),
|
||||
right: right_arg.take(),
|
||||
})),
|
||||
});
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
Expr::Lit(Lit::Num(Number { span, value, .. })) => {
|
||||
@ -64,10 +67,10 @@ impl Pure<'_> {
|
||||
self.changed = true;
|
||||
report_change!("numbers: Lifting `-` in a literal");
|
||||
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: arg.span,
|
||||
op: op!(unary, "-"),
|
||||
arg: Box::new(Expr::Bin(BinExpr {
|
||||
arg: BinExpr {
|
||||
span: arg.span,
|
||||
op: arg.op,
|
||||
left: arg.left.take(),
|
||||
@ -76,8 +79,10 @@ impl Pure<'_> {
|
||||
value: -*value,
|
||||
raw: None,
|
||||
}))),
|
||||
})),
|
||||
});
|
||||
}
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,17 +52,21 @@ impl Pure<'_> {
|
||||
|
||||
let mut exprs = left.exprs.take();
|
||||
|
||||
exprs.push(Box::new(Expr::Bin(BinExpr {
|
||||
exprs.push(
|
||||
BinExpr {
|
||||
span: left.span,
|
||||
op: bin.op,
|
||||
left: left_last,
|
||||
right: bin.right.take(),
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: bin.span,
|
||||
exprs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,17 +103,21 @@ impl Pure<'_> {
|
||||
alt: cond.alt.take(),
|
||||
};
|
||||
|
||||
new_seq.push(Box::new(Expr::Assign(AssignExpr {
|
||||
new_seq.push(
|
||||
AssignExpr {
|
||||
span: assign.span,
|
||||
op: assign.op,
|
||||
left: assign.left.take(),
|
||||
right: Box::new(Expr::Cond(new_cond)),
|
||||
})));
|
||||
right: Box::new(new_cond.into()),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
*e = Expr::Seq(SeqExpr {
|
||||
*e = SeqExpr {
|
||||
span: assign.span,
|
||||
exprs: new_seq,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,7 +177,7 @@ impl Pure<'_> {
|
||||
|
||||
let obj = Box::new(a.take());
|
||||
|
||||
let new = Expr::Call(CallExpr {
|
||||
let new = CallExpr {
|
||||
span,
|
||||
callee: MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -179,7 +187,8 @@ impl Pure<'_> {
|
||||
.as_callee(),
|
||||
args: args.take(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
b.take();
|
||||
self.changed = true;
|
||||
report_change!(
|
||||
|
@ -45,12 +45,13 @@ impl Pure<'_> {
|
||||
report_change!("evaluate: 'foo' + ('bar' + baz) => 'foobar' + baz");
|
||||
|
||||
let s = lls.into_owned() + &*rls;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span,
|
||||
op: op!(bin, "+"),
|
||||
left: s.into(),
|
||||
right: r_r.take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ impl Pure<'_> {
|
||||
|
||||
self.changed = true;
|
||||
report_change!("evaluating a template to a string");
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: tpl.span,
|
||||
op: op!(bin, "+"),
|
||||
left: tpl.quasis[0]
|
||||
@ -91,7 +92,8 @@ impl Pure<'_> {
|
||||
.unwrap_or_else(|| tpl.quasis[0].raw.clone())
|
||||
.into(),
|
||||
right: tpl.exprs[0].take(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +184,7 @@ impl Pure<'_> {
|
||||
raw: s,
|
||||
});
|
||||
|
||||
*e = Expr::Tpl(new_tpl);
|
||||
*e = new_tpl.into();
|
||||
}
|
||||
|
||||
/// Converts template literals to string if `exprs` of [Tpl] is empty.
|
||||
@ -198,11 +200,12 @@ impl Pure<'_> {
|
||||
}) {
|
||||
report_change!("converting a template literal to a string literal");
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: t.span,
|
||||
raw: None,
|
||||
value: value.clone(),
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -224,11 +227,12 @@ impl Pure<'_> {
|
||||
|
||||
report_change!("converting a template literal to a string literal");
|
||||
|
||||
*e = Expr::Lit(Lit::Str(Str {
|
||||
*e = Lit::Str(Str {
|
||||
span: t.span,
|
||||
raw: None,
|
||||
value,
|
||||
}));
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -496,16 +500,18 @@ impl Pure<'_> {
|
||||
new_str
|
||||
);
|
||||
|
||||
*e = Expr::Bin(BinExpr {
|
||||
*e = BinExpr {
|
||||
span: bin.span,
|
||||
op: op!(bin, "+"),
|
||||
left: left.left.take(),
|
||||
right: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
right: Lit::Str(Str {
|
||||
span: left_span,
|
||||
raw: None,
|
||||
value: new_str.into(),
|
||||
}))),
|
||||
});
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,11 +165,12 @@ fn negate_inner(
|
||||
} else {
|
||||
report_change!("negate: e => !e");
|
||||
|
||||
*e = Expr::Unary(UnaryExpr {
|
||||
*e = UnaryExpr {
|
||||
span: DUMMY_SP,
|
||||
op: op!("!"),
|
||||
arg,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
dump_change_detail!("Negated `{}` as `{}`", start_str, dump(&*e, false));
|
||||
|
||||
|
@ -200,11 +200,12 @@ impl Evaluator {
|
||||
}) if !prop.is_computed() => {
|
||||
let obj = self.eval_as_expr(obj)?;
|
||||
|
||||
let mut e = Expr::Member(MemberExpr {
|
||||
let mut e: Expr = MemberExpr {
|
||||
span: *span,
|
||||
obj,
|
||||
prop: prop.clone(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
e.visit_mut_with(&mut expr_simplifier(
|
||||
self.marks.unresolved_mark,
|
||||
@ -226,16 +227,17 @@ impl Evaluator {
|
||||
for expr in &q.exprs {
|
||||
let res = self.eval(expr)?;
|
||||
exprs.push(match res {
|
||||
EvalResult::Lit(v) => Box::new(Expr::Lit(v)),
|
||||
EvalResult::Lit(v) => v.into(),
|
||||
EvalResult::Undefined => Expr::undefined(DUMMY_SP),
|
||||
});
|
||||
}
|
||||
|
||||
let mut e = Expr::Tpl(Tpl {
|
||||
let mut e: Box<Expr> = Tpl {
|
||||
span: q.span,
|
||||
exprs,
|
||||
quasis: q.quasis.clone(),
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
{
|
||||
e.visit_mut_with(&mut pure_optimizer(
|
||||
|
@ -456,28 +456,31 @@ impl From<TerserTopRetainOption> for Vec<JsWord> {
|
||||
|
||||
fn value_to_expr(v: Value) -> Box<Expr> {
|
||||
match v {
|
||||
Value::Null => Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
Value::Bool(value) => Box::new(Expr::Lit(Lit::Bool(Bool {
|
||||
Value::Null => Lit::Null(Null { span: DUMMY_SP }).into(),
|
||||
Value::Bool(value) => Lit::Bool(Bool {
|
||||
span: DUMMY_SP,
|
||||
value,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
Value::Number(v) => {
|
||||
trace_op!("Creating a numeric literal from value");
|
||||
|
||||
Box::new(Expr::Lit(Lit::Num(Number {
|
||||
Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: v.as_f64().unwrap(),
|
||||
raw: None,
|
||||
})))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
Value::String(v) => {
|
||||
let value: JsWord = v.into();
|
||||
|
||||
Box::new(Expr::Lit(Lit::Str(Str {
|
||||
Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
raw: None,
|
||||
value,
|
||||
})))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
Value::Array(arr) => {
|
||||
@ -486,10 +489,11 @@ fn value_to_expr(v: Value) -> Box<Expr> {
|
||||
.map(value_to_expr)
|
||||
.map(|expr| Some(ExprOrSpread { spread: None, expr }))
|
||||
.collect();
|
||||
Box::new(Expr::Array(ArrayLit {
|
||||
ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
Value::Object(obj) => {
|
||||
@ -509,10 +513,11 @@ fn value_to_expr(v: Value) -> Box<Expr> {
|
||||
.map(PropOrSpread::Prop)
|
||||
.collect();
|
||||
|
||||
Box::new(Expr::Object(ObjectLit {
|
||||
ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ impl VisitMut for Mangler<'_> {
|
||||
|
||||
*prop = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(new_ident),
|
||||
value: Box::new(Expr::Ident(ident.clone())),
|
||||
value: ident.clone().into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ pub(crate) mod unit;
|
||||
|
||||
pub(crate) fn make_number(span: Span, value: f64) -> Expr {
|
||||
trace_op!("Creating a numeric literal");
|
||||
Expr::Lit(Lit::Num(Number {
|
||||
Lit::Num(Number {
|
||||
span,
|
||||
value,
|
||||
raw: None,
|
||||
}))
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
pub trait ModuleItemExt:
|
||||
@ -80,15 +81,17 @@ impl ModuleItemExt for ModuleItem {
|
||||
pub(crate) fn make_bool(span: Span, value: bool) -> Expr {
|
||||
trace_op!("Creating a boolean literal");
|
||||
|
||||
Expr::Unary(UnaryExpr {
|
||||
UnaryExpr {
|
||||
span,
|
||||
op: op!("!"),
|
||||
arg: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
arg: Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: if value { 0.0 } else { 1.0 },
|
||||
raw: None,
|
||||
}))),
|
||||
})
|
||||
.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Additional methods for optimizing expressions.
|
||||
@ -128,10 +131,11 @@ pub(crate) trait ExprOptExt: Sized {
|
||||
Expr::Seq(seq) => seq,
|
||||
_ => {
|
||||
let inner = expr.take();
|
||||
*expr = Expr::Seq(SeqExpr {
|
||||
*expr = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![Box::new(inner)],
|
||||
});
|
||||
}
|
||||
.into();
|
||||
expr.force_seq()
|
||||
}
|
||||
}
|
||||
@ -151,10 +155,11 @@ pub(crate) trait ExprOptExt: Sized {
|
||||
_ => {
|
||||
let v = to.take();
|
||||
exprs.push(Box::new(v));
|
||||
*to = Expr::Seq(SeqExpr {
|
||||
*to = SeqExpr {
|
||||
span: DUMMY_SP,
|
||||
exprs,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,12 +323,13 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
|
||||
let args = self.parse_args(false)?;
|
||||
Ok(Box::new(Expr::Call(CallExpr {
|
||||
Ok(CallExpr {
|
||||
span: span!(self, expr.span_lo()),
|
||||
callee: Callee::Expr(expr),
|
||||
args,
|
||||
..Default::default()
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
fn parse_class_body(&mut self) -> PResult<Vec<ClassMember>> {
|
||||
@ -1571,7 +1572,7 @@ impl OutputType for Box<Expr> {
|
||||
ident: Option<Ident>,
|
||||
function: Box<Function>,
|
||||
) -> Result<Self, SyntaxError> {
|
||||
Ok(Box::new(Expr::Fn(FnExpr { ident, function })))
|
||||
Ok(FnExpr { ident, function }.into())
|
||||
}
|
||||
|
||||
fn finish_class(
|
||||
@ -1579,7 +1580,7 @@ impl OutputType for Box<Expr> {
|
||||
ident: Option<Ident>,
|
||||
class: Box<Class>,
|
||||
) -> Result<Self, SyntaxError> {
|
||||
Ok(Box::new(Expr::Class(ClassExpr { ident, class })))
|
||||
Ok(ClassExpr { ident, class }.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,11 @@ impl<I: Tokens> Parser<I> {
|
||||
exprs.push(self.parse_assignment_expr()?);
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Seq(SeqExpr {
|
||||
return Ok(SeqExpr {
|
||||
span: span!(self, start),
|
||||
exprs,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
@ -195,13 +196,14 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
bump!(self);
|
||||
let right = self.parse_assignment_expr()?;
|
||||
Ok(Box::new(Expr::Assign(AssignExpr {
|
||||
Ok(AssignExpr {
|
||||
span: span!(self, start),
|
||||
op,
|
||||
// TODO:
|
||||
left,
|
||||
right,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
_ => Ok(cond),
|
||||
}
|
||||
@ -233,12 +235,13 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
let alt = self.with_ctx(ctx).parse_assignment_expr()?;
|
||||
let span = Span::new(start, alt.span_hi());
|
||||
Ok(Box::new(Expr::Cond(CondExpr {
|
||||
Ok(CondExpr {
|
||||
span,
|
||||
test,
|
||||
cons,
|
||||
alt,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
} else {
|
||||
Ok(test)
|
||||
}
|
||||
@ -262,9 +265,10 @@ impl<I: Tokens> Parser<I> {
|
||||
match tok {
|
||||
tok!("this") => {
|
||||
self.input.bump();
|
||||
return Ok(Box::new(Expr::This(ThisExpr {
|
||||
return Ok(ThisExpr {
|
||||
span: span!(self, start),
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
tok!("async") => {
|
||||
@ -282,7 +286,7 @@ impl<I: Tokens> Parser<I> {
|
||||
assert_and_bump!(p, "async");
|
||||
p.try_parse_ts_generic_async_arrow_fn(start)
|
||||
}) {
|
||||
return Ok(Box::new(Expr::Arrow(res)));
|
||||
return Ok(res.into());
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,7 +324,7 @@ impl<I: Tokens> Parser<I> {
|
||||
| Token::Num { .. }
|
||||
| Token::BigInt { .. }
|
||||
| Token::Str { .. } => {
|
||||
return Ok(Box::new(Expr::Lit(self.parse_lit()?)));
|
||||
return Ok(self.parse_lit()?.into());
|
||||
}
|
||||
|
||||
// Regexp
|
||||
@ -359,11 +363,7 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(span, SyntaxError::DuplicatedRegExpFlags(*flag));
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Lit(Lit::Regex(Regex {
|
||||
span,
|
||||
exp,
|
||||
flags,
|
||||
}))));
|
||||
return Ok(Lit::Regex(Regex { span, exp, flags }).into());
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -377,7 +377,7 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
// parse template literal
|
||||
return Ok(Box::new(Expr::Tpl(self.with_ctx(ctx).parse_tpl(false)?)));
|
||||
return Ok(self.with_ctx(ctx).parse_tpl(false)?.into());
|
||||
}
|
||||
|
||||
tok!('(') => {
|
||||
@ -428,35 +428,37 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(self.input.prev_span(), SyntaxError::TS1106);
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Ident(id)));
|
||||
return Ok(id.into());
|
||||
}
|
||||
|
||||
let ident = self.parse_binding_ident()?;
|
||||
if self.input.syntax().typescript() && ident.sym == "as" && !is!(self, "=>") {
|
||||
// async as type
|
||||
let type_ann = self.in_type().parse_with(|p| p.parse_ts_type())?;
|
||||
return Ok(Box::new(Expr::TsAs(TsAsExpr {
|
||||
return Ok(TsAsExpr {
|
||||
span: span!(self, start),
|
||||
expr: Box::new(Expr::Ident(id)),
|
||||
expr: Box::new(id.into()),
|
||||
type_ann,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// async a => body
|
||||
let arg = Pat::from(ident);
|
||||
let arg = ident.into();
|
||||
let params = vec![arg];
|
||||
expect!(self, "=>");
|
||||
let body =
|
||||
self.parse_fn_body(true, false, true, params.is_simple_parameter_list())?;
|
||||
|
||||
return Ok(Box::new(Expr::Arrow(ArrowExpr {
|
||||
return Ok(ArrowExpr {
|
||||
span: span!(self, start),
|
||||
body,
|
||||
params,
|
||||
is_async: true,
|
||||
is_generator: false,
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
} else if can_be_arrow && !self.input.had_line_break_before_cur() && eat!(self, "=>") {
|
||||
if self.ctx().strict && id.is_reserved_in_strict_bind() {
|
||||
self.emit_strict_mode_err(id.span, SyntaxError::EvalAndArgumentsInStrict)
|
||||
@ -465,25 +467,27 @@ impl<I: Tokens> Parser<I> {
|
||||
let body =
|
||||
self.parse_fn_body(false, false, true, params.is_simple_parameter_list())?;
|
||||
|
||||
return Ok(Box::new(Expr::Arrow(ArrowExpr {
|
||||
return Ok(ArrowExpr {
|
||||
span: span!(self, start),
|
||||
body,
|
||||
params,
|
||||
is_async: false,
|
||||
is_generator: false,
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
} else {
|
||||
return Ok(Box::new(Expr::Ident(id)));
|
||||
return Ok(id.into());
|
||||
}
|
||||
}
|
||||
|
||||
if eat!(self, '#') {
|
||||
let id = self.parse_ident_name()?;
|
||||
return Ok(Box::new(Expr::PrivateName(PrivateName {
|
||||
return Ok(PrivateName {
|
||||
span: span!(self, start),
|
||||
name: id.sym,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
syntax_error!(self, self.input.cur_span(), SyntaxError::TS1109)
|
||||
@ -522,7 +526,7 @@ impl<I: Tokens> Parser<I> {
|
||||
expect!(self, ']');
|
||||
|
||||
let span = span!(self, start);
|
||||
Ok(Box::new(Expr::Array(ArrayLit { span, elems })))
|
||||
Ok(ArrayLit { span, elems }.into())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -549,10 +553,11 @@ impl<I: Tokens> Parser<I> {
|
||||
if eat!(self, '.') {
|
||||
if eat!(self, "target") {
|
||||
let span = span!(self, start);
|
||||
let expr = Box::new(Expr::MetaProp(MetaPropExpr {
|
||||
let expr = MetaPropExpr {
|
||||
span,
|
||||
kind: MetaPropKind::NewTarget,
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
let ctx = self.ctx();
|
||||
if (!ctx.inside_non_arrow_function_scope) && !ctx.in_parameters && !ctx.in_class
|
||||
@ -619,13 +624,16 @@ impl<I: Tokens> Parser<I> {
|
||||
// Parsed with 'MemberExpression' production.
|
||||
let args = self.parse_args(false).map(Some)?;
|
||||
|
||||
let new_expr = Callee::Expr(Box::new(Expr::New(NewExpr {
|
||||
let new_expr = Callee::Expr(
|
||||
NewExpr {
|
||||
span: span!(self, start),
|
||||
callee,
|
||||
args,
|
||||
type_args,
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
// We should parse subscripts for MemberExpression.
|
||||
// Because it's left recursive.
|
||||
@ -634,13 +642,14 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
// Parsed with 'NewExpression' production.
|
||||
|
||||
return Ok(Box::new(Expr::New(NewExpr {
|
||||
return Ok(NewExpr {
|
||||
span: span!(self, start),
|
||||
callee,
|
||||
args: None,
|
||||
type_args,
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
if eat!(self, "super") {
|
||||
@ -662,11 +671,12 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
let obj = if let Some(type_args) = type_args {
|
||||
trace_cur!(self, parse_member_expr_or_new_expr__with_type_args);
|
||||
Box::new(Expr::TsInstantiation(TsInstantiation {
|
||||
TsInstantiation {
|
||||
expr: obj,
|
||||
type_args,
|
||||
span: span!(self, start),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
obj
|
||||
};
|
||||
@ -813,7 +823,8 @@ impl<I: Tokens> Parser<I> {
|
||||
unexpected!(p, "fail")
|
||||
}
|
||||
|
||||
Ok(Some(Box::new(Expr::Arrow(ArrowExpr {
|
||||
Ok(Some(
|
||||
ArrowExpr {
|
||||
span: span!(p, expr_start),
|
||||
is_async: async_span.is_some(),
|
||||
is_generator: false,
|
||||
@ -821,7 +832,9 @@ impl<I: Tokens> Parser<I> {
|
||||
body,
|
||||
return_type: Some(return_type),
|
||||
..Default::default()
|
||||
}))))
|
||||
}
|
||||
.into(),
|
||||
))
|
||||
}) {
|
||||
return Ok(expr);
|
||||
}
|
||||
@ -894,7 +907,7 @@ impl<I: Tokens> Parser<I> {
|
||||
return Ok(errorred_expr);
|
||||
}
|
||||
}
|
||||
return Ok(Box::new(Expr::Arrow(arrow_expr)));
|
||||
return Ok(arrow_expr.into());
|
||||
} else {
|
||||
// If there's no arrow function, we have to check there's no
|
||||
// AssignProp in lhs to check against assignment in object literals
|
||||
@ -925,15 +938,15 @@ impl<I: Tokens> Parser<I> {
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
if let Some(async_span) = async_span {
|
||||
// It's a call expression
|
||||
return Ok(Box::new(Expr::Call(CallExpr {
|
||||
return Ok(CallExpr {
|
||||
span: span!(self, async_span.lo()),
|
||||
callee: Callee::Expr(Box::new(Expr::Ident(Ident::new_no_ctxt(
|
||||
"async".into(),
|
||||
async_span,
|
||||
)))),
|
||||
callee: Callee::Expr(Box::new(
|
||||
Ident::new_no_ctxt("async".into(), async_span).into(),
|
||||
)),
|
||||
args: expr_or_spreads,
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// It was not head of arrow function.
|
||||
@ -957,10 +970,11 @@ impl<I: Tokens> Parser<I> {
|
||||
} => syntax_error!(self, expr.span(), SyntaxError::SpreadInParenExpr),
|
||||
ExprOrSpread { expr, .. } => expr,
|
||||
};
|
||||
Ok(Box::new(Expr::Paren(ParenExpr {
|
||||
Ok(ParenExpr {
|
||||
span: span!(self, expr_start),
|
||||
expr,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
} else {
|
||||
debug_assert!(expr_or_spreads.len() >= 2);
|
||||
|
||||
@ -977,17 +991,19 @@ impl<I: Tokens> Parser<I> {
|
||||
debug_assert!(exprs.len() >= 2);
|
||||
|
||||
// span of sequence expression should not include '(', ')'
|
||||
let seq_expr = Box::new(Expr::Seq(SeqExpr {
|
||||
let seq_expr = SeqExpr {
|
||||
span: Span::new(
|
||||
exprs.first().unwrap().span_lo(),
|
||||
exprs.last().unwrap().span_hi(),
|
||||
),
|
||||
exprs,
|
||||
}));
|
||||
Ok(Box::new(Expr::Paren(ParenExpr {
|
||||
}
|
||||
.into();
|
||||
Ok(ParenExpr {
|
||||
span: span!(self, expr_start),
|
||||
expr: seq_expr,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1140,10 +1156,11 @@ impl<I: Tokens> Parser<I> {
|
||||
Callee::Expr(expr) => expr,
|
||||
};
|
||||
return Ok((
|
||||
Box::new(Expr::TsNonNull(TsNonNullExpr {
|
||||
TsNonNullExpr {
|
||||
span: span!(self, start),
|
||||
expr,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
true,
|
||||
));
|
||||
}
|
||||
@ -1174,7 +1191,7 @@ impl<I: Tokens> Parser<I> {
|
||||
// But it might be a call with a type argument `async<T>();`
|
||||
let async_arrow_fn = p.try_parse_ts_generic_async_arrow_fn(start)?;
|
||||
if let Some(async_arrow_fn) = async_arrow_fn {
|
||||
return Ok(Some((Box::new(Expr::Arrow(async_arrow_fn)), true)));
|
||||
return Ok(Some((async_arrow_fn.into(), true)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,7 +1207,7 @@ impl<I: Tokens> Parser<I> {
|
||||
if let Callee::Expr(callee) = &obj {
|
||||
if let Expr::OptChain(..) = &**callee {
|
||||
return Ok(Some((
|
||||
Box::new(Expr::OptChain(OptChainExpr {
|
||||
OptChainExpr {
|
||||
span: span!(p, start),
|
||||
base: Box::new(OptChainBase::Call(OptCall {
|
||||
span: span!(p, start),
|
||||
@ -1200,20 +1217,22 @@ impl<I: Tokens> Parser<I> {
|
||||
..Default::default()
|
||||
})),
|
||||
optional: false,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
true,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some((
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: span!(p, start),
|
||||
callee: obj,
|
||||
type_args: Some(type_args),
|
||||
args,
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
true,
|
||||
)))
|
||||
} else if is!(p, '`') {
|
||||
@ -1224,18 +1243,19 @@ impl<I: Tokens> Parser<I> {
|
||||
},
|
||||
Some(type_args),
|
||||
)
|
||||
.map(|expr| (Box::new(Expr::TaggedTpl(expr)), true))
|
||||
.map(|expr| (expr.into(), true))
|
||||
.map(Some)
|
||||
} else if is_one_of!(p, '=', "as") {
|
||||
Ok(Some((
|
||||
Box::new(Expr::TsInstantiation(TsInstantiation {
|
||||
TsInstantiation {
|
||||
span: span!(p, start),
|
||||
expr: match mut_obj_opt {
|
||||
Some(Callee::Expr(obj)) => obj.take(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
type_args,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
false,
|
||||
)))
|
||||
} else if no_call {
|
||||
@ -1313,11 +1333,12 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
|
||||
} else {
|
||||
Expr::SuperProp(SuperPropExpr {
|
||||
SuperPropExpr {
|
||||
span,
|
||||
obj,
|
||||
prop: SuperProp::Computed(prop),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
Callee::Expr(obj) => {
|
||||
@ -1328,21 +1349,23 @@ impl<I: Tokens> Parser<I> {
|
||||
prop: MemberProp::Computed(prop),
|
||||
};
|
||||
let expr = if is_opt_chain || question_dot_token.is_some() {
|
||||
Expr::OptChain(OptChainExpr {
|
||||
OptChainExpr {
|
||||
span,
|
||||
optional: question_dot_token.is_some(),
|
||||
base: Box::new(OptChainBase::Member(expr)),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::Member(expr)
|
||||
expr.into()
|
||||
};
|
||||
|
||||
if let Some(type_args) = type_args {
|
||||
Expr::TsInstantiation(TsInstantiation {
|
||||
TsInstantiation {
|
||||
expr: Box::new(expr),
|
||||
type_args,
|
||||
span: span!(self, start),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
@ -1375,7 +1398,7 @@ impl<I: Tokens> Parser<I> {
|
||||
syntax_error!(self, self.input.cur_span(), SyntaxError::SuperCallOptional)
|
||||
}
|
||||
Callee::Expr(callee) => Ok((
|
||||
Box::new(Expr::OptChain(OptChainExpr {
|
||||
OptChainExpr {
|
||||
span,
|
||||
optional: question_dot_token.is_some(),
|
||||
base: Box::new(OptChainBase::Call(OptCall {
|
||||
@ -1385,7 +1408,8 @@ impl<I: Tokens> Parser<I> {
|
||||
type_args,
|
||||
..Default::default()
|
||||
})),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
true,
|
||||
)),
|
||||
}
|
||||
@ -1429,20 +1453,22 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(span, SyntaxError::ImportMetaInScript);
|
||||
}
|
||||
match &*sym {
|
||||
"meta" => Expr::MetaProp(MetaPropExpr {
|
||||
"meta" => MetaPropExpr {
|
||||
span,
|
||||
kind: MetaPropKind::ImportMeta,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
_ => {
|
||||
let args = self.parse_args(true)?;
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span,
|
||||
callee,
|
||||
args,
|
||||
type_args: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1466,11 +1492,12 @@ impl<I: Tokens> Parser<I> {
|
||||
syntax_error!(self, self.input.cur_span(), SyntaxError::InvalidSuper);
|
||||
} else {
|
||||
match prop {
|
||||
MemberProp::Ident(ident) => Expr::SuperProp(SuperPropExpr {
|
||||
MemberProp::Ident(ident) => SuperPropExpr {
|
||||
span,
|
||||
obj,
|
||||
prop: SuperProp::Ident(ident),
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
MemberProp::PrivateName(..) => syntax_error!(
|
||||
self,
|
||||
self.input.cur_span(),
|
||||
@ -1485,20 +1512,22 @@ impl<I: Tokens> Parser<I> {
|
||||
let expr = if unwrap_ts_non_null(&expr.obj).is_opt_chain()
|
||||
|| question_dot_token.is_some()
|
||||
{
|
||||
Expr::OptChain(OptChainExpr {
|
||||
OptChainExpr {
|
||||
span: span!(self, start),
|
||||
optional: question_dot_token.is_some(),
|
||||
base: Box::new(OptChainBase::Member(expr)),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Expr::Member(expr)
|
||||
expr.into()
|
||||
};
|
||||
if let Some(type_args) = type_args {
|
||||
Expr::TsInstantiation(TsInstantiation {
|
||||
TsInstantiation {
|
||||
expr: Box::new(expr),
|
||||
type_args,
|
||||
span: span!(self, start),
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
@ -1511,11 +1540,12 @@ impl<I: Tokens> Parser<I> {
|
||||
match obj {
|
||||
Callee::Expr(expr) => {
|
||||
let expr = if let Some(type_args) = type_args {
|
||||
Box::new(Expr::TsInstantiation(TsInstantiation {
|
||||
TsInstantiation {
|
||||
expr,
|
||||
type_args,
|
||||
span: span!(self, start),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
expr
|
||||
};
|
||||
@ -1528,7 +1558,7 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
let tpl = self.with_ctx(ctx).parse_tagged_tpl(expr, None)?;
|
||||
return Ok((Box::new(Expr::TaggedTpl(tpl)), true));
|
||||
return Ok((tpl.into(), true));
|
||||
}
|
||||
|
||||
Ok((expr, false))
|
||||
@ -1624,7 +1654,7 @@ impl<I: Tokens> Parser<I> {
|
||||
Some(&tok!('(')),
|
||||
"parse_new_expr() should eat paren if it exists"
|
||||
);
|
||||
return Ok(Box::new(Expr::New(NewExpr { type_args, ..ne })));
|
||||
return Ok(NewExpr { type_args, ..ne }.into());
|
||||
}
|
||||
// 'CallExpr' rule contains 'MemberExpr (...)',
|
||||
// and 'MemberExpr' rule contains 'new MemberExpr (...)'
|
||||
@ -1645,8 +1675,7 @@ impl<I: Tokens> Parser<I> {
|
||||
let args = self.parse_args(is_import)?;
|
||||
|
||||
let call_expr = match callee {
|
||||
Callee::Expr(e) if unwrap_ts_non_null(&e).is_opt_chain() => {
|
||||
Box::new(Expr::OptChain(OptChainExpr {
|
||||
Callee::Expr(e) if unwrap_ts_non_null(&e).is_opt_chain() => OptChainExpr {
|
||||
span: span!(self, start),
|
||||
base: Box::new(OptChainBase::Call(OptCall {
|
||||
span: span!(self, start),
|
||||
@ -1656,16 +1685,17 @@ impl<I: Tokens> Parser<I> {
|
||||
..Default::default()
|
||||
})),
|
||||
optional: false,
|
||||
}))
|
||||
}
|
||||
_ => Box::new(Expr::Call(CallExpr {
|
||||
.into(),
|
||||
_ => CallExpr {
|
||||
span: span!(self, start),
|
||||
|
||||
callee,
|
||||
args,
|
||||
type_args,
|
||||
..Default::default()
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
};
|
||||
|
||||
return self.parse_subscripts(Callee::Expr(call_expr), false, false);
|
||||
@ -1794,13 +1824,14 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
arg = ExprOrSpread {
|
||||
spread: None,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
expr: CondExpr {
|
||||
span: Span::new(start, alt.span_hi()),
|
||||
|
||||
test,
|
||||
cons,
|
||||
alt,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
};
|
||||
|
||||
false
|
||||
@ -1829,12 +1860,13 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
if let Some(span) = arg.spread {
|
||||
pat = Pat::Rest(RestPat {
|
||||
pat = RestPat {
|
||||
span: span!(self, pat_start),
|
||||
dot3_token: span,
|
||||
arg: Box::new(pat),
|
||||
type_ann: None,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
match pat {
|
||||
Pat::Ident(BindingIdent {
|
||||
@ -1876,11 +1908,12 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
if eat!(self, '=') {
|
||||
let right = self.parse_assignment_expr()?;
|
||||
pat = Pat::Assign(AssignPat {
|
||||
pat = AssignPat {
|
||||
span: span!(self, pat_start),
|
||||
left: Box::new(pat),
|
||||
right,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
if has_modifier {
|
||||
@ -1979,11 +2012,12 @@ impl<I: Tokens> Parser<I> {
|
||||
.map(|t| t.kind().starts_expr())
|
||||
.unwrap_or(true))
|
||||
{
|
||||
Ok(Box::new(Expr::Yield(YieldExpr {
|
||||
Ok(YieldExpr {
|
||||
span: span!(self, start),
|
||||
arg: None,
|
||||
delegate: false,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
} else {
|
||||
let has_star = eat!(self, '*');
|
||||
let err_span = span!(self, start);
|
||||
@ -1999,11 +2033,12 @@ impl<I: Tokens> Parser<I> {
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(Box::new(Expr::Yield(YieldExpr {
|
||||
Ok(YieldExpr {
|
||||
span: span!(self, start),
|
||||
arg: Some(arg),
|
||||
delegate: has_star,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,12 @@ impl<I: Tokens> Parser<I> {
|
||||
&tok!("in") if ctx.include_in_expr => {
|
||||
self.emit_err(self.input.cur_span(), SyntaxError::TS1109);
|
||||
|
||||
Box::new(Expr::Invalid(Invalid { span: err.span() }))
|
||||
Invalid { span: err.span() }.into()
|
||||
}
|
||||
&tok!("instanceof") | &Token::BinOp(..) => {
|
||||
self.emit_err(self.input.cur_span(), SyntaxError::TS1109);
|
||||
|
||||
Box::new(Expr::Invalid(Invalid { span: err.span() }))
|
||||
Invalid { span: err.span() }.into()
|
||||
}
|
||||
_ => return Err(err),
|
||||
}
|
||||
@ -98,17 +98,19 @@ impl<I: Tokens> Parser<I> {
|
||||
bump!(self); // as
|
||||
let _ = cur!(self, false);
|
||||
bump!(self); // const
|
||||
Box::new(Expr::TsConstAssertion(TsConstAssertion {
|
||||
TsConstAssertion {
|
||||
span: span!(self, start),
|
||||
expr,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
let type_ann = self.next_then_parse_ts_type()?;
|
||||
Box::new(Expr::TsAs(TsAsExpr {
|
||||
TsAsExpr {
|
||||
span: span!(self, start),
|
||||
expr,
|
||||
type_ann,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
return self.parse_bin_op_recursively_inner(node, min_prec);
|
||||
@ -121,11 +123,12 @@ impl<I: Tokens> Parser<I> {
|
||||
let expr = left;
|
||||
let node = {
|
||||
let type_ann = self.next_then_parse_ts_type()?;
|
||||
Box::new(Expr::TsSatisfies(TsSatisfiesExpr {
|
||||
TsSatisfiesExpr {
|
||||
span: span!(self, start),
|
||||
expr,
|
||||
type_ann,
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
};
|
||||
|
||||
return self.parse_bin_op_recursively_inner(node, min_prec);
|
||||
@ -227,12 +230,13 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
let node = Box::new(Expr::Bin(BinExpr {
|
||||
let node = BinExpr {
|
||||
span: Span::new(left.span_lo(), right.span_hi()),
|
||||
op,
|
||||
left,
|
||||
right,
|
||||
}));
|
||||
}
|
||||
.into();
|
||||
|
||||
Ok((node, Some(min_prec)))
|
||||
}
|
||||
@ -248,10 +252,11 @@ impl<I: Tokens> Parser<I> {
|
||||
if eat!(self, "const") {
|
||||
expect!(self, '>');
|
||||
let expr = self.parse_unary_expr()?;
|
||||
return Ok(Box::new(Expr::TsConstAssertion(TsConstAssertion {
|
||||
return Ok(TsConstAssertion {
|
||||
span: span!(self, start),
|
||||
expr,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
return self
|
||||
@ -272,12 +277,13 @@ impl<I: Tokens> Parser<I> {
|
||||
let span = Span::new(start, arg.span_hi());
|
||||
self.check_assign_target(&arg, false);
|
||||
|
||||
return Ok(Box::new(Expr::Update(UpdateExpr {
|
||||
return Ok(UpdateExpr {
|
||||
span,
|
||||
prefix: true,
|
||||
op,
|
||||
arg,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// Parse unary expression
|
||||
@ -297,9 +303,10 @@ impl<I: Tokens> Parser<I> {
|
||||
Ok(expr) => expr,
|
||||
Err(err) => {
|
||||
self.emit_error(err);
|
||||
Box::new(Expr::Invalid(Invalid {
|
||||
Invalid {
|
||||
span: Span::new(arg_start, arg_start),
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
@ -321,11 +328,12 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Unary(UnaryExpr {
|
||||
return Ok(UnaryExpr {
|
||||
span: Span::new(start, arg.span_hi()),
|
||||
op,
|
||||
arg,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
if is!(self, "await") {
|
||||
@ -350,12 +358,13 @@ impl<I: Tokens> Parser<I> {
|
||||
op!("--")
|
||||
};
|
||||
|
||||
return Ok(Box::new(Expr::Update(UpdateExpr {
|
||||
return Ok(UpdateExpr {
|
||||
span: span!(self, expr.span_lo()),
|
||||
prefix: false,
|
||||
op,
|
||||
arg: expr,
|
||||
})));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
Ok(expr)
|
||||
}
|
||||
@ -383,10 +392,7 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(span, SyntaxError::InvalidIdentInAsync);
|
||||
}
|
||||
|
||||
return Ok(Box::new(Expr::Ident(Ident::new_no_ctxt(
|
||||
"await".into(),
|
||||
span,
|
||||
))));
|
||||
return Ok(Ident::new_no_ctxt("await".into(), span).into());
|
||||
}
|
||||
|
||||
if ctx.in_function && !ctx.in_async {
|
||||
@ -398,10 +404,11 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
|
||||
let arg = self.parse_unary_expr()?;
|
||||
Ok(Box::new(Expr::Await(AwaitExpr {
|
||||
Ok(AwaitExpr {
|
||||
span: span!(self, start),
|
||||
arg,
|
||||
})))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,16 +34,20 @@ fn expr(s: &'static str) -> Box<Expr> {
|
||||
})
|
||||
}
|
||||
fn regex_expr() -> Box<Expr> {
|
||||
Box::new(Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span,
|
||||
left: Ident::new_no_ctxt("re".into(), span).into(),
|
||||
op: AssignOp::Assign,
|
||||
right: Box::new(Expr::Lit(Lit::Regex(Regex {
|
||||
right: Box::new(
|
||||
Lit::Regex(Regex {
|
||||
span,
|
||||
exp: "w+".into(),
|
||||
flags: "".into(),
|
||||
}))),
|
||||
}))
|
||||
})
|
||||
.into(),
|
||||
),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
#[test]
|
||||
fn regex_single_line_comment() {
|
||||
|
@ -134,7 +134,7 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
|
||||
if let Some(trailing_comma) = trailing_comma {
|
||||
self.state.trailing_commas.insert(span.lo, trailing_comma);
|
||||
}
|
||||
Ok(Box::new(Expr::Object(ObjectLit { span, props })))
|
||||
Ok(ObjectLit { span, props }.into())
|
||||
}
|
||||
|
||||
/// spec: 'PropertyDefinition'
|
||||
@ -192,9 +192,10 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
|
||||
self.emit_err(self.input.cur_span(), SyntaxError::TS1005);
|
||||
return Ok(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key,
|
||||
value: Box::new(Expr::Invalid(Invalid {
|
||||
value: Invalid {
|
||||
span: span!(self, start),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
}))));
|
||||
}
|
||||
//
|
||||
@ -373,7 +374,7 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
|
||||
SyntaxError::SetterParam,
|
||||
);
|
||||
|
||||
Pat::Invalid(Invalid { span: DUMMY_SP })
|
||||
Invalid { span: DUMMY_SP }.into()
|
||||
}),
|
||||
);
|
||||
|
||||
@ -454,12 +455,13 @@ impl<I: Tokens> ParseObject<Pat> for Parser<I> {
|
||||
|
||||
let optional = (self.input.syntax().dts() || self.ctx().in_declare) && eat!(self, '?');
|
||||
|
||||
Ok(Pat::Object(ObjectPat {
|
||||
Ok(ObjectPat {
|
||||
span,
|
||||
props,
|
||||
optional,
|
||||
type_ann: None,
|
||||
}))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
/// Production 'BindingProperty'
|
||||
|
@ -76,11 +76,12 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(span!(self, start), SyntaxError::TS2371);
|
||||
}
|
||||
|
||||
return Ok(Pat::Assign(AssignPat {
|
||||
return Ok(AssignPat {
|
||||
span: span!(self, start),
|
||||
left: Box::new(left),
|
||||
right,
|
||||
}));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(left)
|
||||
@ -117,12 +118,13 @@ impl<I: Tokens> Parser<I> {
|
||||
|
||||
let pat = self.parse_binding_pat_or_ident()?;
|
||||
rest_span = span!(self, start);
|
||||
let pat = Pat::Rest(RestPat {
|
||||
let pat = RestPat {
|
||||
span: rest_span,
|
||||
dot3_token,
|
||||
arg: Box::new(pat),
|
||||
type_ann: None,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
elems.push(Some(pat));
|
||||
} else {
|
||||
elems.push(self.parse_binding_element().map(Some)?);
|
||||
@ -139,12 +141,13 @@ impl<I: Tokens> Parser<I> {
|
||||
expect!(self, ']');
|
||||
let optional = (self.input.syntax().dts() || self.ctx().in_declare) && eat!(self, '?');
|
||||
|
||||
Ok(Pat::Array(ArrayPat {
|
||||
Ok(ArrayPat {
|
||||
span: span!(self, start),
|
||||
elems,
|
||||
optional,
|
||||
type_ann: None,
|
||||
}))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
pub(super) fn eat_any_ts_modifier(&mut self) -> PResult<bool> {
|
||||
@ -260,11 +263,12 @@ impl<I: Tokens> Parser<I> {
|
||||
self.emit_err(span!(self, start), SyntaxError::TS2371);
|
||||
}
|
||||
|
||||
Pat::Assign(AssignPat {
|
||||
AssignPat {
|
||||
span: span!(self, start),
|
||||
left: Box::new(pat),
|
||||
right,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
pat
|
||||
};
|
||||
@ -304,12 +308,13 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
rest_span = span!(self, pat_start);
|
||||
let pat = Pat::Rest(RestPat {
|
||||
let pat = RestPat {
|
||||
span: rest_span,
|
||||
dot3_token,
|
||||
arg: Box::new(pat),
|
||||
type_ann,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
params.push(ParamOrTsParamProp::Param(Param {
|
||||
span: span!(self, param_start),
|
||||
decorators,
|
||||
@ -429,12 +434,13 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
|
||||
rest_span = span!(self, pat_start);
|
||||
let pat = Pat::Rest(RestPat {
|
||||
let pat = RestPat {
|
||||
span: rest_span,
|
||||
dot3_token,
|
||||
arg: Box::new(pat),
|
||||
type_ann,
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
if self.syntax().typescript() && eat!(self, '?') {
|
||||
self.emit_err(self.input.prev_span(), SyntaxError::TS1047);
|
||||
@ -493,7 +499,7 @@ impl<I: Tokens> Parser<I> {
|
||||
/// rest.
|
||||
pub(super) fn reparse_expr_as_pat(&mut self, pat_ty: PatType, expr: Box<Expr>) -> PResult<Pat> {
|
||||
if let Expr::Invalid(i) = *expr {
|
||||
return Ok(Pat::Invalid(i));
|
||||
return Ok(i.into());
|
||||
}
|
||||
|
||||
if pat_ty == PatType::AssignPat {
|
||||
@ -536,11 +542,11 @@ impl<I: Tokens> Parser<I> {
|
||||
// to these rules if that phrase were substituted for
|
||||
// LeftHandSideExpression. This rule is recursively applied.
|
||||
Expr::Paren(..) => {
|
||||
return Ok(Pat::Expr(expr));
|
||||
return Ok(expr.into());
|
||||
}
|
||||
Expr::Ident(i) => return Ok(i.into()),
|
||||
_ => {
|
||||
return Ok(Pat::Expr(expr));
|
||||
return Ok(expr.into());
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -572,7 +578,7 @@ impl<I: Tokens> Parser<I> {
|
||||
match *expr {
|
||||
Expr::Ident(i) => return Ok(i.into()),
|
||||
_ => {
|
||||
return Ok(Pat::Expr(expr));
|
||||
return Ok(expr.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,7 +593,7 @@ impl<I: Tokens> Parser<I> {
|
||||
match *expr {
|
||||
Expr::Paren(..) => {
|
||||
self.emit_err(span, SyntaxError::InvalidPat);
|
||||
Ok(Pat::Invalid(Invalid { span }))
|
||||
Ok(Invalid { span }.into())
|
||||
}
|
||||
Expr::Assign(
|
||||
assign_expr @ AssignExpr {
|
||||
@ -598,7 +604,7 @@ impl<I: Tokens> Parser<I> {
|
||||
let AssignExpr {
|
||||
span, left, right, ..
|
||||
} = assign_expr;
|
||||
Ok(Pat::Assign(AssignPat {
|
||||
Ok(AssignPat {
|
||||
span,
|
||||
left: match left {
|
||||
AssignTarget::Simple(left) => {
|
||||
@ -607,7 +613,8 @@ impl<I: Tokens> Parser<I> {
|
||||
AssignTarget::Pat(pat) => pat.into(),
|
||||
},
|
||||
right,
|
||||
}))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
Expr::Object(ObjectLit {
|
||||
span: object_span,
|
||||
@ -615,7 +622,7 @@ impl<I: Tokens> Parser<I> {
|
||||
}) => {
|
||||
// {}
|
||||
let len = props.len();
|
||||
Ok(Pat::Object(ObjectPat {
|
||||
Ok(ObjectPat {
|
||||
span: object_span,
|
||||
props: props
|
||||
.into_iter()
|
||||
@ -690,19 +697,21 @@ impl<I: Tokens> Parser<I> {
|
||||
.collect::<PResult<_>>()?,
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
}))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
Expr::Ident(ident) => Ok(ident.into()),
|
||||
Expr::Array(ArrayLit {
|
||||
elems: mut exprs, ..
|
||||
}) => {
|
||||
if exprs.is_empty() {
|
||||
return Ok(Pat::Array(ArrayPat {
|
||||
return Ok(ArrayPat {
|
||||
span,
|
||||
elems: vec![],
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
}));
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
// Trailing comma may exist. We should remove those commas.
|
||||
@ -753,12 +762,13 @@ impl<I: Tokens> Parser<I> {
|
||||
let expr_span = expr.span();
|
||||
self.reparse_expr_as_pat(pat_ty.element(), expr)
|
||||
.map(|pat| {
|
||||
Pat::Rest(RestPat {
|
||||
RestPat {
|
||||
span: expr_span,
|
||||
dot3_token,
|
||||
arg: Box::new(pat),
|
||||
type_ann: None,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.map(Some)?
|
||||
}
|
||||
@ -771,30 +781,31 @@ impl<I: Tokens> Parser<I> {
|
||||
};
|
||||
params.push(last);
|
||||
}
|
||||
Ok(Pat::Array(ArrayPat {
|
||||
Ok(ArrayPat {
|
||||
span,
|
||||
elems: params,
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
}))
|
||||
}
|
||||
.into())
|
||||
}
|
||||
|
||||
// Invalid patterns.
|
||||
// Note that assignment expression with '=' is valid, and handled above.
|
||||
Expr::Lit(..) | Expr::Assign(..) => {
|
||||
self.emit_err(span, SyntaxError::InvalidPat);
|
||||
Ok(Pat::Invalid(Invalid { span }))
|
||||
Ok(Invalid { span }.into())
|
||||
}
|
||||
|
||||
Expr::Yield(..) if self.ctx().in_generator => {
|
||||
self.emit_err(span, SyntaxError::InvalidPat);
|
||||
Ok(Pat::Invalid(Invalid { span }))
|
||||
Ok(Invalid { span }.into())
|
||||
}
|
||||
|
||||
_ => {
|
||||
self.emit_err(span, SyntaxError::InvalidPat);
|
||||
|
||||
Ok(Pat::Invalid(Invalid { span }))
|
||||
Ok(Invalid { span }.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -845,12 +856,13 @@ impl<I: Tokens> Parser<I> {
|
||||
}
|
||||
let expr_span = expr.span();
|
||||
self.reparse_expr_as_pat(pat_ty, expr).map(|pat| {
|
||||
Pat::Rest(RestPat {
|
||||
RestPat {
|
||||
span: expr_span,
|
||||
dot3_token,
|
||||
arg: Box::new(pat),
|
||||
type_ann: None,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
})?
|
||||
}
|
||||
AssignTargetOrSpread::ExprOrSpread(ExprOrSpread { expr, .. }) => {
|
||||
@ -940,12 +952,15 @@ mod tests {
|
||||
}
|
||||
|
||||
fn rest() -> Option<Pat> {
|
||||
Some(Pat::Rest(RestPat {
|
||||
Some(
|
||||
RestPat {
|
||||
span,
|
||||
dot3_token: span,
|
||||
type_ann: None,
|
||||
arg: Box::new(Pat::Ident(ident("tail").into())),
|
||||
}))
|
||||
arg: ident("tail").into(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1153,12 +1168,13 @@ mod tests {
|
||||
fn prop(key: PropName, assign_name: &str, expr: Expr) -> PropOrSpread {
|
||||
PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key,
|
||||
value: Box::new(Expr::Assign(AssignExpr {
|
||||
value: AssignExpr {
|
||||
span,
|
||||
op: AssignOp::Assign,
|
||||
left: ident(assign_name).into(),
|
||||
right: Box::new(expr),
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
|
||||
return Ok(Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Invalid(Invalid { span })),
|
||||
expr: Invalid { span }.into(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
|
||||
return Ok(Stmt::Expr(ExprStmt {
|
||||
span,
|
||||
expr: Box::new(Expr::Invalid(Invalid { span })),
|
||||
expr: Invalid { span }.into(),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -399,7 +399,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
if eat!(self, ':') {
|
||||
return self.parse_labelled_stmt(ident);
|
||||
}
|
||||
Box::new(Expr::Ident(ident))
|
||||
ident.into()
|
||||
}
|
||||
_ => self.verify_expr(expr)?,
|
||||
};
|
||||
@ -1327,7 +1327,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
if is_using_decl {
|
||||
let name = self.parse_binding_ident()?;
|
||||
let decl = VarDeclarator {
|
||||
name: Pat::Ident(name),
|
||||
name: name.into(),
|
||||
span: span!(self, start),
|
||||
init: None,
|
||||
definite: false,
|
||||
|
@ -1027,7 +1027,7 @@ impl<I: Tokens> Parser<I> {
|
||||
// Note: TS uses parseLeftHandSideExpressionOrHigher,
|
||||
// then has grammar errors later if it's not an EntityName.
|
||||
|
||||
let ident = Box::new(Expr::Ident(self.parse_ident_name()?.into()));
|
||||
let ident = self.parse_ident_name()?.into();
|
||||
let expr = self.parse_subscripts(Callee::Expr(ident), true, true)?;
|
||||
if !matches!(
|
||||
&*expr,
|
||||
@ -1390,9 +1390,9 @@ impl<I: Tokens> Parser<I> {
|
||||
Either::Left(e) => {
|
||||
p.emit_err(e.span(), SyntaxError::PrivateNameInInterface);
|
||||
|
||||
Box::new(Expr::PrivateName(e))
|
||||
e.into()
|
||||
}
|
||||
Either::Right(e) => Box::new(Expr::Ident(e.into())),
|
||||
Either::Right(e) => e.into(),
|
||||
}),
|
||||
};
|
||||
|
||||
@ -1736,14 +1736,15 @@ impl<I: Tokens> Parser<I> {
|
||||
expect!(p, ':');
|
||||
|
||||
Ok(Some(if let Some(dot3_token) = rest {
|
||||
Pat::Rest(RestPat {
|
||||
RestPat {
|
||||
span: span!(p, start),
|
||||
dot3_token,
|
||||
arg: Box::new(Pat::Ident(ident.into())),
|
||||
arg: ident.into(),
|
||||
type_ann: None,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Pat::Ident(ident.into())
|
||||
ident.into()
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
@ -25,10 +25,11 @@ impl Fold for Normalizer {
|
||||
|
||||
match e {
|
||||
Expr::Paren(ParenExpr { expr, .. }) if self.is_test262 => *expr,
|
||||
Expr::New(n @ NewExpr { args: None, .. }) if self.is_test262 => Expr::New(NewExpr {
|
||||
Expr::New(n @ NewExpr { args: None, .. }) if self.is_test262 => NewExpr {
|
||||
args: Some(vec![]),
|
||||
..n
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
// Flatten comma expressions.
|
||||
Expr::Seq(SeqExpr { mut exprs, span }) => {
|
||||
let need_work = exprs.iter().any(|n| matches!(**n, Expr::Seq(..)));
|
||||
@ -42,7 +43,7 @@ impl Fold for Normalizer {
|
||||
v
|
||||
});
|
||||
}
|
||||
Expr::Seq(SeqExpr { exprs, span })
|
||||
SeqExpr { exprs, span }.into()
|
||||
}
|
||||
_ => e,
|
||||
}
|
||||
@ -84,9 +85,9 @@ impl Fold for Normalizer {
|
||||
|
||||
if let Pat::Expr(expr) = node {
|
||||
match *expr {
|
||||
Expr::Ident(i) => return Pat::Ident(i.into()),
|
||||
Expr::Ident(i) => return i.into(),
|
||||
_ => {
|
||||
node = Pat::Expr(expr);
|
||||
node = expr.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ impl Fold for Normalizer {
|
||||
|
||||
if let Pat::Expr(expr) = node {
|
||||
match *expr {
|
||||
Expr::Ident(i) => return Pat::Ident(i.into()),
|
||||
Expr::Ident(i) => return i.into(),
|
||||
_ => {
|
||||
node = Pat::Expr(expr);
|
||||
node = expr.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ impl Visit for UsageVisitor {
|
||||
self.visit_object_pat_props(init, &o.props)
|
||||
}
|
||||
} else if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(&Expr::Ident(Ident::default()), &o.props)
|
||||
self.visit_object_pat_props(&Ident::default().into(), &o.props)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ impl Visit for UsageVisitor {
|
||||
self.visit_object_pat_props(init, &o.props)
|
||||
}
|
||||
} else if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(&Expr::Ident(Ident::default()), &o.props)
|
||||
self.visit_object_pat_props(&Ident::default().into(), &o.props)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,11 +511,11 @@ impl VisitMut for Polyfills {
|
||||
span: DUMMY_SP,
|
||||
expr: CallExpr {
|
||||
span,
|
||||
callee: Expr::Ident(Ident {
|
||||
callee: Ident {
|
||||
ctxt: SyntaxContext::empty().apply_mark(self.unresolved_mark),
|
||||
sym: "require".into(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.as_callee(),
|
||||
args: vec![Str {
|
||||
span: DUMMY_SP,
|
||||
@ -538,11 +538,11 @@ impl VisitMut for Polyfills {
|
||||
span: DUMMY_SP,
|
||||
expr: CallExpr {
|
||||
span,
|
||||
callee: Expr::Ident(Ident {
|
||||
callee: Ident {
|
||||
ctxt: SyntaxContext::empty().apply_mark(self.unresolved_mark),
|
||||
sym: "require".into(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.as_callee(),
|
||||
args: vec![Str {
|
||||
span: DUMMY_SP,
|
||||
|
@ -120,12 +120,13 @@ fn fold_noop_impl_vec(b: &mut Bencher) {
|
||||
}
|
||||
|
||||
fn mk_expr() -> Expr {
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Ident::new_no_ctxt("foo".into(), DUMMY_SP).as_callee(),
|
||||
args: vec![],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn boxing_boxed_clone(b: &mut Bencher) {
|
||||
|
@ -486,8 +486,8 @@ impl VisitMut for Fixer<'_> {
|
||||
_ => false,
|
||||
} =>
|
||||
{
|
||||
let expr = Expr::Ident(p.clone().expect_ident().into());
|
||||
s.left = ForHead::Pat(Box::new(Pat::Expr(Box::new(expr))));
|
||||
let expr: Pat = p.clone().expect_ident().into();
|
||||
s.left = ForHead::Pat(expr.into());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
@ -878,7 +878,7 @@ impl Fixer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut expr = Expr::Seq(SeqExpr { span: *span, exprs });
|
||||
let mut expr = SeqExpr { span: *span, exprs }.into();
|
||||
|
||||
if let Context::ForcedExpr = self.ctx {
|
||||
self.wrap(&mut expr);
|
||||
@ -985,7 +985,7 @@ impl Fixer<'_> {
|
||||
};
|
||||
|
||||
let expr = Box::new(e.take());
|
||||
*e = Expr::Paren(ParenExpr { expr, span });
|
||||
*e = ParenExpr { expr, span }.into();
|
||||
}
|
||||
|
||||
/// Removes paren
|
||||
@ -1071,7 +1071,7 @@ fn ignore_return_value(expr: Box<Expr>, has_padding_value: &mut bool) -> Option<
|
||||
|
||||
match exprs.len() {
|
||||
0 | 1 => exprs.pop(),
|
||||
_ => Some(Box::new(Expr::Seq(SeqExpr { span, exprs }))),
|
||||
_ => Some(SeqExpr { span, exprs }.into()),
|
||||
}
|
||||
}
|
||||
Expr::Unary(UnaryExpr {
|
||||
|
@ -434,7 +434,7 @@ impl InjectHelpers {
|
||||
fn build_reqire(&self, name: &str, mark: Mark) -> Stmt {
|
||||
let c = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: Expr::Ident(Ident {
|
||||
callee: Expr::from(Ident {
|
||||
span: DUMMY_SP,
|
||||
ctxt: SyntaxContext::empty().apply_mark(self.global_mark),
|
||||
sym: "require".into(),
|
||||
|
@ -132,7 +132,7 @@ where
|
||||
let var = VarDeclarator {
|
||||
span,
|
||||
name: cls.ident.clone().into(),
|
||||
init: Some(Box::new(Expr::Class(expr))),
|
||||
init: Some(expr.into()),
|
||||
definite: false,
|
||||
};
|
||||
*decl = VarDecl {
|
||||
@ -466,11 +466,12 @@ where
|
||||
*n = KeyValuePatProp {
|
||||
key: PropName::Ident(p.key.take().into()),
|
||||
value: match p.value.take() {
|
||||
Some(default_expr) => Box::new(Pat::Assign(AssignPat {
|
||||
Some(default_expr) => AssignPat {
|
||||
span: p.span,
|
||||
left: renamed.into(),
|
||||
right: default_expr,
|
||||
})),
|
||||
}
|
||||
.into(),
|
||||
None => renamed.into(),
|
||||
},
|
||||
}
|
||||
@ -500,7 +501,7 @@ where
|
||||
span: i.span,
|
||||
sym: i.sym.clone(),
|
||||
}),
|
||||
value: Box::new(Expr::Ident(renamed)),
|
||||
value: renamed.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ pub mod super_field;
|
||||
/// Child.__proto__ || Object.getPrototypeOf(Child)
|
||||
/// ```
|
||||
pub fn get_prototype_of(obj: Box<Expr>) -> Box<Expr> {
|
||||
Box::new(Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: helper!(get_prototype_of),
|
||||
args: vec![obj.as_arg()],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ impl<'a> VisitMut for SuperFieldAccessFolder<'a> {
|
||||
fn visit_mut_expr(&mut self, n: &mut Expr) {
|
||||
match n {
|
||||
Expr::This(ThisExpr { span }) if self.in_nested_scope => {
|
||||
*n = Expr::Ident(quote_ident!(
|
||||
*n = quote_ident!(
|
||||
SyntaxContext::empty().apply_mark(
|
||||
*self
|
||||
.this_alias_mark
|
||||
@ -83,7 +83,8 @@ impl<'a> VisitMut for SuperFieldAccessFolder<'a> {
|
||||
),
|
||||
*span,
|
||||
"_this"
|
||||
));
|
||||
)
|
||||
.into();
|
||||
}
|
||||
// We pretend method folding mode for while folding injected `_define_property`
|
||||
// calls.
|
||||
@ -210,7 +211,7 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
let mut args = args.clone();
|
||||
|
||||
if args.len() == 1 && is_rest_arguments(&args[0]) {
|
||||
*n = Expr::Call(CallExpr {
|
||||
*n = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: callee.make_member(quote_ident!("apply")).as_callee(),
|
||||
args: iter::once(this)
|
||||
@ -221,16 +222,18 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
}))
|
||||
.collect(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
return;
|
||||
}
|
||||
|
||||
*n = Expr::Call(CallExpr {
|
||||
*n = CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: callee.make_member(quote_ident!("call")).as_callee(),
|
||||
args: iter::once(this).chain(args).collect(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -313,7 +316,7 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
});
|
||||
// in static default super class is Function.prototype
|
||||
if self.is_static && self.super_class.is_some() {
|
||||
Expr::Ident(name)
|
||||
name.into()
|
||||
} else {
|
||||
name.make_member(quote_ident!("prototype")).into()
|
||||
}
|
||||
@ -370,18 +373,19 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
},
|
||||
};
|
||||
|
||||
Expr::Assign(AssignExpr {
|
||||
AssignExpr {
|
||||
span: super_token,
|
||||
left: left.into(),
|
||||
op,
|
||||
right: rhs,
|
||||
})
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
let proto_arg = self.proto_arg();
|
||||
|
||||
let prop_arg = prop_arg(prop).as_arg();
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
CallExpr {
|
||||
span: super_token,
|
||||
callee: helper!(set),
|
||||
args: vec![
|
||||
@ -393,7 +397,8 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
true.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,7 +409,7 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
|
||||
let this_arg = self.this_arg(super_token).as_arg();
|
||||
|
||||
let expr = Expr::Call(CallExpr {
|
||||
let expr: Expr = CallExpr {
|
||||
span: super_token,
|
||||
callee: helper!(update),
|
||||
args: vec![
|
||||
@ -415,7 +420,8 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
true.as_arg(),
|
||||
],
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
.into();
|
||||
|
||||
expr.make_member(quote_ident!("_"))
|
||||
}
|
||||
@ -423,7 +429,7 @@ impl<'a> SuperFieldAccessFolder<'a> {
|
||||
fn proto_arg(&mut self) -> Box<Expr> {
|
||||
let expr = if self.is_static {
|
||||
// Foo
|
||||
Box::new(Expr::Ident(self.class_name.clone()))
|
||||
self.class_name.clone().into()
|
||||
} else {
|
||||
// Foo.prototype
|
||||
self.class_name
|
||||
@ -484,11 +490,12 @@ fn prop_arg(prop: SuperProp) -> Expr {
|
||||
match prop {
|
||||
SuperProp::Ident(IdentName {
|
||||
sym: value, span, ..
|
||||
}) => Expr::Lit(Lit::Str(Str {
|
||||
}) => Lit::Str(Str {
|
||||
span,
|
||||
raw: None,
|
||||
value,
|
||||
})),
|
||||
})
|
||||
.into(),
|
||||
SuperProp::Computed(c) => *c.expr,
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ impl VisitMut for ComputedFieldsHandler {
|
||||
if !is_literal(expr) && !is_simple_pure_expr(expr, self.pure_getters) =>
|
||||
{
|
||||
let ref_key = private_ident!("prop");
|
||||
let mut computed_expr = Box::new(Expr::Ident(ref_key.clone()));
|
||||
let mut computed_expr = ref_key.clone().into();
|
||||
|
||||
mem::swap(expr, &mut computed_expr);
|
||||
|
||||
|
@ -25,8 +25,8 @@ impl Fold for ParenRemover {
|
||||
|
||||
match expr {
|
||||
Expr::Paren(ParenExpr { expr, .. }) => match *expr {
|
||||
Expr::Member(e) => Expr::Member(MemberExpr { span, ..e }),
|
||||
Expr::New(e) => Expr::New(NewExpr { span, ..e }),
|
||||
Expr::Member(e) => MemberExpr { span, ..e }.into(),
|
||||
Expr::New(e) => NewExpr { span, ..e }.into(),
|
||||
_ => *expr,
|
||||
},
|
||||
_ => expr,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user