@@ -91,6 +91,14 @@ private struct InProgressIndexStore {
9191 var fileModificationDate : Date ?
9292}
9393
94+ /// The information that's needed to index a file within a given target.
95+ package struct FileIndexInfo : Sendable , Hashable {
96+ package let file : FileToIndex
97+ package let language : Language
98+ package let target : BuildTargetIdentifier
99+ package let outputPath : OutputPath
100+ }
101+
94102/// Status of document indexing / target preparation in `inProgressIndexAndPreparationTasks`.
95103package enum IndexTaskStatus : Comparable {
96104 case scheduled
@@ -500,10 +508,13 @@ package final actor SemanticIndexManager {
500508 continue
501509 }
502510 // If this is a source file, just index it.
511+ guard let language = await buildServerManager. defaultLanguage ( for: uri, in: target) else {
512+ continue
513+ }
503514 didFindTargetToIndex = true
504515 filesToReIndex. append (
505516 (
506- FileIndexInfo ( file: . indexableFile( uri) , target: target, outputPath: outputPath) ,
517+ FileIndexInfo ( file: . indexableFile( uri) , language : language , target: target, outputPath: outputPath) ,
507518 modifiedFilesIndex. modificationDate ( of: uri)
508519 )
509520 )
@@ -543,10 +554,14 @@ package final actor SemanticIndexManager {
543554 {
544555 continue
545556 }
557+ guard let language = await buildServerManager. defaultLanguage ( for: uri, in: targetAndOutputPath. key) else {
558+ continue
559+ }
546560 filesToReIndex. append (
547561 (
548562 FileIndexInfo (
549563 file: . headerFile( header: uri, mainFile: mainFile) ,
564+ language: language,
550565 target: targetAndOutputPath. key,
551566 outputPath: outputPath
552567 ) ,
@@ -722,16 +737,20 @@ package final actor SemanticIndexManager {
722737 }
723738 }
724739
725- /// Update the index store for the given files, assuming that their targets have already been prepared.
740+ /// Update the index store for the given files, assuming that their targets has already been prepared.
726741 private func updateIndexStore(
727- for filesAndTargets: [ FileIndexInfo ] ,
742+ for fileAndOutputPaths: [ FileAndOutputPath ] ,
743+ target: BuildTargetIdentifier ,
744+ language: Language ,
728745 indexFilesWithUpToDateUnit: Bool ,
729746 preparationTaskID: UUID ,
730747 priority: TaskPriority ?
731748 ) async {
732749 let taskDescription = AnyIndexTaskDescription (
733750 UpdateIndexStoreTaskDescription (
734- filesToIndex: filesAndTargets,
751+ filesToIndex: fileAndOutputPaths,
752+ target: target,
753+ language: language,
735754 buildServerManager: self . buildServerManager,
736755 index: index,
737756 indexStoreUpToDateTracker: indexStoreUpToDateTracker,
@@ -747,7 +766,13 @@ package final actor SemanticIndexManager {
747766 self . indexProgressStatusDidChange ( )
748767 return
749768 }
750- for fileAndTarget in filesAndTargets {
769+ for fileAndOutputPath in fileAndOutputPaths {
770+ let fileAndTarget = FileIndexInfo (
771+ file: fileAndOutputPath. file,
772+ language: language,
773+ target: target,
774+ outputPath: fileAndOutputPath. outputPath
775+ )
751776 switch self . inProgressIndexTasks [ fileAndTarget] ? . state {
752777 case . updatingIndexStore( let registeredTask, _) :
753778 if registeredTask == OpaqueQueuedIndexTask ( task) {
@@ -763,7 +788,13 @@ package final actor SemanticIndexManager {
763788 }
764789 self . indexProgressStatusDidChange ( )
765790 }
766- for fileAndTarget in filesAndTargets {
791+ for fileAndOutputPath in fileAndOutputPaths {
792+ let fileAndTarget = FileIndexInfo (
793+ file: fileAndOutputPath. file,
794+ language: language,
795+ target: target,
796+ outputPath: fileAndOutputPath. outputPath
797+ )
767798 switch inProgressIndexTasks [ fileAndTarget] ? . state {
768799 case . waitingForPreparation( preparationTaskID, let indexTask) , . preparing( preparationTaskID, let indexTask) :
769800 inProgressIndexTasks [ fileAndTarget] ? . state = . updatingIndexStore(
@@ -854,13 +885,7 @@ package final actor SemanticIndexManager {
854885 var newIndexTasks = 0
855886
856887 for (fileIndexInfo, fileModificationDate) in filesToIndex {
857- guard
858- let language = await buildServerManager. defaultLanguage (
859- for: fileIndexInfo. file. mainFile,
860- in: fileIndexInfo. target
861- ) ,
862- UpdateIndexStoreTaskDescription . canIndex ( language: language)
863- else {
888+ guard UpdateIndexStoreTaskDescription . canIndex ( language: fileIndexInfo. language) else {
864889 continue
865890 }
866891
@@ -933,17 +958,34 @@ package final actor SemanticIndexManager {
933958 // And after preparation is done, index the files in the targets.
934959 await withTaskGroup ( of: Void . self) { taskGroup in
935960 for target in targetsBatch {
936- // TODO: Once swiftc supports indexing of multiple files in a single invocation, increase the batch size to
937- // allow it to share AST builds between multiple files within a target.
938- // (https://github.com/swiftlang/sourcekit-lsp/issues/1268)
939- for fileBatch in filesByTarget [ target] !. partition ( intoBatchesOfSize: 1 ) {
940- taskGroup. addTask {
941- await self . updateIndexStore (
942- for: fileBatch,
943- indexFilesWithUpToDateUnit: indexFilesWithUpToDateUnit,
944- preparationTaskID: preparationTaskID,
945- priority: priority
946- )
961+ var filesByLanguage : [ Language : [ FileIndexInfo ] ] = [ : ]
962+ for fileInfo in filesByTarget [ target] ! {
963+ filesByLanguage [ fileInfo. language, default: [ ] ] . append ( fileInfo)
964+ }
965+ for (language, fileInfos) in filesByLanguage {
966+ // TODO: Once swiftc supports indexing of multiple files in a single invocation, increase the batch size to
967+ // allow it to share AST builds between multiple files within a target.
968+ // (https://github.com/swiftlang/sourcekit-lsp/issues/1268)
969+ for fileBatch in fileInfos. partition ( intoBatchesOfSize: 1 ) {
970+ taskGroup. addTask {
971+ let fileAndOutputPaths : [ FileAndOutputPath ] = fileBatch. compactMap {
972+ guard $0. target == target else {
973+ logger. fault (
974+ " FileIndexInfo refers to different target than should be indexed \( $0. target. forLogging) vs \( target. forLogging) "
975+ )
976+ return nil
977+ }
978+ return FileAndOutputPath ( file: $0. file, outputPath: $0. outputPath)
979+ }
980+ await self . updateIndexStore (
981+ for: fileAndOutputPaths,
982+ target: target,
983+ language: language,
984+ indexFilesWithUpToDateUnit: indexFilesWithUpToDateUnit,
985+ preparationTaskID: preparationTaskID,
986+ priority: priority
987+ )
988+ }
947989 }
948990 }
949991 }
0 commit comments