@@ -21,19 +21,7 @@ export function hasNgModuleImport(tree: Tree, modulePath: string, className: str
21
21
22
22
const parsedFile = ts . createSourceFile ( modulePath , moduleFileContent . toString ( ) ,
23
23
ts . ScriptTarget . Latest , true ) ;
24
- let ngModuleMetadata : ts . ObjectLiteralExpression | null = null ;
25
-
26
- const findModuleDecorator = ( node : ts . Node ) => {
27
- if ( ts . isDecorator ( node ) && ts . isCallExpression ( node . expression ) &&
28
- isNgModuleCallExpression ( node . expression ) ) {
29
- ngModuleMetadata = node . expression . arguments [ 0 ] as ts . ObjectLiteralExpression ;
30
- return ;
31
- }
32
-
33
- ts . forEachChild ( node , findModuleDecorator ) ;
34
- } ;
35
-
36
- ts . forEachChild ( parsedFile , findModuleDecorator ) ;
24
+ const ngModuleMetadata = findNgModuleMetadata ( parsedFile ) ;
37
25
38
26
if ( ! ngModuleMetadata ) {
39
27
throw new SchematicsException ( `Could not find NgModule declaration inside: "${ modulePath } "` ) ;
@@ -66,6 +54,29 @@ function resolveIdentifierOfExpression(expression: ts.Expression): ts.Identifier
66
54
return null ;
67
55
}
68
56
57
+ /**
58
+ * Finds a NgModule declaration within the specified TypeScript node and returns the
59
+ * corresponding metadata for it. This function searches breadth first because
60
+ * NgModule's are usually not nested within other expressions or declarations.
61
+ */
62
+ function findNgModuleMetadata ( rootNode : ts . Node ) : ts . ObjectLiteralExpression | null {
63
+ // Add immediate child nodes of the root node to the queue.
64
+ const nodeQueue : ts . Node [ ] = [ ...rootNode . getChildren ( ) ] ;
65
+
66
+ while ( nodeQueue . length ) {
67
+ const node = nodeQueue . shift ( ) ! ;
68
+
69
+ if ( ts . isDecorator ( node ) && ts . isCallExpression ( node . expression ) &&
70
+ isNgModuleCallExpression ( node . expression ) ) {
71
+ return node . expression . arguments [ 0 ] as ts . ObjectLiteralExpression ;
72
+ } else {
73
+ nodeQueue . push ( ...node . getChildren ( ) ) ;
74
+ }
75
+ }
76
+
77
+ return null ;
78
+ }
79
+
69
80
/** Whether the specified call expression is referring to a NgModule definition. */
70
81
function isNgModuleCallExpression ( callExpression : ts . CallExpression ) : boolean {
71
82
if ( ! callExpression . arguments . length ||
0 commit comments