@@ -468,68 +468,78 @@ package final actor SemanticIndexManager {
468468 }
469469 let modifiedFilesIndex = index. checked ( for: . modifiedFiles)
470470
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 ?? [ : ] {
479475 // 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
480476 // system at all
481477 if !indexFilesWithUpToDateUnits, await indexStoreUpToDateTracker. isUpToDate ( uri, target) {
482- return nil
478+ continue
483479 }
484480 if sourceFiles. contains ( uri) {
485481 guard let outputPath else {
486482 logger. info ( " Not indexing \( uri. forLogging) because its output file could not be determined " )
487- return nil
483+ continue
488484 }
489485 if !indexFilesWithUpToDateUnits, modifiedFilesIndex. hasUpToDateUnit ( for: uri, outputPath: outputPath) {
490- return nil
486+ continue
491487 }
492488 // 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+ )
496495 )
497496 }
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+ (
525534 FileIndexInfo (
526535 file: . headerFile( header: uri, mainFile: mainFile) ,
527- target: target ,
528- outputPath: mainFileOutputPath
536+ target: targetAndOutputPath . key ,
537+ outputPath: outputPath
529538 ) ,
530539 modifiedFilesIndex. modificationDate ( of: uri)
531540 )
532- }
541+ )
542+ }
533543 return filesToReIndex
534544 }
535545
0 commit comments