function _allImplementations()

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