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);
}
}
}