Search in sources :

Example 56 with JSType

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

the class NewTypeInference method analyzeYieldFwd.

private EnvTypePair analyzeYieldFwd(Node expr, TypeEnv inEnv) {
    if (!expr.hasChildren()) {
        return new EnvTypePair(envPutType(inEnv, YIELDVAL_ID, UNDEFINED), UNKNOWN);
    }
    EnvTypePair resultPair = analyzeExprFwd(expr.getFirstChild(), inEnv);
    // Getting the instantiated declared return type
    JSType iterable = this.commonTypes.getIterableInstance(UNKNOWN);
    JSType iterator = this.commonTypes.getIteratorInstance(UNKNOWN);
    JSType generator = this.commonTypes.getGeneratorInstance(UNKNOWN);
    JSType declRetType = getDeclaredReturnTypeOfCurrentScope(generator);
    JSType yieldType;
    if (!generator.isSubtypeOf(declRetType)) {
        // Return early due to unexpected declared return type, but do not warn
        // Warning will be generated in createSummary of the function
        resultPair.type = UNKNOWN;
        return resultPair;
    } else if (declRetType.isSubtypeOf(iterable)) {
        // This check and implementation is in lieu of calling a hypothetical unifyWithSupertype()
        // method on generator.
        yieldType = declRetType.getInstantiatedTypeArgument(iterable);
    } else if (declRetType.isSubtypeOf(iterator)) {
        yieldType = declRetType.getInstantiatedTypeArgument(iterator);
    } else {
        // declRetType is neither subtype of iterable nor iterator. This means we do not know
        // anything about the yield type.
        yieldType = UNKNOWN;
    }
    // Getting the actual ret type
    JSType actualRetType;
    if (expr.isYieldAll()) {
        JSType boxedType = resultPair.type.autobox();
        if (boxedType.isSubtypeOf(iterable)) {
            actualRetType = boxedType.getInstantiatedTypeArgument(iterable);
        } else {
            warnings.add(JSError.make(expr, YIELD_ALL_EXPECTS_ITERABLE, resultPair.type.toString()));
            resultPair.type = UNKNOWN;
            return resultPair;
        }
    } else {
        actualRetType = resultPair.type;
    }
    if (!yieldType.isBottom() && !actualRetType.isSubtypeOf(yieldType)) {
        // Do not warn if yieldType is bottom because this only happens when unification returns
        // an empty list, which means the declRetType is Generator<?>
        registerMismatchAndWarn(JSError.make(expr, YIELD_NONDECLARED_TYPE, errorMsgWithTypeDiff(yieldType, actualRetType)), actualRetType, yieldType);
        resultPair.type = UNKNOWN;
        return resultPair;
    }
    if (yieldType.isBottom() || yieldType.isUnknown()) {
        // Infer the instantiated yield type of the function if there is no declared type.
        JSType oldType = envGetType(resultPair.env, YIELDVAL_ID);
        if (oldType == null) {
            resultPair.env = envPutType(resultPair.env, YIELDVAL_ID, actualRetType);
        } else {
            resultPair.env = envPutType(resultPair.env, YIELDVAL_ID, JSType.join(oldType, actualRetType));
        }
    }
    resultPair.type = UNKNOWN;
    return resultPair;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType)

Example 57 with JSType

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

the class NTIScope method getLocalDeclaration.

private Declaration getLocalDeclaration(String name, boolean includeTypes) {
    checkArgument(!name.contains("."));
    if (!isDefinedLocally(name, includeTypes)) {
        return null;
    }
    DeclaredFunctionType declaredType = getDeclaredTypeForOwnBody();
    JSType type = null;
    boolean isTypeVar = false;
    if ("this".equals(name)) {
        type = getDeclaredTypeOf("this");
    } else if (locals.containsKey(name)) {
        type = locals.get(name).getDeclaredType();
    } else if (formals.contains(name)) {
        int formalIndex = formals.indexOf(name);
        if (declaredType != null && formalIndex != -1) {
            JSType formalType = declaredType.getFormalType(formalIndex);
            if (formalType != null && !formalType.isBottom()) {
                type = formalType;
            }
        }
    } else if (localFunDefs.containsKey(name)) {
        // external function namespaces, don't rely on localFunDefs
        if (isFrozen && externs.containsKey(name)) {
            type = externs.get(name);
        }
    } else if (localTypedefs.containsKey(name) || localNamespaces.containsKey(name)) {
    // Any further declarations are shadowed
    } else if (declaredType != null && declaredType.isTypeVariableDefinedLocally(name)) {
        isTypeVar = true;
        type = JSType.fromTypeVar(this.commonTypes, declaredType.getTypeVariableDefinedLocally(name));
    } else if (externs.containsKey(name)) {
        type = externs.get(name);
    }
    Namespace ns = null;
    if (localNamespaces.containsKey(name)) {
        ns = localNamespaces.get(name);
    } else if (preservedNamespaces != null) {
        ns = preservedNamespaces.get(name);
    }
    return new Declaration(type, localTypedefs.get(name), ns, localFunDefs.get(name), isTypeVar, constVars.contains(name));
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType) Declaration(com.google.javascript.jscomp.newtypes.Declaration) Namespace(com.google.javascript.jscomp.newtypes.Namespace) FunctionNamespace(com.google.javascript.jscomp.newtypes.FunctionNamespace)

Example 58 with JSType

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

the class NewTypeInference method analyzeNonStrictComparisonFwd.

private EnvTypePair analyzeNonStrictComparisonFwd(Node expr, TypeEnv inEnv, JSType specializedType) {
    Token tokenType = expr.getToken();
    Node lhs = expr.getFirstChild();
    Node rhs = expr.getLastChild();
    if (specializedType.isTrueOrTruthy() || specializedType.isFalseOrFalsy()) {
        if (lhs.isTypeOf()) {
            return analyzeSpecializedTypeof(lhs, rhs, tokenType, inEnv, specializedType);
        } else if (rhs.isTypeOf()) {
            return analyzeSpecializedTypeof(rhs, lhs, tokenType, 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);
    // This env may contain types that have been tightened after nullable deref.
    TypeEnv preciseEnv = rhsPair.env;
    JSType lhsType = lhsPair.type;
    JSType rhsType = rhsPair.type;
    if ((tokenType == Token.EQ && specializedType.isTrueOrTruthy()) || (tokenType == Token.NE && specializedType.isFalseOrFalsy())) {
        if (lhsType.isNullOrUndef()) {
            rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, NULL_OR_UNDEFINED);
        } else if (rhsType.isNullOrUndef()) {
            lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, NULL_OR_UNDEFINED);
            rhsPair = analyzeExprFwd(rhs, lhsPair.env);
        } else if (!NULL.isSubtypeOf(lhsType) && !UNDEFINED.isSubtypeOf(lhsType)) {
            rhsType = rhsType.removeType(NULL_OR_UNDEFINED);
            rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, rhsType);
        } else if (!NULL.isSubtypeOf(rhsType) && !UNDEFINED.isSubtypeOf(rhsType)) {
            lhsType = lhsType.removeType(NULL_OR_UNDEFINED);
            lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
            rhsPair = analyzeExprFwd(rhs, lhsPair.env);
        }
    } else if ((tokenType == Token.EQ && specializedType.isFalseOrFalsy()) || (tokenType == Token.NE && specializedType.isTrueOrTruthy())) {
        if (lhsType.isNullOrUndef()) {
            rhsType = rhsType.removeType(NULL_OR_UNDEFINED);
            rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, rhsType);
        } else if (rhsType.isNullOrUndef()) {
            lhsType = lhsType.removeType(NULL_OR_UNDEFINED);
            lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
            rhsPair = analyzeExprFwd(rhs, lhsPair.env);
        }
    }
    rhsPair.type = BOOLEAN;
    return rhsPair;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) Token(com.google.javascript.rhino.Token) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv)

Example 59 with JSType

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

the class NewTypeInference method analyzeAssignBwd.

private EnvTypePair analyzeAssignBwd(Node expr, TypeEnv outEnv, JSType requiredType) {
    if (expr.getBooleanProp(Node.ANALYZED_DURING_GTI)) {
        return new EnvTypePair(outEnv, requiredType);
    }
    Node lhs = expr.getFirstChild();
    Node rhs = expr.getLastChild();
    if (lhs.getBooleanProp(Node.ANALYZED_DURING_GTI)) {
        return analyzeExprBwd(rhs, outEnv, markAndGetTypeOfPreanalyzedNode(lhs, outEnv, false));
    }
    // Here we analyze the LHS twice:
    // Once to find out what should be removed for the slicedEnv,
    // and again to take into account the side effects of the LHS itself.
    LValueResultBwd lvalue = analyzeLValueBwd(lhs, outEnv, requiredType, true);
    TypeEnv slicedEnv = lvalue.env;
    JSType rhsReqType = specializeKeep2ndWhenBottom(lvalue.type, requiredType);
    EnvTypePair pair = analyzeExprBwd(rhs, slicedEnv, rhsReqType);
    pair.env = analyzeLValueBwd(lhs, pair.env, requiredType, true).env;
    return pair;
}
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 60 with JSType

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

the class SimpleInference method inferCallNew.

private JSType inferCallNew(Node n, NTIScope scope) {
    Node callee = n.getFirstChild();
    // compiler for i18n.
    if (callee.matchesQualifiedName("goog.getMsg")) {
        return this.commonTypes.STRING;
    }
    FunctionType funType = inferFunction(callee, scope);
    if (funType == null) {
        return null;
    }
    if (funType.isGeneric()) {
        funType = inferInstantiatedCallee(n, funType, true, scope);
        if (funType == null) {
            return null;
        }
    }
    JSType retType = n.isNew() ? funType.getThisType() : funType.getReturnType();
    return retType;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) FunctionType(com.google.javascript.jscomp.newtypes.FunctionType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType)

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