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