Search in sources :

Example 1 with UnionType

use of com.google.javascript.rhino.jstype.UnionType in project closure-compiler by google.

the class TypeInference method maybeResolveTemplatedType.

private void maybeResolveTemplatedType(JSType paramType, JSType argType, Map<TemplateType, JSType> resolvedTypes, Set<JSType> seenTypes) {
    if (paramType.isTemplateType()) {
        // example: @param {T}
        resolvedTemplateType(resolvedTypes, paramType.toMaybeTemplateType(), argType);
    } else if (paramType.isUnionType()) {
        // example: @param {Array.<T>|NodeList|Arguments|{length:number}}
        UnionType unionType = paramType.toMaybeUnionType();
        for (JSType alernative : unionType.getAlternates()) {
            maybeResolveTemplatedType(alernative, argType, resolvedTypes, seenTypes);
        }
    } else if (paramType.isFunctionType()) {
        FunctionType paramFunctionType = paramType.toMaybeFunctionType();
        FunctionType argFunctionType = argType.restrictByNotNullOrUndefined().collapseUnion().toMaybeFunctionType();
        if (argFunctionType != null && argFunctionType.isSubtype(paramType)) {
            // infer from return type of the function type
            maybeResolveTemplatedType(paramFunctionType.getTypeOfThis(), argFunctionType.getTypeOfThis(), resolvedTypes, seenTypes);
            // infer from return type of the function type
            maybeResolveTemplatedType(paramFunctionType.getReturnType(), argFunctionType.getReturnType(), resolvedTypes, seenTypes);
            // infer from parameter types of the function type
            maybeResolveTemplateTypeFromNodes(paramFunctionType.getParameters(), argFunctionType.getParameters(), resolvedTypes, seenTypes);
        }
    } else if (paramType.isRecordType() && !paramType.isNominalType()) {
        // example: @param {{foo:T}}
        if (seenTypes.add(paramType)) {
            ObjectType paramRecordType = paramType.toObjectType();
            ObjectType argObjectType = argType.restrictByNotNullOrUndefined().toObjectType();
            if (argObjectType != null && !argObjectType.isUnknownType() && !argObjectType.isEmptyType()) {
                Set<String> names = paramRecordType.getPropertyNames();
                for (String name : names) {
                    if (paramRecordType.hasOwnProperty(name) && argObjectType.hasProperty(name)) {
                        maybeResolveTemplatedType(paramRecordType.getPropertyType(name), argObjectType.getPropertyType(name), resolvedTypes, seenTypes);
                    }
                }
            }
            seenTypes.remove(paramType);
        }
    } else if (paramType.isTemplatizedType()) {
        // example: @param {Array<T>}
        TemplatizedType templatizedParamType = paramType.toMaybeTemplatizedType();
        int keyCount = templatizedParamType.getTemplateTypes().size();
        // types with no type arguments.
        if (keyCount > 0) {
            ObjectType referencedParamType = templatizedParamType.getReferencedType();
            JSType argObjectType = argType.restrictByNotNullOrUndefined().collapseUnion();
            if (argObjectType.isSubtypeOf(referencedParamType)) {
                // If the argument type is a subtype of the parameter type, resolve any
                // template types amongst their templatized types.
                TemplateTypeMap paramTypeMap = paramType.getTemplateTypeMap();
                ImmutableList<TemplateType> keys = paramTypeMap.getTemplateKeys();
                TemplateTypeMap argTypeMap = argObjectType.getTemplateTypeMap();
                for (int index = keys.size() - keyCount; index < keys.size(); index++) {
                    TemplateType key = keys.get(index);
                    maybeResolveTemplatedType(paramTypeMap.getResolvedTemplateType(key), argTypeMap.getResolvedTemplateType(key), resolvedTypes, seenTypes);
                }
            }
        }
    }
}
Also used : UnionType(com.google.javascript.rhino.jstype.UnionType) ObjectType(com.google.javascript.rhino.jstype.ObjectType) TemplateTypeMap(com.google.javascript.rhino.jstype.TemplateTypeMap) JSType(com.google.javascript.rhino.jstype.JSType) Set(java.util.Set) BooleanLiteralSet(com.google.javascript.rhino.jstype.BooleanLiteralSet) FunctionType(com.google.javascript.rhino.jstype.FunctionType) TemplateType(com.google.javascript.rhino.jstype.TemplateType) TemplatizedType(com.google.javascript.rhino.jstype.TemplatizedType)

Example 2 with UnionType

use of com.google.javascript.rhino.jstype.UnionType in project closure-compiler by google.

the class SymbolTable method getAllSymbolsForType.

/**
 * Gets all symbols associated with the given type. For union types, this may be multiple symbols.
 * For instance types, this will return the constructor of that instance.
 */
public List<Symbol> getAllSymbolsForType(JSType type) {
    if (type == null) {
        return ImmutableList.of();
    }
    UnionType unionType = type.toMaybeUnionType();
    if (unionType != null) {
        ImmutableList.Builder<Symbol> result = ImmutableList.builder();
        for (JSType alt : unionType.getAlternates()) {
            // Our type system never has nested unions.
            Symbol altSym = getSymbolForTypeHelper(alt, true);
            if (altSym != null) {
                result.add(altSym);
            }
        }
        return result.build();
    }
    Symbol result = getSymbolForTypeHelper(type, true);
    return result == null ? ImmutableList.of() : ImmutableList.of(result);
}
Also used : UnionType(com.google.javascript.rhino.jstype.UnionType) JSType(com.google.javascript.rhino.jstype.JSType) ImmutableList(com.google.common.collect.ImmutableList)

Example 3 with UnionType

use of com.google.javascript.rhino.jstype.UnionType in project closure-compiler by google.

the class TypeInference method getBigIntPresence.

/**
 * Utility function for determining the BigIntPresence for any type.
 */
static BigIntPresence getBigIntPresence(JSType type) {
    // Base case
    if (type.isOnlyBigInt()) {
        return BigIntPresence.ALL_BIGINT;
    }
    // Checking enum case
    EnumElementType typeAsEnumElement = type.toMaybeEnumElementType();
    if (typeAsEnumElement != null) {
        // No matter what type the enum element is, this function can resolve it to a BigIntPresence
        return getBigIntPresence(typeAsEnumElement.getPrimitiveType());
    }
    // Union case
    UnionType typeAsUnion = type.toMaybeUnionType();
    if (typeAsUnion != null) {
        boolean containsBigInt = false;
        boolean containsNumber = false;
        boolean containsOther = false;
        for (JSType alternate : typeAsUnion.getAlternates()) {
            if (getBigIntPresence(alternate) != BigIntPresence.NO_BIGINT) {
                containsBigInt = true;
            } else if (alternate.isNumber() && !alternate.isUnknownType()) {
                containsNumber = true;
            } else {
                containsOther = true;
            }
        }
        if (containsBigInt) {
            if (containsOther) {
                return BigIntPresence.BIGINT_OR_OTHER;
            } else if (containsNumber) {
                return BigIntPresence.BIGINT_OR_NUMBER;
            } else {
                return BigIntPresence.ALL_BIGINT;
            }
        }
    }
    // safely assume that it’s not a bigint in anyway
    return BigIntPresence.NO_BIGINT;
}
Also used : UnionType(com.google.javascript.rhino.jstype.UnionType) JSType(com.google.javascript.rhino.jstype.JSType) EnumElementType(com.google.javascript.rhino.jstype.EnumElementType)

Example 4 with UnionType

use of com.google.javascript.rhino.jstype.UnionType in project closure-compiler by google.

the class TypeInference method updateTypeOfParameters.

/**
 * For functions with function parameters, type inference will set the type of
 * a function literal argument from the function parameter type.
 */
private void updateTypeOfParameters(Node n, FunctionType fnType) {
    checkState(n.isCall() || n.isNew(), n);
    int i = 0;
    int childCount = n.getChildCount();
    Node iArgument = n.getFirstChild();
    for (Node iParameter : fnType.getParameters()) {
        if (i + 1 >= childCount) {
            // TypeCheck#visitParametersList will warn so we bail.
            return;
        }
        // NOTE: the first child of the call node is the call target, which we want to skip, so
        // it is correct to call getNext on the first iteration.
        iArgument = iArgument.getNext();
        JSType iArgumentType = getJSType(iArgument);
        JSType iParameterType = getJSType(iParameter);
        inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType);
        // If the parameter to the call is a function expression, propagate the
        // function signature from the call site to the function node.
        // Filter out non-function types (such as null and undefined) as
        // we only care about FUNCTION subtypes here.
        FunctionType restrictedParameter = null;
        if (iParameterType.isUnionType()) {
            UnionType union = iParameterType.toMaybeUnionType();
            for (JSType alternative : union.getAlternates()) {
                if (alternative.isFunctionType()) {
                    // There is only one function type per union.
                    restrictedParameter = alternative.toMaybeFunctionType();
                    break;
                }
            }
        } else {
            restrictedParameter = iParameterType.toMaybeFunctionType();
        }
        if (restrictedParameter != null && iArgument.isFunction() && iArgumentType.isFunctionType()) {
            FunctionType argFnType = iArgumentType.toMaybeFunctionType();
            boolean declared = iArgument.getJSDocInfo() != null;
            iArgument.setJSType(matchFunction(restrictedParameter, argFnType, declared));
        }
        i++;
    }
}
Also used : UnionType(com.google.javascript.rhino.jstype.UnionType) JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node) FunctionType(com.google.javascript.rhino.jstype.FunctionType)

Example 5 with UnionType

use of com.google.javascript.rhino.jstype.UnionType in project closure-compiler by google.

the class InvocationTemplateTypeMatcher method matchTemplateTypesRecursive.

private void matchTemplateTypesRecursive(JSType paramType, JSType argType) {
    if (paramType.isTemplateType()) {
        // Recursive base case.
        // example: @param {T}
        this.recordTemplateMatch(paramType.toMaybeTemplateType(), argType);
        return;
    }
    // Unpack unions.
    if (paramType.isUnionType()) {
        // example: @param {Array.<T>|NodeList|Arguments|{length:number}}
        UnionType unionType = paramType.toMaybeUnionType();
        for (JSType alternate : unionType.getAlternates()) {
            this.matchTemplateTypesRecursive(alternate, argType);
        }
        return;
    } else if (argType.isUnionType()) {
        UnionType unionType = argType.toMaybeUnionType();
        for (JSType alternate : unionType.getAlternates()) {
            this.matchTemplateTypesRecursive(paramType, alternate);
        }
        return;
    }
    if (paramType.isFunctionType()) {
        FunctionType paramFunctionType = paramType.toMaybeFunctionType();
        FunctionType argFunctionType = argType.restrictByNotNullOrUndefined().collapseUnion().toMaybeFunctionType();
        if (argFunctionType != null && argFunctionType.isSubtype(paramType)) {
            // infer from return type of the function type
            this.matchTemplateTypesRecursive(paramFunctionType.getTypeOfThis(), argFunctionType.getTypeOfThis());
            // infer from return type of the function type
            this.matchTemplateTypesRecursive(paramFunctionType.getReturnType(), argFunctionType.getReturnType());
            // infer from parameter types of the function type
            this.matchTemplateTypesFromParameters(paramFunctionType.getParameters().iterator(), argFunctionType.getParameters().iterator());
        }
    } else if (paramType.isRecordType() && !paramType.isNominalType()) {
        // example: @param {{foo:T}}
        if (this.seenTypes.add(paramType)) {
            ObjectType paramRecordType = paramType.toObjectType();
            ObjectType argObjectType = argType.restrictByNotNullOrUndefined().toObjectType();
            if (argObjectType != null && !argObjectType.isUnknownType() && !argObjectType.isEmptyType()) {
                Set<String> names = paramRecordType.getPropertyNames();
                for (String name : names) {
                    if (paramRecordType.hasOwnProperty(name) && argObjectType.hasProperty(name)) {
                        this.matchTemplateTypesRecursive(paramRecordType.getPropertyType(name), argObjectType.getPropertyType(name));
                    }
                }
            }
            this.seenTypes.remove(paramType);
        }
    } else if (paramType.isTemplatizedType()) {
        // example: @param {Array<T>}
        TemplatizedType templatizedParamType = paramType.toMaybeTemplatizedType();
        int keyCount = templatizedParamType.getTemplateTypes().size();
        // types with no type arguments.
        if (keyCount == 0) {
            return;
        }
        ObjectType referencedParamType = templatizedParamType.getReferencedType();
        JSType argObjectType = argType.restrictByNotNullOrUndefined().collapseUnion();
        if (argObjectType.isSubtypeOf(referencedParamType)) {
            // If the argument type is a subtype of the parameter type, resolve any
            // template types amongst their templatized types.
            TemplateTypeMap paramTypeMap = paramType.getTemplateTypeMap();
            ImmutableList<TemplateType> keys = paramTypeMap.getTemplateKeys();
            TemplateTypeMap argTypeMap = argObjectType.getTemplateTypeMap();
            for (int index = keys.size() - keyCount; index < keys.size(); index++) {
                TemplateType key = keys.get(index);
                this.matchTemplateTypesRecursive(paramTypeMap.getResolvedTemplateType(key), argTypeMap.getResolvedTemplateType(key));
            }
        }
    }
}
Also used : UnionType(com.google.javascript.rhino.jstype.UnionType) ObjectType(com.google.javascript.rhino.jstype.ObjectType) TemplateTypeMap(com.google.javascript.rhino.jstype.TemplateTypeMap) JSType(com.google.javascript.rhino.jstype.JSType) Set(java.util.Set) FunctionType(com.google.javascript.rhino.jstype.FunctionType) TemplateType(com.google.javascript.rhino.jstype.TemplateType) TemplatizedType(com.google.javascript.rhino.jstype.TemplatizedType)

Aggregations

JSType (com.google.javascript.rhino.jstype.JSType)8 UnionType (com.google.javascript.rhino.jstype.UnionType)8 FunctionType (com.google.javascript.rhino.jstype.FunctionType)5 Node (com.google.javascript.rhino.Node)3 ObjectType (com.google.javascript.rhino.jstype.ObjectType)3 ImmutableList (com.google.common.collect.ImmutableList)2 TemplateType (com.google.javascript.rhino.jstype.TemplateType)2 TemplateTypeMap (com.google.javascript.rhino.jstype.TemplateTypeMap)2 TemplatizedType (com.google.javascript.rhino.jstype.TemplatizedType)2 ArrayList (java.util.ArrayList)2 Set (java.util.Set)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMultimap (com.google.common.collect.ImmutableMultimap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)1 Iterables (com.google.common.collect.Iterables)1 LinkedHashMultimap (com.google.common.collect.LinkedHashMultimap)1