remap head variables when a closure is required in blockScoping transformer - fixes #763

This commit is contained in:
Sebastian McKenzie 2015-02-14 20:21:34 +11:00
parent e1151e08c9
commit 2a2dff0eaf
2 changed files with 31 additions and 3 deletions

View File

@ -124,7 +124,7 @@ BlockScoping.prototype.run = function () {
if (!this.hasLetReferences) return; if (!this.hasLetReferences) return;
if (needsClosure) { if (needsClosure) {
this.needsClosure(); this.wrapClosure();
} else { } else {
this.remap(); this.remap();
} }
@ -205,9 +205,28 @@ BlockScoping.prototype.remap = function () {
* Description * Description
*/ */
BlockScoping.prototype.needsClosure = function () { BlockScoping.prototype.wrapClosure = function () {
var block = this.block; var block = this.block;
var outsideRefs = this.outsideLetReferences;
// remap loop heads with colliding variables
if (this.loopParent) {
for (var name in outsideRefs) {
var id = outsideRefs[name];
if (this.scope.hasGlobal(id.name)) {
delete outsideRefs[id.name];
delete this.letReferences[id.name];
this.scope.rename(id.name);
this.letReferences[id.name] = id;
outsideRefs[id.name] = id;
}
}
}
// if we're inside of a for loop then we search to see if there are any // if we're inside of a for loop then we search to see if there are any
// `break`s, `continue`s, `return`s etc // `break`s, `continue`s, `return`s etc
this.has = this.checkLoop(); this.has = this.checkLoop();
@ -216,7 +235,7 @@ BlockScoping.prototype.needsClosure = function () {
this.hoistVarDeclarations(); this.hoistVarDeclarations();
// turn outsideLetReferences into an array // turn outsideLetReferences into an array
var params = values(this.outsideLetReferences); var params = values(outsideRefs);
// build the closure that we're going to wrap the block with // build the closure that we're going to wrap the block with
var fn = t.functionExpression(null, params, t.blockStatement(block.body)); var fn = t.functionExpression(null, params, t.blockStatement(block.body));

View File

@ -0,0 +1,9 @@
for (let i = 1; i < 3; i += 1) {
(function () {
i;
})();
}
assert.throws(function () {
i;
}, ReferenceError);