function _allTypeReferences()

in src/validator.ts [596:652]


function _allTypeReferences(assm: spec.Assembly): readonly AnnotatedTypeReference[] {
  const typeReferences = new Array<AnnotatedTypeReference>();
  for (const type of _allTypes(assm)) {
    if (!spec.isClassOrInterfaceType(type)) {
      continue;
    }
    if (spec.isClassType(type)) {
      const node = bindings.getClassRelatedNode(type);
      if (type.base) {
        typeReferences.push({
          fqn: type.base,
          node: node?.heritageClauses?.find((hc) => hc.token === ts.SyntaxKind.ExtendsKeyword)?.types[0],
        });
      }
      if (type.initializer?.parameters) {
        for (const param of type.initializer.parameters) {
          _collectTypeReferences(param.type, bindings.getParameterRelatedNode(param)?.type);
        }
      }
    }
    if (type.interfaces) {
      const node = bindings.getClassOrInterfaceRelatedNode(type);
      for (const iface of type.interfaces) {
        typeReferences.push({
          fqn: iface,
          node: node?.heritageClauses?.find(
            (hc) =>
              hc.token ===
              (spec.isInterfaceType(type) ? ts.SyntaxKind.ImplementsKeyword : ts.SyntaxKind.ExtendsKeyword),
          ),
        });
      }
    }
  }
  for (const { member: prop } of _allProperties(assm)) {
    _collectTypeReferences(prop.type, bindings.getPropertyRelatedNode(prop)?.type);
  }
  for (const { member: meth } of _allMethods(assm)) {
    if (meth.returns) {
      _collectTypeReferences(meth.returns.type, bindings.getMethodRelatedNode(meth)?.type);
    }
    for (const param of meth.parameters ?? []) {
      _collectTypeReferences(param.type, bindings.getParameterRelatedNode(param)?.type);
    }
  }
  return typeReferences;

  function _collectTypeReferences(type: spec.TypeReference, node: ts.Node | undefined): void {
    if (spec.isNamedTypeReference(type)) {
      typeReferences.push({ ...type, node });
    } else if (spec.isCollectionTypeReference(type)) {
      _collectTypeReferences(type.collection.elementtype, node);
    } else if (spec.isUnionTypeReference(type)) {
      for (const t of type.union.types) _collectTypeReferences(t, node);
    }
  }
}