refactor(compiler-cli): expose the `walkForDeclaration()` function (#37206)

This test helper can be useful when searching for nodes within an IIFE.
Exporting it here is helpful in ngcc reflection tests.

PR Close #37206
This commit is contained in:
Pete Bacon Darwin 2020-05-19 18:13:33 +01:00 committed by Kara Erickson
parent 03fef736d6
commit d42a912343
1 changed files with 34 additions and 31 deletions

View File

@ -54,7 +54,7 @@ export function getDeclaration<T extends ts.Declaration>(
program: ts.Program, fileName: AbsoluteFsPath, name: string, program: ts.Program, fileName: AbsoluteFsPath, name: string,
assert: (value: any) => value is T): T { assert: (value: any) => value is T): T {
const sf = getSourceFileOrError(program, fileName); const sf = getSourceFileOrError(program, fileName);
const chosenDecl = walkForDeclaration(sf); const chosenDecl = walkForDeclaration(name, sf);
if (chosenDecl === null) { if (chosenDecl === null) {
throw new Error(`No such symbol: ${name} in ${fileName}`); throw new Error(`No such symbol: ${name} in ${fileName}`);
@ -63,9 +63,10 @@ export function getDeclaration<T extends ts.Declaration>(
throw new Error(`Symbol ${name} from ${fileName} is a ${ts.SyntaxKind[chosenDecl.kind]}`); throw new Error(`Symbol ${name} from ${fileName} is a ${ts.SyntaxKind[chosenDecl.kind]}`);
} }
return chosenDecl; return chosenDecl;
}
// We walk the AST tree looking for a declaration that matches // We walk the AST tree looking for a declaration that matches
function walkForDeclaration(rootNode: ts.Node): ts.Declaration|null { export function walkForDeclaration(name: string, rootNode: ts.Node): ts.Declaration|null {
let chosenDecl: ts.Declaration|null = null; let chosenDecl: ts.Declaration|null = null;
rootNode.forEachChild(node => { rootNode.forEachChild(node => {
if (chosenDecl !== null) { if (chosenDecl !== null) {
@ -75,11 +76,13 @@ export function getDeclaration<T extends ts.Declaration>(
node.declarationList.declarations.forEach(decl => { node.declarationList.declarations.forEach(decl => {
if (bindingNameEquals(decl.name, name)) { if (bindingNameEquals(decl.name, name)) {
chosenDecl = decl; chosenDecl = decl;
} else {
chosenDecl = walkForDeclaration(name, node);
} }
}); });
} else if ( } else if (
ts.isClassDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isFunctionDeclaration(node) ||
ts.isInterfaceDeclaration(node)) { ts.isInterfaceDeclaration(node) || ts.isClassExpression(node)) {
if (node.name !== undefined && node.name.text === name) { if (node.name !== undefined && node.name.text === name) {
chosenDecl = node; chosenDecl = node;
} }
@ -88,12 +91,12 @@ export function getDeclaration<T extends ts.Declaration>(
node.importClause.name !== undefined && node.importClause.name.text === name) { node.importClause.name !== undefined && node.importClause.name.text === name) {
chosenDecl = node.importClause; chosenDecl = node.importClause;
} else { } else {
chosenDecl = walkForDeclaration(node); chosenDecl = walkForDeclaration(name, node);
} }
}); });
return chosenDecl; return chosenDecl;
} }
}
function bindingNameEquals(node: ts.BindingName, name: string): boolean { function bindingNameEquals(node: ts.BindingName, name: string): boolean {
if (ts.isIdentifier(node)) { if (ts.isIdentifier(node)) {