in compiler/src/model/utils.ts [1010:1048]
export function getAllBehaviors (node: ClassDeclaration | InterfaceDeclaration): string[] {
const behaviors = getBehaviors(node.getHeritageClauses())
const extended = getExtended(node.getHeritageClauses()).flatMap(clause => clause.getTypeNodes())
.map(t => t.getExpression())
for (const extend of extended) {
assert(extend, Node.isReferenceFindable(extend), 'Should be a reference node')
const declaration = extend.getType().getSymbol()?.getDeclarations()[0]
assert(extend, declaration != null, `Cannot find declaration for ${extend.getText()}`)
if (Node.isClassDeclaration(declaration) || Node.isInterfaceDeclaration(declaration)) {
if (declaration.getHeritageClauses().length > 0) {
behaviors.push(...getAllBehaviors(declaration))
}
} else if (Node.isImportSpecifier(declaration)) {
const sourceFile = declaration.getImportDeclaration().getModuleSpecifierSourceFile()
assert(declaration, sourceFile != null, 'Cannot find source file')
const name = declaration.getName()
for (const declaration of [...sourceFile.getClasses(), ...sourceFile.getInterfaces()]) {
if (declaration.getName() === name && declaration.getHeritageClauses().length > 0) {
behaviors.push(...getAllBehaviors(declaration))
}
}
} else {
assert(declaration, false, `Unhandled extended declaration ${declaration?.getText() ?? ''}`)
}
}
return Array.from(new Set(behaviors))
function getExtended (clauses: HeritageClause[]): HeritageClause[] {
return clauses.filter(clause => clause.getToken() === ts.SyntaxKind.ExtendsKeyword)
}
function getBehaviors (clauses: HeritageClause[]): string[] {
return clauses
.filter(isKnownBehavior)
.map(clause => clause.getTypeNodes()[0].getExpression().getText())
}
}