diff --git a/packages/babel-traverse/src/path/evaluation.js b/packages/babel-traverse/src/path/evaluation.js index 60de0dcbea..0d1175172b 100644 --- a/packages/babel-traverse/src/path/evaluation.js +++ b/packages/babel-traverse/src/path/evaluation.js @@ -211,11 +211,11 @@ function _evaluate(path, state) { if (path.isArrayExpression()) { const arr = []; const elems: Array = 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; diff --git a/packages/babel-traverse/test/evaluation.js b/packages/babel-traverse/test/evaluation.js index ccff086fc4..b49fff158e 100644 --- a/packages/babel-traverse/test/evaluation.js +++ b/packages/babel-traverse/test/evaluation.js @@ -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"]); + }); });