fix multiple references in experimental abstract references #207

This commit is contained in:
Sebastian McKenzie
2014-11-24 00:35:18 +11:00
parent 11ac6ff084
commit 49e7e3b998
6 changed files with 89 additions and 26 deletions

View File

@@ -13,9 +13,8 @@ function File(opts) {
this.opts = File.normaliseOptions(opts);
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
this.declarations = {};
this.uids = {};
this.ast = {};
this.uids = {};
this.ast = {};
}
File.declarations = [
@@ -123,8 +122,10 @@ File.prototype.addDeclaration = function (name) {
throw new ReferenceError("unknown declaration " + name);
}
var declar = this.declarations[name];
if (declar) return declar.uid;
var program = this.ast.program;
var declar = program._declarations && program._declarations[name];
if (declar) return declar.id;
var ref;
var runtimeNamespace = this.opts.runtime;
@@ -135,11 +136,8 @@ File.prototype.addDeclaration = function (name) {
ref = util.template(name);
}
var uid = t.identifier(this.generateUid(name));
this.declarations[name] = {
uid: uid,
node: ref
};
var uid = this.generateUidIdentifier(name);
this.scope.push(name, uid, ref);
return uid;
};

View File

@@ -1,12 +1,11 @@
var t = require("../../types");
var _ = require("lodash");
module.exports = function (ast, file) {
var body = ast.program.body;
for (var i in file.declarations) {
var declar = file.declarations[i];
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(declar.uid, declar.node)
exports.BlockStatement =
exports.Program = function (node, parent, file) {
_.each(node._declarations, function (declar) {
node.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(declar.id, declar.init)
]));
}
});
};

View File

@@ -8,23 +8,48 @@ var container = function (parent, call, ret) {
// we don't need to worry about return values
return call;
} else {
return t.sequenceExpression([call, ret]);
var exprs = [];
if (t.isSequenceExpression(call)) {
exprs = call.expressions;
} else {
exprs.push(call);
}
exprs.push(ret);
return t.sequenceExpression(exprs);
}
};
exports.AssignmentExpression = function (node, parent) {
exports.AssignmentExpression = function (node, parent, file, scope) {
var left = node.left;
if (!t.isVirtualPropertyExpression(left)) return;
var right = node.right;
var value = node.right;
var temp;
// we need to return `node.right`
if (!t.isExpressionStatement(parent)) {
// `node.right` isn't a simple identifier so we need to reference it
if (!t.isIdentifier(value)) {
var tempName = file.generateUid("temp");
temp = value = t.identifier(tempName);
scope.push(tempName, temp);
}
}
var call = util.template("abstract-expression-set", {
PROPERTY: left.property,
OBJECT: left.object,
VALUE: right
VALUE: value
});
return container(parent, call, right);
if (temp) {
call = t.sequenceExpression([
t.assignmentExpression("=", temp, node.right),
call
]);
}
return container(parent, call, value);
};
exports.UnaryExpression = function (node, parent) {
@@ -40,16 +65,33 @@ exports.UnaryExpression = function (node, parent) {
return container(parent, call, t.literal(true));
};
exports.CallExpression = function (node) {
exports.CallExpression = function (node, parent, file, scope) {
var callee = node.callee;
if (!t.isVirtualPropertyExpression(callee)) return;
var temp;
if (!t.isIdentifier(callee.object)) {
// we need to save `callee.object` so we can call it again
var tempName = file.generateUid("temp");
temp = t.identifier(tempName);
scope.push(tempName, temp);
}
var call = util.template("abstract-expression-call", {
PROPERTY: callee.property,
OBJECT: callee.object
OBJECT: temp || callee.object
});
call.arguments = call.arguments.concat(node.arguments);
return call;
if (temp) {
return t.sequenceExpression([
t.assignmentExpression("=", temp, callee.object),
call
]);
} else {
return call;
}
};
exports.VirtualPropertyExpression = function (node) {

View File

@@ -90,6 +90,7 @@ function traverse(parent, callbacks, opts) {
traverse.removeProperties = function (tree) {
var clear = function (node) {
delete node._scopeReferences;
delete node._declarations;
delete node.extendedRange;
delete node._parent;
delete node._scope;

View File

@@ -97,6 +97,25 @@ Scope.prototype.getReferences = function () {
return references;
};
Scope.prototype.push = function (name, id, init) {
var block = this.block;
if (t.isFor(block) || t.isCatchClause(block) || t.isFunction(block)) {
t.ensureBlock(block);
block = block.body;
}
if (t.isBlockStatement(block) || t.isProgram(block)) {
block._declarations = block._declarations || {};
block._declarations[name] = {
id: id,
init: init
};
} else {
throw new Error("wtf");
}
};
Scope.prototype.add = function (node, references) {
if (!node) return;
_.merge(references || this.references, t.getIds(node, true));