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 14c0a9b

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 0a450ca commit 14c0a9b

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

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

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

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

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

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

@@ -167,20 +189,14 @@ export function findNodes<T extends ts.Node>(
167189
*/
168190
export function getSourceNodes(sourceFile: ts.SourceFile): ts.Node[] {
169191
const nodes: ts.Node[] = [sourceFile];
170-
const result: ts.Node[] = [];
171-
172-
while (nodes.length > 0) {
173-
const node = nodes.shift();
174192

175-
if (node) {
176-
result.push(node);
177-
if (node.getChildCount(sourceFile) >= 0) {
178-
nodes.unshift(...node.getChildren());
179-
}
180-
}
193+
// NOTE: nodes.length changes inside of the loop but we only append to the end
194+
for (let i = 0; i < nodes.length; i++) {
195+
const node = nodes[i];
196+
nodes.push(...node.getChildren(sourceFile));
181197
}
182198

183-
return result;
199+
return nodes;
184200
}
185201

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

0 commit comments

Comments
(0)

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