break up let scoping
This commit is contained in:
@@ -143,24 +143,25 @@ var checkFor = function (forParent, block) {
|
||||
return has;
|
||||
};
|
||||
|
||||
var run = function (forParent, block, parent, file, scope) {
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
var hoistVarDeclarations = function (block, pushDeclar) {
|
||||
traverse(block, function (node) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init)) {
|
||||
node.init = t.sequenceExpression(pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node)) {
|
||||
return pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var info = getInfo(block, file, scope);
|
||||
var declarators = info.declarators;
|
||||
var letKeys = info.keys;
|
||||
|
||||
// this is a block within a `Function` so we can safely leave it be
|
||||
if (t.isFunction(parent)) return;
|
||||
|
||||
// this block has no let references so let's clean up
|
||||
if (!letKeys.length) return noClosure(declarators, block, info.duplicates);
|
||||
|
||||
// outside let references that we need to wrap
|
||||
var letReferences = {};
|
||||
|
||||
// are there any outside let references within any functions?
|
||||
var getLetReferences = function (info, block, letReferences) {
|
||||
var closurify = false;
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
@@ -193,6 +194,30 @@ var run = function (forParent, block, parent, file, scope) {
|
||||
}
|
||||
});
|
||||
|
||||
return closurify;
|
||||
};
|
||||
|
||||
var run = function (forParent, block, parent, file, scope) {
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
|
||||
var info = getInfo(block, file, scope);
|
||||
var declarators = info.declarators;
|
||||
var letKeys = info.keys;
|
||||
|
||||
// this is a block within a `Function` so we can safely leave it be
|
||||
if (t.isFunction(parent)) return;
|
||||
|
||||
// this block has no let references so let's clean up
|
||||
if (!letKeys.length) return noClosure(declarators, block, info.duplicates);
|
||||
|
||||
// outside let references that we need to wrap
|
||||
var letReferences = {};
|
||||
|
||||
// returns whether or not there are any outside let references within any
|
||||
// functions
|
||||
var closurify = getLetReferences(info, block, letReferences);
|
||||
|
||||
letReferences = _.values(letReferences);
|
||||
|
||||
// no need for a closure so let's clean up
|
||||
@@ -223,21 +248,7 @@ var run = function (forParent, block, parent, file, scope) {
|
||||
};
|
||||
|
||||
// hoist var references to retain scope
|
||||
traverse(block, function (node) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init)) {
|
||||
node.init = t.sequenceExpression(pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node)) {
|
||||
return pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
hoistVarDeclarations(block, pushDeclar);
|
||||
|
||||
// set let references to plain var references
|
||||
standardiseLets(declarators);
|
||||
@@ -299,7 +310,6 @@ var run = function (forParent, block, parent, file, scope) {
|
||||
|
||||
body.push(t.switchStatement(ret, cases));
|
||||
}
|
||||
|
||||
} else {
|
||||
body.push(t.expressionStatement(call));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user