/** * 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; }
@Override public JSType caseTemplateType(TemplateType type) { if (replacements.hasTemplateKey(type)) { if (hasVisitedType(type) || !replacements.hasTemplateType(type)) { // If we have already encountered this TemplateType during replacement // (i.e. there is a reference loop), or there is no JSType substitution // for the TemplateType, return the TemplateType type itself. return type; } else { JSType replacement = replacements.getUnresolvedOriginalTemplateType(type); if (isRecursive(type, replacement)) { // Recursive templated type definition (e.g. T resolved to Foo<T>). return type; } visitedTypes.push(type); JSType visitedReplacement = replacement.visit(this); visitedTypes.pop(); return visitedReplacement; } } else { return type; } }
@Override @SuppressWarnings("ReferenceEquality") public JSType caseTemplateType(TemplateType type) { if (replacements.hasTemplateKey(type)) { if (hasVisitedType(type)) {
/** * Returns the given `Iterable`s element type. * * <p>If the given type is not an `Iterator`, `Iterable`, `AsyncIterator`, or `AsyncIterable`, * returns the unknown type. */ static final JSType getElementType(JSType iterableOrIterator, JSTypeRegistry typeRegistry) { TemplateTypeMap templateTypeMap = iterableOrIterator // Remember that `string` will box to a `Iterable`. .autobox() .getTemplateTypeMap(); if (templateTypeMap.hasTemplateKey(typeRegistry.getIterableTemplate())) { // `Iterable<SomeElementType>` or `Generator<SomeElementType>` return templateTypeMap.getResolvedTemplateType(typeRegistry.getIterableTemplate()); } else if (templateTypeMap.hasTemplateKey(typeRegistry.getIteratorTemplate())) { // `Iterator<SomeElementType>` return templateTypeMap.getResolvedTemplateType(typeRegistry.getIteratorTemplate()); } else if (templateTypeMap.hasTemplateKey(typeRegistry.getAsyncIterableTemplate())) { // `AsyncIterable<SomeElementType>` or `AsyncGenerator<SomeElementType>` return templateTypeMap.getResolvedTemplateType(typeRegistry.getAsyncIterableTemplate()); } else if (templateTypeMap.hasTemplateKey(typeRegistry.getAsyncIteratorTemplate())) { // `AsyncIterator<SomeElementType>` return templateTypeMap.getResolvedTemplateType(typeRegistry.getAsyncIteratorTemplate()); } return typeRegistry.getNativeType(UNKNOWN_TYPE); }
if (templates.hasTemplateKey(registry.getObjectIndexKey())) { return registry.createTemplatizedType( objectType,
if (dereferenced != null && dereferenced .getTemplateTypeMap() .hasTemplateKey(typeRegistry.getObjectIndexKey())) { expectCanAssignTo(t, indexNode, indexType, dereferenced .getTemplateTypeMap().getResolvedTemplateType(typeRegistry.getObjectIndexKey()),
if (dereferenced != null && dereferenced .getTemplateTypeMap() .hasTemplateKey(typeRegistry.getObjectIndexKey())) { expectCanAssignTo(t, indexNode, indexType, dereferenced .getTemplateTypeMap().getResolvedTemplateType(typeRegistry.getObjectIndexKey()),
if (templates.hasTemplateKey(registry.getIThenableTemplate())) {