Merge pull request #2293 from andrewimm/master
Allow more certainty when evaluating Logical Expressions
This commit is contained in:
commit
f18f79cc6d
@ -141,12 +141,28 @@ export function evaluate(): { confident: boolean; value: any } {
|
||||
}
|
||||
|
||||
if (path.isLogicalExpression()) {
|
||||
// If we are confident that one side of an && is false, or one side of
|
||||
// an || is true, we can be confident about the entire expression
|
||||
let wasConfident = confident;
|
||||
let left = evaluate(path.get("left"));
|
||||
let leftConfident = confident;
|
||||
confident = wasConfident;
|
||||
let right = evaluate(path.get("right"));
|
||||
let rightConfident = confident;
|
||||
let uncertain = leftConfident !== rightConfident;
|
||||
confident = leftConfident && rightConfident;
|
||||
|
||||
switch (node.operator) {
|
||||
case "||": return left || right;
|
||||
case "&&": return left && right;
|
||||
case "||":
|
||||
if ((left || right) && uncertain) {
|
||||
confident = true;
|
||||
}
|
||||
return left || right;
|
||||
case "&&":
|
||||
if ((!left && leftConfident) || (!right && rightConfident)) {
|
||||
confident = true;
|
||||
}
|
||||
return left && right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
164
packages/babel/test/evaluation.js
Normal file
164
packages/babel/test/evaluation.js
Normal file
@ -0,0 +1,164 @@
|
||||
var evaluation = require("../lib/traversal/path/evaluation");
|
||||
var traverse = require('../lib/traversal');
|
||||
var parse = require("../lib/helpers/parse");
|
||||
var assert = require("assert");
|
||||
|
||||
suite("evaluation", function () {
|
||||
test("binary expression", function () {
|
||||
traverse(parse("5 + 5"), {
|
||||
enter: function (node) {
|
||||
if (this.isBinaryExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: 10 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'str' === 'str'"), {
|
||||
enter: function(node) {
|
||||
if (this.isBinaryExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'four' === 4"), {
|
||||
enter: function(node) {
|
||||
if (this.isBinaryExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("logical expression", function () {
|
||||
traverse(parse("'abc' === 'abc' && 1 === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'abc' && 1 === 10"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' && 1 === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' && 1 === 10"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'abc' || 1 === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'abc' || 1 === 10"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' || 1 === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' || 1 === 10"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test("logical expression without certainty", function () {
|
||||
traverse(parse("'abc' === 'abc' || config.flag === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("obj.a === 'abc' || config.flag === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: false, value: undefined });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' !== 'abc' && config.flag === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: false });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("obj.a === 'abc' && 1 === 1"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: false, value: undefined });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'abc' && (1 === 1 || config.flag)"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' || (1 === 1 && config.flag)"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: false, value: undefined });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'xyz' || (1 === 1 && 'four' === 'four')"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
traverse(parse("'abc' === 'abc' && (1 === 1 && 'four' === 'four')"), {
|
||||
enter: function(node) {
|
||||
if (this.isLogicalExpression()) {
|
||||
assert.deepEqual(this.evaluate(), { confident: true, value: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user