@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; } }
} else if (!replacements.hasTemplateType(type)) {
private FlowScope traverseGetElem(Node n, FlowScope scope) { scope = traverseChildren(n, scope); JSType type = getJSType(n.getFirstChild()).restrictByNotNullOrUndefined(); TemplateTypeMap typeMap = type.getTemplateTypeMap(); if (typeMap.hasTemplateType(registry.getObjectElementKey())) { n.setJSType(typeMap.getResolvedTemplateType(registry.getObjectElementKey())); } return dereferencePointer(n.getFirstChild(), scope); }
private FlowScope traverseGetElem(Node n, FlowScope scope) { scope = traverseChildren(n, scope); Node indexKey = n.getLastChild(); JSType indexType = getJSType(indexKey); if (indexType.isSymbolValueType()) { // For now, allow symbols definitions/access on any type. In the future only allow them // on the subtypes for which they are defined. // TODO(b/77474174): Type well known symbol accesses. n.setJSType(unknownType); } else { JSType type = getJSType(n.getFirstChild()).restrictByNotNullOrUndefined(); TemplateTypeMap typeMap = type.getTemplateTypeMap(); if (typeMap.hasTemplateType(registry.getObjectElementKey())) { n.setJSType(typeMap.getResolvedTemplateType(registry.getObjectElementKey())); } } return tightenTypeAfterDereference(n.getFirstChild(), scope); }