break up let scoping

This commit is contained in:
Sebastian McKenzie
2014-11-09 20:31:46 +11:00
parent 19b115c76b
commit f4c81531ad

View File

@@ -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));
}