@@ -189,11 +189,7 @@ package struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
189189 " Starting updating index store with priority \( Task . currentPriority. rawValue, privacy: . public) : \( filesToIndexDescription) "
190190 )
191191 let filesToIndex = filesToIndex. sorted ( by: { $0. file. sourceFile. stringValue < $1. file. sourceFile. stringValue } )
192- // TODO: Once swiftc supports it, we should group files by target and index files within the same target together
193- // in one swiftc invocation. (https://github.com/swiftlang/sourcekit-lsp/issues/1268)
194- for fileIndexInfo in filesToIndex {
195- await updateIndexStore ( forSingleFile: fileIndexInfo. file, outputPath: fileIndexInfo. outputPath)
196- }
192+ await updateIndexStore ( forFiles: filesToIndex)
197193 // If we know the output paths, make sure that we load their units into indexstore-db. We would eventually also
198194 // pick the units up through file watching but that would leave a short time period in which we think that
199195 // indexing has finished (because the index process has terminated) but when the new symbols aren't present in
@@ -233,88 +229,100 @@ package struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
233229 }
234230 }
235231
236- private func updateIndexStore( forSingleFile file : FileToIndex , outputPath : OutputPath ) async {
237- guard await !indexStoreUpToDateTracker . isUpToDate ( file . sourceFile , target ) else {
232+ private func updateIndexStore( forFiles fileInfos : [ FileAndOutputPath ] ) async {
233+ let fileInfos = await fileInfos . asyncFilter { fileInfo in
238234 // If we know that the file is up-to-date without having ot hit the index, do that because it's fastest.
239- return
240- }
241- guard
242- indexFilesWithUpToDateUnit
243- || !index. checked ( for: . modifiedFiles) . hasUpToDateUnit (
244- for: file. sourceFile,
245- mainFile: file. mainFile,
246- outputPath: outputPath
247- )
248- else {
249- logger. debug ( " Not indexing \( file. forLogging) because index has an up-to-date unit " )
250- // We consider a file's index up-to-date if we have any up-to-date unit. Changing build settings does not
251- // invalidate the up-to-date status of the index.
252- return
253- }
254- if file. mainFile != file. sourceFile {
255- logger. log ( " Updating index store of \( file. forLogging) using main file \( file. mainFile. forLogging) " )
256- }
257- guard let language = await buildServerManager. defaultLanguage ( for: file. mainFile, in: target) else {
258- logger. error ( " Not indexing \( file. forLogging) because its language could not be determined " )
259- return
260- }
261- let buildSettings = await buildServerManager. buildSettings (
262- for: file. mainFile,
263- in: target,
264- language: language,
265- fallbackAfterTimeout: false
266- )
267- guard let buildSettings else {
268- logger. error ( " Not indexing \( file. forLogging) because it has no compiler arguments " )
269- return
235+ if await indexStoreUpToDateTracker. isUpToDate ( fileInfo. file. sourceFile, target) {
236+ return false
237+ }
238+ if indexFilesWithUpToDateUnit {
239+ return true
240+ }
241+ let hasUpToDateUnit = index. checked ( for: . modifiedFiles) . hasUpToDateUnit (
242+ for: fileInfo. sourceFile,
243+ mainFile: fileInfo. mainFile,
244+ outputPath: fileInfo. outputPath
245+ )
246+ if !hasUpToDateUnit {
247+ logger. debug ( " Not indexing \( fileInfo. file. forLogging) because index has an up-to-date unit " )
248+ // We consider a file's index up-to-date if we have any up-to-date unit. Changing build settings does not
249+ // invalidate the up-to-date status of the index.
250+ }
251+ return !hasUpToDateUnit
270252 }
271- if buildSettings. isFallback {
272- // Fallback build settings don’t even have an indexstore path set, so they can't generate index data that we would
273- // pick up. Also, indexing with fallback args has some other problems:
274- // - If it did generate a unit file, we would consider the file’s index up-to-date even if the compiler arguments
275- // change, which means that we wouldn't get any up-to-date-index even when we have build settings for the file.
276- // - It's unlikely that the index from a single file with fallback arguments will be very useful as it can't tie
277- // into the rest of the project.
278- // So, don't index the file.
279- logger. error ( " Not indexing \( file. forLogging) because it has fallback compiler arguments " )
253+ if fileInfos. isEmpty {
280254 return
281255 }
282- guard let toolchain = await buildServerManager . toolchain ( for : target , language : language ) else {
283- logger. error (
284- " Not updating index store for \( file. forLogging) because no toolchain could be determined for the document "
256+ for fileInfo in fileInfos where fileInfo . mainFile != fileInfo . sourceFile {
257+ logger. log (
258+ " Updating index store of \( fileInfo . file. forLogging) using main file \( fileInfo . mainFile . forLogging ) "
285259 )
286- return
287260 }
288- let startDate = Date ( )
289- switch language. semanticKind {
290- case . swift:
291- do {
292- try await updateIndexStore (
293- forSwiftFile: file. mainFile,
294- buildSettings: buildSettings,
295- toolchain: toolchain
261+
262+ for fileInfo in fileInfos {
263+ guard let language = await buildServerManager. defaultLanguage ( for: fileInfo. mainFile, in: target) else {
264+ logger. error ( " Not indexing \( fileInfo. file. forLogging) because its language could not be determined " )
265+ continue
266+ }
267+ let buildSettings = await buildServerManager. buildSettings (
268+ for: fileInfo. mainFile,
269+ in: target,
270+ language: language,
271+ fallbackAfterTimeout: false
272+ )
273+ guard let buildSettings else {
274+ logger. error ( " Not indexing \( fileInfo. file. forLogging) because it has no compiler arguments " )
275+ continue
276+ }
277+ if buildSettings. isFallback {
278+ // Fallback build settings don’t even have an indexstore path set, so they can't generate index data that we would
279+ // pick up. Also, indexing with fallback args has some other problems:∂
280+ // - If it did generate a unit file, we would consider the file’s index up-to-date even if the compiler arguments
281+ // change, which means that we wouldn't get any up-to-date-index even when we have build settings for the file.
282+ // - It's unlikely that the index from a single file with fallback arguments will be very useful as it can't tie
283+ // into the rest of the project.
284+ // So, don't index the file.
285+ logger. error ( " Not indexing \( fileInfo. file. forLogging) because it has fallback compiler arguments " )
286+ continue
287+ }
288+
289+ guard let toolchain = await buildServerManager. toolchain ( for: target, language: buildSettings. language) else {
290+ logger. fault (
291+ " Unable to determine toolchain to index \( buildSettings. language. description, privacy: . public) files in \( target. forLogging) "
296292 )
297- } catch {
298- logger. error ( " Updating index store for \( file. forLogging) failed: \( error. forLogging) " )
299- BuildSettingsLogger . log ( settings: buildSettings, for: file. mainFile)
293+ continue
300294 }
301- case . clang:
302- do {
303- try await updateIndexStore (
304- forClangFile: file. mainFile,
305- buildSettings: buildSettings,
306- toolchain: toolchain
295+ let startDate = Date ( )
296+ switch buildSettings. language. semanticKind {
297+ case . swift:
298+ do {
299+ try await updateIndexStore (
300+ forSwiftFile: fileInfo. mainFile,
301+ buildSettings: buildSettings,
302+ toolchain: toolchain
303+ )
304+ } catch {
305+ logger. error ( " Updating index store for \( fileInfo. mainFile) failed: \( error. forLogging) " )
306+ BuildSettingsLogger . log ( settings: buildSettings, for: fileInfo. mainFile)
307+ }
308+ case . clang:
309+ do {
310+ try await updateIndexStore (
311+ forClangFile: fileInfo. mainFile,
312+ buildSettings: buildSettings,
313+ toolchain: toolchain
314+ )
315+ } catch {
316+ logger. error ( " Updating index store for \( fileInfo. mainFile. forLogging) failed: \( error. forLogging) " )
317+ BuildSettingsLogger . log ( settings: buildSettings, for: fileInfo. mainFile)
318+ }
319+ case nil :
320+ logger. error (
321+ " Not updating index store for \( fileInfo. mainFile. forLogging) because it is a language that is not supported by background indexing "
307322 )
308- } catch {
309- logger. error ( " Updating index store for \( file) failed: \( error. forLogging) " )
310- BuildSettingsLogger . log ( settings: buildSettings, for: file. mainFile)
311323 }
312- case nil :
313- logger. error (
314- " Not updating index store for \( file) because it is a language that is not supported by background indexing "
315- )
324+ await indexStoreUpToDateTracker. markUpToDate ( [ ( fileInfo. sourceFile, target) ] , updateOperationStartDate: startDate)
316325 }
317- await indexStoreUpToDateTracker. markUpToDate ( [ ( file. sourceFile, target) ] , updateOperationStartDate: startDate)
318326 }
319327
320328 /// If `args` does not contain an `-index-store-path` argument, add it, pointing to the build server's index store
0 commit comments