Skip to content

Commit

Permalink
empty branch and last break
Browse files Browse the repository at this point in the history
  • Loading branch information
Austaras committed Apr 20, 2022
1 parent d4d11d3 commit f152ac9
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 107 deletions.
63 changes: 24 additions & 39 deletions crates/swc_ecma_minifier/src/compress/optimize/switches.rs
Expand Up @@ -165,58 +165,40 @@ where
/// - drop break at last case
/// - merge branch with default at the end
pub(super) fn optimize_switch_cases(&mut self, cases: &mut Vec<SwitchCase>) {
if !self.options.switches || !self.options.dead_code {
if !self.options.switches || !self.options.dead_code || cases.is_empty() {
return;
}

// If default is not last, we can't remove empty cases.
let default_idx = cases.iter().position(|case| case.test.is_none());
let all_ends_with_break = cases
.iter()
.all(|case| case.cons.is_empty() || case.cons.last().unwrap().is_break_stmt());
let mut preserve_cases = false;
if !all_ends_with_break && default_idx.is_some() {
if let Some(last) = cases.last() {
if last.test.is_some() {
preserve_cases = true;
}
}
}

self.merge_cases_with_same_cons(cases);

let last_non_empty = cases.iter().rposition(|case| {
// We should preserve test cases if the test is not a literal.
match case.test.as_deref() {
Some(Expr::Lit(..)) | None => {}
_ => return true,
}
// last case with no empty body
let mut last = cases.len();

if case.cons.is_empty() {
return false;
}
for (idx, case) in cases.iter_mut().enumerate().rev() {
self.changed |= remove_last_break(&mut case.cons);

if case.cons.len() == 1 {
if let Stmt::Break(BreakStmt { label: None, .. }) = case.cons[0] {
return false;
}
if !case.cons.is_empty() {
last = idx + 1;
break;
}
}

true
let has_side_effect = cases.iter().skip(last).rposition(|case| {
case.test
.as_deref()
.map(|test| test.may_have_side_effects())
.unwrap_or(false)
});

if !preserve_cases {
if let Some(last_non_empty) = last_non_empty {
if last_non_empty + 1 != cases.len() {
report_change!("switches: Removing empty cases at the end");
self.changed = true;
cases.drain(last_non_empty + 1..);
}
}
if let Some(has_side_effect) = has_side_effect {
last += has_side_effect + 1
}

if let Some(last) = cases.last_mut() {
self.changed |= remove_last_break(&mut last.cons);
// if default is before empty cases, we must ensure empty case is preserved
if last < cases.len() && !cases.iter().take(last).any(|case| case.test.is_none()) {
self.changed = true;
report_change!("switches: Removing empty cases at the end");
cases.drain(last..);
}
}

Expand Down Expand Up @@ -247,6 +229,9 @@ where
}

for j in (i + 1)..len {
if cases[j].cons.is_empty() {
continue;
}
if boundary[j] {
// TODO: default
break;
Expand Down
41 changes: 14 additions & 27 deletions crates/swc_ecma_minifier/tests/fixture/issues/2257/full/output.js
Expand Up @@ -12519,6 +12519,7 @@
if (ie) return "compositionend" === a || !ae && ge(a, b) ? (a = nd(), md = ld = kd = null, ie = !1, a) : null;
switch(a){
case "paste":
default:
return null;
case "keypress":
if (!(b.ctrlKey || b.altKey || b.metaKey) || b.ctrlKey && b.altKey) {
Expand All @@ -12528,8 +12529,6 @@
return null;
case "compositionend":
return de && "ko" !== b.locale ? null : b.data;
default:
return null;
}
}(a12, c5)) && 0 < (d = oe(d, "onBeforeInput")).length && (e = new Ld("onBeforeInput", "beforeinput", null, c5, e), g.push({
event: e,
Expand Down Expand Up @@ -13240,7 +13239,6 @@
case 6:
return null !== (b = "" === a.pendingProps || 3 !== b.nodeType ? null : b) && (a.stateNode = b, !0);
case 13:
return !1;
default:
return !1;
}
Expand Down Expand Up @@ -14004,6 +14002,7 @@
case 14:
return null;
case 1:
case 17:
return Ff(b.type) && Gf(), null;
case 3:
return fh(), H(N), H(M), uh(), (d = b.stateNode).pendingContext && (d.context = d.pendingContext, d.pendingContext = null), (null === a || null === a.child) && (rh(b) ? b.flags |= 4 : d.hydrate || (b.flags |= 256)), Ci(b), null;
Expand Down Expand Up @@ -14163,8 +14162,6 @@
return fh(), Ci(b), null === a && cf(b.stateNode.containerInfo), null;
case 10:
return rg(b), null;
case 17:
return Ff(b.type) && Gf(), null;
case 19:
if (H(P), null === (d = b.memoizedState)) return null;
if (f = 0 != (64 & b.flags), null === (g = d.rendering)) {
Expand Down Expand Up @@ -14358,6 +14355,10 @@
case 11:
case 15:
case 22:
case 5:
case 6:
case 4:
case 17:
return;
case 1:
if (256 & b.flags && null !== a) {
Expand All @@ -14368,11 +14369,6 @@
case 3:
256 & b.flags && qf(b.stateNode.containerInfo);
return;
case 5:
case 6:
case 4:
case 17:
return;
}
throw Error(y(163));
}
Expand Down Expand Up @@ -14417,21 +14413,18 @@
a = c.stateNode, null === b && 4 & c.flags && mf(c.type, c.memoizedProps) && a.focus();
return;
case 6:
return;
case 4:
return;
case 12:
return;
case 13:
null === c.memoizedState && null !== (c = c.alternate) && null !== (c = c.memoizedState) && null !== (c = c.dehydrated) && Cc(c);
return;
case 19:
case 17:
case 20:
case 21:
case 23:
case 24:
return;
case 13:
null === c.memoizedState && null !== (c = c.alternate) && null !== (c = c.memoizedState) && null !== (c = c.dehydrated) && Cc(c);
return;
}
throw Error(y(163));
}
Expand Down Expand Up @@ -14565,8 +14558,6 @@
f = !1;
break a;
case 3:
e = e.containerInfo, f = !0;
break a;
case 4:
e = e.containerInfo, f = !0;
break a;
Expand Down Expand Up @@ -14618,6 +14609,8 @@
}
return;
case 1:
case 12:
case 17:
return;
case 5:
if (null != (c = b.stateNode)) {
Expand Down Expand Up @@ -14650,16 +14643,12 @@
case 3:
(c = b.stateNode).hydrate && (c.hydrate = !1, Cc(c.containerInfo));
return;
case 12:
return;
case 13:
null !== b.memoizedState && (jj = O(), aj(b.child, !0)), kj(b);
return;
case 19:
kj(b);
return;
case 17:
return;
case 23:
case 24:
aj(b, null !== b.memoizedState);
Expand Down Expand Up @@ -14800,6 +14789,9 @@
case 1:
throw Error(y(345));
case 2:
case 5:
Uj(a);
break;
case 3:
if (Ii(a, c), (62914560 & c) === c && 10 < (d = jj + 500 - O())) {
if (0 !== Uc(a, 0)) break;
Expand All @@ -14824,9 +14816,6 @@
}
Uj(a);
break;
case 5:
Uj(a);
break;
default:
throw Error(y(329));
}
Expand Down Expand Up @@ -15586,7 +15575,6 @@
case 7:
return fi(a23, b, b.pendingProps, c), b.child;
case 8:
return fi(a23, b, b.pendingProps.children, c), b.child;
case 12:
return fi(a23, b, b.pendingProps.children, c), b.child;
case 10:
Expand Down Expand Up @@ -15640,7 +15628,6 @@
case 19:
return Ai(a23, b, c);
case 23:
return mi(a23, b, c);
case 24:
return mi(a23, b, c);
}
Expand Down

0 comments on commit f152ac9

Please sign in to comment.