@@ -189,11 +189,7 @@ package struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
189
189
" Starting updating index store with priority \( Task . currentPriority. rawValue, privacy: . public) : \( filesToIndexDescription) "
190
190
)
191
191
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)
197
193
// If we know the output paths, make sure that we load their units into indexstore-db. We would eventually also
198
194
// pick the units up through file watching but that would leave a short time period in which we think that
199
195
// 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 {
233
229
}
234
230
}
235
231
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
238
234
// 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
270
252
}
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 {
280
254
return
281
255
}
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 ) "
285
259
)
286
- return
287
260
}
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) "
296
292
)
297
- } catch {
298
- logger. error ( " Updating index store for \( file. forLogging) failed: \( error. forLogging) " )
299
- BuildSettingsLogger . log ( settings: buildSettings, for: file. mainFile)
293
+ continue
300
294
}
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 "
307
322
)
308
- } catch {
309
- logger. error ( " Updating index store for \( file) failed: \( error. forLogging) " )
310
- BuildSettingsLogger . log ( settings: buildSettings, for: file. mainFile)
311
323
}
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)
316
325
}
317
- await indexStoreUpToDateTracker. markUpToDate ( [ ( file. sourceFile, target) ] , updateOperationStartDate: startDate)
318
326
}
319
327
320
328
/// If `args` does not contain an `-index-store-path` argument, add it, pointing to the build server's index store
0 commit comments