in src/validator.ts [170:209]
function _allImplementations<T extends spec.Property | spec.Method>(
type: spec.ClassType | spec.InterfaceType,
getter: (type: spec.ClassType | spec.InterfaceType) => T[] | undefined,
): T[] {
const result = new Array<T>();
const known = new Set<string>();
for (const member of getter(type) ?? []) {
result.push(member);
known.add(member.name);
}
if (spec.isClassType(type) && type.base) {
// We have a parent class, collect their concrete members, too (recursively)...
const base = _dereference(type.base, assembly, validator);
assert(base != null && spec.isClassType(base));
for (const member of _allImplementations(base, getter)) {
if (known.has(member.name)) {
continue;
}
// The member is copied, so that its `overrides` property won't be
// altered, since this member is "borrowed" from a parent type. We
// only check it, but should not record `overrides` relationships to
// it as those could be invalid per the parent type (i.e: the parent
// member may not be able to implement an interface, if that type does
// not actually declare implementing that).
const memberCopy = { ...member };
// Forward the related node if there's one, so diagnostics are bound.
const node = bindings.getRelatedNode(member);
if (node != null) {
bindings.setRelatedNode(memberCopy, node);
}
result.push(memberCopy);
known.add(member.name);
}
}
return result;
}