break up let scoping transformer some more

This commit is contained in:
Sebastian McKenzie
2014-11-09 21:25:14 +11:00
parent 5aff7709f7
commit ab2f652bdf

View File

@@ -161,12 +161,20 @@ var hoistVarDeclarations = function (block, pushDeclar) {
});
};
var getLetReferences = function (info, block, letReferences) {
var getParams = function (info, letReferences) {
var params = _.cloneDeep(letReferences);
_.each(params, function (param) {
param.name = info.duplicates[param.name] || param.name;
});
return params;
};
var getLetReferences = function (block, info, letReferences) {
var closurify = false;
// traverse through this block, stopping on functions and checking if they
// contain any outside let references
traverse(block, function (node, parent, opts) {
traverse(block, function (node, parent, scope) {
if (t.isFunction(node)) {
traverse(node, function (node, parent) {
// not an identifier so we have no use
@@ -177,7 +185,7 @@ var getLetReferences = function (info, block, letReferences) {
// this scope has a variable with the same name so it couldn't belong
// to our let scope
if (opts.scope.hasOwn(node.name)) return;
if (scope.hasOwn(node.name)) return;
closurify = true;
@@ -197,6 +205,25 @@ var getLetReferences = function (info, block, letReferences) {
return closurify;
};
var buildPushDeclar = function (body) {
return function (node) {
body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
var replace = [];
_.each(node.declarations, function (declar) {
if (!declar.init) return;
var expr = t.assignmentExpression("=", declar.id, declar.init);
replace.push(t.inherits(expr, declar));
});
return replace;
};
};
var run = function (forParent, block, parent, file, scope) {
if (block._letDone) return;
block._letDone = true;
@@ -216,7 +243,7 @@ var run = function (forParent, block, parent, file, scope) {
// returns whether or not there are any outside let references within any
// functions
var closurify = getLetReferences(info, block, letReferences);
var closurify = getLetReferences(block, info, letReferences);
letReferences = _.values(letReferences);
@@ -230,22 +257,7 @@ var run = function (forParent, block, parent, file, scope) {
var body = [];
// hoist a `VariableDeclaration` and add `AssignmentExpression`s in it's place
var pushDeclar = function (node) {
body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
var replace = [];
_.each(node.declarations, function (declar) {
if (!declar.init) return;
var expr = t.assignmentExpression("=", declar.id, declar.init);
replace.push(t.inherits(expr, declar));
});
return replace;
};
var pushDeclar = buildPushDeclar(body);
// hoist var references to retain scope
hoistVarDeclarations(block, pushDeclar);
@@ -260,11 +272,8 @@ var run = function (forParent, block, parent, file, scope) {
// replace the current block body with the one we've built
block.body = body;
// cahnge duplicate let references to their uid if they have one
var params = _.cloneDeep(letReferences);
_.each(params, function (param) {
param.name = info.duplicates[param.name] || param.name;
});
// change duplicate let references to their uid if they have one
var params = getParams(info, letReferences);
var call = t.callExpression(fn, params);
var ret = t.identifier(file.generateUid("ret", scope));