mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
chore(schematics): better NgModule search logic (#14449)
* Similarly to https://github.com/angular/material2/pull/12636#discussion_r209788320, I want to improve the logic for finding `NgModule` declarations within a source file by using BFS.
This commit is contained in:
committed by
vivian-hu
parent
7c2bfdebb4
commit
16a88002fc
@@ -21,19 +21,7 @@ export function hasNgModuleImport(tree: Tree, modulePath: string, className: str
|
||||
|
||||
const parsedFile = ts.createSourceFile(modulePath, moduleFileContent.toString(),
|
||||
ts.ScriptTarget.Latest, true);
|
||||
let ngModuleMetadata: ts.ObjectLiteralExpression | null = null;
|
||||
|
||||
const findModuleDecorator = (node: ts.Node) => {
|
||||
if (ts.isDecorator(node) && ts.isCallExpression(node.expression) &&
|
||||
isNgModuleCallExpression(node.expression)) {
|
||||
ngModuleMetadata = node.expression.arguments[0] as ts.ObjectLiteralExpression;
|
||||
return;
|
||||
}
|
||||
|
||||
ts.forEachChild(node, findModuleDecorator);
|
||||
};
|
||||
|
||||
ts.forEachChild(parsedFile, findModuleDecorator);
|
||||
const ngModuleMetadata = findNgModuleMetadata(parsedFile);
|
||||
|
||||
if (!ngModuleMetadata) {
|
||||
throw new SchematicsException(`Could not find NgModule declaration inside: "${modulePath}"`);
|
||||
@@ -66,6 +54,29 @@ function resolveIdentifierOfExpression(expression: ts.Expression): ts.Identifier
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a NgModule declaration within the specified TypeScript node and returns the
|
||||
* corresponding metadata for it. This function searches breadth first because
|
||||
* NgModule's are usually not nested within other expressions or declarations.
|
||||
*/
|
||||
function findNgModuleMetadata(rootNode: ts.Node): ts.ObjectLiteralExpression | null {
|
||||
// Add immediate child nodes of the root node to the queue.
|
||||
const nodeQueue: ts.Node[] = [...rootNode.getChildren()];
|
||||
|
||||
while (nodeQueue.length) {
|
||||
const node = nodeQueue.shift()!;
|
||||
|
||||
if (ts.isDecorator(node) && ts.isCallExpression(node.expression) &&
|
||||
isNgModuleCallExpression(node.expression)) {
|
||||
return node.expression.arguments[0] as ts.ObjectLiteralExpression;
|
||||
} else {
|
||||
nodeQueue.push(...node.getChildren());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Whether the specified call expression is referring to a NgModule definition. */
|
||||
function isNgModuleCallExpression(callExpression: ts.CallExpression): boolean {
|
||||
if (!callExpression.arguments.length ||
|
||||
|
||||
Reference in New Issue
Block a user