Search in sources :

Example 11 with CheckReturnValue

use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.

the class TypeInference method traverseAssign.

@CheckReturnValue
private FlowScope traverseAssign(Node n, FlowScope scope) {
    Node target = n.getFirstChild();
    Node value = n.getLastChild();
    if (target.isDestructuringPattern()) {
        scope = traverse(value, scope);
        JSType valueType = getJSType(value);
        n.setJSType(valueType);
        return traverseDestructuringPattern(target, scope, valueType, AssignmentType.ASSIGN);
    } else {
        scope = traverseChildren(n, scope);
        JSType valueType = getJSType(value);
        n.setJSType(valueType);
        return updateScopeForAssignment(scope, target, valueType, AssignmentType.ASSIGN);
    }
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Example 12 with CheckReturnValue

use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.

the class SemanticReverseAbstractInterpreter method caseIn.

/**
 * Given 'property in object', ensures that the object has the property in the informed scope by
 * defining it as a qualified name if the object type lacks the property and it's not in the blind
 * scope.
 *
 * @param object The node of the right-side of the in.
 * @param propertyName The string of the left-side of the in.
 */
@CheckReturnValue
private FlowScope caseIn(Node object, String propertyName, FlowScope blindScope) {
    JSType jsType = object.getJSType();
    jsType = jsType != null ? jsType.restrictByNotNullOrUndefined() : null;
    boolean hasProperty = false;
    ObjectType objectType = ObjectType.cast(jsType);
    if (objectType != null) {
        hasProperty = objectType.hasProperty(propertyName);
    }
    if (!hasProperty) {
        String qualifiedName = object.getQualifiedName();
        if (qualifiedName != null) {
            String propertyQualifiedName = qualifiedName + "." + propertyName;
            if (blindScope.getSlot(propertyQualifiedName) == null) {
                JSType unknownType = typeRegistry.getNativeType(JSTypeNative.UNKNOWN_TYPE);
                return blindScope.inferQualifiedSlot(object, propertyQualifiedName, unknownType, unknownType, false);
            }
        }
    }
    return blindScope;
}
Also used : ObjectType(com.google.javascript.rhino.jstype.ObjectType) JSType(com.google.javascript.rhino.jstype.JSType) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Example 13 with CheckReturnValue

use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.

the class SemanticReverseAbstractInterpreter method getPreciserScopeKnowingConditionOutcome.

@Override
@CheckReturnValue
public FlowScope getPreciserScopeKnowingConditionOutcome(Node condition, FlowScope blindScope, Outcome outcome) {
    // Check for the typeof operator.
    Token operatorToken = condition.getToken();
    switch(operatorToken) {
        case EQ:
        case NE:
        case SHEQ:
        case SHNE:
        case CASE:
            Node left;
            Node right;
            if (operatorToken == Token.CASE) {
                // the switch condition
                left = condition.getParent().getFirstChild();
                right = condition.getFirstChild();
            } else {
                left = condition.getFirstChild();
                right = condition.getLastChild();
            }
            Node typeOfNode = null;
            Node stringNode = null;
            if (left.isTypeOf() && right.isStringLit()) {
                typeOfNode = left;
                stringNode = right;
            } else if (right.isTypeOf() && left.isStringLit()) {
                typeOfNode = right;
                stringNode = left;
            }
            if (typeOfNode != null && stringNode != null) {
                Node operandNode = typeOfNode.getFirstChild();
                JSType operandType = getTypeIfRefinable(operandNode, blindScope);
                if (operandType != null) {
                    boolean resultEqualsValue = operatorToken == Token.EQ || operatorToken == Token.SHEQ || operatorToken == Token.CASE;
                    if (!outcome.isTruthy()) {
                        resultEqualsValue = !resultEqualsValue;
                    }
                    return caseTypeOf(operandNode, operandType, stringNode.getString(), resultEqualsValue, blindScope);
                }
            }
            break;
        default:
            break;
    }
    switch(operatorToken) {
        case AND:
            if (outcome.isTruthy()) {
                return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.TRUE);
            } else {
                return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.TRUE);
            }
        case OR:
            if (!outcome.isTruthy()) {
                return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.FALSE);
            } else {
                return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.FALSE);
            }
        case EQ:
            if (outcome.isTruthy()) {
                return caseEquality(condition, blindScope, EQ);
            } else {
                return caseEquality(condition, blindScope, NE);
            }
        case NE:
            if (outcome.isTruthy()) {
                return caseEquality(condition, blindScope, NE);
            } else {
                return caseEquality(condition, blindScope, EQ);
            }
        case SHEQ:
            if (outcome.isTruthy()) {
                return caseEquality(condition, blindScope, SHEQ);
            } else {
                return caseEquality(condition, blindScope, SHNE);
            }
        case SHNE:
            if (outcome.isTruthy()) {
                return caseEquality(condition, blindScope, SHNE);
            } else {
                return caseEquality(condition, blindScope, SHEQ);
            }
        case NAME:
        case GETPROP:
            return caseNameOrGetProp(condition, blindScope, outcome);
        case ASSIGN:
            return firstPreciserScopeKnowingConditionOutcome(condition.getFirstChild(), firstPreciserScopeKnowingConditionOutcome(condition.getSecondChild(), blindScope, outcome), outcome);
        case NOT:
            return firstPreciserScopeKnowingConditionOutcome(condition.getFirstChild(), blindScope, outcome.not());
        case LE:
        case LT:
        case GE:
        case GT:
            if (outcome.isTruthy()) {
                return caseEquality(condition, blindScope, ineq);
            }
            break;
        case INSTANCEOF:
            return caseInstanceOf(condition.getFirstChild(), condition.getLastChild(), blindScope, outcome);
        case IN:
            if (outcome.isTruthy() && condition.getFirstChild().isStringLit()) {
                return caseIn(condition.getLastChild(), condition.getFirstChild().getString(), blindScope);
            }
            break;
        case CASE:
            {
                Node left = // the switch condition
                condition.getParent().getFirstChild();
                Node right = condition.getFirstChild();
                if (outcome.isTruthy()) {
                    return caseEquality(left, right, blindScope, SHEQ);
                } else {
                    return caseEquality(left, right, blindScope, SHNE);
                }
            }
        case CALL:
            {
                Node left = condition.getFirstChild();
                String leftName = left.getQualifiedName();
                if ("Array.isArray".equals(leftName) && left.getNext() != null) {
                    return caseIsArray(left.getNext(), blindScope, outcome);
                }
                break;
            }
        default:
            break;
    }
    return nextPreciserScopeKnowingConditionOutcome(condition, blindScope, outcome);
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Example 14 with CheckReturnValue

use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.

the class SemanticReverseAbstractInterpreter method caseAndOrMaybeShortCircuiting.

@CheckReturnValue
private FlowScope caseAndOrMaybeShortCircuiting(Node left, Node right, FlowScope blindScope, Outcome outcome) {
    // Perform two separate refinements, one for if short-circuiting occurred, and one for if it did
    // not.  Because it's not clear whether short-circuiting occurred, we actually have to ignore
    // both separate result flow scopes individually, but if they both refined the same slot, we
    // can join the two refinements.  TODO(sdh): look into simplifying this.  If joining were
    // more efficient, we should just be able to join the scopes unconditionally?
    Set<String> refinements = new HashSet<>();
    blindScope = new RefinementTrackingFlowScope(blindScope, refinements);
    FlowScope leftScope = firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome.not());
    StaticTypedSlot leftVar = refinements.size() == 1 ? leftScope.getSlot(refinements.iterator().next()) : null;
    if (leftVar == null) {
        // must create a child instead.
        return unwrap(blindScope);
    }
    refinements.clear();
    // Note: re-wrap the scope, in case it was unwrapped by a nested call to this method.
    FlowScope rightScope = new RefinementTrackingFlowScope(firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome), refinements);
    rightScope = firstPreciserScopeKnowingConditionOutcome(right, rightScope, outcome.not());
    StaticTypedSlot rightVar = refinements.size() == 1 ? rightScope.getSlot(refinements.iterator().next()) : null;
    if (rightVar == null || !leftVar.getName().equals(rightVar.getName())) {
        return unwrap(blindScope);
    }
    JSType type = leftVar.getType().getLeastSupertype(rightVar.getType());
    return unwrap(blindScope).inferSlotType(leftVar.getName(), type);
}
Also used : StaticTypedSlot(com.google.javascript.rhino.jstype.StaticTypedSlot) JSType(com.google.javascript.rhino.jstype.JSType) HashSet(java.util.HashSet) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Example 15 with CheckReturnValue

use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.

the class SemanticReverseAbstractInterpreter method caseAndOrNotShortCircuiting.

@CheckReturnValue
private FlowScope caseAndOrNotShortCircuiting(Node left, Node right, FlowScope blindScope, Outcome outcome) {
    // left type
    JSType leftType = getTypeIfRefinable(left, blindScope);
    boolean leftIsRefineable;
    if (leftType != null) {
        leftIsRefineable = true;
    } else {
        leftIsRefineable = false;
        leftType = left.getJSType();
        blindScope = firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome);
    }
    // restricting left type
    JSType restrictedLeftType = (leftType == null) ? null : leftType.getRestrictedTypeGivenOutcome(outcome);
    if (restrictedLeftType == null) {
        return firstPreciserScopeKnowingConditionOutcome(right, blindScope, outcome);
    }
    blindScope = maybeRestrictName(blindScope, left, leftType, leftIsRefineable ? restrictedLeftType : null);
    // right type
    JSType rightType = getTypeIfRefinable(right, blindScope);
    boolean rightIsRefineable;
    if (rightType != null) {
        rightIsRefineable = true;
    } else {
        rightIsRefineable = false;
        rightType = right.getJSType();
        blindScope = firstPreciserScopeKnowingConditionOutcome(right, blindScope, outcome);
    }
    if (outcome.isTruthy()) {
        JSType restrictedRightType = (rightType == null) ? null : rightType.getRestrictedTypeGivenOutcome(outcome);
        // creating new scope
        return maybeRestrictName(blindScope, right, rightType, rightIsRefineable ? restrictedRightType : null);
    }
    return blindScope;
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Aggregations

CheckReturnValue (com.google.errorprone.annotations.CheckReturnValue)16 JSType (com.google.javascript.rhino.jstype.JSType)11 Node (com.google.javascript.rhino.Node)7 ObjectType (com.google.javascript.rhino.jstype.ObjectType)3 BugCheckerInfo (com.google.errorprone.BugCheckerInfo)2 SeverityLevel (com.google.errorprone.BugPattern.SeverityLevel)2 ErrorProneFlags (com.google.errorprone.ErrorProneFlags)2 HashSet (java.util.HashSet)2 LinkedHashMap (java.util.LinkedHashMap)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Predicate (com.google.common.base.Predicate)1 Supplier (com.google.common.base.Supplier)1 HashBiMap (com.google.common.collect.HashBiMap)1 ImmutableBiMap (com.google.common.collect.ImmutableBiMap)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Sets (com.google.common.collect.Sets)1 ErrorProneOptions (com.google.errorprone.ErrorProneOptions)1 Severity (com.google.errorprone.ErrorProneOptions.Severity)1