public final boolean isGenericObjectType() { return isTemplatizedType(); }
private boolean isTemplateOf(JSType type, String typeName) { return type.isTemplatizedType() && type.toMaybeTemplatizedType().getReferenceName().equals(typeName); }
/** Returns an integer that uniquely identifies a JSType. */ private int getIntForType(JSType type) { // Templatized types don't exist at runtime, so collapse to raw type if (type != null && type.isTemplatizedType()) { type = type.toMaybeTemplatizedType().getReferencedType(); } if (intForType.containsKey(type)) { return intForType.get(type).intValue(); } int newInt = intForType.size() + 1; intForType.put(type, newInt); return newInt; }
/** * Whether the typedef should be emitted by name or by the type it is defining. * * <p>Because, we do not access the original type signature, the replacement is done for all * references of the type (through the typedef or direct). Thus it is undesirable to always emit * by name. For example: * * <pre> * \@constructor A; * \@typedef {A} B; * \@const {A} var a; * </pre> * * If we emit the name, we would emit `var a: B;`, which is undesirable (consider A being string). * * <p>For now, only emit by name typedefs that are unlikely to have more than one name referring * to them - record types, templatized types and function types. */ private boolean shouldEmitTypedefByName(JSType realType) { return realType.isRecordType() || realType.isTemplatizedType() || realType.isFunctionType(); }
private boolean isSubtype(JSType rightType, JSType leftType) { // if thisType or thatType is an unresolved templatized type, // then there is no structural interface matching boolean thisUnresolved = rightType.isTemplatizedType() && !rightType.toMaybeTemplatizedType().isResolved(); boolean thatUnresolved = leftType.isTemplatizedType() && !leftType.toMaybeTemplatizedType().isResolved(); if (structuralSubtypesAreCollapsed && !thisUnresolved && !thatUnresolved) { return rightType.isSubtypeOf(leftType); } else { return rightType.isSubtypeWithoutStructuralTyping(leftType); } }
public final JSType evaluate(JSTypeExpression expression) { JSType jsType = null; if (expression != null) { try { jsType = expression.evaluate(null, jscompiler.getTypeRegistry()); if (jsType.isTemplatizedType()) { jsType = ((TemplatizedType)jsType).getReferencedType(); } } catch (Exception e) { e.printStackTrace(); } } return jsType; }
private boolean isSubtype( JSType rightType, JSType leftType, boolean isStructural) { // if thisType or thatType is an unresolved templatized type, // then there is no structural interface matching boolean thisUnresolved = rightType.isTemplatizedType() && !rightType.toMaybeTemplatizedType().isResolved(); boolean thatUnresolved = leftType.isTemplatizedType() && !leftType.toMaybeTemplatizedType().isResolved(); if (isStructural && !thisUnresolved && !thatUnresolved) { return rightType.isSubtype(leftType); } else { return rightType.isSubtypeWithoutStructuralTyping(leftType); } }
private JSType evalTemplateTypeOf(Node ttlAst, NameResolver nameResolver) { ImmutableList<Node> params = getCallParams(ttlAst); JSType type = evalInternal(params.get(0), nameResolver); if (!type.isTemplatizedType()) { reportWarning(ttlAst, TEMPTYPE_INVALID, "templateTypeOf", type.toString()); return getUnknownType(); } int index = (int) params.get(1).getDouble(); ImmutableList<JSType> templateTypes = ((TemplatizedType) type).getTemplateTypes(); if (index > templateTypes.size()) { reportWarning(ttlAst, INDEX_OUTOFBOUNDS, Integer.toString(index), Integer.toString(templateTypes.size())); return getUnknownType(); } return templateTypes.get(index); }
/** * Determines if the specified type is exempt from standard invariant templatized typing rules. */ static boolean isIThenableSubtype(JSType type) { if (type.isTemplatizedType()) { TemplatizedType ttype = type.toMaybeTemplatizedType(); return ttype.getTemplateTypeMap().hasTemplateKey(ttype.registry.getThenableValueKey()); } return false; }
/** * Checks whether current type is Object type with non-stringifable key. */ private boolean isObjectTypeWithNonStringifiableKey(JSType type) { if (!type.isTemplatizedType()) { return false; } TemplatizedType templatizedType = type.toMaybeTemplatizedType(); if (templatizedType.getReferencedType().isNativeObjectType() && templatizedType.getTemplateTypes().size() > 1) { return !isReasonableObjectPropertyKey(templatizedType.getTemplateTypes().get(0)); } else { return false; } }
/** * Checks whether current type is Object type with non-stringifable key. */ private boolean isObjectTypeWithNonStringifiableKey(JSType type) { if (!type.isTemplatizedType()) { return false; } TemplatizedType templatizedType = type.toMaybeTemplatizedType(); if (templatizedType.getReferencedType().isNativeObjectType() && templatizedType.getTemplateTypes().size() > 1) { return !isStringifiable(templatizedType.getTemplateTypes().get(0)); } else { return false; } }
private static boolean areTypesEquivalentIgnoringGenerics(JSType a, JSType b) { boolean equivalent = a.isEquivalentTo(b); if (equivalent) { return true; } if (a.isTemplatizedType()) { return a.toMaybeTemplatizedType().getReferencedType().isEquivalentTo(b); } return false; }
boolean wrapsSameRawType(JSType that) { return that.isTemplatizedType() && this.getReferencedTypeInternal() .isEquivalentTo( that.toMaybeTemplatizedType().getReferencedTypeInternal()); }
boolean wrapsSameRawType(JSType that) { return that.isTemplatizedType() && this.getReferencedTypeInternal() .isEquivalentTo( that.toMaybeTemplatizedType().getReferencedTypeInternal()); }
private JSType evalRawTypeOf(Node ttlAst, NameResolver nameResolver) { ImmutableList<Node> params = getCallParams(ttlAst); JSType type = evalInternal(params.get(0), nameResolver); if (!type.isTemplatizedType()) { reportWarning(ttlAst, TEMPTYPE_INVALID, "rawTypeOf", type.toString()); return getUnknownType(); } return ((TemplatizedType) type).getReferencedType(); }
/** * Special handling for simple typing returning polymorphic this type in TypeScript. Prefer * `func(): this` instead of `func<T>(this: T): T` when any params are not templatized. */ private boolean shouldSkipEmittingThisTemplateAndParam(FunctionType ftype) { final JSType typeOfThis = ftype.getTypeOfThis(); if (typeOfThis == null || !typeOfThis.isTemplateType() || !typeOfThis.equals(ftype.getReturnType())) { return false; } Iterator<Node> parameters = ftype.getParameters().iterator(); while (parameters.hasNext()) { final JSType paramType = parameters.next().getJSType(); if (!paramType.isTemplatizedType()) { continue; } final TemplateTypeMap templateTypeMap = paramType.getTemplateTypeMap(); for (TemplateType key : templateTypeMap.getTemplateKeys()) { if (templateTypeMap.getResolvedTemplateType(key).equals(typeOfThis)) { return false; } } } return true; }
private boolean evalTypePredicate(Node ttlAst, NameResolver nameResolver) { JSType[] params = evalTypeParams(ttlAst, nameResolver); String name = getCallName(ttlAst); Keywords keyword = nameToKeyword(name); switch (keyword) { case EQ: return params[0].isEquivalentTo(params[1]); case SUB: return params[0].isSubtype(params[1]); case ISCTOR: return params[0].isConstructor(); case ISTEMPLATIZED: return params[0].isTemplatizedType(); case ISRECORD: return params[0].isRecordType(); case ISUNKNOWN: return params[0].isUnknownType() || params[0].isCheckedUnknownType(); default: throw new IllegalStateException( "Invalid type predicate in the type transformation"); } }
/** * Computes the greatest subtype of two related templatized types. * @return The greatest subtype. */ JSType getGreatestSubtypeHelper(JSType rawThat) { checkNotNull(rawThat); if (!wrapsSameRawType(rawThat)) { if (!rawThat.isTemplatizedType()) { if (this.isSubtype(rawThat)) { return this; } else if (rawThat.isSubtypeOf(this)) { return filterNoResolvedType(rawThat); } } if (this.isObject() && rawThat.isObject()) { return this.getNativeType(JSTypeNative.NO_OBJECT_TYPE); } return this.getNativeType(JSTypeNative.NO_TYPE); } TemplatizedType that = rawThat.toMaybeTemplatizedType(); checkNotNull(that); if (getTemplateTypeMap().checkEquivalenceHelper( that.getTemplateTypeMap(), EquivalenceMethod.INVARIANT, SubtypingMode.NORMAL)) { return this; } // For types that have the same raw type but different type parameters, // we simply create a type has a "unknown" type parameter. This is // equivalent to the raw type. return getReferencedObjTypeInternal(); }
Boolean castCastToHelper(JSType thisType, JSType thatType) { if (thatType.isUnknownType() || thatType.isAllType() || thatType.isNoObjectType() // TODO(johnlenz): restrict to objects || thatType.isNoType()) { return true; } else if (thisType.isRecordType() || thatType.isRecordType()) { return true; // TODO(johnlenz): are there any misuses we can catch? } else if (isInterface(thisType) || isInterface(thatType)) { return true; // TODO(johnlenz): are there any misuses we can catch? } else if (thatType.isEnumElementType()) { return thisType.visit(this, thatType.toMaybeEnumElementType().getPrimitiveType()); } else if (thatType.isUnionType()) { return canCastToUnion(thisType, thatType.toMaybeUnionType()); } else if (thatType.isFunctionType()) { return canCastToFunction(thisType, thatType.toMaybeFunctionType()); } else if (thatType.isTemplatizedType()) { // TODO(johnlenz): once the templated type work is finished, // restrict the type parameters. return thisType.visit(this, thatType.toMaybeTemplatizedType().getReferencedTypeInternal()); } return thisType.isSubtypeOf(thatType) || thatType.isSubtypeOf(thisType); }
Boolean castCastToHelper(JSType thisType, JSType thatType) { if (thatType.isUnknownType() || thatType.isAllType() || thatType.isNoObjectType() // TODO(johnlenz): restrict to objects || thatType.isNoType()) { return true; } else if (thisType.isRecordType() || thatType.isRecordType()) { return true; // TODO(johnlenz): are there any misuses we can catch? } else if (isInterface(thisType) || isInterface(thatType)) { return true; // TODO(johnlenz): are there any misuses we can catch? } else if (thatType.isEnumElementType()) { return thisType.visit(this, thatType.toMaybeEnumElementType().getPrimitiveType()); } else if (thatType.isUnionType()) { return canCastToUnion(thisType, thatType.toMaybeUnionType()); } else if (thatType.isFunctionType()) { return canCastToFunction(thisType, thatType.toMaybeFunctionType()); } else if (thatType.isTemplatizedType()) { // TODO(johnlenz): once the templated type work is finished, // restrict the type parameters. return thisType.visit(this, thatType.toMaybeTemplatizedType().getReferencedTypeInternal()); } return thisType.isSubtype(thatType) || thatType.isSubtype(thisType); }