Search in sources :

Example 21 with TypeEnv

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

the class NewTypeInference method analyzeObjLitBwd.

private EnvTypePair analyzeObjLitBwd(Node objLit, TypeEnv outEnv, JSType requiredType) {
    if (NodeUtil.isEnumDecl(objLit.getParent())) {
        return analyzeEnumObjLitBwd(objLit, outEnv, requiredType);
    }
    TypeEnv env = outEnv;
    JSType result = pickReqObjType(objLit);
    for (Node prop = objLit.getLastChild(); prop != null; prop = prop.getPrevious()) {
        if (prop.isGetterDef() || prop.isSetterDef()) {
            env = analyzeExprBwd(prop.getFirstChild(), env).env;
        } else if (prop.isComputedProp() && !prop.getFirstChild().isString()) {
            env = analyzeExprBwd(prop, env).env;
        } else {
            QualifiedName pname = new QualifiedName(NodeUtil.getObjectLitKeyName(prop));
            JSType jsdocType = (JSType) prop.getTypeI();
            JSType reqPtype;
            if (jsdocType != null) {
                reqPtype = jsdocType;
            } else if (requiredType.mayHaveProp(pname)) {
                reqPtype = requiredType.getProp(pname);
            } else {
                reqPtype = UNKNOWN;
            }
            EnvTypePair pair = analyzeExprBwd(prop, env, reqPtype);
            result = result.withProperty(pname, pair.type);
            env = pair.env;
        }
    }
    return new EnvTypePair(env, result);
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) QualifiedName(com.google.javascript.jscomp.newtypes.QualifiedName) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv)

Example 22 with TypeEnv

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

the class NewTypeInference method getExitTypeEnv.

private TypeEnv getExitTypeEnv() {
    for (int i = 0; i < exitEnvs.size(); i++) {
        TypeEnv env = exitEnvs.get(i);
        exitEnvs.set(i, envPutType(env, RETVAL_ID, BOTTOM));
    }
    if (!this.cfg.getImplicitReturn().getInEdges().isEmpty()) {
        exitEnvs.add(getInEnv(this.cfg.getImplicitReturn()));
    }
    checkState(!exitEnvs.isEmpty(), "There must be at least one exit env, either from a normal function exit or a throw.");
    return TypeEnv.join(exitEnvs);
}
Also used : TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv)

Example 23 with TypeEnv

use of com.google.javascript.jscomp.newtypes.TypeEnv 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 24 with TypeEnv

use of com.google.javascript.jscomp.newtypes.TypeEnv 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 25 with TypeEnv

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

the class NewTypeInference method createSummary.

private void createSummary(NTIScope fn) {
    Node fnRoot = fn.getRoot();
    checkArgument(!fnRoot.isFromExterns());
    FunctionTypeBuilder builder = new FunctionTypeBuilder(this.commonTypes);
    TypeEnv entryEnv = getEntryTypeEnv();
    TypeEnv exitEnv = getExitTypeEnv();
    DeclaredFunctionType declType = fn.getDeclaredFunctionType();
    int reqArity = declType.getRequiredArity();
    int optArity = declType.getOptionalArity();
    if (declType.isGeneric()) {
        builder.addTypeParameters(declType.getTypeParameters());
    }
    // Every trailing undeclared formal whose inferred type is ?
    // or contains undefined can be marked as optional.
    List<String> formals = fn.getFormals();
    for (int i = reqArity - 1; i >= 0; i--) {
        JSType formalType = declType.getFormalType(i);
        if (formalType != null) {
            break;
        }
        String formalName = formals.get(i);
        formalType = getTypeAfterFwd(formalName, entryEnv, exitEnv);
        if (formalType.isUnknown() || UNDEFINED.isSubtypeOf(formalType)) {
            reqArity--;
        } else {
            break;
        }
    }
    // Collect types of formals in the builder
    int i = 0;
    for (String formalName : formals) {
        JSType formalType = declType.getFormalType(i);
        if (formalType == null) {
            formalType = getTypeAfterFwd(formalName, entryEnv, exitEnv);
        }
        if (i < reqArity) {
            builder.addReqFormal(formalType);
        } else if (i < optArity) {
            builder.addOptFormal(formalType);
        }
        i++;
    }
    if (declType.hasRestFormals()) {
        builder.addRestFormals(declType.getFormalType(i));
    }
    for (String outer : fn.getOuterVars()) {
        println("Free var ", outer, " going in summary");
        builder.addOuterVarPrecondition(outer, envGetType(entryEnv, outer));
    }
    builder.addNominalType(declType.getNominalType());
    builder.addReceiverType(declType.getReceiverType());
    builder.addAbstract(declType.isAbstract());
    addRetTypeAndWarn(fn, exitEnv, declType, builder);
    JSType summary = commonTypes.fromFunctionType(builder.buildFunction());
    println("Function summary for ", fn.getReadableName());
    println("\t", summary);
    summary = changeTypeIfFunctionNamespace(fn, summary);
    summaries.put(fn, summary);
    maybeSetTypeI(fnRoot, summary);
    Node fnNameNode = NodeUtil.getNameNode(fnRoot);
    if (fnNameNode != null) {
        maybeSetTypeI(fnNameNode, summary);
    }
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv) FunctionTypeBuilder(com.google.javascript.jscomp.newtypes.FunctionTypeBuilder)

Aggregations

TypeEnv (com.google.javascript.jscomp.newtypes.TypeEnv)35 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)30 Node (com.google.javascript.rhino.Node)30 JSType (com.google.javascript.jscomp.newtypes.JSType)28 DeclaredFunctionType (com.google.javascript.jscomp.newtypes.DeclaredFunctionType)9 FunctionType (com.google.javascript.jscomp.newtypes.FunctionType)7 QualifiedName (com.google.javascript.jscomp.newtypes.QualifiedName)7 FunctionTypeBuilder (com.google.javascript.jscomp.newtypes.FunctionTypeBuilder)4 DiGraphEdge (com.google.javascript.jscomp.graph.DiGraph.DiGraphEdge)2 ArrayList (java.util.ArrayList)2 LinkedHashSet (java.util.LinkedHashSet)2 AssertionFunctionSpec (com.google.javascript.jscomp.CodingConvention.AssertionFunctionSpec)1 Bind (com.google.javascript.jscomp.CodingConvention.Bind)1 JSDocInfo (com.google.javascript.rhino.JSDocInfo)1 Token (com.google.javascript.rhino.Token)1