@@ -465,67 +465,78 @@ package final actor SemanticIndexManager {
465
465
}
466
466
let modifiedFilesIndex = index. checked ( for: . modifiedFiles)
467
467
468
- let filesWithTargetAndOutput : [ ( file: DocumentURI , target: BuildTargetIdentifier , outputPath: OutputPath ? ) ] =
469
- await files. asyncFlatMap { file in
470
- await buildSystemManager. sourceFileInfo ( for: file) ? . targetsToOutputPaths. map { ( file, $0, $1) } ?? [ ]
471
- }
472
-
473
- let filesToReIndex =
474
- await filesWithTargetAndOutput
475
- . asyncCompactMap { ( uri, target, outputPath) -> ( FileIndexInfo , Date ? ) ? in
468
+ var filesToReIndex : [ ( FileIndexInfo , Date ? ) ] = [ ]
469
+ for uri in files {
470
+ var didFindTargetToIndex = false
471
+ for (target, outputPath) in await buildSystemManager. sourceFileInfo ( for: uri) ? . targetsToOutputPaths ?? [ : ] {
476
472
// First, check if we know that the file is up-to-date, in which case we don't need to hit the index or file
477
473
// system at all
478
474
if !indexFilesWithUpToDateUnits, await indexStoreUpToDateTracker. isUpToDate ( uri, target) {
479
- return nil
475
+ continue
480
476
}
481
477
if sourceFiles. contains ( uri) {
482
478
guard let outputPath else {
483
479
logger. info ( " Not indexing \( uri. forLogging) because its output file could not be determined " )
484
- return nil
480
+ continue
485
481
}
486
482
if !indexFilesWithUpToDateUnits, modifiedFilesIndex. hasUpToDateUnit ( for: uri, outputPath: outputPath) {
487
- return nil
483
+ continue
488
484
}
489
485
// If this is a source file, just index it.
490
- return (
491
- FileIndexInfo ( file: . indexableFile( uri) , target: target, outputPath: outputPath) ,
492
- modifiedFilesIndex. modificationDate ( of: uri)
493
- )
494
- }
495
- // Otherwise, see if it is a header file. If so, index a main file that that imports it to update header file's
496
- // index.
497
- // Deterministically pick a main file. This ensures that we always pick the same main file for a header. This way,
498
- // if we request the same header to be indexed twice, we'll pick the same unit file the second time around,
499
- // realize that its timestamp is later than the modification date of the header and we don't need to re-index.
500
- let mainFile = await buildSystemManager. mainFiles ( containing: uri)
501
- . sorted ( by: { $0. stringValue < $1. stringValue } ) . first
502
- guard let mainFile else {
503
- logger. info ( " Not indexing \( uri) because its main file could not be inferred " )
504
- return nil
505
- }
506
- let mainFileOutputPath = await orLog ( " Getting output path " ) {
507
- try await buildSystemManager. outputPath ( for: mainFile, in: target)
508
- }
509
- guard let mainFileOutputPath else {
510
- logger. info (
511
- " Not indexing \( uri. forLogging) because the output file of its main file \( mainFile. forLogging) could not be determined "
486
+ didFindTargetToIndex = true
487
+ filesToReIndex. append (
488
+ (
489
+ FileIndexInfo ( file: . indexableFile( uri) , target: target, outputPath: outputPath) ,
490
+ modifiedFilesIndex. modificationDate ( of: uri)
491
+ )
512
492
)
513
- return nil
514
493
}
515
- if !indexFilesWithUpToDateUnits,
516
- modifiedFilesIndex. hasUpToDateUnit ( for: uri, mainFile: mainFile, outputPath: mainFileOutputPath)
517
- {
518
- return nil
519
- }
520
- return (
494
+ }
495
+
496
+ if didFindTargetToIndex {
497
+ continue
498
+ }
499
+ // If we haven't found any ways to index the file, see if it is a header file. If so, index a main file that
500
+ // that imports it to update header file's index.
501
+ // Deterministically pick a main file. This ensures that we always pick the same main file for a header. This way,
502
+ // if we request the same header to be indexed twice, we'll pick the same unit file the second time around,
503
+ // realize that its timestamp is later than the modification date of the header and we don't need to re-index.
504
+ let mainFile = await buildSystemManager. mainFiles ( containing: uri)
505
+ . sorted ( by: { $0. stringValue < $1. stringValue } ) . first
506
+ guard let mainFile else {
507
+ logger. info ( " Not indexing \( uri. forLogging) because its main file could not be inferred " )
508
+ continue
509
+ }
510
+ let targetAndOutputPath = ( await buildSystemManager. sourceFileInfo ( for: mainFile) ? . targetsToOutputPaths ?? [ : ] )
511
+ . sorted ( by: { $0. key. uri. stringValue < $1. key. uri. stringValue } ) . first
512
+ guard let targetAndOutputPath else {
513
+ logger. info (
514
+ " Not indexing \( uri. forLogging) because the target file of its main file \( mainFile. forLogging) could not be determined "
515
+ )
516
+ continue
517
+ }
518
+ guard let outputPath = targetAndOutputPath. value else {
519
+ logger. info (
520
+ " Not indexing \( uri. forLogging) because the output file of its main file \( mainFile. forLogging) could not be determined "
521
+ )
522
+ continue
523
+ }
524
+ if !indexFilesWithUpToDateUnits,
525
+ modifiedFilesIndex. hasUpToDateUnit ( for: uri, mainFile: mainFile, outputPath: outputPath)
526
+ {
527
+ continue
528
+ }
529
+ filesToReIndex. append (
530
+ (
521
531
FileIndexInfo (
522
532
file: . headerFile( header: uri, mainFile: mainFile) ,
523
- target: target ,
524
- outputPath: mainFileOutputPath
533
+ target: targetAndOutputPath . key ,
534
+ outputPath: outputPath
525
535
) ,
526
536
modifiedFilesIndex. modificationDate ( of: uri)
527
537
)
528
- }
538
+ )
539
+ }
529
540
return filesToReIndex
530
541
}
531
542
0 commit comments