From 16100127de193b47b0dd086c901b4888231f235f Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Thu, 29 Sep 2016 12:02:47 +0200 Subject: [PATCH] Fix var hoisting bug in DCE Fix bug where var declarations after compleition statements are deadcode eliminated - vars are hoisted in JS and need to be preserved like function declarations (Close #167) --- .../__tests__/dead-code-elimination-test.js | 35 +++++++++++++++++++ .../src/index.js | 10 ++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/babel-plugin-minify-dead-code-elimination/__tests__/dead-code-elimination-test.js b/packages/babel-plugin-minify-dead-code-elimination/__tests__/dead-code-elimination-test.js index 6f02deaed..95c87fe3b 100644 --- a/packages/babel-plugin-minify-dead-code-elimination/__tests__/dead-code-elimination-test.js +++ b/packages/babel-plugin-minify-dead-code-elimination/__tests__/dead-code-elimination-test.js @@ -1999,4 +1999,39 @@ describe("dce-plugin", () => { const expected = source; expect(transform(source)).toBe(expected); }); + + it("should preserve variabledeclarations(var) after completion statements", () => { + const source = unpad(` + function foo() { + a = 1; + return a; + var a; + } + `); + + const expected = source; + + expect(transform(source)).toBe(expected); + }); + + it("should NOT preserve variabledeclarations(let) after completion statements", () => { + const source = unpad(` + function foo() { + a = 1; + b = 2; + return a + b; + let a, b; + } + `); + + const expected = unpad(` + function foo() { + a = 1; + b = 2; + return a + b; + } + `); + + expect(transform(source)).toBe(expected); + }); }); 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 003dbb7c1..11308c034 100644 --- a/packages/babel-plugin-minify-dead-code-elimination/src/index.js +++ b/packages/babel-plugin-minify-dead-code-elimination/src/index.js @@ -283,7 +283,7 @@ module.exports = ({ types: t, traverse }) => { continue; } - if (purge && !p.isFunctionDeclaration()) { + if (purge && !canExistAfterCompletion(p)) { removeOrVoid(p); } } @@ -299,7 +299,7 @@ module.exports = ({ types: t, traverse }) => { // Not last in it's block? (See BlockStatement visitor) if (path.container.length - 1 !== path.key && - !path.getSibling(path.key + 1).isFunctionDeclaration() && + !canExistAfterCompletion(path.getSibling(path.key + 1)) && path.parentPath.isBlockStatement() ) { // This is probably a new oppurtinity by some other transform @@ -900,4 +900,10 @@ module.exports = ({ types: t, traverse }) => { }; } } + + // things that are hoisted + function canExistAfterCompletion(path) { + return path.isFunctionDeclaration() + || path.isVariableDeclaration({ kind: "var" }); + } };