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