refactor(es/minifier): Clean up logging (#4322)

This commit is contained in:
Donny/강동윤 2022-04-13 23:23:07 +09:00 committed by GitHub
parent 279145022d
commit 2002554fa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 588 additions and 648 deletions

View File

@ -577,7 +577,7 @@ where
if let Expr::Ident(i) = e {
if cfg!(feature = "debug") {
// tracing::debug!(
// debug!(
// "Usage: `{}``; update = {:?}, assign_lhs = {:?} ",
// i,
// self.ctx.in_update_arg,

View File

@ -32,7 +32,7 @@ impl Storage for ProgramData {
}
for (id, mut var_info) in child.vars {
// tracing::trace!("merge({:?},{}{:?})", kind, id.0, id.1);
// trace!("merge({:?},{}{:?})", kind, id.0, id.1);
match self.vars.entry(id) {
Entry::Occupied(mut e) => {
e.get_mut().inline_prevented |= var_info.inline_prevented;
@ -118,7 +118,7 @@ impl Storage for ProgramData {
kind: Option<VarDeclKind>,
) -> &mut VarUsageInfo {
// if cfg!(feature = "debug") {
// tracing::debug!(has_init = has_init, "declare_decl(`{}`)", i);
// debug!(has_init = has_init, "declare_decl(`{}`)", i);
// }
let v = self
@ -126,9 +126,7 @@ impl Storage for ProgramData {
.entry(i.to_id())
.and_modify(|v| {
if has_init && v.declared {
if cfg!(feature = "debug") {
tracing::debug!("declare_decl(`{}`): Already declared", i);
}
trace_op!("declare_decl(`{}`): Already declared", i);
v.mutated = true;
v.reassigned_with_var_decl = true;
@ -184,7 +182,7 @@ impl ScopeDataLike for ScopeData {
impl ProgramData {
fn report(&mut self, i: Id, ctx: Ctx, is_modify: bool, dejavu: &mut AHashSet<Id>) {
// tracing::trace!("report({}{:?})", i.0, i.1);
// trace!("report({}{:?})", i.0, i.1);
let is_first = dejavu.is_empty();
@ -193,7 +191,7 @@ impl ProgramData {
}
let e = self.vars.entry(i).or_insert_with(|| {
// tracing::trace!("insert({}{:?})", i.0, i.1);
// trace!("insert({}{:?})", i.0, i.1);
VarUsageInfo {
is_fn_local: true,

View File

@ -22,7 +22,7 @@ use swc_ecma_transforms_optimization::simplify::{
use swc_ecma_utils::StmtLike;
use swc_ecma_visit::{as_folder, noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
use swc_timer::timer;
use tracing::error;
use tracing::{debug, error};
pub(crate) use self::pure::pure_optimizer;
use self::{hoist_decls::DeclHoisterConfig, optimize::optimizer};
@ -128,7 +128,7 @@ where
where
N: Send + Sync + for<'aa> VisitMutWith<Compressor<'aa, M>>,
{
tracing::debug!("visit_par(left_depth = {})", self.left_parallel_depth);
trace_op!("visit_par(left_depth = {})", self.left_parallel_depth);
if self.left_parallel_depth == 0 || cfg!(target_arch = "wasm32") {
for node in nodes {
@ -181,12 +181,10 @@ where
+ for<'aa> VisitMutWith<Compressor<'aa, M>>
+ VisitWith<AssertValid>,
{
if cfg!(feature = "debug") {
tracing::debug!(
trace_op!(
"Optimizing a compile unit within `{:?}`",
thread::current().name()
);
}
{
let data = analyze(&*n, Some(self.marks));
@ -236,7 +234,7 @@ where
if self.options.passes != 0 && self.options.passes < self.pass {
let done = dump(&*n, false);
tracing::debug!("===== Done =====\n{}", done);
debug!("===== Done =====\n{}", done);
return;
}
@ -268,7 +266,7 @@ where
let start = if cfg!(feature = "debug") {
let start = n.dump();
tracing::debug!("===== Start =====\n{}", start);
debug!("===== Start =====\n{}", start);
start
} else {
String::new()
@ -288,9 +286,9 @@ where
if visitor.changed() {
n.invoke();
tracing::debug!("compressor: Simplified expressions");
debug!("compressor: Simplified expressions");
if cfg!(feature = "debug") {
tracing::debug!("===== Simplified =====\n{}", dump(&*n, false));
debug!("===== Simplified =====\n{}", dump(&*n, false));
}
}
@ -335,7 +333,7 @@ where
n.invoke();
let src = n.dump();
tracing::debug!("===== After pure =====\n{}\n{}", start, src);
debug!("===== After pure =====\n{}\n{}", start, src);
}
}
@ -363,7 +361,7 @@ where
self.changed |= visitor.changed();
// let done = dump(&*n);
// tracing::debug!("===== Result =====\n{}", done);
// debug!("===== Result =====\n{}", done);
}
if self.options.conditionals || self.options.dead_code {
@ -392,10 +390,9 @@ where
let simplified = dump(&*n, false);
if start != simplified {
tracing::debug!(
debug!(
"===== Removed dead branches =====\n{}\n==== ===== ===== ===== ======\n{}",
start,
simplified
start, simplified
);
}
}

View File

@ -30,7 +30,7 @@ where
}
self.changed = true;
tracing::debug!("arguments: Optimizing computed access to arguments");
report_change!("arguments: Optimizing computed access to arguments");
*prop = MemberProp::Ident(Ident {
span: s.span,
sym: s.take().value,
@ -48,7 +48,7 @@ where
}
self.changed = true;
tracing::debug!("arguments: Optimizing computed access to arguments");
report_change!("arguments: Optimizing computed access to arguments");
*prop = SuperProp::Ident(Ident {
span: s.span,
sym: s.take().value,
@ -127,7 +127,7 @@ impl ArgReplacer<'_> {
let new_args = idx + 1 - self.params.len();
self.changed = true;
tracing::debug!("arguments: Injecting {} parameters", new_args);
report_change!("arguments: Injecting {} parameters", new_args);
let mut start = self.params.len();
self.params.extend(
repeat_with(|| {
@ -206,8 +206,8 @@ impl VisitMut for ArgReplacer<'_> {
//
if let Some(param) = self.params.get(idx) {
if let Pat::Ident(i) = &param.pat {
tracing::debug!(
"arguments: Replacing access to arguments to normal reference",
report_change!(
"arguments: Replacing access to arguments to normal reference"
);
self.changed = true;
*n = Expr::Ident(i.id.clone());

View File

@ -62,7 +62,7 @@ where
// =>
//
// `_ || 'undefined' == typeof require`
tracing::debug!(
report_change!(
is_return_value_ignored = is_ret_val_ignored,
negate_cost = cost,
"bools: Negating: (!a && !b) => !(a || b) (because both expression are good for \
@ -84,9 +84,7 @@ where
self.with_ctx(ctx).negate(&mut e.left, false);
self.with_ctx(ctx).negate(&mut e.right, is_ret_val_ignored);
if cfg!(feature = "debug") {
tracing::debug!("[Change] {} => {}", start, dump(&*e, false));
}
dump_change_detail!("{} => {}", start, dump(&*e, false));
true
}
@ -104,7 +102,7 @@ where
if stmt.alt == None {
if let Stmt::Expr(cons) = &mut *stmt.cons {
self.changed = true;
tracing::debug!("conditionals: `if (foo) bar;` => `foo && bar`");
report_change!("conditionals: `if (foo) bar;` => `foo && bar`");
*s = Stmt::Expr(ExprStmt {
span: stmt.span,
expr: Box::new(Expr::Bin(BinExpr {
@ -283,7 +281,7 @@ where
match (lt, rt) {
(Type::Undefined, Type::Null) | (Type::Null, Type::Undefined) => {
if op == op!("===") {
tracing::debug!(
report_change!(
"Reducing `!== null || !== undefined` check to `!= null`"
);
return Some(BinExpr {
@ -293,7 +291,7 @@ where
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
});
} else {
tracing::debug!(
report_change!(
"Reducing `=== null || === undefined` check to `== null`"
);
return Some(BinExpr {

View File

@ -62,7 +62,7 @@ where
_ => return,
};
tracing::debug!(
report_change!(
"collpase_vars: Decided to inline {}{:?}",
left.id.sym,
left.id.span.ctxt

View File

@ -34,7 +34,7 @@ where
}
if negate_cost(&stmt.test, true, false) < 0 {
tracing::debug!("if_return: Negating `cond` of an if statement which has cons and alt");
report_change!("if_return: Negating `cond` of an if statement which has cons and alt");
let ctx = Ctx {
in_bool_ctx: true,
..self.ctx
@ -47,7 +47,7 @@ where
match &*alt {
Stmt::Return(..) | Stmt::Continue(ContinueStmt { label: None, .. }) => {
self.changed = true;
tracing::debug!(
report_change!(
"if_return: Negating an if statement because the alt is return / continue"
);
self.negate(&mut stmt.test, false);
@ -68,7 +68,7 @@ where
if !cond.cons.may_have_side_effects() {
self.changed = true;
tracing::debug!("conditionals: `cond ? useless : alt` => `cond || alt`");
report_change!("conditionals: `cond ? useless : alt` => `cond || alt`");
*e = Expr::Bin(BinExpr {
span: cond.span,
op: op!("||"),
@ -80,7 +80,7 @@ where
if !cond.alt.may_have_side_effects() {
self.changed = true;
tracing::debug!("conditionals: `cond ? cons : useless` => `cond && cons`");
report_change!("conditionals: `cond ? cons : useless` => `cond && cons`");
*e = Expr::Bin(BinExpr {
span: cond.span,
op: op!("&&"),
@ -127,7 +127,7 @@ where
}
self.changed = true;
tracing::debug!("conditionals: Merging if statements with same `cons`");
report_change!("conditionals: Merging if statements with same `cons`");
let mut cur: Option<IfStmt> = None;
let mut new = Vec::with_capacity(stmts.len());
@ -214,7 +214,7 @@ where
expr: stmt.test.take(),
});
self.changed = true;
tracing::debug!("conditionals: `if (foo);` => `foo` ");
report_change!("conditionals: `if (foo);` => `foo` ");
return;
}
}
@ -240,7 +240,7 @@ where
Expr::Unary(UnaryExpr {
op: op!("!"), arg, ..
}) => {
tracing::debug!("Optimizing `if (!foo); else bar();` as `foo && bar();`");
report_change!("Optimizing `if (!foo); else bar();` as `foo && bar();`");
let mut expr = Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
@ -255,7 +255,7 @@ where
});
}
_ => {
tracing::debug!("Optimizing `if (foo); else bar();` as `foo || bar();`");
report_change!("Optimizing `if (foo); else bar();` as `foo || bar();`");
let mut expr = Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
@ -290,7 +290,7 @@ where
if self.options.conditionals || self.options.bools {
// if (a) b(); else c(); => a ? b() : c()
tracing::debug!(
report_change!(
"Compressing if statement as conditional expression (even though cons and alt is \
not compressable)"
);
@ -325,7 +325,7 @@ where
// x ? x : y => x || y
if cond.test.is_ident() && cond.test.eq_ignore_span(&cond.cons) {
tracing::debug!("Compressing `x ? x : y` as `x || y`");
report_change!("Compressing `x ? x : y` as `x || y`");
self.changed = true;
*e = Expr::Bin(BinExpr {
span: cond.span,
@ -344,7 +344,7 @@ where
is_for_if_stmt: bool,
) -> Option<Expr> {
if cons.eq_ignore_span(alt) && !matches!(&*cons, Expr::Yield(..) | Expr::Fn(..)) {
tracing::debug!("conditionals: cons is same as alt");
report_change!("conditionals: cons is same as alt");
return Some(Expr::Seq(SeqExpr {
span: DUMMY_SP,
exprs: vec![test.take(), Box::new(cons.take())],
@ -384,7 +384,7 @@ where
.count();
if diff_count == 1 {
tracing::debug!(
report_change!(
"conditionals: Merging cons and alt as only one argument differs"
);
self.changed = true;
@ -446,7 +446,7 @@ where
}
.as_arg()];
tracing::debug!(
report_change!(
"Compressing if into cond as there's no side effect and the number of \
arguments is 1"
);
@ -459,7 +459,7 @@ where
}
if !side_effect_free && is_for_if_stmt {
tracing::debug!("Compressing if into cond while preserving side effects");
report_change!("Compressing if into cond while preserving side effects");
return Some(Expr::Cond(CondExpr {
span: DUMMY_SP,
test: test.take(),
@ -512,7 +512,7 @@ where
});
}
tracing::debug!(
report_change!(
"Compressing if statement into a conditional expression of `new` as \
there's no side effect and the number of arguments is 1"
);
@ -533,7 +533,7 @@ where
&& cons.left.eq_ignore_span(&alt.left)
&& is_simple_lhs(&cons.left) =>
{
tracing::debug!("Merging assignments in cons and alt of if statement");
report_change!("Merging assignments in cons and alt of if statement");
Some(Expr::Assign(AssignExpr {
span: DUMMY_SP,
op: cons.op,
@ -549,7 +549,7 @@ where
// a ? b ? c() : d() : d() => a && b ? c() : d()
(Expr::Cond(cons), alt) if (*cons.alt).eq_ignore_span(&*alt) => {
tracing::debug!("conditionals: a ? b ? c() : d() : d() => a && b ? c() : d()");
report_change!("conditionals: a ? b ? c() : d() : d() => a && b ? c() : d()");
Some(Expr::Cond(CondExpr {
span: DUMMY_SP,
test: Box::new(Expr::Bin(BinExpr {
@ -568,7 +568,7 @@ where
// (z || condition(), "fuji");
(cons, Expr::Seq(alt)) if (**alt.exprs.last().unwrap()).eq_ignore_span(&*cons) => {
self.changed = true;
tracing::debug!("conditionals: Reducing seq expr in alt");
report_change!("conditionals: Reducing seq expr in alt");
//
alt.exprs.pop();
let first = Box::new(Expr::Bin(BinExpr {
@ -591,7 +591,7 @@ where
// (z && condition(), "fuji");
(Expr::Seq(cons), alt) if (**cons.exprs.last().unwrap()).eq_ignore_span(&*alt) => {
self.changed = true;
tracing::debug!("conditionals: Reducing seq expr in cons");
report_change!("conditionals: Reducing seq expr in cons");
//
cons.exprs.pop();
let first = Box::new(Expr::Bin(BinExpr {
@ -647,7 +647,7 @@ where
};
self.changed = true;
tracing::debug!("if_return: Injecting else because it's shorter");
report_change!("if_return: Injecting else because it's shorter");
let mut new = vec![];
new.reserve(pos_of_if + 1);
@ -738,7 +738,7 @@ where
}
self.changed = true;
tracing::debug!("conditionals: Dropped useless `else` token");
report_change!("conditionals: Dropped useless `else` token");
*stmts = new_stmts;
}
}

View File

@ -57,7 +57,7 @@ where
.map(|var| var.is_fn_local && !var.declared_as_fn_param)
.unwrap_or(false)
{
tracing::debug!(
report_change!(
"dead_code: Dropping an assignment to a variable declared in function \
because function is being terminated"
);
@ -80,7 +80,7 @@ where
.map(|var| var.is_fn_local)
.unwrap_or(false)
{
tracing::debug!(
report_change!(
"dead_code: Converting an assignment into a binary expression in \
function termination"
);

View File

@ -50,7 +50,7 @@ where
if self.options.unsafe_passes {
match &*prop.sym {
"length" => {
tracing::debug!("evaluate: function.length");
report_change!("evaluate: function.length");
*e = Expr::Lit(Lit::Num(Number {
span: *span,
@ -61,7 +61,7 @@ where
}
"name" => {
tracing::debug!("evaluate: function.name");
report_change!("evaluate: function.name");
*e = Expr::Lit(Lit::Str(Str {
span: *span,
@ -108,7 +108,7 @@ where
sym: js_word!("undefined"),
..
}) => {
tracing::debug!("evaluate: `undefined` -> `void 0`");
report_change!("evaluate: `undefined` -> `void 0`");
self.changed = true;
*e = *undefined(*span);
}
@ -118,7 +118,7 @@ where
sym: js_word!("Infinity"),
..
}) => {
tracing::debug!("evaluate: `Infinity` -> `1 / 0`");
report_change!("evaluate: `Infinity` -> `1 / 0`");
self.changed = true;
*e = Expr::Bin(BinExpr {
span: *span,
@ -192,7 +192,7 @@ where
1 => {
if let Expr::Lit(Lit::Str(exp)) = &*args[0].expr {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Converting RegExpr call into a regexp literal `/{}/`",
exp.value
);
@ -209,7 +209,7 @@ where
(&*args[0].expr, &*args[1].expr)
{
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Converting RegExpr call into a regexp literal `/{}/{}`",
exp.value,
flags.value
@ -244,7 +244,7 @@ where
if let Some(v) = char::from_u32(v) {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Evaluated `String.charCodeAt({})` as `{}`",
char_code,
v
@ -346,7 +346,7 @@ where
if let Expr::Call(..) = e {
if let Some(value) = eval_as_number(e) {
self.changed = true;
tracing::debug!("evaluate: Evaluated an expression as `{}`", value);
report_change!("evaluate: Evaluated an expression as `{}`", value);
*e = Expr::Lit(Lit::Num(Number {
span: e.span(),
@ -365,7 +365,7 @@ where
if let Known(l) = l {
if let Known(r) = r {
self.changed = true;
tracing::debug!("evaluate: Evaluated `{:?} ** {:?}`", l, r);
report_change!("evaluate: Evaluated `{:?} ** {:?}`", l, r);
let value = l.powf(r);
*e = Expr::Lit(Lit::Num(Number {
@ -405,7 +405,7 @@ where
}
self.changed = true;
tracing::debug!("evaluate: `0 / 0` => `NaN`");
report_change!("evaluate: `0 / 0` => `NaN`");
// Sign does not matter for NaN
*e = Expr::Ident(Ident::new(
@ -415,7 +415,7 @@ where
}
(FpCategory::Normal, FpCategory::Zero) => {
self.changed = true;
tracing::debug!("evaluate: `{} / 0` => `Infinity`", ln);
report_change!("evaluate: `{} / 0` => `Infinity`", ln);
// Sign does not matter for NaN
*e = if ln.is_sign_positive() == rn.is_sign_positive() {
@ -469,7 +469,7 @@ where
// As we used as_pure_bool, we can drop it.
if v && e.op == op!("&&") {
self.changed = true;
tracing::debug!("Removing `b` from `a && b && c` because b is always truthy");
report_change!("Removing `b` from `a && b && c` because b is always truthy");
left.right.take();
return;
@ -477,7 +477,7 @@ where
if !v && e.op == op!("||") {
self.changed = true;
tracing::debug!("Removing `b` from `a || b || c` because b is always falsy");
report_change!("Removing `b` from `a || b || c` because b is always falsy");
left.right.take();
}

View File

@ -72,7 +72,7 @@ where
}
self.changed = true;
tracing::debug!("fns: Reordering statements");
report_change!("fns: Reordering statements");
let mut fns = vec![];
let mut other = vec![];

View File

@ -41,9 +41,7 @@ where
})
.unwrap_or(false)
{
if cfg!(feature = "debug") {
tracing::trace!("[x] bad usage");
}
log_abort!("[x] bad usage");
return;
}
@ -87,9 +85,7 @@ where
}
if !unknown_used_props.is_empty() {
if cfg!(feature = "debug") {
tracing::trace!("[x] unknown used props: {:?}", unknown_used_props);
}
log_abort!("[x] unknown used props: {:?}", unknown_used_props);
return;
}
@ -115,7 +111,7 @@ where
match &p.key {
PropName::Str(s) => {
tracing::debug!(
trace_op!(
"hoist_props: Storing a variable (`{}`) to inline properties",
name.id
);
@ -124,7 +120,7 @@ where
self.mode.store(name.to_id(), n.init.as_deref().unwrap());
}
PropName::Ident(i) => {
tracing::debug!(
trace_op!(
"hoist_props: Storing a variable(`{}`) to inline properties",
name.id
);
@ -177,7 +173,7 @@ where
);
}
None => {
tracing::debug!(
trace_op!(
"hoist_props: Stored {}{:?} to inline property access",
name.id.sym,
name.id.span.ctxt
@ -204,7 +200,7 @@ where
f.function.span = DUMMY_SP;
}
tracing::debug!("hoist_props: Inlining `{}.{}`", obj.sym, prop.sym);
report_change!("hoist_props: Inlining `{}.{}`", obj.sym, prop.sym);
self.changed = true;
*e = *value;
return;
@ -214,7 +210,7 @@ where
if let Some(value) = self.vars_for_prop_hoisting.remove(&obj.to_id()) {
member.obj = value;
self.changed = true;
tracing::debug!("hoist_props: Inlined a property");
report_change!("hoist_props: Inlined a property");
}
}
}

View File

@ -34,7 +34,7 @@ where
}) = &mut *s.cons
{
self.changed = true;
tracing::debug!("if_return: Merging nested if statements");
report_change!("if_return: Merging nested if statements");
s.test = Box::new(Expr::Bin(BinExpr {
span: s.test.span(),
@ -74,7 +74,7 @@ where
}
self.changed = true;
tracing::debug!("if_return: Merging `else if` into `else`");
report_change!("if_return: Merging `else if` into `else`");
match &mut **alt_of_alt {
Stmt::Block(alt_of_alt) => {
@ -181,7 +181,7 @@ where
None => true,
});
let skip = idx_of_not_mergable.map(|v| v + 1).unwrap_or(0);
tracing::trace!("if_return: Skip = {}", skip);
trace_op!("if_return: Skip = {}", skip);
let mut last_idx = stmts.len() - 1;
{
@ -207,7 +207,7 @@ where
}
if last_idx <= skip {
tracing::trace!("if_return: [x] Aborting because of skip");
log_abort!("if_return: [x] Aborting because of skip");
return;
}
@ -218,7 +218,7 @@ where
// There's no return statement so merging requires injecting unnecessary `void
// 0`
if return_count == 0 {
tracing::trace!("if_return: [x] Aborting because we failed to find return");
log_abort!("if_return: [x] Aborting because we failed to find return");
return;
}
@ -244,7 +244,7 @@ where
(_, Some(Stmt::If(IfStmt { alt: None, .. }) | Stmt::Expr(..)))
if if_return_count <= 1 =>
{
tracing::trace!(
log_abort!(
"if_return: [x] Aborting because last stmt is a not return stmt"
);
return;
@ -258,7 +258,7 @@ where
) => match &**cons {
Stmt::Return(ReturnStmt { arg: Some(..), .. }) => {}
_ => {
tracing::trace!(
log_abort!(
"if_return: [x] Aborting because stmt before last is an if stmt \
and cons of it is not a return stmt"
);
@ -314,14 +314,8 @@ where
}
}
tracing::debug!("if_return: Merging returns");
if cfg!(feature = "debug") {
let block = BlockStmt {
span: DUMMY_SP,
stmts: stmts.clone(),
};
tracing::trace!("if_return: {}", dump(&block, false))
}
report_change!("if_return: Merging returns");
self.changed = true;
let mut cur: Option<Box<Expr>> = None;
@ -442,9 +436,7 @@ where
expr: Box::new(cur),
}))
} else {
if cfg!(feature = "debug") {
tracing::debug!("if_return: Ignoring return value");
}
trace_op!("if_return: Ignoring return value");
}
}
_ => {
@ -535,7 +527,7 @@ where
_ => false,
};
// if !res {
// tracing::trace!("Cannot merge: {}", dump(s));
// trace!("Cannot merge: {}", dump(s));
// }
res
@ -633,9 +625,7 @@ fn can_merge_as_if_return(s: &Stmt) -> bool {
let c = cost(s);
if cfg!(feature = "debug") {
tracing::trace!("merging cost of `{}` = {:?}", dump(s, false), c);
}
trace_op!("merging cost of `{}` = {:?}", dump(s, false), c);
c.unwrap_or(0) < 0
}

View File

@ -42,7 +42,7 @@ where
};
if let Expr::Fn(..) = callee {
tracing::debug!("negate_iife: Negating iife");
report_change!("negate_iife: Negating iife");
*e = Expr::Unary(UnaryExpr {
span: DUMMY_SP,
op: op!("!"),
@ -73,7 +73,7 @@ where
match callee {
Expr::Fn(..) => {
tracing::debug!("negate_iife: Swapping cons and alt");
report_change!("negate_iife: Swapping cons and alt");
cond.test = Box::new(Expr::Unary(UnaryExpr {
span: DUMMY_SP,
op: op!("!"),
@ -214,7 +214,7 @@ where
let should_be_inlined = self.can_be_inlined_for_iife(arg);
if should_be_inlined {
tracing::trace!(
trace_op!(
"iife: Trying to inline argument ({}{:?})",
param.id.sym,
param.id.span.ctxt
@ -222,7 +222,7 @@ where
vars.insert(param.to_id(), arg.clone());
}
} else {
tracing::trace!(
trace_op!(
"iife: Trying to inline argument ({}{:?}) (undefined)",
param.id.sym,
param.id.span.ctxt
@ -241,11 +241,11 @@ where
let mut optimizer = self.with_ctx(ctx);
match find_body(callee) {
Some(Either::Left(body)) => {
tracing::trace!("inline: Inlining arguments");
trace_op!("inline: Inlining arguments");
optimizer.inline_vars_in_node(body, vars);
}
Some(Either::Right(body)) => {
tracing::trace!("inline: Inlining arguments");
trace_op!("inline: Inlining arguments");
optimizer.inline_vars_in_node(body, vars);
}
_ => {}
@ -258,9 +258,7 @@ where
where
N: for<'aa> VisitMutWith<MultiReplacer<'aa>>,
{
if cfg!(feature = "debug") {
tracing::trace!("inline: inline_vars_in_node");
}
trace_op!("inline: inline_vars_in_node");
n.visit_mut_with(&mut MultiReplacer::new(
&mut vars,
@ -315,19 +313,19 @@ where
};
if self.ctx.dont_invoke_iife {
tracing::trace!("iife: [x] Inline is prevented");
log_abort!("iife: [x] Inline is prevented");
return;
}
match callee {
Expr::Arrow(f) => {
if f.is_async {
tracing::trace!("iife: [x] Cannot inline async fn");
log_abort!("iife: [x] Cannot inline async fn");
return;
}
if f.is_generator {
tracing::trace!("iife: [x] Cannot inline generator");
log_abort!("iife: [x] Cannot inline generator");
return;
}
@ -359,7 +357,7 @@ where
let new = self.inline_fn_like(&param_ids, body, &mut call.args);
if let Some(new) = new {
self.changed = true;
tracing::debug!("inline: Inlining a function call (arrow)");
report_change!("inline: Inlining a function call (arrow)");
*e = new;
}
@ -446,7 +444,7 @@ where
body.visit_mut_with(&mut Remapper { vars: remap });
exprs.push(body.take());
tracing::debug!("inline: Inlining a call to an arrow function");
report_change!("inline: Inlining a call to an arrow function");
*e = Expr::Seq(SeqExpr {
span: DUMMY_SP,
exprs,
@ -460,18 +458,18 @@ where
let body = f.function.body.as_ref().unwrap();
let has_decl = body.stmts.iter().any(|stmt| matches!(stmt, Stmt::Decl(..)));
if has_decl {
tracing::trace!("iife: [x] Found decl");
log_abort!("iife: [x] Found decl");
return;
}
}
if f.function.is_async {
tracing::trace!("iife: [x] Cannot inline async fn");
log_abort!("iife: [x] Cannot inline async fn");
return;
}
if f.function.is_generator {
tracing::trace!("iife: [x] Cannot inline generator");
log_abort!("iife: [x] Cannot inline generator");
return;
}
@ -482,25 +480,25 @@ where
Pat::Object(..) | Pat::Array(..) | Pat::Assign(..) | Pat::Rest(..)
)
}) {
tracing::trace!("iife: [x] Found complex pattern");
log_abort!("iife: [x] Found complex pattern");
return;
}
if let Some(i) = &f.ident {
if idents_used_by(&f.function.body).contains(&i.to_id()) {
tracing::trace!("iife: [x] Recursive?");
log_abort!("iife: [x] Recursive?");
return;
}
}
for arg in &call.args {
if arg.spread.is_some() {
tracing::trace!("iife: [x] Found spread argument");
log_abort!("iife: [x] Found spread argument");
return;
}
match &*arg.expr {
Expr::Fn(..) | Expr::Arrow(..) => {
tracing::trace!("iife: [x] Found callable argument");
log_abort!("iife: [x] Found callable argument");
return;
}
_ => {}
@ -521,18 +519,16 @@ where
.collect::<Vec<_>>();
if !self.can_inline_fn_like(&param_ids, body) {
tracing::trace!("iife: [x] Body is not inlinable");
log_abort!("iife: [x] Body is not inlinable");
return;
}
let new = self.inline_fn_like(&param_ids, body, &mut call.args);
if let Some(new) = new {
self.changed = true;
tracing::debug!("inline: Inlining a function call");
report_change!("inline: Inlining a function call");
if cfg!(feature = "debug") {
tracing::debug!("[Change]: {}", dump(&new, false));
}
dump_change_detail!("{}", dump(&new, false));
*e = new;
}
@ -579,9 +575,7 @@ where
for pid in param_ids {
if let Some(usage) = self.data.vars.get(&pid.to_id()) {
if usage.ref_count > 1 || usage.assign_count > 0 || usage.inline_prevented {
if cfg!(feature = "debug") {
tracing::trace!("iife: [x] Cannot inline because of usage of {}", pid);
}
log_abort!("iife: [x] Cannot inline because of usage of `{}`", pid);
return false;
}
}
@ -594,12 +588,10 @@ where
for param in param_ids {
if captured.contains(&param.to_id()) {
if cfg!(feature = "debug") {
tracing::trace!(
"iife: [x] Cannot inline because of the capture of {}",
log_abort!(
"iife: [x] Cannot inline because of the capture of `{}`",
param
);
}
return false;
}
}
@ -682,7 +674,7 @@ where
}
self.changed = true;
tracing::debug!("inline: Inlining an iife");
report_change!("inline: Inlining an iife");
let mut exprs = vec![];
@ -739,9 +731,8 @@ where
.collect::<Vec<_>>();
if !vars.is_empty() {
if cfg!(feature = "debug") {
tracing::debug!("iife: Creating variables: {:?}", vars);
}
trace_op!("iife: Creating variables: {:?}", vars);
self.prepend_stmts.push(Stmt::Decl(Decl::Var(VarDecl {
span: DUMMY_SP.apply_mark(self.marks.non_top_level),
kind: VarDeclKind::Var,

View File

@ -30,13 +30,11 @@ where
&& (!self.options.top_level() && self.options.top_retain.is_empty())
&& self.ctx.in_top_level();
if cfg!(feature = "debug") {
tracing::trace!(
trace_op!(
"inline: store_var_for_inlining({}, should_preserve = {:?})",
dump(&var.name, false),
should_preserve
);
}
if self.data.top.has_eval_call {
return;
@ -64,19 +62,15 @@ where
}
if should_preserve && usage.var_kind != Some(VarDeclKind::Const) {
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"inline: [x] Preserving non-const variable `{}` because it's top-level",
dump(&var.name, false)
);
}
return;
}
if usage.cond_init || usage.used_above_decl {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] It's cond init or used before decl",);
}
log_abort!("inline: [x] It's cond init or used before decl",);
return;
}
@ -97,16 +91,12 @@ where
}) => {
if body.stmts.len() == 1 && matches!(&body.stmts[0], Stmt::Return(..)) {
} else {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] It's not fn-local");
}
log_abort!("inline: [x] It's not fn-local");
return;
}
}
_ => {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] It's not fn-local");
}
log_abort!("inline: [x] It's not fn-local");
return;
}
}
@ -175,7 +165,7 @@ where
{
self.changed = true;
tracing::debug!(
report_change!(
"inline: Decided to inline '{}{:?}' because it's simple",
i.id.sym,
i.id.span.ctxt
@ -189,7 +179,7 @@ where
var.name.take();
} else if self.options.inline != 0 || self.options.reduce_vars {
tracing::debug!(
trace_op!(
"inline: Decided to copy '{}{:?}' because it's simple",
i.id.sym,
i.id.span.ctxt
@ -289,7 +279,7 @@ where
return;
}
tracing::debug!(
report_change!(
"inline: Decided to inline var '{}' because it's used only once",
i.id
);
@ -364,7 +354,7 @@ where
if let Some(usage) = self.data.vars.get(&i.to_id()) {
if !usage.reassigned() {
tracing::trace!("typeofs: Storing typeof `{}{:?}`", i.sym, i.span.ctxt);
trace_op!("typeofs: Storing typeof `{}{:?}`", i.sym, i.span.ctxt);
match &*decl {
Decl::Fn(..) => {
self.typeofs.insert(i.to_id(), js_word!("function"));
@ -393,45 +383,33 @@ where
_ => return,
};
if cfg!(feature = "debug") {
tracing::trace!("inline: Trying to inline decl ({}{:?})", i.sym, i.span.ctxt);
}
trace_op!("inline: Trying to inline decl ({}{:?})", i.sym, i.span.ctxt);
if self.options.inline == 0 && !self.options.reduce_vars {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] Inline disabled");
}
log_abort!("inline: [x] Inline disabled");
return;
}
if (!self.options.top_level() && self.options.top_retain.is_empty())
&& self.ctx.in_top_level()
{
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] Top level");
}
log_abort!("inline: [x] Top level");
return;
}
if self.has_noinline(decl.span()) {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] Has noinline");
}
log_abort!("inline: [x] Has noinline");
return;
}
// Respect `top_retain`
if self.ctx.in_top_level() && self.options.top_retain.contains(&i.sym) {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] top_retain");
}
log_abort!("inline: [x] top_retain");
return;
}
if self.ctx.is_exported {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] exported");
}
log_abort!("inline: [x] exported");
return;
}
@ -441,20 +419,16 @@ where
if let Some(usage) = self.data.vars.get(&i.to_id()) {
if usage.declared_as_catch_param {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] Declared as a catch parameter");
}
log_abort!("inline: [x] Declared as a catch parameter");
return;
}
if usage.reassigned() || usage.inline_prevented {
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"inline: [x] reassigned = {}, inline_prevented = {}",
usage.reassigned(),
usage.inline_prevented
);
}
return;
}
@ -466,7 +440,7 @@ where
if !UsageFinder::find(&i, body)
&& self.is_fn_body_simple_enough_to_inline(body)
{
tracing::debug!(
trace_op!(
"inline: Decided to inline function '{}{:?}' as it's very \
simple",
f.ident.sym,
@ -529,14 +503,14 @@ where
self.changed = true;
match &decl {
Decl::Class(c) => {
tracing::debug!(
report_change!(
"inline: Decided to inline class `{}{:?}` as it's used only once",
c.ident.sym,
c.ident.span.ctxt
);
}
Decl::Fn(f) => {
tracing::debug!(
report_change!(
"inline: Decided to inline function `{}{:?}` as it's used only once",
f.ident.sym,
f.ident.span.ctxt
@ -561,9 +535,7 @@ where
self.vars.vars_for_inlining.insert(i.to_id(), e);
} else {
if cfg!(feature = "debug") {
tracing::trace!("inline: [x] Usage: {:?}", usage);
}
log_abort!("inline: [x] Usage: {:?}", usage);
}
}
}
@ -609,7 +581,7 @@ where
}
self.changed = true;
tracing::debug!("inline: Replacing a variable with cheap expression");
report_change!("inline: Replacing a variable with cheap expression");
*e = *value;
return;
@ -630,17 +602,11 @@ where
if let Some(value) = self.vars.vars_for_inlining.remove(&i.to_id()) {
self.changed = true;
tracing::debug!(
"inline: Replacing '{}{:?}' with an expression",
i.sym,
i.span.ctxt
);
report_change!("inline: Replacing '{}' with an expression", i);
*e = *value;
if cfg!(feature = "debug") {
tracing::trace!("inline: [Change] {}", dump(&*e, false))
}
log_abort!("inline: [Change] {}", dump(&*e, false))
}
}
}

View File

@ -46,7 +46,7 @@ where
self.changed = true;
// Remove the labeled statement.
self.label = None;
tracing::debug!("loops: Removing a for loop with instant break");
report_change!("loops: Removing a for loop with instant break");
self.prepend_stmts
.extend(f.init.take().map(|init| match init {
VarDeclOrExpr::VarDecl(var) => Stmt::Decl(Decl::Var(var)),
@ -79,7 +79,7 @@ where
let changed = UnreachableHandler::preserve_vars(stmt);
self.changed |= changed;
if changed {
tracing::debug!(
report_change!(
"loops: Removing unreachable while statement without side effects"
);
}
@ -87,9 +87,7 @@ where
let changed = UnreachableHandler::preserve_vars(&mut w.body);
self.changed |= changed;
if changed {
tracing::debug!(
"loops: Removing unreachable body of a while statement"
);
report_change!("loops: Removing unreachable body of a while statement");
}
}
}
@ -101,7 +99,7 @@ where
let changed = UnreachableHandler::preserve_vars(&mut f.body);
self.changed |= changed;
if changed {
tracing::debug!("loops: Removing unreachable body of a for statement");
report_change!("loops: Removing unreachable body of a for statement");
}
self.changed |= f.init.is_some() | f.update.is_some();
@ -122,7 +120,7 @@ where
} else if let Known(true) = val {
if purity.is_pure() {
self.changed = true;
tracing::debug!(
report_change!(
"loops: Removing `test` part of a for stmt as it's always true"
);
f.test = None;
@ -151,7 +149,7 @@ where
} else {
s.init = None;
self.changed = true;
tracing::debug!(
report_change!(
"loops: Removed side-effect-free expressions in `init` of a for stmt"
);
}

View File

@ -15,7 +15,7 @@ use swc_ecma_utils::{
StmtLike, Type, Value,
};
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
use tracing::{span, Level};
use tracing::{debug, span, Level};
use Value::Known;
use self::{
@ -673,7 +673,7 @@ where
}
}
tracing::debug!("Compressing array.join()");
report_change!("Compressing array.join()");
self.changed = true;
*e = Expr::Lit(Lit::Str(Str {
@ -708,7 +708,7 @@ where
if self.options.bools_as_ints || self.options.bools {
if let Lit::Bool(v) = lit {
self.changed = true;
tracing::debug!("Compressing boolean literal");
report_change!("Compressing boolean literal");
*e = Expr::Unary(UnaryExpr {
span: v.span,
op: op!("!"),
@ -751,27 +751,23 @@ where
match e {
Expr::This(_) | Expr::Invalid(_) | Expr::Lit(..) => {
if cfg!(feature = "debug") {
tracing::debug!(
report_change!(
"ignore_return_value: Dropping unused expr: {}",
dump(&*e, false)
);
}
self.changed = true;
return None;
}
Expr::Tpl(t) if t.exprs.is_empty() => {
if cfg!(feature = "debug") {
tracing::debug!("ignore_return_value: Dropping tpl expr without expr");
}
report_change!("ignore_return_value: Dropping tpl expr without expr");
self.changed = true;
return None;
}
// Function expression cannot have a side effect.
Expr::Fn(_) => {
tracing::debug!(
report_change!(
"ignore_return_value: Dropping unused fn expr as it does not have any side \
effect"
);
@ -913,7 +909,7 @@ where
_ => false,
} && args.is_empty() =>
{
tracing::debug!("ignore_return_value: Dropping a pure call");
report_change!("ignore_return_value: Dropping a pure call");
self.changed = true;
return None;
}
@ -1020,7 +1016,7 @@ where
Expr::Array(arr) => {
let mut exprs = vec![];
self.changed = true;
tracing::debug!("ignore_return_value: Inverting an array literal");
report_change!("ignore_return_value: Inverting an array literal");
exprs.extend(
arr.elems
.take()
@ -1044,7 +1040,7 @@ where
Expr::Object(obj) => {
let mut exprs = vec![];
self.changed = true;
tracing::debug!("ignore_return_value: Inverting an object literal");
report_change!("ignore_return_value: Inverting an object literal");
for prop in obj.props.take() {
match prop {
PropOrSpread::Spread(mut e) => {
@ -1114,14 +1110,14 @@ where
*arg = Box::new(processed_arg);
tracing::trace!("ignore_return_value: Preserving negated iife");
log_abort!("ignore_return_value: Preserving negated iife");
return Some(e.take());
}
// `delete` is handled above
Expr::Unary(expr) => {
self.changed = true;
tracing::debug!("ignore_return_value: Reducing unary ({})", expr.op);
report_change!("ignore_return_value: Reducing unary ({})", expr.op);
return self.ignore_return_value(&mut expr.arg);
}
@ -1132,7 +1128,7 @@ where
op,
..
}) => {
tracing::debug!("ignore_return_value: Reducing binary ({})", *op);
report_change!("ignore_return_value: Reducing binary ({})", *op);
let left = self.ignore_return_value(&mut **left).map(Box::new);
let right = self.ignore_return_value(&mut **right).map(Box::new);
@ -1145,7 +1141,7 @@ where
}
Expr::Cond(cond) => {
tracing::trace!("ignore_return_value: Cond expr");
trace_op!("ignore_return_value: Cond expr");
self.restore_negated_iife(cond);
@ -1172,12 +1168,12 @@ where
span: cond.span,
test: cond.test.take(),
cons: cons.unwrap_or_else(|| {
tracing::debug!("ignore_return_value: Dropped `cons`");
report_change!("ignore_return_value: Dropped `cons`");
self.changed = true;
undefined(cons_span)
}),
alt: alt.unwrap_or_else(|| {
tracing::debug!("ignore_return_value: Dropped `alt`");
report_change!("ignore_return_value: Dropped `alt`");
self.changed = true;
undefined(alt_span)
}),
@ -1223,7 +1219,7 @@ where
// Make return type undefined.
if let Some(last) = exprs.last_mut() {
tracing::debug!("ignore_return_value: Shifting void");
report_change!("ignore_return_value: Shifting void");
self.changed = true;
*last = Box::new(Expr::Unary(UnaryExpr {
span: DUMMY_SP,
@ -1234,7 +1230,7 @@ where
}
if exprs.is_empty() {
tracing::debug!("ignore_return_value: Dropping empty seq");
report_change!("ignore_return_value: Dropping empty seq");
return None;
}
@ -1335,7 +1331,7 @@ where
})
.unwrap_or(js_word!(""));
tracing::debug!("Converting call to RegExp into a regexp literal");
report_change!("Converting call to RegExp into a regexp literal");
self.changed = true;
*e = Expr::Lit(Lit::Regex(Regex {
span,
@ -1403,9 +1399,8 @@ where
}) {
self.changed = true;
if cfg!(feature = "debug") {
tracing::debug!("Merging variable declarations");
tracing::trace!(
report_change!("Merging variable declarations");
dump_change_detail!(
"[Before]: {}",
dump(
&BlockStmt {
@ -1414,8 +1409,7 @@ where
},
false
)
)
}
);
let orig = take(stmts);
let mut new = Vec::with_capacity(orig.len());
@ -1448,8 +1442,7 @@ where
new.extend(var_decl.take().map(Decl::Var).map(Stmt::Decl));
if cfg!(feature = "debug") {
tracing::trace!(
dump_change_detail!(
"[Change] merged: {}",
dump(
&BlockStmt {
@ -1458,8 +1451,8 @@ where
},
false
)
)
}
);
*stmts = new
}
}
@ -1485,7 +1478,7 @@ where
.iter()
.all(|stmt| !matches!(stmt, Stmt::Decl(..)))
{
tracing::debug!("optimizer: Removing nested block");
report_change!("optimizer: Removing nested block");
self.changed = true;
bs.stmts = block.stmts.take();
}
@ -1506,7 +1499,7 @@ where
)
})
{
tracing::debug!("optimizer: Unwrapping a block with variable statements");
report_change!("optimizer: Unwrapping a block with variable statements");
self.changed = true;
*s = bs.stmts[0].take();
return;
@ -1516,7 +1509,7 @@ where
if let Stmt::Block(block) = &stmt {
if block.stmts.is_empty() {
self.changed = true;
tracing::debug!("optimizer: Removing empty block");
report_change!("optimizer: Removing empty block");
*stmt = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
}
}
@ -1526,12 +1519,12 @@ where
match &bs.stmts[0] {
Stmt::Expr(..) | Stmt::If(..) => {
*s = bs.stmts[0].take();
tracing::debug!("optimizer: Unwrapping block stmt");
report_change!("optimizer: Unwrapping block stmt");
self.changed = true;
}
Stmt::Decl(Decl::Fn(..)) if !self.ctx.in_strict => {
*s = bs.stmts[0].take();
tracing::debug!("optimizer: Unwrapping block stmt in non strcit mode");
report_change!("optimizer: Unwrapping block stmt in non strcit mode");
self.changed = true;
}
_ => {}
@ -1602,7 +1595,7 @@ where
if stmt.alt.is_none() {
if let Stmt::Expr(cons) = &mut *stmt.cons {
self.changed = true;
tracing::debug!("Converting if statement to a form `test && cons`");
report_change!("Converting if statement to a form `test && cons`");
*s = Stmt::Expr(ExprStmt {
span: stmt.span,
expr: Box::new(stmt.test.take().make_bin(op!("&&"), *cons.expr.take())),
@ -1637,9 +1630,8 @@ where
}
BlockStmtOrExpr::Expr(v) => {
self.changed = true;
if cfg!(feature = "debug") {
tracing::debug!("Converting a body of an arrow expression to BlockStmt");
}
report_change!("Converting a body of an arrow expression to BlockStmt");
stmts.push(Stmt::Return(ReturnStmt {
span: DUMMY_SP,
arg: Some(v.take()),
@ -1772,7 +1764,7 @@ where
raw: None,
})));
self.changed = true;
tracing::debug!("injecting zero to preserve `this` in call");
report_change!("injecting zero to preserve `this` in call");
*callee = Box::new(Expr::Seq(SeqExpr {
span: callee.span(),
@ -1925,7 +1917,7 @@ where
if let Expr::Bin(bin) = e {
let expr = self.optimize_lit_cmp(bin);
if let Some(expr) = expr {
tracing::debug!("Optimizing: Literal comparison");
report_change!("Optimizing: Literal comparison");
self.changed = true;
*e = expr;
}
@ -2016,9 +2008,7 @@ where
}
let expr = self.ignore_return_value(&mut n.expr);
n.expr = expr.map(Box::new).unwrap_or_else(|| {
if cfg!(feature = "debug") {
tracing::debug!("visit_mut_expr_stmt: Dropped an expression statement");
}
report_change!("visit_mut_expr_stmt: Dropped an expression statement");
undefined(DUMMY_SP)
});
} else {
@ -2040,6 +2030,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_fn_decl(&mut self, f: &mut FnDecl) {
self.functions
.entry(f.ident.to_id())
@ -2049,10 +2040,14 @@ where
self.drop_unused_params(&mut f.function.params);
}
let ctx = Ctx { ..self.ctx };
let ctx = Ctx {
top_level: false,
..self.ctx
};
f.visit_mut_children_with(&mut *self.with_ctx(ctx));
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_fn_expr(&mut self, e: &mut FnExpr) {
if let Some(ident) = &e.ident {
self.functions
@ -2067,6 +2062,7 @@ where
e.visit_mut_children_with(self);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_for_in_stmt(&mut self, n: &mut ForInStmt) {
n.right.visit_mut_with(self);
@ -2087,6 +2083,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_for_of_stmt(&mut self, n: &mut ForOfStmt) {
n.right.visit_mut_with(self);
@ -2107,6 +2104,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_for_stmt(&mut self, s: &mut ForStmt) {
let ctx = Ctx {
executed_multiple_time: true,
@ -2149,6 +2147,7 @@ where
in_fn_like: true,
scope: n.span.ctxt,
can_inline_arguments: true,
top_level: false,
..self.ctx
};
@ -2188,6 +2187,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_if_stmt(&mut self, n: &mut IfStmt) {
n.test.visit_mut_with(self);
@ -2207,6 +2207,7 @@ where
self.merge_else_if(n);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_labeled_stmt(&mut self, n: &mut LabeledStmt) {
let ctx = Ctx {
stmt_labelled: true,
@ -2223,6 +2224,7 @@ where
self.label = old_label;
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_member_expr(&mut self, n: &mut MemberExpr) {
{
let ctx = Ctx {
@ -2271,6 +2273,7 @@ where
drop_invalid_stmts(stmts);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_new_expr(&mut self, n: &mut NewExpr) {
{
let ctx = Ctx {
@ -2289,16 +2292,18 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_opt_stmt(&mut self, s: &mut Option<Box<Stmt>>) {
s.visit_mut_children_with(self);
if let Some(Stmt::Empty(..)) = s.as_deref() {
self.changed = true;
tracing::debug!("misc: Removing empty statement");
report_change!("misc: Removing empty statement");
*s = None;
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_opt_var_decl_or_expr(&mut self, n: &mut Option<VarDeclOrExpr>) {
n.visit_mut_children_with(self);
@ -2321,6 +2326,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_param(&mut self, n: &mut Param) {
let ctx = Ctx {
var_kind: None,
@ -2338,6 +2344,7 @@ where
n.retain(|p| !p.pat.is_invalid());
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_prop(&mut self, n: &mut Prop) {
n.visit_mut_children_with(self);
@ -2358,6 +2365,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_return_stmt(&mut self, n: &mut ReturnStmt) {
n.visit_mut_children_with(self);
@ -2533,7 +2541,7 @@ where
let text = dump(&*s, false);
if text.lines().count() < 10 {
tracing::debug!("after: visit_mut_children_with: {}", text);
debug!("after: visit_mut_children_with: {}", text);
}
}
@ -2555,7 +2563,7 @@ where
_ => false,
}
{
tracing::debug!("Removing 'use strict'");
report_change!("Removing 'use strict'");
*s = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
return;
}
@ -2566,10 +2574,8 @@ where
if can_be_removed {
self.changed = true;
tracing::debug!("unused: Dropping an expression without side effect");
if cfg!(feature = "debug") {
tracing::trace!("unused: [Change] Dropping \n{}\n", dump(&*expr, false));
}
report_change!("unused: Dropping an expression without side effect");
dump_change_detail!("unused: Dropping \n{}\n", dump(&*expr, false));
*s = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
return;
}
@ -2619,7 +2625,7 @@ where
let text = dump(&*s, false);
if text.lines().count() < 10 {
tracing::debug!("after: visit_mut_stmt: {}", text);
debug!("after: visit_mut_stmt: {}", text);
}
}
@ -2678,6 +2684,7 @@ where
s.visit_mut_children_with(self);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_super_prop_expr(&mut self, n: &mut SuperPropExpr) {
if let SuperProp::Computed(c) = &mut n.prop {
let ctx = Ctx {
@ -2689,12 +2696,14 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_switch_cases(&mut self, n: &mut Vec<SwitchCase>) {
n.visit_mut_children_with(self);
self.optimize_switch_cases(n);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_switch_stmt(&mut self, n: &mut SwitchStmt) {
n.discriminant.visit_mut_with(self);
@ -2704,18 +2713,21 @@ where
}
/// We don't optimize [Tpl] contained in [TaggedTpl].
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_tagged_tpl(&mut self, n: &mut TaggedTpl) {
n.tag.visit_mut_with(self);
n.tpl.exprs.visit_mut_with(self);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_throw_stmt(&mut self, n: &mut ThrowStmt) {
n.visit_mut_children_with(self);
self.optimize_in_fn_termination(&mut n.arg);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_tpl(&mut self, n: &mut Tpl) {
debug_assert_eq!(n.exprs.len() + 1, n.quasis.len());
@ -2733,6 +2745,7 @@ where
.for_each(|expr| self.optimize_expr_in_str_ctx(&mut **expr));
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_try_stmt(&mut self, n: &mut TryStmt) {
let ctx = Ctx {
in_try_block: true,
@ -2745,6 +2758,7 @@ where
n.finalizer.visit_mut_with(self);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_unary_expr(&mut self, n: &mut UnaryExpr) {
let ctx = Ctx {
in_bang_arg: n.op == op!("!"),
@ -2760,7 +2774,7 @@ where
Expr::Lit(Lit::Num(..)) => {}
_ => {
tracing::debug!("Ignoring arg of `void`");
report_change!("Ignoring arg of `void`");
let arg = self.ignore_return_value(&mut n.arg);
n.arg = Box::new(arg.unwrap_or_else(|| make_number(DUMMY_SP, 0.0)));
@ -2769,6 +2783,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_update_expr(&mut self, n: &mut UpdateExpr) {
let ctx = Ctx {
is_update_arg: true,
@ -2778,6 +2793,7 @@ where
n.visit_mut_children_with(&mut *self.with_ctx(ctx));
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_var_decl(&mut self, n: &mut VarDecl) {
{
let ctx = Ctx {
@ -2795,7 +2811,7 @@ where
if let Some(e) = &var.init {
if is_pure_undefined(e) {
self.changed = true;
tracing::debug!(
report_change!(
"Dropping explicit initializer which evaluates to `undefined`"
);
@ -2806,6 +2822,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_var_declarator(&mut self, var: &mut VarDeclarator) {
var.name.visit_mut_with(self);
@ -2817,6 +2834,7 @@ where
self.store_var_for_prop_hoisting(var);
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_var_declarators(&mut self, vars: &mut Vec<VarDeclarator>) {
vars.retain_mut(|var| {
let had_init = var.init.is_some();
@ -2950,6 +2968,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_while_stmt(&mut self, n: &mut WhileStmt) {
{
let ctx = Ctx {
@ -2960,6 +2979,7 @@ where
}
}
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
fn visit_mut_yield_expr(&mut self, n: &mut YieldExpr) {
n.visit_mut_children_with(self);

View File

@ -48,7 +48,7 @@ where
if e.op == op!("===") || e.op == op!("!==") {
if (e.left.is_ident() || e.left.is_member()) && e.left.eq_ignore_span(&e.right) {
self.changed = true;
tracing::debug!("Reducing comparison of same variable ({})", e.op);
report_change!("Reducing comparison of same variable ({})", e.op);
e.op = if e.op == op!("===") {
op!("==")
@ -68,7 +68,7 @@ where
if lt == rt {
e.op = op!("==");
self.changed = true;
tracing::debug!(
report_change!(
"Reduced `===` to `==` because types of operands are identical"
)
}
@ -99,19 +99,19 @@ where
(Type::Num, Type::Num) => {
let l = n.left.as_number().opt()?;
let r = n.right.as_number().opt()?;
tracing::debug!("Optimizing: literal comparison => num");
report_change!("Optimizing: literal comparison => num");
return make_lit_bool(l == r);
}
(Type::Str, Type::Str) => {
let l = &n.left.as_string().opt()?;
let r = &n.right.as_string().opt()?;
tracing::debug!("Optimizing: literal comparison => str");
report_change!("Optimizing: literal comparison => str");
return make_lit_bool(l == r);
}
(_, _) => {
let l = n.left.as_pure_bool().opt()?;
let r = n.right.as_pure_bool().opt()?;
tracing::debug!("Optimizing: literal comparison => bool");
report_change!("Optimizing: literal comparison => bool");
return make_lit_bool(l == r);
}
};
@ -148,7 +148,7 @@ where
| Expr::Bin(BinExpr { op: op!(">"), .. }) => {
if let Known(Type::Bool) = arg.get_type() {
self.changed = true;
tracing::debug!("Optimizing: `!!expr` => `expr`");
report_change!("Optimizing: `!!expr` => `expr`");
*e = *arg.take();
}
}
@ -230,7 +230,7 @@ where
_ => return,
};
tracing::debug!("Compressing: `e = 3 & e` => `e &= 3`");
report_change!("Compressing: `e = 3 & e` => `e &= 3`");
self.changed = true;
e.op = op;
@ -290,13 +290,13 @@ where
if rb {
self.changed = true;
tracing::debug!("Optimizing: e && true => !!e");
report_change!("Optimizing: e && true => !!e");
self.negate_twice(&mut bin.left, false);
*e = *bin.left.take();
} else {
self.changed = true;
tracing::debug!("Optimizing: e && false => e");
report_change!("Optimizing: e && false => e");
*e = *bin.left.take();
}
@ -310,7 +310,7 @@ where
if !rb {
self.changed = true;
tracing::debug!("Optimizing: e || false => !!e");
report_change!("Optimizing: e || false => !!e");
self.negate_twice(&mut bin.left, false);
*e = *bin.left.take();
@ -370,7 +370,7 @@ where
match l {
Expr::Lit(Lit::Null(..)) => {
tracing::debug!("Removing null from lhs of ??");
report_change!("Removing null from lhs of ??");
self.changed = true;
*e = r.take();
}
@ -379,7 +379,7 @@ where
| Expr::Lit(Lit::BigInt(..))
| Expr::Lit(Lit::Bool(..))
| Expr::Lit(Lit::Regex(..)) => {
tracing::debug!("Removing rhs of ?? as lhs cannot be null nor undefined");
report_change!("Removing rhs of ?? as lhs cannot be null nor undefined");
self.changed = true;
*e = l.take();
}
@ -403,7 +403,7 @@ where
match &**arg {
Expr::Ident(arg) => {
if let Some(value) = self.typeofs.get(&arg.to_id()).cloned() {
tracing::debug!(
report_change!(
"Converting typeof of variable to literal as we know the value"
);
self.changed = true;
@ -416,7 +416,7 @@ where
}
Expr::Arrow(..) | Expr::Fn(..) => {
tracing::debug!("Converting typeof to 'function' as we know the value");
report_change!("Converting typeof to 'function' as we know the value");
self.changed = true;
*e = Expr::Lit(Lit::Str(Str {
span: *span,
@ -426,7 +426,7 @@ where
}
Expr::Array(..) | Expr::Object(..) => {
tracing::debug!("Converting typeof to 'object' as we know the value");
report_change!("Converting typeof to 'object' as we know the value");
self.changed = true;
*e = Expr::Lit(Lit::Str(Str {
span: *span,

View File

@ -139,7 +139,7 @@ where
}
}
tracing::debug!("sequences: Compressing statements as a sequences");
report_change!("sequences: Compressing statements as a sequences");
self.changed = true;
let mut exprs = vec![];
@ -415,7 +415,7 @@ where
}
}
self.changed = true;
tracing::debug!(
report_change!(
"sequences: Splitted a sequence expression to multiple expression statements"
);
*stmts = new_stmts;
@ -449,7 +449,7 @@ where
if !can_work {
return;
}
tracing::debug!("sequences: Lifting");
report_change!("sequences: Lifting");
self.changed = true;
}
@ -526,7 +526,7 @@ where
if lhs.sym == last_id.sym && lhs.span.ctxt == last_id.span.ctxt {
e.exprs.pop();
self.changed = true;
tracing::debug!("sequences: Shifting assignment");
report_change!("sequences: Shifting assignment");
}
};
}
@ -548,7 +548,7 @@ where
if let Some(last) = e.exprs.last() {
if is_pure_undefined(last) {
self.changed = true;
tracing::debug!("sequences: Shifting void");
report_change!("sequences: Shifting void");
e.exprs.pop();
let last = e.exprs.last_mut().unwrap();
@ -601,16 +601,12 @@ where
T: ModuleItemExt,
{
if !self.options.sequences() && !self.options.collapse_vars {
if cfg!(feature = "debug") {
tracing::trace!("sequences: [x] Disabled");
}
log_abort!("sequences: [x] Disabled");
return;
}
if self.ctx.in_top_level() && !self.options.top_level() {
if cfg!(feature = "debug") {
tracing::trace!("sequences: [x] Top level");
}
log_abort!("sequences: [x] Top level");
return;
}
@ -1033,19 +1029,19 @@ where
Expr::Update(..) | Expr::Arrow(..) | Expr::Fn(..) => return Ok(false),
Expr::Cond(b) => {
tracing::trace!("seq: Try test of cond");
trace_op!("seq: Try test of cond");
return self.merge_sequential_expr(a, &mut *b.test);
}
Expr::Unary(b) => {
tracing::trace!("seq: Try arg of unary");
trace_op!("seq: Try arg of unary");
return self.merge_sequential_expr(a, &mut b.arg);
}
Expr::Bin(BinExpr {
op, left, right, ..
}) => {
tracing::trace!("seq: Try left of bin");
trace_op!("seq: Try left of bin");
if self.merge_sequential_expr(a, &mut **left)? {
return Ok(true);
}
@ -1059,12 +1055,12 @@ where
_ => {}
}
tracing::trace!("seq: Try right of bin");
trace_op!("seq: Try right of bin");
return self.merge_sequential_expr(a, &mut **right);
}
Expr::Member(MemberExpr { obj, prop, .. }) if !prop.is_computed() => {
tracing::trace!("seq: Try object of member");
trace_op!("seq: Try object of member");
return self.merge_sequential_expr(a, &mut **obj);
}
@ -1073,7 +1069,7 @@ where
prop: MemberProp::Computed(c),
..
}) => {
tracing::trace!("seq: Try object of member (computed)");
trace_op!("seq: Try object of member (computed)");
if self.merge_sequential_expr(a, &mut **obj)? {
return Ok(true);
}
@ -1082,7 +1078,7 @@ where
return Ok(false);
}
tracing::trace!("seq: Try prop of member (computed)");
trace_op!("seq: Try prop of member (computed)");
return self.merge_sequential_expr(a, &mut c.expr);
}
@ -1090,14 +1086,14 @@ where
prop: SuperProp::Computed(c),
..
}) => {
tracing::trace!("seq: Try prop of member (computed)");
trace_op!("seq: Try prop of member (computed)");
return self.merge_sequential_expr(a, &mut c.expr);
}
Expr::Assign(b @ AssignExpr { op: op!("="), .. }) => {
match &mut b.left {
PatOrExpr::Expr(b_left) => {
tracing::trace!("seq: Try lhs of assign");
trace_op!("seq: Try lhs of assign");
if self.merge_sequential_expr(a, &mut **b_left)? {
return Ok(true);
}
@ -1112,7 +1108,7 @@ where
}
PatOrExpr::Pat(b_left) => match &mut **b_left {
Pat::Expr(b_left) => {
tracing::trace!("seq: Try lhs of assign");
trace_op!("seq: Try lhs of assign");
if self.merge_sequential_expr(a, &mut **b_left)? {
return Ok(true);
}
@ -1133,7 +1129,7 @@ where
return Ok(false);
}
tracing::trace!("seq: Try rhs of assign");
trace_op!("seq: Try rhs of assign");
return self.merge_sequential_expr(a, &mut b.right);
}
@ -1152,7 +1148,7 @@ where
return Err(());
}
tracing::trace!("seq: Try rhs of assign with op");
trace_op!("seq: Try rhs of assign with op");
return self.merge_sequential_expr(a, &mut b.right);
}
@ -1160,7 +1156,7 @@ where
for elem in &mut b.elems {
match elem {
Some(elem) => {
tracing::trace!("seq: Try element of array");
trace_op!("seq: Try element of array");
if self.merge_sequential_expr(a, &mut elem.expr)? {
return Ok(true);
}
@ -1183,7 +1179,7 @@ where
..
}) => {
let is_this_undefined = b_callee.is_ident();
tracing::trace!("seq: Try callee of call");
trace_op!("seq: Try callee of call");
if self.merge_sequential_expr(a, &mut **b_callee)? {
if is_this_undefined {
if let Expr::Member(..) = &**b_callee {
@ -1192,7 +1188,7 @@ where
value: 0.0,
raw: None,
})));
tracing::debug!("injecting zero to preserve `this` in call");
report_change!("injecting zero to preserve `this` in call");
*b_callee = Box::new(Expr::Seq(SeqExpr {
span: b_callee.span(),
@ -1209,7 +1205,7 @@ where
}
for arg in b_args {
tracing::trace!("seq: Try arg of call");
trace_op!("seq: Try arg of call");
if self.merge_sequential_expr(a, &mut arg.expr)? {
return Ok(true);
}
@ -1225,7 +1221,7 @@ where
Expr::New(NewExpr {
callee: b_callee, ..
}) => {
tracing::trace!("seq: Try callee of new");
trace_op!("seq: Try callee of new");
if self.merge_sequential_expr(a, &mut **b_callee)? {
return Ok(true);
}
@ -1235,7 +1231,7 @@ where
Expr::Seq(SeqExpr { exprs: b_exprs, .. }) => {
for b_expr in b_exprs {
tracing::trace!("seq: Try elem of seq");
trace_op!("seq: Try elem of seq");
if self.merge_sequential_expr(a, &mut **b_expr)? {
return Ok(true);
@ -1311,24 +1307,22 @@ where
_ => {}
}
if cfg!(feature = "debug") {
match a {
Mergable::Var(a) => {
tracing::trace!(
trace_op!(
"sequences: Trying to merge `{}` => `{}`",
crate::debug::dump(&**a, false),
crate::debug::dump(&*b, false)
);
}
Mergable::Expr(a) => {
tracing::trace!(
trace_op!(
"sequences: Trying to merge `{}` => `{}`",
crate::debug::dump(&**a, false),
crate::debug::dump(&*b, false)
);
}
}
}
if self.replace_seq_update(a, b)? {
return Ok(true);
@ -1375,15 +1369,13 @@ where
};
b.visit_with(&mut v);
if v.expr_usage != 1 || v.pat_usage != 0 {
if cfg!(feature = "debug") {
tracing::trace!(
"[X] sequences: Aborting merging of an update expression because \
of usage counts ({}, ref = {}, pat = {})",
log_abort!(
"sequences: Aborting merging of an update expression because of usage \
counts ({}, ref = {}, pat = {})",
a_id,
v.expr_usage,
v.pat_usage
);
}
return Ok(false);
}
@ -1418,7 +1410,7 @@ where
});
if replaced {
self.changed = true;
tracing::debug!(
report_change!(
"sequences: Merged update expression into another expression",
);
@ -1450,7 +1442,7 @@ where
let left_id = match left.as_ident() {
Some(v) => v,
None => {
tracing::trace!("[X] sequences: Aborting because lhs is not an id");
log_abort!("sequences: Aborting because lhs is not an id");
return Ok(false);
}
};
@ -1466,8 +1458,8 @@ where
}
if usage.declared_as_fn_expr {
tracing::trace!(
"sequences: [X] Declared as fn expr ({}, {:?})",
log_abort!(
"sequences: Declared as fn expr ({}, {:?})",
left_id.sym,
left_id.span.ctxt
);
@ -1545,7 +1537,7 @@ where
}
if used_by_b.contains(id) {
tracing::trace!("[X] sequences: Aborting because of deps");
log_abort!("[X] sequences: Aborting because of deps");
return Err(());
}
}
@ -1560,22 +1552,20 @@ where
};
b.visit_with(&mut v);
if v.expr_usage != 1 || v.pat_usage != 0 {
if cfg!(feature = "debug") {
tracing::trace!(
"[X] sequences: Aborting because of usage counts ({}{:?}, ref = {}, pat = \
{})",
log_abort!(
"sequences: Aborting because of usage counts ({}{:?}, ref = {}, pat = {})",
left_id.sym,
left_id.span.ctxt,
v.expr_usage,
v.pat_usage
);
}
return Ok(false);
}
}
self.changed = true;
tracing::debug!(
report_change!(
"sequences: Inlining sequential expressions (`{}{:?}`)",
left_id.sym,
left_id.span.ctxt
@ -1588,9 +1578,7 @@ where
replace_id_with_expr(b, left_id.to_id(), to);
if cfg!(feature = "debug") {
tracing::debug!("sequences: [Changed] {}", dump(&*b, false));
}
dump_change_detail!("sequences: {}", dump(&*b, false));
Ok(true)
}

View File

@ -38,7 +38,7 @@ where
if let Expr::Lit(Lit::Str(..)) = &*args[0].expr {
self.changed = true;
tracing::debug!(
report_change!(
"strings: Unsafely reduced `RegExp` call in a string context"
);
@ -59,7 +59,7 @@ where
if let Expr::Lit(Lit::Str(..)) = &*e.expr {
*n = *e.expr.take();
self.changed = true;
tracing::debug!("string: Removed a paren in a string context");
report_change!("string: Removed a paren in a string context");
}
return;
@ -72,7 +72,7 @@ where
let span = n.span();
self.changed = true;
tracing::debug!(
report_change!(
"strings: Converted an expression into a string literal (in string context)"
);
*n = Expr::Lit(Lit::Str(Str {
@ -86,7 +86,7 @@ where
match n {
Expr::Lit(Lit::Num(v)) => {
self.changed = true;
tracing::debug!(
report_change!(
"strings: Converted a numeric literal ({}) into a string literal (in string \
context)",
v.value
@ -106,7 +106,7 @@ where
return;
}
self.changed = true;
tracing::debug!(
report_change!(
"strings: Converted a regex (/{}/{}) into a string literal (in string context)",
v.exp,
v.flags
@ -139,7 +139,7 @@ where
.unwrap_or(false)
{
self.changed = true;
tracing::debug!(
report_change!(
"strings: Converting an unresolved reference ({}{:?}) into `undefined` \
(in string context)",
i.sym,

View File

@ -66,9 +66,9 @@ where
return;
}
tracing::debug!("switches: Removing unreachable cases from a constant switch");
report_change!("switches: Removing unreachable cases from a constant switch");
} else {
tracing::debug!("switches: Removing a constant switch");
report_change!("switches: Removing a constant switch");
}
self.changed = true;
@ -233,7 +233,7 @@ where
if !preserve_cases {
if let Some(last_non_empty) = last_non_empty {
if last_non_empty + 1 != cases.len() {
tracing::debug!("switches: Removing empty cases at the end");
report_change!("switches: Removing empty cases at the end");
self.changed = true;
cases.drain(last_non_empty + 1..);
}
@ -242,14 +242,14 @@ where
if let Some(last) = cases.last_mut() {
if let Some(Stmt::Break(BreakStmt { label: None, .. })) = last.cons.last() {
tracing::debug!("switches: Removing `break` at the end");
report_change!("switches: Removing `break` at the end");
self.changed = true;
last.cons.pop();
}
}
}
/// If a case ends with break but content is same with the consequtive case
/// If a case ends with break but content is same with the consecutive case
/// except the break statement, we merge them.
fn merge_cases_with_same_cons(&mut self, cases: &mut Vec<SwitchCase>) {
let mut stop_pos_opt = cases
@ -301,7 +301,7 @@ where
if let Some(idx) = found {
self.changed = true;
tracing::debug!("switches: Merging cases with same cons");
report_change!("switches: Merging cases with same cons");
cases[idx].cons.clear();
}
}

View File

@ -49,7 +49,7 @@ where
self.drop_unused_vars(var.span, &mut var.name, Some(init));
if var.name.is_invalid() {
tracing::debug!("unused: Removing an unused variable declarator");
report_change!("unused: Removing an unused variable declarator");
let side_effects = self.ignore_return_value(init).map(Box::new);
if let Some(e) = side_effects {
*storage_for_side_effects = Some(e);
@ -118,9 +118,7 @@ where
}
}
if cfg!(feature = "debug") {
tracing::trace!("unused: drop_unused_vars({})", dump(&*name, false));
}
trace_op!("unused: drop_unused_vars({})", dump(&*name, false));
// Top-level
if !has_mark {
@ -128,12 +126,10 @@ where
Some(VarDeclKind::Var) => {
if !self.options.top_level() && self.options.top_retain.is_empty() {
if self.ctx.in_top_level() {
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"unused: [X] Preserving `var` `{}` because it's top-level",
dump(&*name, false)
);
}
return;
}
@ -141,13 +137,11 @@ where
}
Some(VarDeclKind::Let) | Some(VarDeclKind::Const) => {
if !self.options.top_level() && self.ctx.is_top_level_for_block_level_vars() {
if cfg!(feature = "debug") {
tracing::trace!(
"unused: [X] Preserving block scoped var `{}` because it's \
top-level",
log_abort!(
"unused: Preserving block scoped var `{}` because it's top-level",
dump(&*name, false)
);
}
return;
}
}
@ -157,12 +151,10 @@ where
if let Some(scope) = self.data.scopes.get(&self.ctx.scope) {
if scope.has_eval_call || scope.has_with_stmt {
if cfg!(feature = "debug") {
tracing::trace!(
"unused: [X] Preserving `{}` because of usages",
log_abort!(
"unused: Preserving `{}` because of usages",
dump(&*name, false)
);
}
return;
}
}
@ -192,16 +184,12 @@ where
i: &mut Ident,
init: Option<&mut Expr>,
) {
if cfg!(debug_assertions) {
tracing::trace!("unused: Checking identifier `{}`", i);
}
trace_op!("unused: Checking identifier `{}`", i);
if !parent_span.has_mark(self.marks.non_top_level)
&& self.options.top_retain.contains(&i.sym)
{
if cfg!(feature = "debug") {
tracing::trace!("unused: [X] Top-retain")
}
log_abort!("unused: [X] Top-retain");
return;
}
@ -213,7 +201,7 @@ where
&& !v.declared_as_catch_param
{
self.changed = true;
tracing::debug!(
report_change!(
"unused: Dropping a variable '{}{:?}' because it is not used",
i.sym,
i.span.ctxt
@ -244,14 +232,12 @@ where
}
}
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"unused: Cannot drop ({}) because it's used",
dump(&*i, false)
);
}
}
}
pub(crate) fn should_preserve_property_access(
&self,
@ -331,9 +317,7 @@ where
return;
}
if cfg!(feature = "debug") {
tracing::trace!("unused: take_pat_if_unused({})", dump(&*name, false));
}
trace_op!("unused: take_pat_if_unused({})", dump(&*name, false));
if !name.is_ident() {
// TODO: Use smart logic
@ -488,7 +472,7 @@ where
.unwrap_or(false)
{
self.changed = true;
tracing::debug!(
report_change!(
"unused: Dropping a decl '{}{:?}' because it is not used",
ident.sym,
ident.span.ctxt
@ -525,7 +509,7 @@ where
// Update is counted as usage
if var.declared && var.is_fn_local && var.usage_count == 1 {
self.changed = true;
tracing::debug!(
report_change!(
"unused: Dropping an update '{}{:?}' because it is not used",
arg.sym,
arg.span.ctxt
@ -570,7 +554,7 @@ where
// TODO: We don't need fn_local check
if var.declared && var.is_fn_local && var.usage_count == 1 {
self.changed = true;
tracing::debug!(
report_change!(
"unused: Dropping an op-assign '{}{:?}' because it is not used",
left.id.sym,
left.id.span.ctxt
@ -616,23 +600,19 @@ where
})
.used_arguments;
if cfg!(feature = "debug") {
tracing::trace!(
trace_op!(
"unused: drop_unused_assignments: Target: `{}`",
dump(&assign.left, false)
)
}
);
if !has_mark
&& (!self.options.top_level() && self.options.top_retain.is_empty())
&& self.ctx.in_top_level()
{
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"unused: Preserving assignment to `{}` because it's top-level",
dump(&assign.left, false)
)
}
);
return;
}
@ -640,12 +620,10 @@ where
match &mut assign.left {
PatOrExpr::Expr(_) => {
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"unused: Preserving assignment to `{}` because it's an expression",
dump(&assign.left, false)
)
}
);
}
PatOrExpr::Pat(left) => {
if let Pat::Ident(i) = &**left {
@ -659,7 +637,7 @@ where
&& var.declared
&& (!var.declared_as_fn_param || !used_arguments || self.ctx.in_strict)
{
tracing::debug!(
report_change!(
"unused: Dropping assignment to var '{}{:?}', which is never used",
i.id.sym,
i.id.span.ctxt
@ -674,8 +652,7 @@ where
*e = *assign.right.take();
}
} else {
if cfg!(feature = "debug") {
tracing::trace!(
log_abort!(
"unused: Preserving assignment to `{}` because of usage: {:?}",
dump(&assign.left, false),
var
@ -686,7 +663,6 @@ where
}
}
}
}
/// Make `name` [None] if the name is not used.
#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
@ -709,7 +685,7 @@ where
if can_remove_ident {
self.changed = true;
tracing::debug!("Removing ident of an class / function expression");
report_change!("Removing ident of an class / function expression");
*name = None;
}
}
@ -731,7 +707,7 @@ where
if let Some(usage) = self.data.vars.get(&name.to_id()) {
if usage.is_fn_local && usage.declared_as_fn_param {
d.name.take();
tracing::debug!(
report_change!(
"Removing a variable statement because it's a function parameter"
);
self.changed = true;
@ -762,7 +738,7 @@ where
}
self.changed = true;
tracing::debug!(
report_change!(
"unused: Removing the name of a function expression because it's not used by it'"
);
f.ident = None;

View File

@ -26,7 +26,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("unsafe_arrows: Fn expr => arrow");
report_change!("unsafe_arrows: Fn expr => arrow");
*e = Expr::Arrow(ArrowExpr {
span: function.span,
@ -50,7 +50,7 @@ impl Pure<'_> {
if s.stmts.len() == 1 {
if let Stmt::Return(s) = &mut s.stmts[0] {
if let Some(arg) = &mut s.arg {
tracing::debug!("arrows: Optimizing the body of an arrow");
report_change!("arrows: Optimizing the body of an arrow");
*b = BlockStmtOrExpr::Expr(arg.take());
}
}
@ -90,7 +90,7 @@ impl Pure<'_> {
return;
}
self.changed = true;
tracing::debug!("Method property => arrow");
report_change!("Method property => arrow");
let arg = body
.take()

View File

@ -47,7 +47,7 @@ impl Pure<'_> {
{
return;
}
tracing::debug!("bools: Optimizing `!(a && b)` as `!a || !b`");
report_change!("bools: Optimizing `!(a && b)` as `!a || !b`");
self.negate(arg, false, false);
*e = *arg.take();
}
@ -69,7 +69,7 @@ impl Pure<'_> {
{
return;
}
tracing::debug!("bools: Optimizing `!!(a || b)` as `!a && !b`");
report_change!("bools: Optimizing `!!(a || b)` as `!a && !b`");
self.negate(arg_of_arg, false, false);
*e = *arg.take();
}
@ -111,7 +111,7 @@ impl Pure<'_> {
if should_optimize(&e.left, &e.right, self.options)
|| should_optimize(&e.right, &e.left, self.options)
{
tracing::debug!("bools: Compressing comparison of `typeof` with literal");
report_change!("bools: Compressing comparison of `typeof` with literal");
self.changed = true;
e.op = match e.op {
op!("===") => {
@ -164,9 +164,9 @@ impl Pure<'_> {
if can_remove {
if *op == op!("&&") {
tracing::debug!("booleans: Compressing `!foo && true` as `!foo`");
report_change!("booleans: Compressing `!foo && true` as `!foo`");
} else {
tracing::debug!("booleans: Compressing `!foo || false` as `!foo`");
report_change!("booleans: Compressing `!foo || false` as `!foo`");
}
self.changed = true;
*e = *left.take();
@ -237,7 +237,7 @@ impl Pure<'_> {
} else {
self.changed = true;
let span = delete.arg.span();
tracing::debug!("booleans: Compressing `delete` as sequence expression");
report_change!("booleans: Compressing `delete` as sequence expression");
*e = Expr::Seq(SeqExpr {
span,
exprs: vec![delete.arg.take(), Box::new(make_bool(span, true))],
@ -252,7 +252,7 @@ impl Pure<'_> {
if convert_to_true {
self.changed = true;
let span = delete.arg.span();
tracing::debug!("booleans: Compressing `delete` => true");
report_change!("booleans: Compressing `delete` => true");
*e = make_bool(span, true);
}
}
@ -269,7 +269,7 @@ impl Pure<'_> {
if exprs.is_empty() {
return;
}
tracing::debug!("bools: Optimizing negated sequences");
report_change!("bools: Optimizing negated sequences");
{
let last = exprs.last_mut().unwrap();
@ -323,7 +323,7 @@ impl Pure<'_> {
arg,
}) => match &mut **arg {
Expr::Lit(Lit::Num(Number { value, .. })) => {
tracing::debug!("Optimizing: number => number (in bool context)");
report_change!("Optimizing: number => number (in bool context)");
self.changed = true;
*n = Expr::Lit(Lit::Num(Number {
@ -336,7 +336,7 @@ impl Pure<'_> {
Expr::Unary(UnaryExpr {
op: op!("!"), arg, ..
}) => {
tracing::debug!("bools: !!expr => expr (in bool ctx)");
report_change!("bools: !!expr => expr (in bool ctx)");
self.changed = true;
*n = *arg.take();
}
@ -348,7 +348,7 @@ impl Pure<'_> {
op: op!("typeof"),
arg,
}) => {
tracing::debug!("Optimizing: typeof => true (in bool context)");
report_change!("Optimizing: typeof => true (in bool context)");
self.changed = true;
match &**arg {
@ -376,7 +376,7 @@ impl Pure<'_> {
Expr::Lit(Lit::Str(s)) => {
if !is_ignore {
tracing::debug!("Converting string as boolean expressions");
report_change!("Converting string as boolean expressions");
self.changed = true;
*n = Expr::Lit(Lit::Num(Number {
span: s.span,
@ -391,7 +391,7 @@ impl Pure<'_> {
return;
}
if self.options.bools {
tracing::debug!("booleans: Converting number as boolean expressions");
report_change!("booleans: Converting number as boolean expressions");
self.changed = true;
*n = Expr::Lit(Lit::Num(Number {
span: num.span,
@ -409,7 +409,7 @@ impl Pure<'_> {
}) => {
// Optimize if (a ?? false); as if (a);
if let Value::Known(false) = right.as_pure_bool() {
tracing::debug!(
report_change!(
"Dropping right operand of `??` as it's always false (in bool context)"
);
self.changed = true;
@ -426,7 +426,7 @@ impl Pure<'_> {
// `a || false` => `a` (as it will be casted to boolean anyway)
if let Value::Known(false) = right.as_pure_bool() {
tracing::debug!("bools: `expr || false` => `expr` (in bool context)");
report_change!("bools: `expr || false` => `expr` (in bool context)");
self.changed = true;
*n = *left.take();
}
@ -436,7 +436,7 @@ impl Pure<'_> {
let v = n.as_pure_bool();
if let Value::Known(v) = v {
let span = n.span();
tracing::debug!("Optimizing expr as {} (in bool context)", v);
report_change!("Optimizing expr as {} (in bool context)", v);
*n = make_bool(span, v);
}
}
@ -520,7 +520,7 @@ impl Pure<'_> {
}
if self.can_swap_bin_operands(left, right, false) {
tracing::debug!("Swapping operands of binary expession");
report_change!("Swapping operands of binary expession");
swap(left, right);
return true;
}
@ -535,7 +535,7 @@ impl Pure<'_> {
| Expr::Bin(e @ BinExpr { op: op!("<"), .. }) => {
if self.options.comparisons && self.can_swap_bin_operands(&e.left, &e.right, true) {
self.changed = true;
tracing::debug!("comparisons: Swapping operands of {}", e.op);
report_change!("comparisons: Swapping operands of {}", e.op);
e.op = if e.op == op!("<=") {
op!(">=")

View File

@ -22,7 +22,7 @@ impl Pure<'_> {
if let Value::Known(Type::Bool) = lt {
let lb = cond.cons.as_pure_bool();
if let Value::Known(true) = lb {
tracing::debug!("conditionals: `foo ? true : bar` => `!!foo || bar`");
report_change!("conditionals: `foo ? true : bar` => `!!foo || bar`");
// Negate twice to convert `test` to boolean.
self.negate_twice(&mut cond.test, false);
@ -39,7 +39,7 @@ impl Pure<'_> {
// TODO: Verify this rule.
if let Value::Known(false) = lb {
tracing::debug!("conditionals: `foo ? false : bar` => `!foo && bar`");
report_change!("conditionals: `foo ? false : bar` => `!foo && bar`");
self.changed = true;
self.negate(&mut cond.test, false, false);
@ -58,7 +58,7 @@ impl Pure<'_> {
if let Value::Known(Type::Bool) = rt {
let rb = cond.alt.as_pure_bool();
if let Value::Known(false) = rb {
tracing::debug!("conditionals: `foo ? bar : false` => `!!foo && bar`");
report_change!("conditionals: `foo ? bar : false` => `!!foo && bar`");
self.changed = true;
// Negate twice to convert `test` to boolean.
@ -74,7 +74,7 @@ impl Pure<'_> {
}
if let Value::Known(true) = rb {
tracing::debug!("conditionals: `foo ? bar : true` => `!foo || bar");
report_change!("conditionals: `foo ? bar : true` => `!foo || bar");
self.changed = true;
self.negate(&mut cond.test, false, false);
@ -105,7 +105,7 @@ impl Pure<'_> {
{
let cons_span = cons.span;
tracing::debug!("conditionals: `x ? y || z : z` => `x || y && z`");
report_change!("conditionals: `x ? y || z : z` => `x || y && z`");
self.changed = true;
*e = Expr::Bin(BinExpr {
@ -129,19 +129,17 @@ impl Pure<'_> {
return;
}
tracing::debug!("conditionals: `a ? foo : bar` => `!a ? bar : foo` (considered cost)");
report_change!("conditionals: `a ? foo : bar` => `!a ? bar : foo` (considered cost)");
let start_str = dump(&*cond, false);
self.negate(&mut cond.test, true, false);
swap(&mut cond.cons, &mut cond.alt);
if cfg!(feature = "debug") {
tracing::trace!(
dump_change_detail!(
"[Change] Negated cond: `{}` => `{}`",
start_str,
dump(&*cond, false)
)
}
);
}
/// Removes useless operands of an logical expressions.
@ -174,7 +172,7 @@ impl Pure<'_> {
// `!!b || true` => true
if let Value::Known(true) = rb {
self.changed = true;
tracing::debug!("conditionals: `!!foo || true` => `true`");
report_change!("conditionals: `!!foo || true` => `true`");
*e = make_bool(bin.span, true);
}
}

View File

@ -21,7 +21,7 @@ impl Pure<'_> {
{
if label.sym == ls.label.sym {
self.changed = true;
tracing::debug!("Dropping instant break");
report_change!("Dropping instant break");
s.take();
}
}
@ -67,7 +67,7 @@ impl Pure<'_> {
{
if ls.label.sym == label.sym {
self.changed = true;
tracing::debug!("Optimizing labeled stmt with a break to if statement");
report_change!("Optimizing labeled stmt with a break to if statement");
self.negate(test, true, false);
let test = test.take();
@ -99,7 +99,7 @@ impl Pure<'_> {
{
if ls.label.sym == label.sym {
self.changed = true;
tracing::debug!(
report_change!(
"Optimizing labeled stmt with a break in alt to if statement"
);
@ -175,7 +175,7 @@ impl Pure<'_> {
return None;
}
self.changed = true;
tracing::debug!("Remove useless continue (last stmt of a loop)");
report_change!("Remove useless continue (last stmt of a loop)");
b.stmts.remove(b.stmts.len() - 1);
if let Some(label) = &label {
@ -222,7 +222,7 @@ impl Pure<'_> {
}
Some(..) => {
tracing::debug!("Removing unreachable statements");
report_change!("Removing unreachable statements");
self.changed = true;
stmt.take();
}
@ -249,7 +249,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("Dropping useless block");
report_change!("Dropping useless block");
let mut new = vec![];
for stmt in stmts.take() {
@ -277,7 +277,7 @@ impl Pure<'_> {
arg,
})) = r.arg.as_deref_mut()
{
tracing::debug!("unused: Removing `return void` in end of a function");
report_change!("unused: Removing `return void` in end of a function");
self.changed = true;
*s = Stmt::Expr(ExprStmt {
span: *span,
@ -303,7 +303,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("dead_code: Removing dead codes");
report_change!("dead_code: Removing dead codes");
let mut new = vec![];

View File

@ -44,7 +44,7 @@ impl Pure<'_> {
}
}
tracing::debug!("drop_console: Removing console call");
report_change!("drop_console: Removing console call");
self.changed = true;
*e = *undefined(DUMMY_SP);
}

View File

@ -88,7 +88,7 @@ impl Pure<'_> {
if args.is_empty() && params.is_empty() {
self.changed = true;
tracing::debug!("Flattening iife");
report_change!("Flattening iife");
*s = Stmt::Block(body.take());
}
}
@ -157,7 +157,7 @@ impl Pure<'_> {
match call.args.len() {
0 => {
self.changed = true;
tracing::debug!("evaluate: Dropping array.slice call");
report_change!("evaluate: Dropping array.slice call");
*e = *obj.take();
}
1 => {
@ -165,7 +165,7 @@ impl Pure<'_> {
let start = start.floor() as usize;
self.changed = true;
tracing::debug!("evaluate: Reducing array.slice({}) call", start);
report_change!("evaluate: Reducing array.slice({}) call", start);
if start >= arr.elems.len() {
*e = Expr::Array(ArrayLit {
@ -189,7 +189,7 @@ impl Pure<'_> {
if let Value::Known(end) = end {
let end = end.floor() as usize;
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Reducing array.slice({}, {}) call",
start,
end
@ -216,7 +216,7 @@ impl Pure<'_> {
if self.options.unsafe_passes && &*method_name.sym == "toString" && arr.elems.len() == 1
{
tracing::debug!("evaluate: Reducing array.toString() call");
report_change!("evaluate: Reducing array.toString() call");
self.changed = true;
*obj = arr.elems[0]
.take()
@ -274,9 +274,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!(
"evaluate: Reduced `function.valueOf()` into a function expression"
);
report_change!("evaluate: Reduced `function.valueOf()` into a function expression");
*e = *obj.take();
return;
@ -292,7 +290,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("evaluate: Reduced `function.toString()` into a string");
report_change!("evaluate: Reduced `function.toString()` into a string");
*e = Str {
span: call.span,
@ -321,7 +319,7 @@ impl Pure<'_> {
}) = &**callee
{
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Reducing a call to `Number` into an unary operation"
);
@ -372,7 +370,7 @@ impl Pure<'_> {
let value = num_to_fixed(num.value, precision + 1);
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Evaluating `{}.toFixed({})` as `{}`",
num,
precision,
@ -399,7 +397,7 @@ impl Pure<'_> {
//
if is_pure_undefined_or_null(obj) {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Reduced an optional chaining operation because object is \
always null or undefined"
);
@ -411,7 +409,7 @@ impl Pure<'_> {
OptChainBase::Call(OptCall { span, callee, .. }) => {
if is_pure_undefined_or_null(callee) {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Reduced a call expression with optional chaining operation \
because object is always null or undefined"
);
@ -441,7 +439,7 @@ impl Pure<'_> {
// foo || 1 => foo, 1
if v {
self.changed = true;
tracing::debug!("evaluate: `foo || true` => `foo, 1`");
report_change!("evaluate: `foo || true` => `foo, 1`");
*e = Expr::Seq(SeqExpr {
span: bin_expr.span,
@ -450,7 +448,7 @@ impl Pure<'_> {
e.visit_mut_with(self);
} else {
self.changed = true;
tracing::debug!("evaluate: `foo || false` => `foo` (bool ctx)");
report_change!("evaluate: `foo || false` => `foo` (bool ctx)");
*e = *bin_expr.left.take();
}
@ -460,7 +458,7 @@ impl Pure<'_> {
// 1 || foo => foo
if let Value::Known(true) = bin_expr.left.as_pure_bool() {
self.changed = true;
tracing::debug!("evaluate: `true || foo` => `foo`");
report_change!("evaluate: `true || foo` => `foo`");
*e = *bin_expr.right.take();
}
@ -470,12 +468,12 @@ impl Pure<'_> {
if let Value::Known(v) = bin_expr.right.as_pure_bool() {
if v {
self.changed = true;
tracing::debug!("evaluate: `foo && true` => `foo` (bool ctx)");
report_change!("evaluate: `foo && true` => `foo` (bool ctx)");
*e = *bin_expr.left.take();
} else {
self.changed = true;
tracing::debug!("evaluate: `foo && false` => `foo, false`");
report_change!("evaluate: `foo && false` => `foo, false`");
*e = Expr::Seq(SeqExpr {
span: bin_expr.span,
@ -488,7 +486,7 @@ impl Pure<'_> {
if let Value::Known(true) = bin_expr.left.as_pure_bool() {
self.changed = true;
tracing::debug!("evaluate: `true && foo` => `foo`");
report_change!("evaluate: `true && foo` => `foo`");
*e = *bin_expr.right.take();
}
@ -540,7 +538,7 @@ impl Pure<'_> {
if let Pat::Ident(a_left) = &**a_left {
if let Expr::Ident(b_id) = b {
if b_id.to_id() == a_left.id.to_id() {
tracing::debug!("evaluate: Trivial: `{}`", a_left.id);
report_change!("evaluate: Trivial: `{}`", a_left.id);
*b = *a_right.clone();
self.changed = true;
}
@ -631,7 +629,7 @@ impl Pure<'_> {
match c {
Some(v) => {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Evaluated `charCodeAt` of a string literal as `{}`",
v
);
@ -643,7 +641,7 @@ impl Pure<'_> {
}
None => {
self.changed = true;
tracing::debug!(
report_change!(
"evaluate: Evaluated `charCodeAt` of a string literal as `NaN`",
);
*e = Expr::Ident(Ident::new(
@ -659,7 +657,7 @@ impl Pure<'_> {
};
self.changed = true;
tracing::debug!("evaluate: Evaluated `{}` of a string literal", method);
report_change!("evaluate: Evaluated `{}` of a string literal", method);
*e = Expr::Lit(Lit::Str(Str {
value: new_val.into(),
..s

View File

@ -80,7 +80,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!(
report_change!(
"if_return: Negating `foo` in `if (foo) return; bar()` to make it `if (!foo) bar()`"
);

View File

@ -16,7 +16,7 @@ impl Pure<'_> {
match s {
Stmt::While(stmt) => {
self.changed = true;
tracing::debug!("loops: Converting a while loop to a for loop");
report_change!("loops: Converting a while loop to a for loop");
*s = Stmt::For(ForStmt {
span: stmt.span,
init: None,
@ -29,7 +29,7 @@ impl Pure<'_> {
let val = stmt.test.as_pure_bool();
if let Value::Known(true) = val {
self.changed = true;
tracing::debug!("loops: Converting an always-true do-while loop to a for loop");
report_change!("loops: Converting an always-true do-while loop to a for loop");
*s = Stmt::For(ForStmt {
span: stmt.span,
@ -91,7 +91,7 @@ impl Pure<'_> {
}
}
tracing::debug!("loops: Optimizing a for loop with an if-then-break");
report_change!("loops: Optimizing a for loop with an if-then-break");
first.take();
return None;
@ -122,7 +122,7 @@ impl Pure<'_> {
}
}
tracing::debug!("loops: Optimizing a for loop with an if-else-break");
report_change!("loops: Optimizing a for loop with an if-else-break");
*first = *cons.take();
return None;
@ -166,7 +166,7 @@ impl Pure<'_> {
// will remove block and with the next pass we can apply
// this pass.
self.changed = true;
tracing::debug!("loops: Compressing for-if-break into a for statement");
report_change!("loops: Compressing for-if-break into a for statement");
// We negate because this `test` is used as a condition for `break`.
self.negate(test, true, false);

View File

@ -27,7 +27,7 @@ impl Pure<'_> {
if let Some(e) = s.arg.as_deref() {
if is_pure_undefined(e) {
self.changed = true;
tracing::debug!("Dropped `undefined` from `return undefined`");
report_change!("Dropped `undefined` from `return undefined`");
s.arg.take();
}
}
@ -36,7 +36,7 @@ impl Pure<'_> {
pub(super) fn remove_useless_return(&mut self, stmts: &mut Vec<Stmt>) {
if let Some(Stmt::Return(ReturnStmt { arg: None, .. })) = stmts.last() {
self.changed = true;
tracing::debug!("misc: Removing useless return");
report_change!("misc: Removing useless return");
stmts.pop();
}
}
@ -82,9 +82,7 @@ impl Pure<'_> {
Stmt::Block(s) => self.drop_return_value(&mut s.stmts),
Stmt::Return(ret) => {
self.changed = true;
if cfg!(feature = "debug") {
tracing::trace!("Dropping `return` token");
}
report_change!("Dropping `return` token");
let span = ret.span;
match ret.arg.take() {
@ -177,7 +175,7 @@ impl Pure<'_> {
}
Expr::Call(CallExpr { span, args, .. }) if span.has_mark(self.marks.pure) => {
tracing::debug!("ignore_return_value: Dropping a pure call");
report_change!("ignore_return_value: Dropping a pure call");
self.changed = true;
let new = self.make_ignored_expr(args.take().into_iter().map(|arg| arg.expr));
@ -191,7 +189,7 @@ impl Pure<'_> {
tpl: Tpl { exprs, .. },
..
}) if span.has_mark(self.marks.pure) => {
tracing::debug!("ignore_return_value: Dropping a pure call");
report_change!("ignore_return_value: Dropping a pure call");
self.changed = true;
let new = self.make_ignored_expr(exprs.take().into_iter());
@ -201,7 +199,7 @@ impl Pure<'_> {
}
Expr::New(NewExpr { span, args, .. }) if span.has_mark(self.marks.pure) => {
tracing::debug!("ignore_return_value: Dropping a pure call");
report_change!("ignore_return_value: Dropping a pure call");
self.changed = true;
let new =
@ -232,13 +230,13 @@ impl Pure<'_> {
|| (self.options.unused && opts.drop_global_refs_if_unused)
{
if is_global_var(&i.sym) {
tracing::debug!("Dropping a reference to a global variable");
report_change!("Dropping a reference to a global variable");
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
return;
}
}
} else {
tracing::debug!("Dropping an identifier as it's declared");
report_change!("Dropping an identifier as it's declared");
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
return;
}
@ -262,7 +260,7 @@ impl Pure<'_> {
);
if arg.is_invalid() {
tracing::debug!("Dropping an unary expression");
report_change!("Dropping an unary expression");
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
return;
}
@ -277,7 +275,7 @@ impl Pure<'_> {
self.ignore_return_value(&mut be.right, opts);
if be.right.is_invalid() {
tracing::debug!("Dropping the RHS of a binary expression ('&&' / '||')");
report_change!("Dropping the RHS of a binary expression ('&&' / '||')");
*e = *be.left.take();
return;
}
@ -300,7 +298,7 @@ impl Pure<'_> {
Expr::Ident(i) => {
if let Some(bindings) = self.bindings.as_deref() {
if bindings.contains(&i.to_id()) {
tracing::debug!("Dropping an identifier as it's declared");
report_change!("Dropping an identifier as it's declared");
self.changed = true;
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
@ -310,7 +308,7 @@ impl Pure<'_> {
}
Expr::Lit(Lit::Null(..) | Lit::BigInt(..) | Lit::Bool(..) | Lit::Regex(..)) => {
tracing::debug!("Dropping literals");
report_change!("Dropping literals");
self.changed = true;
*e = Expr::Invalid(Invalid { span: DUMMY_SP });
@ -376,7 +374,7 @@ impl Pure<'_> {
if matches!(*bin.left, Expr::Await(..) | Expr::Update(..)) {
self.changed = true;
tracing::debug!("ignore_return_value: Compressing binary as seq");
report_change!("ignore_return_value: Compressing binary as seq");
*e = Expr::Seq(SeqExpr {
span,
exprs: vec![bin.left.take(), bin.right.take()],

View File

@ -7,7 +7,7 @@ use swc_common::{collections::AHashSet, pass::Repeated, util::take::Take, DUMMY_
use swc_ecma_ast::*;
use swc_ecma_utils::{collect_decls, undefined};
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
use tracing::{span, Level};
use tracing::{debug, span, Level};
use self::{ctx::Ctx, misc::DropOpts};
use crate::{
@ -551,7 +551,7 @@ impl VisitMut for Pure<'_> {
e.exprs.retain(|e| {
if e.is_invalid() {
self.changed = true;
tracing::debug!("Removing invalid expr in seq");
report_change!("Removing invalid expr in seq");
return false;
}
@ -615,7 +615,7 @@ impl VisitMut for Pure<'_> {
let text = dump(&*s, false);
if text.lines().count() < 10 {
tracing::debug!("after: visit_mut_children_with: {}", text);
debug!("after: visit_mut_children_with: {}", text);
}
}
@ -623,7 +623,7 @@ impl VisitMut for Pure<'_> {
if let Stmt::Debugger(..) = s {
self.changed = true;
*s = Stmt::Empty(EmptyStmt { span: DUMMY_SP });
tracing::debug!("drop_debugger: Dropped a debugger statement");
report_change!("drop_debugger: Dropped a debugger statement");
return;
}
}
@ -649,7 +649,7 @@ impl VisitMut for Pure<'_> {
let text = dump(&*s, false);
if text.lines().count() < 10 {
tracing::debug!("after: visit_mut_stmt: {}", text);
debug!("after: visit_mut_stmt: {}", text);
}
}

View File

@ -9,7 +9,7 @@ impl Pure<'_> {
let value = if value.is_empty() { 0f64 } else { 1f64 };
self.changed = true;
tracing::debug!("numbers: Converting a string literal to {:?}", value);
report_change!("numbers: Converting a string literal to {:?}", value);
*e = Expr::Lit(Lit::Num(Number {
span: *span,
value,
@ -37,7 +37,7 @@ impl Pure<'_> {
..
}) => {
self.changed = true;
tracing::debug!("numbers: Lifting `-`");
report_change!("numbers: Lifting `-`");
*e = Expr::Unary(UnaryExpr {
span: arg.span,
@ -54,7 +54,7 @@ impl Pure<'_> {
Expr::Lit(Lit::Num(Number { span, value, .. })) => {
if value.is_sign_negative() {
self.changed = true;
tracing::debug!("numbers: Lifting `-` in a literal");
report_change!("numbers: Lifting `-` in a literal");
*e = Expr::Unary(UnaryExpr {
span: arg.span,

View File

@ -25,7 +25,7 @@ impl Pure<'_> {
match &*c.expr {
Expr::Lit(Lit::Str(s)) if is_valid_identifier(&s.value, true) => {
self.changed = true;
tracing::debug!(
report_change!(
"properties: Computed member => member expr with identifier as a prop"
);
@ -79,7 +79,7 @@ impl Pure<'_> {
if is_valid_identifier(&s.value, false) {
self.changed = true;
tracing::debug!("misc: Optimizing string property name");
report_change!("misc: Optimizing string property name");
*name = PropName::Ident(Ident {
span: s.span,
sym: s.value.clone(),
@ -165,7 +165,7 @@ impl Pure<'_> {
Prop::Shorthand(_) => {}
Prop::KeyValue(p) => {
if prop_name_eq(&p.key, &key.sym) {
tracing::debug!(
report_change!(
"properties: Inlining a key-value property `{}`",
key.sym
);

View File

@ -25,7 +25,7 @@ impl Pure<'_> {
PatOrExpr::Pat(left) => {
if let Pat::Ident(left) = &**left {
if left.id.sym == ident.sym && left.id.span.ctxt == ident.span.ctxt {
tracing::debug!(
report_change!(
"drop_useless_ident_ref_in_seq: Dropping `{}` as it's useless",
left.id
);
@ -52,7 +52,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("sequences: Lifting sequence in a binary expression");
report_change!("sequences: Lifting sequence in a binary expression");
let left_last = left.exprs.pop().unwrap();
@ -97,7 +97,7 @@ impl Pure<'_> {
new_seq.extend(test.exprs.drain(..test.exprs.len() - 1));
self.changed = true;
tracing::debug!("sequences: Lifting sequences in a assignment with cond expr");
report_change!("sequences: Lifting sequences in a assignment with cond expr");
let new_cond = CondExpr {
span: cond.span,
test: test.exprs.pop().unwrap(),
@ -188,7 +188,7 @@ impl Pure<'_> {
});
b.take();
self.changed = true;
tracing::debug!(
report_change!(
"sequences: Reducing `(a = foo, a.call())` to `((a = foo).call())`"
);

View File

@ -55,9 +55,7 @@ impl Pure<'_> {
return;
}
if cfg!(feature = "debug") {
tracing::debug!("compress_tpl");
}
trace_op!("compress_tpl");
let mut quasis = vec![];
let mut exprs = vec![];
@ -112,7 +110,7 @@ impl Pure<'_> {
if let Some(l_last) = l.quasis.last_mut() {
self.changed = true;
tracing::debug!(
report_change!(
"template: Concatted a string (`{}`) on rhs of `+` to a template literal",
rs.value
);
@ -130,7 +128,7 @@ impl Pure<'_> {
if let Some(r_first) = r.quasis.first_mut() {
self.changed = true;
tracing::debug!(
report_change!(
"template: Prepended a string (`{}`) on lhs of `+` to a template literal",
ls.value
);
@ -162,7 +160,7 @@ impl Pure<'_> {
debug_assert!(l.quasis.len() == l.exprs.len() + 1, "{:?} is invalid", l);
self.changed = true;
tracing::debug!("strings: Merged to template literals");
report_change!("strings: Merged to template literals");
}
_ => {}
}
@ -194,7 +192,7 @@ impl Pure<'_> {
let left_span = left.span;
self.changed = true;
tracing::debug!(
report_change!(
"strings: Concatting `{} + {}` to `{}`",
second_str,
third_str,
@ -237,7 +235,7 @@ impl Pure<'_> {
})) = &**left
{
self.changed = true;
tracing::debug!(
report_change!(
"string: Dropping empty string literal (in lhs) because it does not \
changes type"
);
@ -252,7 +250,7 @@ impl Pure<'_> {
})) = &**right
{
self.changed = true;
tracing::debug!(
report_change!(
"string: Dropping empty string literal (in rhs) because it does not \
changes type"
);

View File

@ -53,7 +53,7 @@ impl Pure<'_> {
}
}
tracing::debug!("join_vars: Joining variables");
report_change!("join_vars: Joining variables");
self.changed = true;
let mut cur: Option<VarDecl> = None;
@ -209,7 +209,7 @@ impl Pure<'_> {
}
self.changed = true;
tracing::debug!("collapse_vars: Collapsing variables without an initializer");
report_change!("collapse_vars: Collapsing variables without an initializer");
let vars = {
let mut v = VarMover {

View File

@ -54,7 +54,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
unreachable!()
}
};
tracing::debug!("negate: binary");
report_change!("negate: binary");
return true;
}
@ -64,7 +64,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
op: op @ op!("&&"),
..
}) if is_ok_to_negate_rhs(right) => {
tracing::debug!("negate: a && b => !a || !b");
trace_op!("negate: a && b => !a || !b");
let a = negate_inner(&mut **left, in_bool_ctx, false);
let b = negate_inner(&mut **right, in_bool_ctx, is_ret_val_ignored);
@ -78,7 +78,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
op: op @ op!("||"),
..
}) if is_ok_to_negate_rhs(right) => {
tracing::debug!("negate: a || b => !a && !b");
trace_op!("negate: a || b => !a && !b");
let a = negate_inner(&mut **left, in_bool_ctx, false);
let b = negate_inner(&mut **right, in_bool_ctx, is_ret_val_ignored);
@ -89,7 +89,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
Expr::Cond(CondExpr { cons, alt, .. })
if is_ok_to_negate_for_cond(cons) && is_ok_to_negate_for_cond(alt) =>
{
tracing::debug!("negate: cond");
trace_op!("negate: cond");
let a = negate_inner(&mut **cons, in_bool_ctx, false);
let b = negate_inner(&mut **alt, in_bool_ctx, is_ret_val_ignored);
@ -98,7 +98,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
Expr::Seq(SeqExpr { exprs, .. }) => {
if let Some(last) = exprs.last_mut() {
tracing::debug!("negate: seq");
trace_op!("negate: seq");
return negate_inner(&mut **last, in_bool_ctx, is_ret_val_ignored);
}
@ -115,7 +115,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
{
match &mut **arg {
Expr::Unary(UnaryExpr { op: op!("!"), .. }) => {
tracing::debug!("negate: !!bool => !bool");
report_change!("negate: !!bool => !bool");
*e = *arg.take();
return true;
}
@ -124,19 +124,19 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
op: op!("instanceof"),
..
}) => {
tracing::debug!("negate: !bool => bool");
report_change!("negate: !bool => bool");
*e = *arg.take();
return true;
}
_ => {
if in_bool_ctx {
tracing::debug!("negate: !expr => expr (in bool context)");
report_change!("negate: !expr => expr (in bool context)");
*e = *arg.take();
return true;
}
if is_ret_val_ignored {
tracing::debug!("negate: !expr => expr (return value ignored)");
report_change!("negate: !expr => expr (return value ignored)");
*e = *arg.take();
return true;
}
@ -145,12 +145,12 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
}
if is_ret_val_ignored {
tracing::debug!("negate: noop because it's ignored");
log_abort!("negate: noop because it's ignored");
*e = *arg;
false
} else {
tracing::debug!("negate: e => !e");
report_change!("negate: e => !e");
*e = Expr::Unary(UnaryExpr {
span: DUMMY_SP,
@ -158,9 +158,7 @@ fn negate_inner(e: &mut Expr, in_bool_ctx: bool, is_ret_val_ignored: bool) -> bo
arg,
});
if cfg!(feature = "debug") {
tracing::trace!("[Change] Negated `{}` as `{}`", start_str, dump(&*e, false));
}
dump_change_detail!("Negated `{}` as `{}`", start_str, dump(&*e, false));
true
}
@ -343,7 +341,7 @@ pub(crate) fn negate_cost(e: &Expr, in_bool_ctx: bool, is_ret_val_ignored: bool)
// Print more info while testing negate_cost
if cfg!(test) {
tracing::debug!(
trace_op!(
"negation cost of `{}` = {}",
dump(&e.clone().fold_with(&mut as_folder(fixer(None))), true),
cost,
@ -355,15 +353,13 @@ pub(crate) fn negate_cost(e: &Expr, in_bool_ctx: bool, is_ret_val_ignored: bool)
let cost = cost(e, in_bool_ctx, None, is_ret_val_ignored);
if cfg!(feature = "debug") {
tracing::trace!(
trace_op!(
"negation cost of `{}` = {}\nin_book_ctx={:?}\nis_ret_val_ignored={:?}",
dump(&e.clone().fold_with(&mut as_folder(fixer(None))), false),
cost,
in_bool_ctx,
is_ret_val_ignored
);
}
cost
}

View File

@ -43,6 +43,8 @@ use crate::{
},
};
#[macro_use]
mod macros;
mod analyzer;
mod compress;
mod debug;

View File

@ -0,0 +1,42 @@
/// Used when something is modified.
macro_rules! report_change {
($($tt:tt)+) => {{
tracing::debug!(
kind = "change",
$($tt)*
);
}};
}
/// Used when a function decided to give up.
macro_rules! log_abort {
($($tt:tt)+) => {{
if cfg!(feature = "debug") {
tracing::trace!(
kind = "abort",
$($tt)*
);
}
}};
}
macro_rules! dump_change_detail {
($($tt:tt)+) => {{
if cfg!(feature = "debug") {
tracing::trace!(
kind = "detail",
$($tt)*
);
}
}};
}
macro_rules! trace_op {
($($tt:tt)+) => {{
if cfg!(feature = "debug") {
tracing::trace!(
$($tt)*
);
}
}};
}

View File

@ -292,27 +292,25 @@ where
}
if external_bindings.contains(used_id) {
if cfg!(feature = "debug") {
tracing::debug!(
trace_op!(
"bundle: Due to {}{:?} (top-level), it's not a bundle",
used_id.0,
used_id.1
);
}
return false;
}
if used_id.1 == top_level_ctxt {
// if cfg!(feature = "debug") {
// tracing::debug!("bundle: Ignoring {}{:?} (top level)", used_id.0,
// debug!("bundle: Ignoring {}{:?} (top level)", used_id.0,
// used_id.1); }
continue;
}
if bindings.contains(used_id) {
// if cfg!(feature = "debug") {
// tracing::debug!(
// debug!(
// "bundle: Ignoring {}{:?} (local to fn)",
// used_id.0,
// used_id.1
@ -321,13 +319,12 @@ where
continue;
}
if cfg!(feature = "debug") {
tracing::debug!(
trace_op!(
"bundle: Due to {}{:?}, it's not a bundle",
used_id.0,
used_id.1
);
}
return false;
}

View File

@ -499,9 +499,7 @@ fn value_to_expr(v: Value) -> Box<Expr> {
value,
}))),
Value::Number(v) => {
if cfg!(feature = "debug") {
tracing::debug!("Creating a numeric literal from value");
}
trace_op!("Creating a numeric literal from value");
Box::new(Expr::Lit(Lit::Num(Number {
span: DUMMY_SP,

View File

@ -1,5 +1,6 @@
use fxhash::{AHashMap, AHashSet};
use std::cell::RefCell;
use fxhash::{AHashMap, AHashSet};
use swc_atoms::JsWord;
use swc_common::{SyntaxContext, DUMMY_SP};
use swc_ecma_ast::*;
@ -100,7 +101,7 @@ impl Visit for VarAnalyzer<'_> {
}
fn visit_ident(&mut self, i: &Ident) {
tracing::trace!("hygiene/vars: Found {}", i);
trace!("hygiene/vars: Found {}", i);
self.cur.add(i);
}

View File

@ -44,7 +44,7 @@ impl PostcompressOptimizer<'_> {
op!("&&")
};
tracing::debug!(
report_change!(
"bools: `(a {} !b)` => `(a {} b)` (in bool context)",
*op,
new_op

View File

@ -16,9 +16,7 @@ pub(crate) mod unit;
///
pub(crate) fn make_number(span: Span, value: f64) -> Expr {
if cfg!(feature = "debug") {
tracing::debug!("Creating a numeric literal");
}
trace_op!("Creating a numeric literal");
Expr::Lit(Lit::Num(Number {
span,
value,
@ -94,9 +92,8 @@ impl ModuleItemExt for ModuleItem {
/// - `!0` for true
/// - `!1` for false
pub(crate) fn make_bool(span: Span, value: bool) -> Expr {
if cfg!(feature = "debug") {
tracing::debug!("Creating a boolean literal");
}
trace_op!("Creating a boolean literal");
Expr::Unary(UnaryExpr {
span,
op: op!("!"),

View File

@ -455,9 +455,6 @@ issue_2719/warn/input.js
issue_281/collapse_vars_constants/input.js
issue_281/inner_var_for_in_1/input.js
issue_281/issue_1758/input.js
issue_281/pure_annotation_1/input.js
issue_281/pure_annotation_2/input.js
issue_281/ref_scope/input.js
issue_2871/comparison_with_undefined/input.js
issue_368/collapse/input.js
issue_417/test_unexpected_crash/input.js

View File

@ -788,6 +788,9 @@ issue_281/negate_iife_4/input.js
issue_281/negate_iife_5/input.js
issue_281/negate_iife_5_off/input.js
issue_281/negate_iife_issue_1073/input.js
issue_281/pure_annotation_1/input.js
issue_281/pure_annotation_2/input.js
issue_281/ref_scope/input.js
issue_281/safe_undefined/input.js
issue_281/wrap_iife/input.js
issue_281/wrap_iife_in_expression/input.js

View File

@ -1,3 +1,3 @@
(function () {
/*#__PURE__*/ (function () {
console.log("hello");
})();

View File

@ -1,3 +1,3 @@
(function (n) {
/*#__PURE__*/ (function (n) {
console.log("hello", n);
})(42);

View File

@ -1,9 +1,5 @@
console.log(
(function () {
var a = 1,
b = 2,
c = 3;
b = b /= a = c++;
console.log(function() {
var a = 1, b = 2, c = 3;
var a = c++, b = b /= a;
return a + b;
})()
);
}());

View File

@ -75,6 +75,7 @@
"impls",
"indexmap",
"initializers",
"inlinable",
"inlines",
"instanceof",
"interner",