From 274648ec2664297043f5acb5cba659ace724fc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 18 May 2022 17:39:57 +0900 Subject: [PATCH] feat(es/minifier): Improve `if_return` (#4694) --- .../src/compress/optimize/conditionals.rs | 26 ++++++++++++++++--- .../src/compress/pure/dead_code.rs | 2 +- crates/swc_ecma_minifier/tests/TODO.txt | 2 -- crates/swc_ecma_minifier/tests/golden.txt | 3 +++ crates/swc_ecma_minifier/tests/postponed.txt | 1 - .../conditionals/issue_2994/output.js | 9 +++---- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs b/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs index 2604d94d961..ea93a828a04 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/conditionals.rs @@ -7,7 +7,10 @@ use swc_ecma_utils::{ExprExt, ExprFactory, StmtExt, StmtLike}; use super::Optimizer; use crate::{ - compress::{optimize::Ctx, util::negate_cost}, + compress::{ + optimize::Ctx, + util::{negate, negate_cost}, + }, mode::Mode, DISABLE_BUGGY_PASSES, }; @@ -687,6 +690,10 @@ where *stmts = new; } + /// if (foo) return bar() + /// else baz() + /// + /// `else` token can be removed from the code above. /// if (foo) return bar() /// else baz() /// @@ -716,11 +723,22 @@ where Ok(stmt) => match stmt { Stmt::If(IfStmt { span, - test, - cons, - alt: Some(alt), + mut test, + mut cons, + alt: Some(mut alt), .. }) if cons.terminates() => { + if let ( + Stmt::Return(ReturnStmt { arg: None, .. }), + Stmt::Decl(Decl::Fn(..)), + ) = (&*cons, &*alt) + { + // I don't know why, but terser behaves differently + negate(&self.expr_ctx, &mut test, true, false); + + swap(&mut cons, &mut alt); + } + new_stmts.push(T::from_stmt(Stmt::If(IfStmt { span, test, diff --git a/crates/swc_ecma_minifier/src/compress/pure/dead_code.rs b/crates/swc_ecma_minifier/src/compress/pure/dead_code.rs index 8abf09377e1..2ae492434c8 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/dead_code.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/dead_code.rs @@ -193,7 +193,7 @@ impl Pure<'_> { where T: StmtLike + ModuleItemExt + Take, { - if !self.options.dead_code { + if !self.options.dead_code && !self.options.if_return { return; } diff --git a/crates/swc_ecma_minifier/tests/TODO.txt b/crates/swc_ecma_minifier/tests/TODO.txt index 1d09d5972be..4d0b28f852e 100644 --- a/crates/swc_ecma_minifier/tests/TODO.txt +++ b/crates/swc_ecma_minifier/tests/TODO.txt @@ -8,8 +8,6 @@ drop_unused/var_catch_toplevel/input.js evaluate/issue_2535_1/input.js harmony/array_literal_with_spread_4a/input.js inline/dont_inline_funcs_into_default_param_2/input.js -issue_1052/defun_else_if_return/input.js -issue_1052/defun_if_return/input.js issue_281/inner_var_for_in_1/input.js issue_368/collapse/input.js nullish/conditional_to_nullish_coalescing_2/input.js diff --git a/crates/swc_ecma_minifier/tests/golden.txt b/crates/swc_ecma_minifier/tests/golden.txt index 63badc4165f..a53b14258c8 100644 --- a/crates/swc_ecma_minifier/tests/golden.txt +++ b/crates/swc_ecma_minifier/tests/golden.txt @@ -271,6 +271,7 @@ conditionals/issue_1645_1/input.js conditionals/issue_1645_2/input.js conditionals/issue_2535_2/input.js conditionals/issue_2560/input.js +conditionals/issue_2994/input.js conditionals/no_evaluate/input.js conditionals/ternary_boolean_alternative/input.js conditionals/ternary_boolean_consequent/input.js @@ -711,6 +712,8 @@ issue_1041/const_pragma/input.js issue_1041/not_const/input.js issue_1043/issue_1043/input.js issue_1044/issue_1044/input.js +issue_1052/defun_else_if_return/input.js +issue_1052/defun_if_return/input.js issue_1105/Infinity_in_with_scope/input.js issue_1105/Infinity_not_in_with_scope/input.js issue_1105/with_in_global_scope/input.js diff --git a/crates/swc_ecma_minifier/tests/postponed.txt b/crates/swc_ecma_minifier/tests/postponed.txt index c172daf0816..7625a1fa1fe 100644 --- a/crates/swc_ecma_minifier/tests/postponed.txt +++ b/crates/swc_ecma_minifier/tests/postponed.txt @@ -100,7 +100,6 @@ conditionals/ifs_6/input.js conditionals/ifs_same_consequent/input.js conditionals/issue_1154/input.js conditionals/issue_2535_1/input.js -conditionals/issue_2994/input.js dead_code/dead_code_2_should_warn/input.js dead_code/dead_code_2_should_warn_strict/input.js dead_code/dead_code_const_annotation/input.js diff --git a/crates/swc_ecma_minifier/tests/terser/compress/conditionals/issue_2994/output.js b/crates/swc_ecma_minifier/tests/terser/compress/conditionals/issue_2994/output.js index c9c3e2e4487..0288204e074 100644 --- a/crates/swc_ecma_minifier/tests/terser/compress/conditionals/issue_2994/output.js +++ b/crates/swc_ecma_minifier/tests/terser/compress/conditionals/issue_2994/output.js @@ -3,14 +3,13 @@ function f(condition1, condition2, condition3) { if (condition2) return aValue; { const variable1 = "something"; - if (condition3) { + if (!condition3) return; + { const variable2 = "else"; return anotherValue; } - return; } } } -let aValue = 2, - anotherValue = 3; -for (let i = 0; i < 8; ++i) console.log(f(4 & i, 2 & i, 1 & i)); +let aValue = 2, anotherValue = 3; +for(let i = 0; i < 8; ++i)console.log(f(4 & i, 2 & i, 1 & i));