Skip to content

Commit 573df54

Browse files
committed
Refactor walkAndAnalyze: dedupe cached/uncached paths
1 parent b63fbd9 commit 573df54

1 file changed

Lines changed: 21 additions & 26 deletions

File tree

packages/knip/src/ProjectPrincipal.ts

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -174,58 +174,53 @@ export class ProjectPrincipal {
174174
let lastEntrySize = this.entryPaths.size;
175175
let lastProgramSize = this.programPaths.size;
176176

177+
const rescanFrontier = () => {
178+
if (this.entryPaths.size > lastEntrySize || this.programPaths.size > lastProgramSize) {
179+
for (const p of this.entryPaths) visited.add(p);
180+
for (const p of this.programPaths) visited.add(p);
181+
lastEntrySize = this.entryPaths.size;
182+
lastProgramSize = this.programPaths.size;
183+
}
184+
};
185+
177186
for (const filePath of visited) {
178187
const isProjectPath = this.projectPaths.has(filePath);
179188

180-
// Skip read+parse for project files when the cache will hit downstream in analyzeSourceFile.
181-
// Pass the cached FileNode through to skip a redundant cache lookup there too.
189+
// Cached project files: skip read+parse and pass the cached FileNode through.
190+
let cachedFile: FileNode | undefined;
182191
if (isProjectPath) {
183192
const fd = this.cache.getFileDescriptor(filePath);
184-
if (!fd.changed && fd.meta?.data) {
185-
const internalPaths = analyzeFile(filePath, undefined, '', fd.meta.data);
186-
if (internalPaths) {
187-
for (const p of internalPaths) visited.add(p);
188-
}
189-
if (this.entryPaths.size > lastEntrySize || this.programPaths.size > lastProgramSize) {
190-
for (const p of this.entryPaths) visited.add(p);
191-
for (const p of this.programPaths) visited.add(p);
192-
lastEntrySize = this.entryPaths.size;
193-
lastProgramSize = this.programPaths.size;
194-
}
195-
continue;
196-
}
193+
if (!fd.changed && fd.meta?.data) cachedFile = fd.meta.data;
197194
}
198195

199-
const sourceText = this.fileManager.readFile(filePath);
196+
if (cachedFile) {
197+
const internalPaths = analyzeFile(filePath, undefined, '', cachedFile);
198+
if (internalPaths) for (const p of internalPaths) visited.add(p);
199+
rescanFrontier();
200+
continue;
201+
}
200202

203+
const sourceText = this.fileManager.readFile(filePath);
201204
if (!sourceText) {
202205
if (isProjectPath) analyzeFile(filePath, undefined, '');
203206
continue;
204207
}
205208

206209
try {
207210
const result = parseFile(filePath, sourceText);
208-
209211
this.fileManager.sourceTextCache.delete(filePath);
210212

211213
if (isProjectPath) {
212214
const internalPaths = analyzeFile(filePath, result, sourceText);
213-
if (internalPaths) {
214-
for (const p of internalPaths) visited.add(p);
215-
}
215+
if (internalPaths) for (const p of internalPaths) visited.add(p);
216216
} else {
217217
for (const specifier of extractSpecifiers(result, sourceText, filePath)) {
218218
const resolved = this.resolveSpecifier(specifier, filePath);
219219
if (resolved && !isInNodeModules(resolved)) visited.add(resolved);
220220
}
221221
}
222222

223-
if (this.entryPaths.size > lastEntrySize || this.programPaths.size > lastProgramSize) {
224-
for (const p of this.entryPaths) visited.add(p);
225-
for (const p of this.programPaths) visited.add(p);
226-
lastEntrySize = this.entryPaths.size;
227-
lastProgramSize = this.programPaths.size;
228-
}
223+
rescanFrontier();
229224
} catch {
230225
// Parse error — skip this file
231226
}

0 commit comments

Comments
 (0)