Search in sources :

Example 21 with JSType

use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.

the class NewTypeInference method collectTypesForEscapedVarsFwd.

/**
 * Used when analyzing a scope that defines variables used in inner scopes.
 * Returns a type environment that combines the types from all uses of a variable.
 */
private TypeEnv collectTypesForEscapedVarsFwd(Node n, TypeEnv env) {
    checkArgument(n.isFunction() || (n.isName() && NodeUtil.isInvocationTarget(n)), "Expected invovation target, found %s", n);
    String fnName = n.isFunction() ? symbolTable.getFunInternalName(n) : n.getString();
    NTIScope innerScope = this.currentScope.getScope(fnName);
    JSType summaryAsJstype = summaries.get(innerScope);
    if (summaryAsJstype == null) {
        // NOTE(dimvar): The n.isFromExterns part is here because the polymer pass does some weird
        // rewriting which AFAIU can copy some @polymerBehavior code from the externs to the source,
        // but the AST function nodes are still marked as externs, and don't have summaries.
        // We don't have a unit test for it.
        checkState(NodeUtil.isUnannotatedCallback(n) || n.isFromExterns());
        return env;
    }
    FunctionType summary = summaryAsJstype.getFunType();
    for (String freeVar : innerScope.getOuterVars()) {
        if (innerScope.getDeclaredTypeOf(freeVar) == null) {
            JSType outerType = envGetType(env, freeVar);
            if (outerType == null) {
                outerType = UNKNOWN;
            }
            JSType innerType = summary.getOuterVarPrecondition(freeVar);
            if (// haven't found an easy way to avoid false positives.
            !innerType.isLoose() && // so we don't warn for uninitialized variables.
            (n.isName() || (n.isFunction() && !outerType.isUndefined())) && !JSType.haveCommonSubtype(outerType, innerType)) {
                warnings.add(JSError.make(n, CROSS_SCOPE_GOTCHA, freeVar, outerType.toString(), innerType.toString()));
            }
            // If n is a callee node, we only want to keep the type in the callee.
            // If n is a function expression, we don't know if it will get called, so we take the
            // types from both scopes into account.
            JSType freeVarType;
            if (n.isFunction()) {
                // defined in this scope, and it's more likely that this type is correct.
                if (// only keep outerType for initialized variables
                !outerType.isNullOrUndef() && !outerType.isUnknown() && !innerType.isUnknown() && outerType.isSubtypeOf(innerType)) {
                    freeVarType = outerType;
                } else {
                    freeVarType = JSType.join(innerType, outerType);
                }
            } else {
                freeVarType = innerType;
            }
            env = envPutType(env, freeVar, freeVarType);
        }
    }
    return env;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) FunctionType(com.google.javascript.jscomp.newtypes.FunctionType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType)

Example 22 with JSType

use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.

the class NewTypeInference method maybeSetTypeI.

private void maybeSetTypeI(Node n, JSType t) {
    TypeI oldType = n.getTypeI();
    checkState(oldType == null || oldType instanceof JSType);
    // outer scope; we've already computed a good type for it, don't lose it.
    if (oldType == null) {
        n.setTypeI(t);
    }
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) TypeI(com.google.javascript.rhino.TypeI)

Example 23 with JSType

use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.

the class NewTypeInference method analyzeStrictComparisonFwd.

private EnvTypePair analyzeStrictComparisonFwd(Token comparisonOp, Node lhs, Node rhs, TypeEnv inEnv, JSType specializedType) {
    if (specializedType.isTrueOrTruthy() || specializedType.isFalseOrFalsy()) {
        if (lhs.isTypeOf()) {
            return analyzeSpecializedTypeof(lhs, rhs, comparisonOp, inEnv, specializedType);
        } else if (rhs.isTypeOf()) {
            return analyzeSpecializedTypeof(rhs, lhs, comparisonOp, inEnv, specializedType);
        } else if (isGoogTypeof(lhs)) {
            return analyzeGoogTypeof(lhs, rhs, inEnv, specializedType);
        } else if (isGoogTypeof(rhs)) {
            return analyzeGoogTypeof(rhs, lhs, inEnv, specializedType);
        }
    }
    EnvTypePair lhsPair = analyzeExprFwd(lhs, inEnv);
    EnvTypePair rhsPair = analyzeExprFwd(rhs, lhsPair.env);
    JSType rhstype = rhsPair.type;
    JSType lhstype = lhsPair.type;
    if (!rhstype.isNullOrUndef()) {
        if (JSType.haveCommonSubtype(lhstype, rhstype)) {
            registerImplicitUses(lhs, lhstype, rhstype);
        } else {
            JSError error = JSError.make(lhs, INCOMPATIBLE_STRICT_COMPARISON, lhstype.toString(), rhstype.toString());
            registerMismatchAndWarn(error, lhstype, rhstype);
        }
    }
    // This env may contain types that have been tightened after nullable deref.
    TypeEnv preciseEnv = rhsPair.env;
    if ((comparisonOp == Token.SHEQ && specializedType.isTrueOrTruthy()) || (comparisonOp == Token.SHNE && specializedType.isFalseOrFalsy())) {
        lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsPair.type.specialize(rhsPair.type));
        rhsPair = analyzeExprFwd(rhs, lhsPair.env, UNKNOWN, rhsPair.type.specialize(lhsPair.type));
    } else if ((comparisonOp == Token.SHEQ && specializedType.isFalseOrFalsy()) || (comparisonOp == Token.SHNE && specializedType.isTrueOrTruthy())) {
        JSType lhsType = lhsPair.type;
        JSType rhsType = rhsPair.type;
        if (lhsType.isNullOrUndef()) {
            rhsType = rhsType.removeType(lhsType);
        } else if (rhsType.isNullOrUndef()) {
            lhsType = lhsType.removeType(rhsType);
        }
        lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env, UNKNOWN, rhsType);
    }
    rhsPair.type = BOOLEAN;
    return rhsPair;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv)

Example 24 with JSType

use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.

the class NewTypeInference method analyzeArrayLitBwd.

private EnvTypePair analyzeArrayLitBwd(Node expr, TypeEnv outEnv) {
    TypeEnv env = outEnv;
    JSType elementType = BOTTOM;
    for (Node elm = expr.getLastChild(); elm != null; elm = elm.getPrevious()) {
        EnvTypePair pair = analyzeExprBwd(elm, env);
        env = pair.env;
        elementType = JSType.join(elementType, pair.type);
    }
    elementType = firstNonBottom(elementType, UNKNOWN);
    return new EnvTypePair(env, commonTypes.getArrayInstance(elementType));
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv)

Example 25 with JSType

use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.

the class NewTypeInference method analyzeReceiverLvalFwd.

private LValueResultFwd analyzeReceiverLvalFwd(Node obj, QualifiedName pname, TypeEnv inEnv, JSType propType) {
    // pname is null when the property name is not known.
    checkArgument(pname == null || pname.isIdentifier());
    JSType reqObjType = pickReqObjType(obj.getParent());
    if (pname != null) {
        reqObjType = reqObjType.withProperty(pname, propType);
    }
    LValueResultFwd lvalue = analyzeLValueFwd(obj, inEnv, reqObjType, true);
    EnvTypePair pair = mayWarnAboutNullableReferenceAndTighten(obj, lvalue.type, null, lvalue.env);
    JSType lvalueType = pair.type;
    if (lvalueType.isEnumElement()) {
        lvalueType = lvalueType.getEnumeratedTypeOfEnumElement();
    }
    if (!lvalueType.isSubtypeOf(TOP_OBJECT)) {
        warnings.add(JSError.make(obj, ADDING_PROPERTY_TO_NON_OBJECT, getPropNameForErrorMsg(obj.getParent()), lvalueType.toString()));
    }
    lvalue.type = lvalueType;
    lvalue.env = pair.env;
    return lvalue;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType)

Aggregations

JSType (com.google.javascript.jscomp.newtypes.JSType)86 Node (com.google.javascript.rhino.Node)60 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)54 TypeEnv (com.google.javascript.jscomp.newtypes.TypeEnv)28 DeclaredFunctionType (com.google.javascript.jscomp.newtypes.DeclaredFunctionType)20 QualifiedName (com.google.javascript.jscomp.newtypes.QualifiedName)18 FunctionType (com.google.javascript.jscomp.newtypes.FunctionType)16 Declaration (com.google.javascript.jscomp.newtypes.Declaration)5 FunctionTypeBuilder (com.google.javascript.jscomp.newtypes.FunctionTypeBuilder)5 FunctionNamespace (com.google.javascript.jscomp.newtypes.FunctionNamespace)4 Namespace (com.google.javascript.jscomp.newtypes.Namespace)4 ArrayList (java.util.ArrayList)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 TypeI (com.google.javascript.rhino.TypeI)3 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 NamespaceLit (com.google.javascript.jscomp.newtypes.NamespaceLit)2 NominalType (com.google.javascript.jscomp.newtypes.NominalType)2 RawNominalType (com.google.javascript.jscomp.newtypes.RawNominalType)2 JSDocInfo (com.google.javascript.rhino.JSDocInfo)2