From 72510d657fed4fbe125f3f9fd58c29520dc2418f Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Thu, 13 Oct 2016 03:38:18 +0200 Subject: [PATCH 1/3] Fix label shadowing in mangler --- .../src/index.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/babel-plugin-minify-mangle-names/src/index.js b/packages/babel-plugin-minify-mangle-names/src/index.js index 62222864a..bcdb7239d 100644 --- a/packages/babel-plugin-minify-mangle-names/src/index.js +++ b/packages/babel-plugin-minify-mangle-names/src/index.js @@ -77,6 +77,42 @@ module.exports = ({ types: t }) => { mangle() { const mangler = this; + this.program.traverse({ + Scopable(path) { + const {scope} = path; + + const bindings = scope.getAllBindings(); + const names = Object.keys(bindings); + + for (let i = 0; i < names.length; i++) { + const oldName = names[i]; + const binding = bindings[oldName]; + + if (binding.path.isLabeledStatement()) { + const faulty = binding.referencePaths.filter(ref => { + return !(ref.parentPath.isBreakStatement() || ref.parentPath.isContinueStatement()); + }); + faulty.forEach(f => { + const index = binding.referencePaths.indexOf(f); + if (index > -1) { + binding.referencePaths.splice(index, 1); + binding.references--; + if (binding.references === 0) { + binding.referenced = false; + } + } + }); + + scope.removeBinding(oldName); + const newBinding = scope.getBinding(oldName); + faulty.forEach(f => newBinding.reference(f)); + + continue; + } + } + } + }) + this.program.traverse({ Scopable(path) { const {scope} = path; From 771611bf291fcaf9d2f72e1e5896f11a498decca Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Thu, 13 Oct 2016 04:12:47 +0200 Subject: [PATCH 2/3] Fix lint --- packages/babel-plugin-minify-mangle-names/src/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/babel-plugin-minify-mangle-names/src/index.js b/packages/babel-plugin-minify-mangle-names/src/index.js index bcdb7239d..d3a6d609f 100644 --- a/packages/babel-plugin-minify-mangle-names/src/index.js +++ b/packages/babel-plugin-minify-mangle-names/src/index.js @@ -89,10 +89,10 @@ module.exports = ({ types: t }) => { const binding = bindings[oldName]; if (binding.path.isLabeledStatement()) { - const faulty = binding.referencePaths.filter(ref => { + const faulty = binding.referencePaths.filter((ref) => { return !(ref.parentPath.isBreakStatement() || ref.parentPath.isContinueStatement()); }); - faulty.forEach(f => { + faulty.forEach((f) => { const index = binding.referencePaths.indexOf(f); if (index > -1) { binding.referencePaths.splice(index, 1); @@ -105,13 +105,13 @@ module.exports = ({ types: t }) => { scope.removeBinding(oldName); const newBinding = scope.getBinding(oldName); - faulty.forEach(f => newBinding.reference(f)); + faulty.forEach((f) => newBinding.reference(f)); continue; } } } - }) + }); this.program.traverse({ Scopable(path) { From 1eb50975d733ebbdb1e21ea3c8bd5075c7c48fa9 Mon Sep 17 00:00:00 2001 From: Boopathi Rajaa Date: Thu, 13 Oct 2016 04:38:19 +0200 Subject: [PATCH 3/3] Fix for same scope collissions --- .../__tests__/mangle-names-test.js | 27 ++++++++++++++++- .../src/index.js | 30 +++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/packages/babel-plugin-minify-mangle-names/__tests__/mangle-names-test.js b/packages/babel-plugin-minify-mangle-names/__tests__/mangle-names-test.js index e38983089..5fa1c84f2 100644 --- a/packages/babel-plugin-minify-mangle-names/__tests__/mangle-names-test.js +++ b/packages/babel-plugin-minify-mangle-names/__tests__/mangle-names-test.js @@ -177,7 +177,7 @@ describe("mangle-names", () => { }); // https://phabricator.babeljs.io/T6957 - xit("labels should not shadow bindings", () => { + it("labels should not shadow bindings", () => { const source = unpad(` function foo() { var meh; @@ -201,6 +201,31 @@ describe("mangle-names", () => { expect(transform(source)).toBe(expected); }); + // https://github.com/babel/babili/issues/185 + it("labels should not shadow bindings 2", () => { + const source = unpad(` + function f(a) { + try { + a: { + console.log(a); + } + } catch ($a) {} + } + `); + + const expected = unpad(` + function f(b) { + try { + a: { + console.log(b); + } + } catch (c) {} + } + `); + + expect(transform(source)).toBe(expected); + }); + it("should be order independent", () => { const source = unpad(` function foo() { diff --git a/packages/babel-plugin-minify-mangle-names/src/index.js b/packages/babel-plugin-minify-mangle-names/src/index.js index d3a6d609f..4df3932a8 100644 --- a/packages/babel-plugin-minify-mangle-names/src/index.js +++ b/packages/babel-plugin-minify-mangle-names/src/index.js @@ -103,11 +103,37 @@ module.exports = ({ types: t }) => { } }); + // probably really bad for labels scope.removeBinding(oldName); + const newBinding = scope.getBinding(oldName); - faulty.forEach((f) => newBinding.reference(f)); + if (newBinding) { + // we found a binding in outer scopes + faulty.forEach((f) => newBinding.reference(f)); + } else { + // we might have a binding in the same scope + // slow + + // register binding + path.traverse({ + BindingIdentifier(bindingIdPath) { + if (bindingIdPath.parentPath.isLabeledStatement({ label: bindingIdPath.node })) { + return; + } + if (bindingIdPath.node.name === oldName) { + scope.registerDeclaration(bindingIdPath); + } + } + }); - continue; + // update references + const registeredBinding = scope.getBinding(oldName); + if (!registeredBinding) { + // I'm not sure what this is - a global? + return; + } + faulty.forEach((f) => registeredBinding.reference(f)); + } } } }