Search in sources :

Example 71 with JSType

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

the class NewTypeInference method computeFnDeclaredTypeForCallback.

/**
 * Given a scope whose root is an unannotated callback, finds a declared type for the callback
 * using the types in the callback's context.
 * Similar to GlobalTypeInfoCollector#computeFnDeclaredTypeFromCallee, but not similar enough
 * to use the same code for both.
 */
private void computeFnDeclaredTypeForCallback(NTIScope scope) {
    Node callback = scope.getRoot();
    checkState(NodeUtil.isUnannotatedCallback(callback));
    Node call = callback.getParent();
    JSType calleeType = (JSType) call.getFirstChild().getTypeI();
    if (calleeType == null) {
        return;
    }
    FunctionType calleeFunType = calleeType.getFunType();
    if (calleeFunType == null) {
        return;
    }
    int argIndex = call.getIndexOfChild(callback) - 1;
    JSType formalType = calleeFunType.getFormalType(argIndex);
    if (formalType == null) {
        return;
    }
    FunctionType ft = formalType.getFunType();
    if (ft == null || ft.isLoose()) {
        return;
    }
    DeclaredFunctionType callbackDft = scope.getDeclaredFunctionType();
    JSType scopeType = this.commonTypes.fromFunctionType(callbackDft.toFunctionType());
    if (ft.isUniqueConstructor() || ft.isInterfaceDefinition()) {
        warnAboutInvalidArgument(call, callback, argIndex, formalType, scopeType);
        return;
    }
    DeclaredFunctionType declaredDft = checkNotNull(ft.toDeclaredFunctionType());
    // the arity of the callback.
    if (ft.acceptsAnyArguments() || callbackDft.getRequiredArity() <= declaredDft.getMaxArity()) {
        scope.setDeclaredType(declaredDft);
    } else {
        warnAboutInvalidArgument(call, callback, argIndex, formalType, scopeType);
    }
}
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) FunctionType(com.google.javascript.jscomp.newtypes.FunctionType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType)

Example 72 with JSType

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

the class NewTypeInference method addRetTypeAndWarn.

private void addRetTypeAndWarn(NTIScope fn, TypeEnv exitEnv, DeclaredFunctionType declType, FunctionTypeBuilder builder) {
    Node fnRoot = fn.getRoot();
    JSType declRetType = declType.getReturnType();
    JSType actualRetType = checkNotNull(envGetType(exitEnv, RETVAL_ID));
    if (declRetType != null) {
        if (fnRoot.isGeneratorFunction()) {
            JSType generator = this.commonTypes.getGeneratorInstance(UNKNOWN);
            if (!generator.isSubtypeOf(declRetType)) {
                registerMismatchAndWarn(JSError.make(fnRoot, INVALID_DECLARED_RETURN_TYPE_OF_GENERATOR_FUNCTION, errorMsgWithTypeDiff(generator, declRetType)), declRetType, generator);
                builder.addRetType(UNKNOWN);
            } else {
                builder.addRetType(declRetType);
            }
        } else {
            builder.addRetType(declRetType);
            if (!isAllowedToNotReturn(fn) && !UNDEFINED.isSubtypeOf(declRetType) && hasPathWithNoReturn(this.cfg)) {
                warnings.add(JSError.make(fnRoot, MISSING_RETURN_STATEMENT, declRetType.toString()));
            }
        }
    } else if (fnRoot.isGeneratorFunction()) {
        // No declared return type for Generator. Use inferred type.
        JSType yieldType = envGetType(exitEnv, YIELDVAL_ID);
        builder.addRetType(this.commonTypes.getGeneratorInstance(firstNonNull(yieldType, UNKNOWN)));
    } else if (declType.getNominalType() == null) {
        // If a function doesn't return, make the return type unknown.
        builder.addRetType(firstNonBottom(actualRetType, UNKNOWN));
    } else {
        // Don't infer a return type for constructors. We want to warn for
        // constructors called without new who don't explicitly declare @return.
        builder.addRetType(UNDEFINED);
    }
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)

Example 73 with JSType

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

the class NewTypeInference method analyzeSuperFwd.

private EnvTypePair analyzeSuperFwd(Node expr, TypeEnv inEnv) {
    checkArgument(expr.isSuper());
    if (this.currentScope.hasThis()) {
        NominalType thisClass = checkNotNull(envGetType(inEnv, THIS_ID).getNominalTypeIfSingletonObj());
        NominalType superClass = thisClass.getInstantiatedSuperclass();
        if (superClass == null) {
            // This indicates bad code and there will probably be other errors reported.
            // In particular JSC_NTI_INHERITANCE_CYCLE for `class Foo extends Foo ...`.
            warnings.add(JSError.make(expr, UNDEFINED_SUPER_CLASS, thisClass.toString()));
            return new EnvTypePair(inEnv, UNKNOWN);
        }
        if (this.currentScope.isConstructor()) {
            JSType superCtor = commonTypes.fromFunctionType(superClass.getConstructorFunction());
            return new EnvTypePair(inEnv, superCtor);
        }
        return new EnvTypePair(inEnv, superClass.getInstanceAsJSType());
    }
    // Use of super in a static method.
    Node funName = NodeUtil.getBestLValue(this.currentScope.getRoot());
    Node classNameNode = funName.getFirstChild();
    JSType thisClassAsJstype = analyzeExprFwd(classNameNode, inEnv).type;
    FunctionType thisCtor = thisClassAsJstype.getFunTypeIfSingletonObj();
    NominalType thisClass = thisCtor.getThisType().getNominalTypeIfSingletonObj();
    NominalType superClass = thisClass.getInstantiatedSuperclass();
    if (superClass == null) {
        // This indicates bad code and there will probably be other errors reported.
        // In particular JSC_NTI_INHERITANCE_CYCLE for `class Foo extends Foo ...`.
        warnings.add(JSError.make(expr, UNDEFINED_SUPER_CLASS, funName.toString()));
        return new EnvTypePair(inEnv, UNKNOWN);
    }
    return new EnvTypePair(inEnv, superClass.getNamespaceType());
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) NominalType(com.google.javascript.jscomp.newtypes.NominalType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) FunctionType(com.google.javascript.jscomp.newtypes.FunctionType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType)

Example 74 with JSType

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

the class NewTypeInference method analyzeLooseCallNodeFwd.

private EnvTypePair analyzeLooseCallNodeFwd(Node callNode, TypeEnv inEnv, JSType requiredType) {
    checkArgument(callNode.isCall() || callNode.isNew());
    Node callee = callNode.getFirstChild();
    FunctionTypeBuilder builder = new FunctionTypeBuilder(this.commonTypes);
    TypeEnv tmpEnv = inEnv;
    for (Node arg = callee.getNext(); arg != null; arg = arg.getNext()) {
        EnvTypePair pair = analyzeExprFwd(arg, tmpEnv);
        tmpEnv = pair.env;
        builder.addReqFormal(pair.type);
    }
    JSType looseRetType = requiredType.isUnknown() ? BOTTOM : requiredType;
    JSType looseFunctionType = commonTypes.fromFunctionType(builder.addRetType(looseRetType).addLoose().buildFunction());
    // Unsound if the arguments and callee have interacting side effects
    EnvTypePair calleePair = analyzeExprFwd(callee, tmpEnv, commonTypes.topFunction(), looseFunctionType);
    FunctionType calleeType = calleePair.type.getFunType();
    JSType result = calleeType.getReturnType();
    return new EnvTypePair(calleePair.env, isImpreciseType(result) ? requiredType : result);
}
Also used : JSType(com.google.javascript.jscomp.newtypes.JSType) Node(com.google.javascript.rhino.Node) DiGraphNode(com.google.javascript.jscomp.graph.DiGraph.DiGraphNode) FunctionType(com.google.javascript.jscomp.newtypes.FunctionType) DeclaredFunctionType(com.google.javascript.jscomp.newtypes.DeclaredFunctionType) TypeEnv(com.google.javascript.jscomp.newtypes.TypeEnv) FunctionTypeBuilder(com.google.javascript.jscomp.newtypes.FunctionTypeBuilder)

Example 75 with JSType

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

the class NewTypeInference method analyzeForOfFwd.

private TypeEnv analyzeForOfFwd(Node n, TypeEnv inEnv) {
    Node rhs = n.getSecondChild();
    EnvTypePair rhsPair = analyzeExprFwd(rhs, inEnv, pickReqObjType(n));
    rhsPair = mayWarnAboutNullableReferenceAndTighten(n, rhsPair.type, null, inEnv);
    JSType rhsObjType = rhsPair.type;
    JSType boxedType = rhsObjType.autobox();
    JSType lhsExpectedType;
    JSType iterable = this.commonTypes.getIterableInstance(UNKNOWN);
    if (boxedType.isSubtypeOf(iterable)) {
        lhsExpectedType = boxedType.getInstantiatedTypeArgument(iterable);
    } else {
        warnings.add(JSError.make(rhs, FOROF_EXPECTS_ITERABLE, rhsObjType.toString()));
        lhsExpectedType = UNKNOWN;
    }
    Node lhsNode = n.getFirstChild();
    LValueResultFwd lhsLval = analyzeLValueFwd(lhsNode, inEnv, lhsExpectedType);
    TypeEnv outEnv;
    if (lhsLval.declType == null || lhsExpectedType.isSubtypeOf(lhsLval.declType)) {
        outEnv = updateLvalueTypeInEnv(lhsLval.env, lhsNode, lhsLval.ptr, lhsExpectedType);
    } else {
        registerMismatchAndWarn(JSError.make(n, MISTYPED_FOROF_ELEMENT_TYPE, errorMsgWithTypeDiff(lhsLval.declType, lhsExpectedType)), lhsExpectedType, lhsLval.declType);
        outEnv = updateLvalueTypeInEnv(lhsLval.env, lhsNode, lhsLval.ptr, lhsLval.declType);
    }
    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)

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