diff --git a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs index e9c4cc43e890..9a18835ccad1 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs @@ -470,6 +470,13 @@ impl Optimizer<'_> { return; } + trace_op!("iife: Checking pure"); + + if self.has_pure(call.span) { + log_abort!("iife: Has pure mark"); + return; + } + trace_op!("iife: Checking callee"); match callee { diff --git a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs index 93fa0200b3a5..81362f956131 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs @@ -833,7 +833,8 @@ impl Optimizer<'_> { BlockStmtOrExpr::Expr(_) => false, }, _ => false, - } && args.is_empty() => + } && args.is_empty() + || e.span().has_mark(self.marks.pure) => { report_change!("ignore_return_value: Dropping a pure call"); self.changed = true; diff --git a/crates/swc_ecma_minifier/src/compress/optimize/util.rs b/crates/swc_ecma_minifier/src/compress/optimize/util.rs index 7ae6087aeae3..eaa051c5979b 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/util.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/util.rs @@ -77,6 +77,11 @@ impl<'b> Optimizer<'b> { span.has_mark(self.marks.noinline) } + /// Check for `/*#__PURE__*/` + pub(super) fn has_pure(&self, span: Span) -> bool { + span.has_mark(self.marks.pure) + } + /// RAII guard to change context temporarically pub(super) fn with_ctx(&mut self, mut ctx: Ctx) -> WithCtx<'_, 'b> { let mut scope_ctxt = ctx.scope; diff --git a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs index 76bfb7995209..61ceab5e3d9a 100644 --- a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs +++ b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs @@ -1,4 +1,4 @@ -use swc_common::{collections::AHashMap, SyntaxContext}; +use swc_common::{collections::AHashMap, Spanned, SyntaxContext}; use swc_ecma_ast::*; use swc_ecma_utils::{find_pat_ids, ExprCtx, ExprExt, IsEmpty, StmtExt}; use swc_ecma_visit::{noop_visit_type, Visit, VisitWith}; @@ -1294,7 +1294,7 @@ where ..self.ctx }; - if self.marks.is_some() { + if let Some(marks) = self.marks { if let VarDeclarator { name: Pat::Ident(id), init: Some(init), @@ -1306,7 +1306,8 @@ where self.used_recursively.insert( id.clone(), RecursiveUsage::Var { - can_ignore: !init.may_have_side_effects(&self.expr_ctx), + can_ignore: !init.may_have_side_effects(&self.expr_ctx) + || init.span().has_mark(marks.pure), }, ); e.init.visit_with(&mut *self.with_ctx(ctx));