This allows us to more easily test behavior for build servers that have different behavior than SwiftPM and compile commands without having to implement the build server in Python.
When the client supports it, communicate the structure of tasks that were stared during background indexing or by the build server to the client. If there are multiple operations happening in parallel, this allows the client to display them in separate log tracks instead of interspersing them with the emoji prefixes like we do today.
On Darwin platforms, this fixes the following problem: indexstore-db by itself returns realpaths but the build system might be using standardized Darwin paths (eg. realpath is `/private/tmp` but the standardized path is `/tmp`). Because of this, when inferring the main file for a file, we might get a URI that the build system doesn’t know about. To fix this, if the realpath that indexstore-db returns could not be found in the build system's source files but the standardized path is part of the source files, use the standardized path instead.
This fixes the following problem, which caused files to get indexed twice: You open a workspace, which schedules initial indexing. While we are waiting for the build graph generation from the build server, the build servers sends `buildTarget/didChange` notification to SourceKit-LSP (eg. because it has finished loading the build graph). This causes all files in the changed targets to be scheduled for re-indexing since new files might be present in the updated targets. And since we have already started indexing of those files, we assumed that we need to index them again because the contents might have changed.
To fix this, keep track of the file’s modification time at the time at which we scheduled indexing for it. If that time hasn’t changed and we have an in-progress indexing operation for it, there is no need to schedule another one.
For each file in the changed targets, we still check whether it has an up-to-date unit based on timestamps. The important thing for this change is that we start indexing files for which we only receive build settings after an update from the build server.
Indexing a header via a main file and indexing the main file itself are two different index tasks that update the `indexStoreUpToDateTracker` in different ways. We should thus consider them differently in `inProgressIndexTasks` as well.
We had checks for whether we need to index a file or if it is up-to-date in multiple places of `SemanticIndexManager`. Centralize them in `filesToCover(toIndex:)`, so that it’s easier to reason about them.
This helps in the following situation: A build system takes 5s to return build settings for a file and we have 10 requests for those build settings coming in that time period. Once we get build settings, we get 10 calls to `resultReceivedAfterTimeout` in `buildSettings(for:in:language:fallbackAfterTimeout:)`, all for the same document.
But calling `fileBuildSettingsChanged` once is totally sufficient.
We were blocking the initialization response on `self.buildSystemManager.testFiles`, which requires the list of test files to be determined. Make that operation asynchronous so that a slow build server can’t take down all of SourceKit-LSP.
This can be useful to IDEs that want to perform some additional semantic processing of source files, which requires knowledge of a file’s build settings.