Search in sources :

Example 1 with JSType

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

the class NTIScope method isNamespace.

boolean isNamespace(String name) {
    checkArgument(!name.contains("."));
    Declaration decl = getDeclaration(name, false);
    if (decl == null) {
        return false;
    }
    JSType simpleType = decl.getTypeOfSimpleDecl();
    return decl.getNamespace() != null || (simpleType != null && simpleType.isNamespace());
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Declaration(com.google.javascript.jscomp.newtypes.Declaration)

Example 2 with JSType

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

the class NewTypeInference method analyzeReturnFwd.

private TypeEnv analyzeReturnFwd(Node n, TypeEnv inEnv) {
    if (this.currentScope.getRoot().isGeneratorFunction()) {
        JSType declRetType = getDeclaredReturnTypeOfCurrentScope(this.commonTypes.getGeneratorInstance(UNKNOWN));
        if (n.hasChildren()) {
            EnvTypePair retPair = analyzeExprFwd(n.getFirstChild(), inEnv, UNKNOWN);
            return envPutType(retPair.env, RETVAL_ID, declRetType);
        }
        return envPutType(inEnv, RETVAL_ID, declRetType);
    }
    TypeEnv outEnv;
    JSType declRetType = getDeclaredReturnTypeOfCurrentScope(UNKNOWN);
    JSType actualRetType;
    Node retExp = n.getFirstChild();
    if (retExp == null) {
        actualRetType = UNDEFINED;
        outEnv = envPutType(inEnv, RETVAL_ID, actualRetType);
    } else {
        EnvTypePair retPair = analyzeExprFwd(retExp, inEnv, declRetType);
        actualRetType = retPair.type;
        outEnv = envPutType(retPair.env, RETVAL_ID, actualRetType);
    }
    if (!actualRetType.isSubtypeOf(declRetType)) {
        registerMismatchAndWarn(JSError.make(n, RETURN_NONDECLARED_TYPE, errorMsgWithTypeDiff(declRetType, actualRetType)), actualRetType, declRetType);
    }
    return outEnv;
}
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 3 with JSType

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

the class NewTypeInference method analyzeLValueFwd.

private LValueResultFwd analyzeLValueFwd(Node expr, TypeEnv inEnv, JSType requiredType, boolean insideQualifiedName) {
    LValueResultFwd lvalResult = null;
    switch(expr.getToken()) {
        case THIS:
            {
                mayWarnAboutGlobalThis(expr);
                if (this.currentScope.hasThis()) {
                    lvalResult = new LValueResultFwd(inEnv, envGetType(inEnv, THIS_ID), this.currentScope.getDeclaredTypeOf(THIS_ID), new QualifiedName(THIS_ID));
                } else {
                    lvalResult = new LValueResultFwd(inEnv, UNKNOWN, null, null);
                }
                break;
            }
        case NAME:
            {
                String varName = expr.getString();
                JSType varType = analyzeExprFwd(expr, inEnv).type;
                lvalResult = new LValueResultFwd(inEnv, varType, this.currentScope.getDeclaredTypeOf(varName), varType.hasNonScalar() ? new QualifiedName(varName) : null);
                break;
            }
        case GETPROP:
        case GETELEM:
            {
                Node obj = expr.getFirstChild();
                Node prop = expr.getLastChild();
                QualifiedName pname = expr.isGetProp() || prop.isString() ? new QualifiedName(prop.getString()) : null;
                LValueResultFwd recvLvalue = analyzeReceiverLvalFwd(obj, pname, inEnv, requiredType);
                if (!recvLvalue.type.isSubtypeOf(TOP_OBJECT)) {
                    EnvTypePair pair = analyzeExprFwd(prop, recvLvalue.env, requiredType);
                    lvalResult = new LValueResultFwd(pair.env, requiredType, null, null);
                    break;
                }
                JSType indexType = recvLvalue.type.getIndexType();
                // (1) A getelem where the receiver is an IObject
                if (expr.isGetElem() && indexType != null) {
                    lvalResult = analyzeIObjectElmLvalFwd(prop, recvLvalue, indexType);
                    break;
                }
                // (2) A getelem where the prop is a string literal is like a getprop
                if (expr.isGetProp() || prop.isString()) {
                    lvalResult = analyzePropLValFwd(obj, pname, recvLvalue, requiredType, insideQualifiedName);
                    break;
                }
                // (3) All other getelems
                // TODO(dimvar): there is some recomputation here; the receiver will be
                // analyzed again. Some more refactoring can fix this.
                EnvTypePair pair = analyzeExprFwd(expr, recvLvalue.env, requiredType);
                lvalResult = new LValueResultFwd(pair.env, pair.type, null, null);
                break;
            }
        case VAR:
            {
                // Can happen iff its parent is a for/in or for/of.
                checkState(expr.getParent().isForIn() || expr.getParent().isForOf());
                Node nameNode = expr.getFirstChild();
                String name = nameNode.getString();
                // For/in and for/of can never have rhs of its VAR
                checkState(!nameNode.hasChildren());
                maybeSetTypeI(nameNode, requiredType);
                if (expr.getParent().isForIn()) {
                    return new LValueResultFwd(inEnv, STRING, null, new QualifiedName(name));
                } else {
                    JSType declType = this.currentScope.getDeclaredTypeOf(name);
                    return new LValueResultFwd(inEnv, requiredType, declType, new QualifiedName(name));
                }
            }
        default:
            {
                // Expressions that aren't lvalues should be handled because they may
                // be, e.g., the left child of a getprop.
                // We must check that they are not the direct lvalues.
                checkState(insideQualifiedName);
                EnvTypePair pair = analyzeExprFwd(expr, inEnv, requiredType);
                return new LValueResultFwd(pair.env, pair.type, null, null);
            }
    }
    maybeSetTypeI(expr, lvalResult.type);
    mayWarnAboutUnknownType(expr, lvalResult.type);
    return lvalResult;
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) QualifiedName(com.google.javascript.jscomp.newtypes.QualifiedName) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)

Example 4 with JSType

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

the class NewTypeInference method analyzeNameBwd.

private EnvTypePair analyzeNameBwd(Node expr, TypeEnv outEnv, JSType requiredType) {
    String varName = expr.getString();
    if (varName.equals("undefined")) {
        return new EnvTypePair(outEnv, UNDEFINED);
    }
    JSType inferredType = envGetType(outEnv, varName);
    println(varName, "'s inferredType: ", inferredType, " requiredType:  ", requiredType);
    if (inferredType == null) {
        return new EnvTypePair(outEnv, UNKNOWN);
    }
    JSType preciseType = inferredType.specialize(requiredType);
    if ((this.currentScope.isUndeclaredFormal(varName) || this.currentScope.isUndeclaredOuterVar(varName)) && preciseType.hasNonScalar()) {
        preciseType = preciseType.withLoose();
    }
    println(varName, "'s preciseType: ", preciseType);
    if (preciseType.isBottom()) {
        // If there is a type mismatch, we can propagate the previously
        // inferred type or the required type.
        // Propagating the already inferred type means that the type of the
        // variable is stable throughout the function body.
        // Propagating the required type means that the type chosen for a
        // formal is the one closest to the function header, which helps
        // generate more intuitive warnings in the fwd direction.
        // But there is a small chance that the different types of the same
        // variable flow to other variables and this can also be a source of
        // unintuitive warnings.
        // It's a trade-off.
        JSType declType = this.currentScope.getDeclaredTypeOf(varName);
        preciseType = firstNonNull(declType, requiredType);
    }
    return EnvTypePair.addBinding(outEnv, varName, preciseType);
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType)

Example 5 with JSType

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

the class NewTypeInference method isFunctionBind.

private boolean isFunctionBind(Node callee, TypeEnv env, boolean isFwd) {
    if (NodeUtil.isFunctionBind(callee)) {
        if (isFwd) {
            analyzeExprFwdIgnoreResult(callee, env);
        }
        return true;
    }
    if (!callee.isGetProp() || !callee.isQualifiedName() || !callee.getLastChild().getString().equals("bind")) {
        return false;
    }
    Node recv = callee.getFirstChild();
    JSType recvType;
    if (isFwd) {
        recvType = analyzeExprFwd(recv, env).type;
        maybeSetTypeI(callee, recvType.getProp(new QualifiedName("bind")));
    } else {
        recvType = analyzeExprBwd(recv, env).type;
    }
    return !recvType.isUnknown() && recvType.isSubtypeOf(commonTypes.topFunction());
}
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)

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