@@ -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