mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 22:22:34 +03:00
perf(es/compat): Migrate regenerator
to VisitMut
partially (#3007)
This commit is contained in:
parent
9a00c9a13f
commit
91d6343d7f
@ -3,14 +3,16 @@ use smallvec::SmallVec;
|
||||
use std::mem::take;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
util::{map::Map, move_map::MoveMap},
|
||||
util::{map::Map, move_map::MoveMap, take::Take},
|
||||
BytePos, Span, Spanned, SyntaxContext, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{
|
||||
ident::IdentLike, member_expr, quote_ident, quote_str, undefined, ExprFactory,
|
||||
};
|
||||
use swc_ecma_visit::{noop_fold_type, noop_visit_type, Fold, FoldWith, Visit, VisitWith};
|
||||
use swc_ecma_visit::{
|
||||
noop_visit_mut_type, noop_visit_type, Visit, VisitMut, VisitMutWith, VisitWith,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(super) struct Loc {
|
||||
@ -849,14 +851,15 @@ impl CaseHandler<'_> {
|
||||
// case, we can skip the rest of the statements until the next case.
|
||||
let mut already_ended = false;
|
||||
|
||||
let stmts = {
|
||||
let stmts = take(&mut self.listing);
|
||||
let mut stmts = {
|
||||
let mut stmts = take(&mut self.listing);
|
||||
let mut v = InvalidToLit { map: &self.marked };
|
||||
|
||||
stmts.fold_with(&mut v)
|
||||
stmts.visit_mut_with(&mut v);
|
||||
stmts
|
||||
};
|
||||
|
||||
for (i, stmt) in stmts.into_iter().enumerate() {
|
||||
for (i, stmt) in stmts.iter_mut().enumerate() {
|
||||
let case = SwitchCase {
|
||||
span: DUMMY_SP,
|
||||
test: Some(Box::new(Expr::Lit(Lit::Num(Number {
|
||||
@ -879,11 +882,10 @@ impl CaseHandler<'_> {
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
cases
|
||||
.last_mut()
|
||||
.unwrap()
|
||||
.cons
|
||||
.push(stmt.fold_with(&mut UnmarkedInvalidHandler { case_id: i }));
|
||||
|
||||
stmt.visit_mut_with(&mut UnmarkedInvalidHandler { case_id: i });
|
||||
|
||||
cases.last_mut().unwrap().cons.push(stmt.take());
|
||||
|
||||
if is_completion {
|
||||
already_ended = true;
|
||||
@ -1273,13 +1275,16 @@ impl CaseHandler<'_> {
|
||||
// getSafeParam: () => t.cloneDeep(safeParam),
|
||||
// catchParamName: handler.param.name
|
||||
//});
|
||||
handler = handler.map(|handler| {
|
||||
let body = handler.body.fold_with(&mut CatchParamHandler {
|
||||
handler = handler.map(|mut handler| {
|
||||
handler.body.visit_mut_with(&mut CatchParamHandler {
|
||||
safe_param: &safe_param,
|
||||
param: handler.param.as_ref(),
|
||||
});
|
||||
|
||||
CatchClause { body, ..handler }
|
||||
CatchClause {
|
||||
body: handler.body,
|
||||
..handler
|
||||
}
|
||||
});
|
||||
|
||||
try_entry.catch_entry = match folder.with_entry(
|
||||
@ -1583,19 +1588,17 @@ struct UnmarkedInvalidHandler {
|
||||
case_id: usize,
|
||||
}
|
||||
|
||||
/// TODO: VisitMut
|
||||
impl Fold for UnmarkedInvalidHandler {
|
||||
noop_fold_type!();
|
||||
impl VisitMut for UnmarkedInvalidHandler {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::Invalid(Invalid { span }) => Expr::Lit(Lit::Num(Number {
|
||||
span,
|
||||
if let Expr::Invalid(Invalid { span }) = e {
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
span: *span,
|
||||
value: self.case_id as _,
|
||||
})),
|
||||
_ => e,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1606,30 +1609,24 @@ struct InvalidToLit<'a> {
|
||||
map: &'a [Loc],
|
||||
}
|
||||
|
||||
/// TODO: VisitMut
|
||||
impl Fold for InvalidToLit<'_> {
|
||||
noop_fold_type!();
|
||||
impl VisitMut for InvalidToLit<'_> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::Invalid(Invalid { span }) => {
|
||||
//
|
||||
if span.lo == span.hi {
|
||||
if let Some(Loc { stmt_index, .. }) =
|
||||
self.map.iter().find(|loc| loc.id == span.lo.0)
|
||||
{
|
||||
return Expr::Lit(Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: (*stmt_index) as _,
|
||||
}));
|
||||
}
|
||||
if let Expr::Invalid(Invalid { span }) = e {
|
||||
if span.lo == span.hi {
|
||||
if let Some(Loc { stmt_index, .. }) =
|
||||
self.map.iter().find(|loc| loc.id == span.lo.0)
|
||||
{
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: (*stmt_index) as _,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
Expr::Invalid(Invalid { span })
|
||||
}
|
||||
_ => e,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1639,24 +1636,19 @@ struct CatchParamHandler<'a> {
|
||||
param: Option<&'a Pat>,
|
||||
}
|
||||
|
||||
/// TODO: VisitMut
|
||||
impl Fold for CatchParamHandler<'_> {
|
||||
noop_fold_type!();
|
||||
impl VisitMut for CatchParamHandler<'_> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn fold_expr(&mut self, node: Expr) -> Expr {
|
||||
match self.param {
|
||||
None => return node,
|
||||
Some(Pat::Ident(i)) => match &node {
|
||||
Expr::Ident(r) => {
|
||||
if r.sym == i.id.sym && i.id.span.ctxt() == r.span.ctxt() {
|
||||
return self.safe_param.clone();
|
||||
}
|
||||
fn visit_mut_expr(&mut self, node: &mut Expr) {
|
||||
if let Some(Pat::Ident(i)) = self.param {
|
||||
if let Expr::Ident(r) = node {
|
||||
if r.sym == i.id.sym && i.id.span.ctxt() == r.span.ctxt() {
|
||||
*node = self.safe_param.clone();
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
node.fold_children_with(self)
|
||||
node.visit_mut_children_with(self);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
use smallvec::SmallVec;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_common::{util::take::Take, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{find_ids, private_ident};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
|
||||
|
||||
pub(super) type Vars = SmallVec<[Ident; 12]>;
|
||||
|
||||
pub(super) fn hoist<T>(node: T) -> (T, Hoister)
|
||||
pub(super) fn hoist<T>(mut node: T) -> (T, Hoister)
|
||||
where
|
||||
T: FoldWith<Hoister>,
|
||||
T: VisitMutWith<Hoister>,
|
||||
{
|
||||
let mut v = Hoister {
|
||||
vars: Default::default(),
|
||||
arguments: None,
|
||||
};
|
||||
let t = node.fold_with(&mut v);
|
||||
node.visit_mut_with(&mut v);
|
||||
|
||||
(t, v)
|
||||
(node, v)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -27,8 +27,8 @@ pub(super) struct Hoister {
|
||||
}
|
||||
|
||||
impl Hoister {
|
||||
fn var_decl_to_expr(&mut self, var: VarDecl) -> Expr {
|
||||
let var = var.fold_children_with(self);
|
||||
fn var_decl_to_expr(&mut self, mut var: VarDecl) -> Expr {
|
||||
var.visit_mut_children_with(self);
|
||||
|
||||
let ids = find_ids(&var);
|
||||
self.vars.extend(ids);
|
||||
@ -56,122 +56,103 @@ impl Hoister {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: VisitMut
|
||||
impl Fold for Hoister {
|
||||
noop_fold_type!();
|
||||
impl VisitMut for Hoister {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
/// Noop
|
||||
fn fold_function(&mut self, n: Function) -> Function {
|
||||
n
|
||||
fn visit_mut_function(&mut self, _n: &mut Function) {
|
||||
//noop
|
||||
}
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("arguments"),
|
||||
..
|
||||
}) => {
|
||||
if self.arguments.is_none() {
|
||||
self.arguments = Some(private_ident!("_args"));
|
||||
}
|
||||
|
||||
return Expr::Ident(self.arguments.clone().unwrap());
|
||||
if let Expr::Ident(Ident {
|
||||
sym: js_word!("arguments"),
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
if self.arguments.is_none() {
|
||||
self.arguments = Some(private_ident!("_args"));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
*e = Expr::Ident(self.arguments.clone().unwrap());
|
||||
}
|
||||
|
||||
e
|
||||
}
|
||||
|
||||
fn fold_member_expr(&mut self, mut e: MemberExpr) -> MemberExpr {
|
||||
e.obj = e.obj.fold_with(self);
|
||||
fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
|
||||
e.obj.visit_mut_with(self);
|
||||
|
||||
if e.computed {
|
||||
e.prop = e.prop.fold_with(self);
|
||||
e.prop.visit_mut_with(self);
|
||||
}
|
||||
|
||||
e
|
||||
}
|
||||
|
||||
fn fold_module_decl(&mut self, decl: ModuleDecl) -> ModuleDecl {
|
||||
match decl {
|
||||
ModuleDecl::ExportDecl(ExportDecl {
|
||||
span,
|
||||
decl: Decl::Var(var),
|
||||
}) => {
|
||||
return ModuleDecl::ExportDefaultExpr(ExportDefaultExpr {
|
||||
span,
|
||||
expr: Box::new(self.var_decl_to_expr(var)),
|
||||
})
|
||||
}
|
||||
|
||||
_ => {}
|
||||
fn visit_mut_module_decl(&mut self, decl: &mut ModuleDecl) {
|
||||
if let ModuleDecl::ExportDecl(ExportDecl {
|
||||
span,
|
||||
decl: Decl::Var(var),
|
||||
}) = decl
|
||||
{
|
||||
*decl = ModuleDecl::ExportDefaultExpr(ExportDefaultExpr {
|
||||
span: *span,
|
||||
expr: Box::new(self.var_decl_to_expr(var.take())),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
decl.fold_children_with(self)
|
||||
decl.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
fn fold_stmt(&mut self, s: Stmt) -> Stmt {
|
||||
match s {
|
||||
Stmt::Decl(Decl::Var(var)) => {
|
||||
let span = var.span;
|
||||
let expr = Box::new(self.var_decl_to_expr(var));
|
||||
fn visit_mut_stmt(&mut self, s: &mut Stmt) {
|
||||
if let Stmt::Decl(Decl::Var(var)) = s {
|
||||
let span = var.span;
|
||||
let expr = Box::new(self.var_decl_to_expr(var.take()));
|
||||
|
||||
return Stmt::Expr(ExprStmt { span, expr });
|
||||
}
|
||||
|
||||
_ => {}
|
||||
*s = Stmt::Expr(ExprStmt { span, expr });
|
||||
return;
|
||||
}
|
||||
|
||||
s.fold_children_with(self)
|
||||
s.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
fn fold_var_decl(&mut self, var: VarDecl) -> VarDecl {
|
||||
fn visit_mut_var_decl(&mut self, var: &mut VarDecl) {
|
||||
unreachable!("VarDecl should be removed by other pass: {:?}", var);
|
||||
}
|
||||
|
||||
fn fold_var_decl_or_pat(&mut self, v: VarDeclOrPat) -> VarDeclOrPat {
|
||||
fn visit_mut_var_decl_or_pat(&mut self, v: &mut VarDeclOrPat) {
|
||||
match v {
|
||||
VarDeclOrPat::Pat(v) => VarDeclOrPat::Pat(v.fold_children_with(self)),
|
||||
VarDeclOrPat::Pat(v) => {
|
||||
v.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
VarDeclOrPat::VarDecl(mut var) => {
|
||||
VarDeclOrPat::VarDecl(var) => {
|
||||
if var.decls.len() == 1 && var.decls[0].init.is_none() {
|
||||
let pat = var.decls.remove(0).name;
|
||||
self.vars.extend(find_ids(&pat));
|
||||
|
||||
return pat.into();
|
||||
*v = pat.into();
|
||||
return;
|
||||
}
|
||||
|
||||
var.into()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn fold_var_decl_or_expr(&mut self, var: VarDeclOrExpr) -> VarDeclOrExpr {
|
||||
fn visit_mut_var_decl_or_expr(&mut self, var: &mut VarDeclOrExpr) {
|
||||
match var {
|
||||
VarDeclOrExpr::VarDecl(var) => {
|
||||
VarDeclOrExpr::Expr(Box::new(self.var_decl_to_expr(var)))
|
||||
VarDeclOrExpr::VarDecl(var_decl) => {
|
||||
*var = VarDeclOrExpr::Expr(Box::new(self.var_decl_to_expr(var_decl.take())));
|
||||
}
|
||||
_ => var.fold_children_with(self),
|
||||
}
|
||||
_ => {
|
||||
var.visit_mut_children_with(self);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn fold_opt_var_decl_or_expr(&mut self, v: Option<VarDeclOrExpr>) -> Option<VarDeclOrExpr> {
|
||||
let v = v.fold_children_with(self);
|
||||
fn visit_mut_opt_var_decl_or_expr(&mut self, v: &mut Option<VarDeclOrExpr>) {
|
||||
v.visit_mut_children_with(self);
|
||||
|
||||
match &v {
|
||||
Some(VarDeclOrExpr::Expr(e)) => {
|
||||
if e.is_invalid() {
|
||||
return None;
|
||||
}
|
||||
if let Some(VarDeclOrExpr::Expr(e)) = v {
|
||||
if e.is_invalid() {
|
||||
*v = None;
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user