diff --git a/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs b/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs index 39eaa67ab73e..e6c9f935361c 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs @@ -1,4 +1,4 @@ -use std::mem::swap; +use std::mem::{swap, take}; use swc_common::{util::take::Take, EqIgnoreSpan, Spanned, SyntaxContext, DUMMY_SP}; use swc_ecma_ast::*; @@ -184,6 +184,49 @@ impl Optimizer<'_> { *stmts = new; } + pub(super) fn expand_if_stmt_from_cond(&mut self, s: &mut Stmt) { + // let mut changed = false; + if self.options.conditionals { + if let Stmt::Return(r) = s { + if let Some(Expr::Cond(c)) = r.arg.as_deref_mut() { + // changed = true; + *s = Stmt::If(IfStmt { + span: c.span, + test: take(&mut c.test), + cons: Box::new(Stmt::Return(ReturnStmt { + span: r.span, + arg: Some(take(&mut c.cons)), + })), + alt: Some(Box::new(Stmt::Return(ReturnStmt { + span: r.span, + arg: Some(take(&mut c.alt)), + }))), + }); + // continue; + } + } + if let Stmt::Expr(e) = s { + if let Expr::Cond(c) = &mut *e.expr { + // changed = true; + *s = Stmt::If(IfStmt { + span: c.span, + test: take(&mut c.test), + cons: Box::new(Stmt::Expr(ExprStmt { + span: e.span, + expr: take(&mut c.cons), + })), + alt: Some(Box::new(Stmt::Expr(ExprStmt { + span: e.span, + expr: take(&mut c.alt), + }))), + }); + // continue; + } + } + } + // changed + } + /// /// # Examples /// @@ -364,6 +407,7 @@ impl Optimizer<'_> { cons: &mut Expr, alt: &mut Expr, is_for_if_stmt: bool, + // change: bool, ) -> Option { debug_assert_valid(cons); debug_assert_valid(alt); diff --git a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs index 05b280a00be9..96ed2e3514f1 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs @@ -2401,6 +2401,8 @@ impl VisitMut for Optimizer<'_> { } }; + self.expand_if_stmt_from_cond(s); + let ctx = self .ctx .clone() diff --git a/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/input.js b/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/input.js new file mode 100644 index 000000000000..606d2d5ae088 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/input.js @@ -0,0 +1 @@ +return a ? b : (d => d)(c) \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/output.js b/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/output.js new file mode 100644 index 000000000000..9a201af4fd5e --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/simple/if/unfolding-refolding/output.js @@ -0,0 +1,2 @@ +if (a) return b; +return c;