use of com.google.javascript.rhino.jstype.TernaryValue in project closure-compiler by google.
the class PeepholeFoldConstants method tryStrictEqualityComparison.
/**
* http://www.ecma-international.org/ecma-262/6.0/#sec-strict-equality-comparison
*/
private static TernaryValue tryStrictEqualityComparison(Node left, Node right) {
// First, try to evaluate based on the general type.
ValueType leftValueType = NodeUtil.getKnownValueType(left);
ValueType rightValueType = NodeUtil.getKnownValueType(right);
if (leftValueType != ValueType.UNDETERMINED && rightValueType != ValueType.UNDETERMINED) {
// Strict equality can only be true for values of the same type.
if (leftValueType != rightValueType) {
return TernaryValue.FALSE;
}
switch(leftValueType) {
case VOID:
case NULL:
return TernaryValue.TRUE;
case NUMBER:
{
if (NodeUtil.isNaN(left)) {
return TernaryValue.FALSE;
}
if (NodeUtil.isNaN(right)) {
return TernaryValue.FALSE;
}
Double lv = NodeUtil.getNumberValue(left);
Double rv = NodeUtil.getNumberValue(right);
if (lv != null && rv != null) {
return TernaryValue.forBoolean(lv.doubleValue() == rv.doubleValue());
}
break;
}
case STRING:
{
String lv = NodeUtil.getStringValue(left);
String rv = NodeUtil.getStringValue(right);
if (lv != null && rv != null) {
// equal if one contains \v.
if (lv.indexOf('\u000B') != -1 || rv.indexOf('\u000B') != -1) {
return TernaryValue.UNKNOWN;
} else {
return lv.equals(rv) ? TernaryValue.TRUE : TernaryValue.FALSE;
}
} else if (left.isTypeOf() && right.isTypeOf() && left.getFirstChild().isName() && right.getFirstChild().isName() && left.getFirstChild().getString().equals(right.getFirstChild().getString())) {
// Special case, typeof a == typeof a is always true.
return TernaryValue.TRUE;
}
break;
}
case BOOLEAN:
{
TernaryValue lv = NodeUtil.getPureBooleanValue(left);
TernaryValue rv = NodeUtil.getPureBooleanValue(right);
return lv.and(rv).or(lv.not().and(rv.not()));
}
default:
// Symbol and Object cannot be folded in the general case.
return TernaryValue.UNKNOWN;
}
}
// Any strict equality comparison against NaN returns false.
if (NodeUtil.isNaN(left) || NodeUtil.isNaN(right)) {
return TernaryValue.FALSE;
}
return TernaryValue.UNKNOWN;
}
Aggregations