From 7fc2fe41af2b25c1c04ab01f41cb7171534f624b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Wed, 19 Nov 2014 13:46:00 +1100 Subject: [PATCH] fix bug in let scoping resulting in unneccesary replacement - closes #193, closes #185 --- .../transformers/let-scoping.js | 25 +++++++++++++------ .../let-scoping/exec-block-scoped/exec.js | 7 ++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/6to5/transformation/transformers/let-scoping.js b/lib/6to5/transformation/transformers/let-scoping.js index 6741207e7e..a56d6af6b7 100644 --- a/lib/6to5/transformation/transformers/let-scoping.js +++ b/lib/6to5/transformation/transformers/let-scoping.js @@ -88,6 +88,9 @@ LetScoping.prototype.run = function () { this.info = this.getInfo(); + // remap all let references that exist in upper scopes to their uid + this.remap(); + // this is a block within a `Function` so we can safely leave it be if (t.isFunction(this.parent)) return this.noClosure(); @@ -138,23 +141,29 @@ LetScoping.prototype.run = function () { }; /** - * There are no let references accessed within a closure so we can just traverse - * through this block and replace all references that exist in a higher scope to - * their uids. + * There are no let references accessed within a closure so we can just turn the + * lets into vars. */ LetScoping.prototype.noClosure = function () { - var replacements = this.info.duplicates; - var declarators = this.info.declarators; - var block = this.block; + standardiseLets(this.info.declarators); +}; - standardiseLets(declarators); +/** + * Traverse through block and replace all references that exist in a higher + * scope to their uids. + */ + +LetScoping.prototype.remap = function () { + var replacements = this.info.duplicates; + var block = this.block; if (_.isEmpty(replacements)) return; - var replace = function (node, parent) { + var replace = function (node, parent, scope) { if (!t.isIdentifier(node)) return; if (!t.isReferenced(node, parent)) return; + if (scope && scope.hasOwn(node.name)) return; node.name = replacements[node.name] || node.name; }; diff --git a/test/fixtures/transformation/let-scoping/exec-block-scoped/exec.js b/test/fixtures/transformation/let-scoping/exec-block-scoped/exec.js index 8b1fd6db2b..d90256cbb2 100644 --- a/test/fixtures/transformation/let-scoping/exec-block-scoped/exec.js +++ b/test/fixtures/transformation/let-scoping/exec-block-scoped/exec.js @@ -2,5 +2,12 @@ let x = 1; { let x = 2; assert.equal(x, 2); + { + let x = 3; + assert.equal(x, 3); + + x++; + assert.equal(x, 4); + } } assert.equal(x, 1);