Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4d591ff

Browse files
committed
perf(@schematics/angular): optimize AST traversal utilities
Improves the performance of AST utility functions by reducing redundant work and memory allocations. - The `findNodes` function is now memoized with a `WeakMap`-based cache. This prevents repeated traversals of the entire source file AST when searching for nodes of the same kind, which is a common pattern. - The `getSourceNodes` function has been refactored to use a single array instead of two, reducing memory overhead and avoiding costly `shift()` operations.
1 parent db775e1 commit 4d591ff

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

‎packages/schematics/angular/utility/ast-utils.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ export function insertImport(
9191
);
9292
}
9393

94+
const findNodesCache = new WeakMap<
95+
ts.SourceFile,
96+
Map<ts.SyntaxKind | ((node: ts.Node) => boolean), ts.Node[]>
97+
>();
98+
9499
/**
95100
* Find all nodes from the AST in the subtree of node of SyntaxKind kind.
96101
* @param node
@@ -138,6 +143,14 @@ export function findNodes<T extends ts.Node>(
138143
? kindOrGuard
139144
: (node: ts.Node): node is T => node.kind === kindOrGuard;
140145

146+
// Caching is only supported for the entire file
147+
if (ts.isSourceFile(node)) {
148+
const sourceFileCache = findNodesCache.get(node);
149+
if (sourceFileCache?.has(kindOrGuard)) {
150+
return sourceFileCache.get(kindOrGuard) as T[];
151+
}
152+
}
153+
141154
const arr: T[] = [];
142155
if (test(node)) {
143156
arr.push(node);
@@ -158,6 +171,15 @@ export function findNodes<T extends ts.Node>(
158171
}
159172
}
160173

174+
if (ts.isSourceFile(node)) {
175+
let sourceFileCache = findNodesCache.get(node);
176+
if (!sourceFileCache) {
177+
sourceFileCache = new Map();
178+
findNodesCache.set(node, sourceFileCache);
179+
}
180+
sourceFileCache.set(kindOrGuard, arr);
181+
}
182+
161183
return arr;
162184
}
163185

@@ -168,20 +190,13 @@ export function findNodes<T extends ts.Node>(
168190
*/
169191
export function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[] {
170192
const nodes: ts.Node[] = [sourceFile];
171-
const result: ts.Node[] = [];
172-
173-
while (nodes.length > 0) {
174-
const node = nodes.shift();
175193

176-
if (node) {
177-
result.push(node);
178-
if (node.getChildCount(sourceFile) >= 0) {
179-
nodes.unshift(...node.getChildren());
180-
}
181-
}
194+
for (let i = 0; i < nodes.length; i++) {
195+
const node = nodes[i];
196+
nodes.push(...node.getChildren(sourceFile));
182197
}
183198

184-
return result;
199+
return nodes;
185200
}
186201

187202
export function findNode(node: ts.Node, kind: ts.SyntaxKind, text: string): ts.Node | null {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /