TemplatizedType( JSTypeRegistry registry, ObjectType objectType, ImmutableList<JSType> templateTypes) { super(registry, objectType, objectType.getTemplateTypeMap().addValues( templateTypes)); // Cache which template keys were filled, and what JSTypes they were filled // with. ImmutableList<TemplateType> filledTemplateKeys = objectType.getTemplateTypeMap().getUnfilledTemplateKeys(); ImmutableList.Builder<JSType> builder = ImmutableList.builder(); for (TemplateType filledTemplateKey : filledTemplateKeys) { builder.add(getTemplateTypeMap().getResolvedTemplateType(filledTemplateKey)); } this.templateTypes = builder.build(); replacer = new TemplateTypeMapReplacer(registry, getTemplateTypeMap()); }
TemplatizedType( JSTypeRegistry registry, ObjectType objectType, ImmutableList<JSType> templateTypes) { super( registry, objectType, objectType.getTemplateTypeMap().copyFilledWithValues(templateTypes)); ImmutableList.Builder<JSType> builder = ImmutableList.builder(); boolean maybeIsSpecializedOnlyWithUnknown = true; for (TemplateType newlyFilledTemplateKey : objectType.getTemplateTypeMap().getUnfilledTemplateKeys()) { JSType resolvedType = getTemplateTypeMap().getResolvedTemplateType(newlyFilledTemplateKey); builder.add(resolvedType); maybeIsSpecializedOnlyWithUnknown = maybeIsSpecializedOnlyWithUnknown && resolvedType.isUnknownType(); } this.templateTypes = builder.build(); this.isSpecializedOnlyWithUnknown = maybeIsSpecializedOnlyWithUnknown; this.replacer = new TemplateTypeMapReplacer(registry, getTemplateTypeMap()); }
/** * 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; }
/** * 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(); }
/** * Computes the greatest subtype of two related templatized types. * @return The greatest subtype. */ JSType getGreatestSubtypeHelper(JSType rawThat) { Preconditions.checkNotNull(rawThat); if (!wrapsSameRawType(rawThat)) { if (!rawThat.isTemplatizedType()) { if (this.isSubtype(rawThat)) { return this; } else if (rawThat.isSubtype(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(); Preconditions.checkNotNull(that); if (getTemplateTypeMap().checkEquivalenceHelper( that.getTemplateTypeMap(), EquivalenceMethod.INVARIANT)) { 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(); }