@@ -93,16 +93,16 @@ package enum IndexTaskStatus: Comparable {
9393/// messages to the user, we only show the highest priority task.
9494package enum IndexProgressStatus : Sendable {
9595 case preparingFileForEditorFunctionality
96- case generatingBuildGraph
96+ case schedulingIndexing
9797 case indexing( preparationTasks: [ BuildTargetIdentifier : IndexTaskStatus ] , indexTasks: [ DocumentURI : IndexTaskStatus ] )
9898 case upToDate
9999
100100 package func merging( with other: IndexProgressStatus ) -> IndexProgressStatus {
101101 switch ( self , other) {
102102 case ( _, . preparingFileForEditorFunctionality) , ( . preparingFileForEditorFunctionality, _) :
103103 return . preparingFileForEditorFunctionality
104- case ( _, . generatingBuildGraph ) , ( . generatingBuildGraph , _) :
105- return . generatingBuildGraph
104+ case ( _, . schedulingIndexing ) , ( . schedulingIndexing , _) :
105+ return . schedulingIndexing
106106 case (
107107 . indexing( let selfPreparationTasks, let selfIndexTasks) ,
108108 . indexing( let otherPreparationTasks, let otherIndexTasks)
@@ -162,9 +162,9 @@ package final actor SemanticIndexManager {
162162
163163 private let testHooks : IndexTestHooks
164164
165- /// The task to generate the build graph (resolving package dependencies, generating the build description,
166- /// ...). `nil` if no build graph is currently being generated .
167- private var generateBuildGraphTask : Task < Void , Never > ?
165+ /// The tasks to generate the build graph (resolving package dependencies, generating the build description,
166+ /// ...) and to schedule indexing of modified tasks .
167+ private var scheduleIndexingTasks : [ UUID : Task < Void , Never > ] = [ : ]
168168
169169 private let preparationUpToDateTracker = UpToDateTracker < BuildTargetIdentifier > ( )
170170
@@ -213,8 +213,8 @@ package final actor SemanticIndexManager {
213213 if inProgressPreparationTasks. values. contains ( where: { $0. purpose == . forEditorFunctionality } ) {
214214 return . preparingFileForEditorFunctionality
215215 }
216- if generateBuildGraphTask != nil {
217- return . generatingBuildGraph
216+ if !scheduleIndexingTasks . isEmpty {
217+ return . schedulingIndexing
218218 }
219219 let preparationTasks = inProgressPreparationTasks. mapValues { inProgressTask in
220220 return inProgressTask. task. isExecuting ? IndexTaskStatus . executing : IndexTaskStatus . scheduled
@@ -275,7 +275,8 @@ package final actor SemanticIndexManager {
275275 filesToIndex: [ DocumentURI ] ? ,
276276 indexFilesWithUpToDateUnit: Bool
277277 ) async {
278- generateBuildGraphTask = Task ( priority: . low) {
278+ let taskId = UUID ( )
279+ let generateBuildGraphTask = Task ( priority: . low) {
279280 await withLoggingSubsystemAndScope ( subsystem: indexLoggingSubsystem, scope: " build-graph-generation " ) {
280281 await testHooks. buildGraphGenerationDidStart ? ( )
281282 await self . buildSystemManager. waitForUpToDateBuildGraph ( )
@@ -308,9 +309,10 @@ package final actor SemanticIndexManager {
308309 }
309310 }
310311 await scheduleBackgroundIndex ( files: filesToIndex, indexFilesWithUpToDateUnit: indexFilesWithUpToDateUnit)
311- generateBuildGraphTask = nil
312+ scheduleIndexingTasks [ taskId ] = nil
312313 }
313314 }
315+ scheduleIndexingTasks [ taskId] = generateBuildGraphTask
314316 indexProgressStatusDidChange ( )
315317 }
316318
@@ -322,12 +324,22 @@ package final actor SemanticIndexManager {
322324 await scheduleBuildGraphGenerationAndBackgroundIndexAllFiles ( filesToIndex: nil , indexFilesWithUpToDateUnit: true )
323325 }
324326
327+ private func waitForBuildGraphGenerationTasks( ) async {
328+ await withTaskGroup ( of: Void . self) { taskGroup in
329+ for generateBuildGraphTask in scheduleIndexingTasks. values {
330+ taskGroup. addTask {
331+ await generateBuildGraphTask. value
332+ }
333+ }
334+ }
335+ }
336+
325337 /// Wait for all in-progress index tasks to finish.
326338 package func waitForUpToDateIndex( ) async {
327339 logger. info ( " Waiting for up-to-date index " )
328340 // Wait for a build graph update first, if one is in progress. This will add all index tasks to `indexStatus`, so we
329341 // can await the index tasks below.
330- await generateBuildGraphTask ? . value
342+ await waitForBuildGraphGenerationTasks ( )
331343
332344 await withTaskGroup ( of: Void . self) { taskGroup in
333345 for (_, status) in inProgressIndexTasks {
@@ -356,7 +368,7 @@ package final actor SemanticIndexManager {
356368 )
357369 // If there's a build graph update in progress wait for that to finish so we can discover new files in the build
358370 // system.
359- await generateBuildGraphTask ? . value
371+ await waitForBuildGraphGenerationTasks ( )
360372
361373 // Create a new index task for the files that aren't up-to-date. The newly scheduled index tasks will
362374 // - Wait for the existing index operations to finish if they have the same number of files.
0 commit comments