Search in sources :

Example 1 with TernaryValue

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;
}
Also used : ValueType(com.google.javascript.jscomp.NodeUtil.ValueType) TernaryValue(com.google.javascript.rhino.jstype.TernaryValue)

Aggregations

ValueType (com.google.javascript.jscomp.NodeUtil.ValueType)1 TernaryValue (com.google.javascript.rhino.jstype.TernaryValue)1