From 30e06eb9d1c224841001250643f3047630508d3f Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Tue, 17 Jul 2018 21:13:12 +0200 Subject: [PATCH 1/2] fix(deadcode): sequence expressions in switch discriminant --- .../src/index.js | 38 +++++++++++++++---- .../__tests__/preset-tests.js | 35 +++++++++++++++++ 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/packages/babel-plugin-minify-dead-code-elimination/src/index.js b/packages/babel-plugin-minify-dead-code-elimination/src/index.js index 099a02c1d..6034c8b93 100644 --- a/packages/babel-plugin-minify-dead-code-elimination/src/index.js +++ b/packages/babel-plugin-minify-dead-code-elimination/src/index.js @@ -563,10 +563,31 @@ module.exports = ({ types: t, traverse }) => { SwitchStatement: { exit(path) { - const evaluated = evaluate(path.get("discriminant"), { tdz: this.tdz }); + const discriminantPath = path.get("discriminant"); + const evaluated = evaluate(discriminantPath, { tdz: this.tdz }); if (!evaluated.confident) return; + // the simplify transformation might have brought in the previous + // expressions into the switch's test expression and instead of + // bailing out of impure path, we collect the impurities of it's + // a sequence expression and bail out if the primary test itself + // is impure + let beforeTest = null; + if (t.isSequenceExpression(discriminantPath.node)) { + const expressions = discriminantPath.get("expressions"); + const lastExpression = expressions[expressions.length - 1]; + if (!lastExpression.isPure()) { + return; + } + + beforeTest = t.sequenceExpression( + expressions.slice(0, expressions.length - 1).map(path => path.node) + ); + } else if (!discriminantPath.isPure()) { + return; + } + const discriminant = evaluated.value; const cases = path.get("cases"); @@ -582,7 +603,9 @@ module.exports = ({ types: t, traverse }) => { continue; } - const testResult = evaluate(test, { tdz: this.tdz }); + const testResult = evaluate(test, { + tdz: this.tdz + }); // if we are not able to deternine a test during // compile time, we terminate immediately @@ -613,13 +636,14 @@ module.exports = ({ types: t, traverse }) => { // we extract vars from the entire switch statement // and there will be duplicates which // will be again removed by DCE - replaceSwitch([...extractVars(path), ...result.statements]); + replaceSwitch([ + ...extractVars(path), + t.expressionStatement(beforeTest), + ...result.statements + ]); function getStatementsUntilBreak(start) { - const result = { - bail: false, - statements: [] - }; + const result = { bail: false, statements: [] }; for (let i = start; i < cases.length; i++) { const consequent = cases[i].get("consequent"); diff --git a/packages/babel-preset-minify/__tests__/preset-tests.js b/packages/babel-preset-minify/__tests__/preset-tests.js index a5482a945..79c553132 100644 --- a/packages/babel-preset-minify/__tests__/preset-tests.js +++ b/packages/babel-preset-minify/__tests__/preset-tests.js @@ -170,4 +170,39 @@ describe("preset", () => { var bar; ` ); + + thePlugin( + "should fix issue#880 - switch test in deadcode after simplify", + ` + (function () { + const test = 2; + + console.log("before switch"); + + switch (test) { + case 1: + console.log("case 1"); + break; + + case 2: + console.log("case 2"); + break; + + case 3: + default: + console.log("case 3"); + break; + } + + console.log("after switch"); + })(); + `, + ` + (function () { + console.log("before switch"); + console.log("case 2"); + console.log("after switch"); + })(); + ` + ); }); From edd52a3375bb72a14b4e5e82a06a8d14f3421b90 Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Tue, 17 Jul 2018 21:15:57 +0200 Subject: [PATCH 2/2] fix null case to expressionStatement --- .../src/index.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/babel-plugin-minify-dead-code-elimination/src/index.js b/packages/babel-plugin-minify-dead-code-elimination/src/index.js index 6034c8b93..207a01910 100644 --- a/packages/babel-plugin-minify-dead-code-elimination/src/index.js +++ b/packages/babel-plugin-minify-dead-code-elimination/src/index.js @@ -573,7 +573,7 @@ module.exports = ({ types: t, traverse }) => { // bailing out of impure path, we collect the impurities of it's // a sequence expression and bail out if the primary test itself // is impure - let beforeTest = null; + let beforeTest = []; if (t.isSequenceExpression(discriminantPath.node)) { const expressions = discriminantPath.get("expressions"); const lastExpression = expressions[expressions.length - 1]; @@ -581,9 +581,15 @@ module.exports = ({ types: t, traverse }) => { return; } - beforeTest = t.sequenceExpression( - expressions.slice(0, expressions.length - 1).map(path => path.node) - ); + beforeTest = [ + t.expressionStatement( + t.sequenceExpression( + expressions + .slice(0, expressions.length - 1) + .map(path => path.node) + ) + ) + ]; } else if (!discriminantPath.isPure()) { return; } @@ -638,7 +644,7 @@ module.exports = ({ types: t, traverse }) => { // will be again removed by DCE replaceSwitch([ ...extractVars(path), - t.expressionStatement(beforeTest), + ...beforeTest, ...result.statements ]);