Search in sources :

Example 1 with NamedType

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

the class TypeCheck method isReasonableObjectPropertyKey.

/**
 * Checks whether type is useful as the key of an object property access.
 * This means it should be either stringifiable or a symbol.
 * Stringifiable types are types that can be converted to string
 * and give unique results for different objects. For example objects have native toString()
 * method that on chrome returns "[object Object]" for all objects making it useless when used
 * as keys. At the same time native types like numbers can be safely converted to strings and
 * used as keys. Also user might have provided custom toString() methods for a class making it
 * suitable for using as key.
 */
private boolean isReasonableObjectPropertyKey(JSType type) {
    // Check built-in types
    if (type.isUnknownType() || type.isNumber() || type.isString() || type.isSymbol() || type.isBooleanObjectType() || type.isBooleanValueType() || type.isDateType() || type.isRegexpType() || type.isInterface() || type.isRecordType() || type.isNullType() || type.isVoidType()) {
        return true;
    }
    // For enums check that underlying type is stringifiable.
    if (type.toMaybeEnumElementType() != null) {
        return isReasonableObjectPropertyKey(type.toMaybeEnumElementType().getPrimitiveType());
    }
    // Bad: Array.<!Object>
    if (type.isArrayType()) {
        return true;
    }
    if (type.isTemplatizedType()) {
        TemplatizedType templatizedType = type.toMaybeTemplatizedType();
        if (templatizedType.getReferencedType().isArrayType()) {
            return isReasonableObjectPropertyKey(templatizedType.getTemplateTypes().get(0));
        }
    }
    // in @typedef annotation.
    if (type instanceof NamedType) {
        return isReasonableObjectPropertyKey(((NamedType) type).getReferencedType());
    }
    // For union type every alternate must be stringifiable.
    if (type.isUnionType()) {
        for (JSType alternateType : type.toMaybeUnionType().getAlternates()) {
            if (!isReasonableObjectPropertyKey(alternateType)) {
                return false;
            }
        }
        return true;
    }
    // Handle interfaces and classes.
    if (type.isObject()) {
        ObjectType objectType = type.toMaybeObjectType();
        JSType constructor = objectType.getConstructor();
        // classes-implementations.
        if (constructor != null && constructor.isInterface()) {
            return true;
        }
        // This is user-defined class so check if it has custom toString() method.
        return classHasToString(objectType);
    }
    return false;
}
Also used : ObjectType(com.google.javascript.rhino.jstype.ObjectType) JSType(com.google.javascript.rhino.jstype.JSType) NamedType(com.google.javascript.rhino.jstype.NamedType) TemplatizedType(com.google.javascript.rhino.jstype.TemplatizedType)

Aggregations

JSType (com.google.javascript.rhino.jstype.JSType)1 NamedType (com.google.javascript.rhino.jstype.NamedType)1 ObjectType (com.google.javascript.rhino.jstype.ObjectType)1 TemplatizedType (com.google.javascript.rhino.jstype.TemplatizedType)1