Fix setting deopt properly after evaluating multiple expressions (#6882)

This commit is contained in:
Brian Ng 2017-11-22 19:06:57 -06:00 committed by Henry Zhu
parent edbf5d33dc
commit c583a04a55
2 changed files with 49 additions and 5 deletions

View File

@ -211,11 +211,11 @@ function _evaluate(path, state) {
if (path.isArrayExpression()) {
const arr = [];
const elems: Array<NodePath> = path.get("elements");
for (let elem of elems) {
elem = elem.evaluate();
for (const elem of elems) {
const elemValue = elem.evaluate();
if (elem.confident) {
arr.push(elem.value);
if (elemValue.confident) {
arr.push(elemValue.value);
} else {
return deopt(elem, state);
}
@ -268,7 +268,7 @@ function _evaluate(path, state) {
switch (node.operator) {
case "||":
// TODO consider having a "truthy type" that doesn't bail on
// left uncertainity but can still evaluate to truthy.
// left uncertainty but can still evaluate to truthy.
if (left && leftConfident) {
state.confident = true;
return left;

View File

@ -216,4 +216,48 @@ describe("evaluation", function() {
"\\d",
);
});
it("sets deopt properly when not confident after evaluating multiple expressions", () => {
const ast = parse(`
const parts = [foo, bar];
console.log(parts.join('-'));
`);
let result;
traverse(ast, {
MemberExpression: {
enter(path) {
result = path.get("object").evaluate();
},
},
});
assert.strictEqual(result.confident, false);
assert.strictEqual(result.deopt.type, "Identifier");
assert.strictEqual(result.deopt.node.name, "foo");
});
it("sets deopt properly when confident after evaluating multiple expressions", () => {
const ast = parse(`
const foo = 'foo';
const bar = 'bar';
const parts = [foo, bar];
console.log(parts.join('-'))
`);
let result;
traverse(ast, {
MemberExpression: {
enter(path) {
result = path.get("object").evaluate();
},
},
});
assert.strictEqual(result.confident, true);
assert.strictEqual(result.deopt, null);
assert.deepStrictEqual(result.value, ["foo", "bar"]);
});
});