mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
refactor(es/minifier): Cleanup (#4020)
**Description:** - `Optimizer.data`: `Option<ProgramData>` => `ProgramData`. - `Optimizer.done`: Remvoed. - `Optimzer.done_ctxt`: Removed. - `Pure`: Add `data: Option<&'a ProgramData>`.
This commit is contained in:
parent
1902682bed
commit
3173047f58
@ -325,6 +325,7 @@ where
|
||||
|
||||
let mut visitor = pure_optimizer(
|
||||
self.options,
|
||||
None,
|
||||
self.marks,
|
||||
M::force_str_for_tpl(),
|
||||
self.pass > 1,
|
||||
@ -348,12 +349,12 @@ where
|
||||
{
|
||||
let _timer = timer!("apply full optimizer");
|
||||
|
||||
let mut data = analyze(&*n, Some(self.marks));
|
||||
|
||||
// TODO: reset_opt_flags
|
||||
//
|
||||
// This is swc version of `node.optimize(this);`.
|
||||
|
||||
let mut data = analyze(&*n, Some(self.marks));
|
||||
|
||||
let mut visitor = optimizer(
|
||||
self.marks,
|
||||
self.options,
|
||||
|
@ -78,8 +78,8 @@ where
|
||||
}) => true,
|
||||
Pat::Ident(i) => self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|v| v.vars.get(&i.id.to_id()))
|
||||
.vars
|
||||
.get(&i.id.to_id())
|
||||
.map(|v| v.declared_count >= 2)
|
||||
.unwrap_or(false),
|
||||
_ => true,
|
||||
|
@ -136,9 +136,7 @@ where
|
||||
) => {
|
||||
// TODO?
|
||||
if let Expr::Ident(arg) = &**arg {
|
||||
if let Some(usage) =
|
||||
o.data.as_ref().and_then(|data| data.vars.get(&arg.to_id()))
|
||||
{
|
||||
if let Some(usage) = o.data.vars.get(&arg.to_id()) {
|
||||
if !usage.declared {
|
||||
return false;
|
||||
}
|
||||
|
@ -31,11 +31,7 @@ where
|
||||
},
|
||||
};
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&left.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&left.to_id()) {
|
||||
if !usage.declared
|
||||
|| !usage.is_fn_local
|
||||
|| usage.assign_count != 1
|
||||
|
@ -12,7 +12,6 @@ use crate::{
|
||||
util::{always_terminates, negate_cost},
|
||||
},
|
||||
mode::Mode,
|
||||
util::SpanExt,
|
||||
DISABLE_BUGGY_PASSES,
|
||||
};
|
||||
|
||||
@ -296,9 +295,9 @@ where
|
||||
);
|
||||
self.changed = true;
|
||||
*s = Stmt::Expr(ExprStmt {
|
||||
span: stmt.span.with_mark(self.done),
|
||||
span: stmt.span,
|
||||
expr: Box::new(Expr::Cond(CondExpr {
|
||||
span: DUMMY_SP.with_ctxt(self.done_ctxt),
|
||||
span: DUMMY_SP,
|
||||
test: stmt.test.take(),
|
||||
cons: Box::new(cons.take()),
|
||||
alt: Box::new(alt.take()),
|
||||
@ -353,10 +352,8 @@ where
|
||||
|
||||
match (cons, alt) {
|
||||
(Expr::Call(cons), Expr::Call(alt)) => {
|
||||
if let Some(data) = &self.data {
|
||||
if data.contains_unresolved(&**test) {
|
||||
return None;
|
||||
}
|
||||
if self.data.contains_unresolved(&**test) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let cons_callee = cons.callee.as_expr().and_then(|e| e.as_ident())?;
|
||||
@ -368,8 +365,8 @@ where
|
||||
|
||||
let side_effect_free = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&cons_callee.to_id()))
|
||||
.vars
|
||||
.get(&cons_callee.to_id())
|
||||
.map(|v| v.is_fn_local && v.declared)
|
||||
.unwrap_or(false);
|
||||
|
||||
@ -453,7 +450,7 @@ where
|
||||
arguments is 1"
|
||||
);
|
||||
return Some(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP.with_ctxt(self.done_ctxt),
|
||||
span: DUMMY_SP,
|
||||
callee: cons.callee.take(),
|
||||
args,
|
||||
type_args: Default::default(),
|
||||
@ -463,7 +460,7 @@ where
|
||||
if !side_effect_free && is_for_if_stmt {
|
||||
tracing::debug!("Compressing if into cond while preserving side effects");
|
||||
return Some(Expr::Cond(CondExpr {
|
||||
span: DUMMY_SP.with_ctxt(self.done_ctxt),
|
||||
span: DUMMY_SP,
|
||||
test: test.take(),
|
||||
cons: Box::new(Expr::Call(cons.take())),
|
||||
alt: Box::new(Expr::Call(alt.take())),
|
||||
@ -474,10 +471,8 @@ where
|
||||
}
|
||||
|
||||
(Expr::New(cons), Expr::New(alt)) => {
|
||||
if let Some(data) = &self.data {
|
||||
if data.contains_unresolved(&**test) {
|
||||
return None;
|
||||
}
|
||||
if self.data.contains_unresolved(&**test) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// TODO: Handle new expression with no args.
|
||||
@ -521,7 +516,7 @@ where
|
||||
there's no side effect and the number of arguments is 1"
|
||||
);
|
||||
return Some(Expr::New(NewExpr {
|
||||
span: DUMMY_SP.with_ctxt(self.done_ctxt),
|
||||
span: DUMMY_SP,
|
||||
callee: cons.callee.take(),
|
||||
args: Some(args),
|
||||
type_args: Default::default(),
|
||||
@ -555,7 +550,7 @@ where
|
||||
(Expr::Cond(cons), alt) if (*cons.alt).eq_ignore_span(&*alt) => {
|
||||
tracing::debug!("conditionals: a ? b ? c() : d() : d() => a && b ? c() : d()");
|
||||
Some(Expr::Cond(CondExpr {
|
||||
span: DUMMY_SP.with_ctxt(self.done_ctxt),
|
||||
span: DUMMY_SP,
|
||||
test: Box::new(Expr::Bin(BinExpr {
|
||||
span: DUMMY_SP,
|
||||
left: test.take(),
|
||||
|
@ -52,8 +52,8 @@ where
|
||||
//
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&lhs.to_id()))
|
||||
.vars
|
||||
.get(&lhs.to_id())
|
||||
.map(|var| var.is_fn_local && !var.declared_as_fn_param)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
@ -75,8 +75,8 @@ where
|
||||
//
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&lhs.to_id()))
|
||||
.vars
|
||||
.get(&lhs.to_id())
|
||||
.map(|var| var.is_fn_local)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ where
|
||||
{
|
||||
/// Evaluate expression if possible.
|
||||
///
|
||||
/// This method call apppropriate methods for each ast types.
|
||||
/// This method call appropriate methods for each ast types.
|
||||
pub(super) fn evaluate(&mut self, e: &mut Expr) {
|
||||
self.eval_global_vars(e);
|
||||
|
||||
@ -37,8 +37,8 @@ where
|
||||
if let Expr::Ident(i) = e {
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
.vars
|
||||
.get(&i.to_id())
|
||||
.map(|var| var.declared)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
@ -65,7 +65,7 @@ where
|
||||
tracing::debug!("evaluate: `Infinity` -> `1 / 0`");
|
||||
self.changed = true;
|
||||
*e = Expr::Bin(BinExpr {
|
||||
span: span.with_ctxt(self.done_ctxt),
|
||||
span: *span,
|
||||
op: op!("/"),
|
||||
left: Box::new(Expr::Lit(Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
@ -187,7 +187,7 @@ where
|
||||
if let Some(v) = char::from_u32(v) {
|
||||
self.changed = true;
|
||||
tracing::debug!(
|
||||
"evanluate: Evaluated `String.charCodeAt({})` as `{}`",
|
||||
"evaluate: Evaluated `String.charCodeAt({})` as `{}`",
|
||||
char_code,
|
||||
v
|
||||
);
|
||||
@ -306,7 +306,7 @@ where
|
||||
if let Known(l) = l {
|
||||
if let Known(r) = r {
|
||||
self.changed = true;
|
||||
tracing::debug!("evaluate: Evaulated `{:?} ** {:?}`", l, r);
|
||||
tracing::debug!("evaluate: Evaluated `{:?} ** {:?}`", l, r);
|
||||
|
||||
let value = l.powf(r);
|
||||
*e = Expr::Lit(Lit::Num(Number {
|
||||
@ -337,13 +337,9 @@ where
|
||||
// If a variable named `NaN` is in scope, don't convert e into NaN.
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.map(|data| {
|
||||
data.vars
|
||||
.iter()
|
||||
.any(|(name, v)| v.declared && name.0 == js_word!("NaN"))
|
||||
})
|
||||
.unwrap_or(false)
|
||||
.vars
|
||||
.iter()
|
||||
.any(|(name, v)| v.declared && name.0 == js_word!("NaN"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -24,14 +24,13 @@ where
|
||||
// smart.
|
||||
if !self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| {
|
||||
data.vars.get(&name.to_id()).map(|v| {
|
||||
!v.mutated
|
||||
&& !v.reassigned_with_assignment
|
||||
&& !v.reassigned_with_var_decl
|
||||
&& !v.is_infected()
|
||||
})
|
||||
.vars
|
||||
.get(&name.to_id())
|
||||
.map(|v| {
|
||||
!v.mutated
|
||||
&& !v.reassigned_with_assignment
|
||||
&& !v.reassigned_with_var_decl
|
||||
&& !v.is_infected()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
@ -41,12 +40,9 @@ where
|
||||
// We should abort if unknown property is used.
|
||||
let mut unknown_used_props = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| {
|
||||
data.vars
|
||||
.get(&name.to_id())
|
||||
.map(|v| v.accessed_props.clone())
|
||||
})
|
||||
.vars
|
||||
.get(&name.to_id())
|
||||
.map(|v| v.accessed_props.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
if let Some(Expr::Object(init)) = n.init.as_deref() {
|
||||
@ -120,15 +116,14 @@ where
|
||||
// If the variable is used multiple time, just ignore it.
|
||||
if !self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| {
|
||||
data.vars.get(&name.to_id()).map(|v| {
|
||||
v.ref_count == 1
|
||||
&& v.has_property_access
|
||||
&& v.is_fn_local
|
||||
&& !v.executed_multiple_time
|
||||
&& !v.used_in_cond
|
||||
})
|
||||
.vars
|
||||
.get(&name.to_id())
|
||||
.map(|v| {
|
||||
v.ref_count == 1
|
||||
&& v.has_property_access
|
||||
&& v.is_fn_local
|
||||
&& !v.executed_multiple_time
|
||||
&& !v.used_in_cond
|
||||
})
|
||||
.unwrap_or(false)
|
||||
{
|
||||
|
@ -185,11 +185,7 @@ where
|
||||
for (idx, param) in params.iter().enumerate() {
|
||||
let arg = e.args.get(idx).map(|v| &v.expr);
|
||||
if let Pat::Ident(param) = ¶m {
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(¶m.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(¶m.to_id()) {
|
||||
if usage.reassigned() {
|
||||
continue;
|
||||
}
|
||||
@ -514,11 +510,7 @@ where
|
||||
// Don't create top-level variables.
|
||||
if !param_ids.is_empty() && self.ctx.in_top_level() {
|
||||
for pid in param_ids {
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&pid.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&pid.to_id()) {
|
||||
if usage.ref_count > 1 || usage.assign_count > 0 || usage.inline_prevented {
|
||||
return false;
|
||||
}
|
||||
|
@ -38,12 +38,7 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.map(|v| v.top.has_eval_call)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
if self.data.top.has_eval_call {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -60,11 +55,7 @@ where
|
||||
}
|
||||
|
||||
// Store variables if it's used only once
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&i.to_id()) {
|
||||
if usage.declared_as_catch_param {
|
||||
return;
|
||||
}
|
||||
@ -255,11 +246,7 @@ where
|
||||
}
|
||||
|
||||
if let Expr::Ident(v) = &**init {
|
||||
if let Some(v_usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&v.to_id()))
|
||||
{
|
||||
if let Some(v_usage) = self.data.vars.get(&v.to_id()) {
|
||||
if v_usage.reassigned() {
|
||||
return;
|
||||
}
|
||||
@ -351,11 +338,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&i.to_id()) {
|
||||
if !usage.reassigned() {
|
||||
tracing::trace!("typeofs: Storing typeof `{}{:?}`", i.sym, i.span.ctxt);
|
||||
match &*decl {
|
||||
@ -428,20 +411,11 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.map(|data| data.top.has_eval_call || data.top.has_with_stmt)
|
||||
.unwrap_or_default()
|
||||
{
|
||||
if self.data.top.has_eval_call || self.data.top.has_with_stmt {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
{
|
||||
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");
|
||||
|
@ -5,7 +5,7 @@ use std::{fmt::Write, iter::once, mem::take};
|
||||
use retain_mut::RetainMut;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{
|
||||
collections::AHashMap, iter::IdentifyLast, pass::Repeated, util::take::Take, Mark, Spanned,
|
||||
collections::AHashMap, iter::IdentifyLast, pass::Repeated, util::take::Take, Spanned,
|
||||
SyntaxContext, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
@ -64,8 +64,6 @@ where
|
||||
"top_retain should not contain empty string"
|
||||
);
|
||||
|
||||
let done = Mark::fresh(Mark::root());
|
||||
let done_ctxt = SyntaxContext::empty().apply_mark(done);
|
||||
Optimizer {
|
||||
marks,
|
||||
changed: false,
|
||||
@ -78,10 +76,8 @@ where
|
||||
simple_props: Default::default(),
|
||||
_simple_array_values: Default::default(),
|
||||
typeofs: Default::default(),
|
||||
data: Some(data),
|
||||
data,
|
||||
ctx: Default::default(),
|
||||
done,
|
||||
done_ctxt,
|
||||
label: Default::default(),
|
||||
mode,
|
||||
debug_infinite_loop,
|
||||
@ -208,11 +204,8 @@ struct Optimizer<'a, M> {
|
||||
///
|
||||
/// This is calculated multiple time, but only once per one
|
||||
/// `visit_mut_module`.
|
||||
data: Option<&'a mut ProgramData>,
|
||||
data: &'a mut ProgramData,
|
||||
ctx: Ctx,
|
||||
/// In future: This will be used to `mark` node as done.
|
||||
done: Mark,
|
||||
done_ctxt: SyntaxContext,
|
||||
|
||||
/// Closest label.
|
||||
///
|
||||
@ -244,12 +237,6 @@ where
|
||||
T: StmtLike + ModuleItemLike + ModuleItemExt + VisitMutWith<Self> + VisitWith<AssertValid>,
|
||||
Vec<T>: VisitMutWith<Self> + VisitWith<UsageAnalyzer> + VisitWith<AssertValid>,
|
||||
{
|
||||
match self.data {
|
||||
Some(..) => {}
|
||||
None => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
let mut use_asm = false;
|
||||
let prepend_stmts = self.prepend_stmts.take();
|
||||
let append_stmts = self.append_stmts.take();
|
||||
@ -894,11 +881,7 @@ where
|
||||
|
||||
if let Expr::Ident(callee) = &**callee {
|
||||
if self.options.reduce_vars && self.options.side_effects {
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&callee.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&callee.to_id()) {
|
||||
if !usage.reassigned() && usage.pure_fn {
|
||||
let args = args
|
||||
.take()
|
||||
@ -2852,11 +2835,7 @@ where
|
||||
|
||||
if let Some(Expr::Invalid(..)) = var.init.as_deref() {
|
||||
if let Pat::Ident(i) = &var.name {
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.id.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&i.id.to_id()) {
|
||||
if usage.declared_as_catch_param {
|
||||
var.init = None;
|
||||
return true;
|
||||
|
@ -1404,11 +1404,7 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&left_id.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&left_id.to_id()) {
|
||||
if usage.inline_prevented {
|
||||
return Ok(false);
|
||||
}
|
||||
@ -1440,11 +1436,7 @@ where
|
||||
_ => return Ok(false),
|
||||
};
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&left.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&left.to_id()) {
|
||||
if usage.ref_count != 1 {
|
||||
return Ok(false);
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ where
|
||||
}
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
.vars
|
||||
.get(&i.to_id())
|
||||
.map(|v| v.assign_count == 0 && !v.declared_as_fn_param)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
|
@ -81,11 +81,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(scope) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.scopes.get(&self.ctx.scope))
|
||||
{
|
||||
if let Some(scope) = self.data.scopes.get(&self.ctx.scope) {
|
||||
if scope.has_eval_call || scope.has_with_stmt {
|
||||
return;
|
||||
}
|
||||
@ -159,11 +155,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(scope) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.scopes.get(&self.ctx.scope))
|
||||
{
|
||||
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!(
|
||||
@ -213,11 +205,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(v) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()).cloned())
|
||||
{
|
||||
if let Some(v) = self.data.vars.get(&i.to_id()).cloned() {
|
||||
if v.ref_count == 0
|
||||
&& v.usage_count == 0
|
||||
&& !v.reassigned_with_assignment
|
||||
@ -282,11 +270,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(usage) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&e.to_id()))
|
||||
{
|
||||
if let Some(usage) = self.data.vars.get(&e.to_id()) {
|
||||
if !usage.declared {
|
||||
return true;
|
||||
}
|
||||
@ -476,11 +460,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(scope) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.scopes.get(&self.ctx.scope))
|
||||
{
|
||||
if let Some(scope) = self.data.scopes.get(&self.ctx.scope) {
|
||||
if scope.has_eval_call || scope.has_with_stmt {
|
||||
return;
|
||||
}
|
||||
@ -502,8 +482,8 @@ where
|
||||
// If it is not used, drop it.
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&ident.to_id()))
|
||||
.vars
|
||||
.get(&ident.to_id())
|
||||
.map(|v| v.usage_count == 0 && !v.has_property_mutation)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
@ -545,28 +525,21 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if self
|
||||
.data
|
||||
.as_ref()
|
||||
.map(|v| v.top.has_eval_call || v.top.has_with_stmt)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
if self.data.top.has_eval_call || self.data.top.has_with_stmt {
|
||||
return;
|
||||
}
|
||||
|
||||
let used_arguments = self
|
||||
.data
|
||||
.as_ref()
|
||||
.map(|data| {
|
||||
data.scopes.get(&self.ctx.scope).unwrap_or_else(|| {
|
||||
unreachable!(
|
||||
"scope should exist\nScopes: {:?};\nCtxt: {:?}",
|
||||
data.scopes, self.ctx.scope
|
||||
)
|
||||
})
|
||||
.scopes
|
||||
.get(&self.ctx.scope)
|
||||
.unwrap_or_else(|| {
|
||||
unreachable!(
|
||||
"scope should exist\nScopes: {:?};\nCtxt: {:?}",
|
||||
self.data.scopes, self.ctx.scope
|
||||
)
|
||||
})
|
||||
.map(|scope| scope.used_arguments)
|
||||
.unwrap_or(false);
|
||||
.used_arguments;
|
||||
|
||||
if cfg!(feature = "debug") {
|
||||
tracing::trace!(
|
||||
@ -603,11 +576,7 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(var) = self
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|data| data.vars.get(&i.to_id()))
|
||||
{
|
||||
if let Some(var) = self.data.vars.get(&i.to_id()) {
|
||||
if var.is_fn_local
|
||||
&& var.usage_count == 0
|
||||
&& var.declared
|
||||
@ -647,18 +616,17 @@ where
|
||||
}
|
||||
|
||||
if let Some(i) = &name {
|
||||
if let Some(data) = &self.data {
|
||||
let can_remove_ident = data
|
||||
.vars
|
||||
.get(&i.to_id())
|
||||
.map(|v| (v.ref_count == 0 && v.usage_count == 0) || v.var_kind.is_some())
|
||||
.unwrap_or(true);
|
||||
let can_remove_ident = self
|
||||
.data
|
||||
.vars
|
||||
.get(&i.to_id())
|
||||
.map(|v| (v.ref_count == 0 && v.usage_count == 0) || v.var_kind.is_some())
|
||||
.unwrap_or(true);
|
||||
|
||||
if can_remove_ident {
|
||||
self.changed = true;
|
||||
tracing::debug!("Removing ident of an class / function expression");
|
||||
*name = None;
|
||||
}
|
||||
if can_remove_ident {
|
||||
self.changed = true;
|
||||
tracing::debug!("Removing ident of an class / function expression");
|
||||
*name = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,21 +74,13 @@ where
|
||||
span.has_mark(self.marks.noinline)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub(super) fn is_done(&mut self, span: Span) -> bool {
|
||||
span.has_mark(self.done)
|
||||
}
|
||||
|
||||
/// RAII guard to change context temporarically
|
||||
#[inline]
|
||||
pub(super) fn with_ctx(&mut self, ctx: Ctx) -> WithCtx<'_, 'b, M> {
|
||||
if cfg!(debug_assertions) {
|
||||
let scope_ctxt = ctx.scope;
|
||||
if self.ctx.scope != scope_ctxt {
|
||||
if let Some(data) = &self.data {
|
||||
data.scopes.get(&scope_ctxt).expect("scope not found");
|
||||
}
|
||||
self.data.scopes.get(&scope_ctxt).expect("scope not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use tracing::{span, Level};
|
||||
|
||||
use self::{ctx::Ctx, misc::DropOpts};
|
||||
use crate::{
|
||||
analyzer::ProgramData,
|
||||
debug::{dump, AssertValid},
|
||||
marks::Marks,
|
||||
option::CompressOptions,
|
||||
@ -38,6 +39,7 @@ mod vars;
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
pub(crate) fn pure_optimizer<'a>(
|
||||
options: &'a CompressOptions,
|
||||
data: Option<&'a ProgramData>,
|
||||
marks: Marks,
|
||||
force_str_for_tpl: bool,
|
||||
enable_everything: bool,
|
||||
@ -46,6 +48,7 @@ pub(crate) fn pure_optimizer<'a>(
|
||||
Pure {
|
||||
options,
|
||||
marks,
|
||||
data,
|
||||
ctx: Ctx {
|
||||
force_str_for_tpl,
|
||||
..Default::default()
|
||||
@ -60,6 +63,8 @@ pub(crate) fn pure_optimizer<'a>(
|
||||
struct Pure<'a> {
|
||||
options: &'a CompressOptions,
|
||||
marks: Marks,
|
||||
#[allow(unused)]
|
||||
data: Option<&'a ProgramData>,
|
||||
ctx: Ctx,
|
||||
changed: bool,
|
||||
enable_everything: bool,
|
||||
@ -153,13 +158,9 @@ impl Pure<'_> {
|
||||
if self.ctx.par_depth >= MAX_PAR_DEPTH * 2 || cfg!(target_arch = "wasm32") {
|
||||
for node in nodes {
|
||||
let mut v = Pure {
|
||||
options: self.options,
|
||||
marks: self.marks,
|
||||
ctx: self.ctx,
|
||||
changed: false,
|
||||
enable_everything: self.enable_everything,
|
||||
debug_infinite_loop: self.debug_infinite_loop,
|
||||
bindings: self.bindings.clone(),
|
||||
..*self
|
||||
};
|
||||
node.visit_mut_with(&mut v);
|
||||
|
||||
@ -172,16 +173,13 @@ impl Pure<'_> {
|
||||
.map(|node| {
|
||||
GLOBALS.set(globals, || {
|
||||
let mut v = Pure {
|
||||
options: self.options,
|
||||
marks: self.marks,
|
||||
ctx: Ctx {
|
||||
par_depth: self.ctx.par_depth + 1,
|
||||
..self.ctx
|
||||
},
|
||||
changed: false,
|
||||
enable_everything: self.enable_everything,
|
||||
debug_infinite_loop: self.debug_infinite_loop,
|
||||
bindings: self.bindings.clone(),
|
||||
..*self
|
||||
};
|
||||
node.visit_mut_with(&mut v);
|
||||
|
||||
|
@ -222,6 +222,7 @@ impl Evaluator {
|
||||
{
|
||||
e.visit_mut_with(&mut pure_optimizer(
|
||||
&serde_json::from_str("{}").unwrap(),
|
||||
None,
|
||||
self.marks,
|
||||
Eval::force_str_for_tpl(),
|
||||
true,
|
||||
|
@ -141,6 +141,7 @@ pub fn optimize(
|
||||
m.visit_mut_with(&mut postcompress_optimizer(options));
|
||||
m.visit_mut_with(&mut Repeat::new(pure_optimizer(
|
||||
options,
|
||||
None,
|
||||
marks,
|
||||
Minification::force_str_for_tpl(),
|
||||
true,
|
||||
|
Loading…
Reference in New Issue
Block a user