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;
}
Aggregations