fix remaining AssignmentExpression LHS ReferencedIdentifier bugs

This commit is contained in:
Sebastian McKenzie 2015-06-04 22:43:50 +01:00
parent d5e7b5616c
commit 5aef7afade
4 changed files with 77 additions and 25 deletions

View File

@ -2,18 +2,29 @@ import getFunctionArity from "./get-function-arity";
import * as util from "../../util";
import * as t from "../../types";
function visitIdentifier(context, node, scope, state) {
// check if this node matches our function id
if (node.name !== state.name) return;
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.getBindingIdentifier(state.name);
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
context.stop();
}
var visitor = {
ReferencedIdentifier(node, parent, scope, state) {
// check if this node matches our function id
if (node.name !== state.name) return;
visitIdentifier(this, node, scope, state);
},
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.getBindingIdentifier(state.name);
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
this.stop();
AssignmentExpression(node, parent, scope, state) {
var ids = this.getBindingIdentifiers();
for (var name in ids) {
visitIdentifier(this, ids[name], scope, state);
}
}
};

View File

@ -1,28 +1,59 @@
import * as t from "../../../types";
function buildAssert(node, file) {
return t.callExpression(
file.addHelper("temporal-assert-defined"),
[node, t.literal(node.name), file.addHelper("temporal-undefined")]
);
}
function references(node, scope, state) {
var declared = state.letRefs[node.name];
if (!declared) return false;
// declared node is different in this scope
return scope.getBindingIdentifier(node.name) === declared;
}
var visitor = {
ReferencedIdentifier(node, parent, scope, state) {
if (t.isFor(parent) && parent.left === node) return;
var declared = state.letRefs[node.name];
if (!declared) return;
if (!references(node, scope, state)) return;
// declared node is different in this scope
if (scope.getBindingIdentifier(node.name) !== declared) return;
var assert = t.callExpression(
state.file.addHelper("temporal-assert-defined"),
[node, t.literal(node.name), state.file.addHelper("temporal-undefined")]
);
var assert = buildAssert(node, state.file);
this.skip();
if (t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) {
if (t.isUpdateExpression(parent)) {
if (parent._ignoreBlockScopingTDZ) return;
this.parentPath.replaceWith(t.sequenceExpression([assert, parent]));
} else {
return t.logicalExpression("&&", assert, node);
}
},
AssignmentExpression: {
exit(node, parent, scope, state) {
if (node._ignoreBlockScopingTDZ) return;
var nodes = [];
var ids = this.getBindingIdentifiers();
for (var name in ids) {
var id = ids[name];
if (references(id, scope, state)) {
nodes.push(buildAssert(id, state.file));
}
}
if (nodes.length) {
node._ignoreBlockScopingTDZ = true;
nodes.push(node);
return nodes.map(t.expressionStatement);
}
}
}
};

View File

@ -119,6 +119,10 @@ export function updateSiblingKeys(fromIndex, incrementBy) {
}
}
/**
* Description
*/
/**
* Description
*/

View File

@ -30,27 +30,33 @@ export function getBindingIdentifiers(node: Object): Object {
}
getBindingIdentifiers.keys = {
ComprehensionBlock: "left",
CatchClause: "param",
UnaryExpression: "argument",
AssignmentExpression: "left",
ImportSpecifier: "local",
ImportNamespaceSpecifier: "local",
ImportDefaultSpecifier: "local",
VariableDeclarator: "id",
ImportDeclaration: "specifiers",
FunctionDeclaration: "id",
FunctionExpression: "id",
ClassDeclaration: "id",
ClassExpression: "id",
SpreadElement: "argument",
RestElement: "argument",
UpdateExpression: "argument",
SpreadProperty: "argument",
Property: "value",
ComprehensionBlock: "left",
AssignmentPattern: "left",
ComprehensionExpression: "blocks",
ImportDeclaration: "specifiers",
VariableDeclaration: "declarations",
ArrayPattern: "elements",
ObjectPattern: "properties"
ObjectPattern: "properties",
VariableDeclaration: "declarations",
VariableDeclarator: "id"
};