When swift-format crashes before we send all data to its stdin, we get a SIGPIPE when trying to write more data to its studio on Linux. This, in turn, takes SourceKit-LSP down.
Do the same trick that we do when launching `JSONRPCConnection` of disabling SIGPIPE globally if we can’t disable it for individual pipes.
rdar://147665695
There is only one real class that implements the `SourceKitD` protocol, so there really isn’t any need for the protocol + class split at all. Unify them to make code simpler to reason about.
This request is generally useful, not only for tests within SourceKit-LSP but also:
- In editor tests that want to test the integration with SourceKit-LSP
- In code analysis tools that want to gather project information using SourceKit-LSP and need an up-to-date index for that.
Remove the experimental feature guard from `workspace/_synchronize`, consequently rename it to `workspace/synchronize` and only guard the `buildServerUpdates` option on the synchronize request by an experimental feature because its long-term usefulness is still not fully understood yet.
When SourceKit-LSP is shut down, we should make sure that we don’t leave behind child processes, which will become orphans after SourceKit-LSP has terminated. What’s worse, when SourceKit-LSP has exited, these processes might not have any process to read their stdout/stderr, which can lead to them running indefinitely.
This change does not cover the termination of subprocess trees. For example, if we launch `swift build` and need to kill it because it doesn’t honor SIGINT, its child processes will still live on. Similarly, if we kill a BSP server, its child processes might live on. Fixing this is a drastically bigger endeavor, likely requiring changes to Foundation and/or TSC. I filed https://github.com/swiftlang/sourcekit-lsp/issues/2080 for it.
We would hit quadratic behavior in `AsyncQueue` when the build system floods us with `build/logMessage` or `build/task(Start|Progress|Finish)` notifications because we record a dependency on all of the pending log message handling tasks.
We can extend the improvement made in https://github.com/swiftlang/sourcekit-lsp/pull/1840 to fix this quadratic problem: If the current task depends on a task with metadata that depends on itself (ie. all tasks of metadata that needs to be executed in-order), we only need to depend on the last task with that metadata.
This covers many message types and we can now only get into quadratic behavior if we get flooded with two different kinds of messages: One that does not have a self-dependency and one that depends on the message without a self-dependency. In terms of LSP messages, this could be a document read followed by a document update, but I think this is a lot more unlikely than getting spammed with one type of message.
Since we re-index source files if the build server sends us a `buildTarget/didChange` notification, we no longer need to wait for an up-to-date build graph when a file is modified. This resolves an issue that causes a `Scheduling tasks` progress to appear in the status bar whenever a file in the project is changed. Before https://github.com/swiftlang/sourcekit-lsp/pull/1973, this happened fairly frequently during the initial indexing when a header file was written into the build directory. After that PR the `Scheduling Indexing` status appears a lot more frequently, namely every time the index’s database is modified, which happens quite all the time during indexing...
If a source file is part of multiple targets, we should index it in the context of all of those targets because the different targets may produce different USRs since they might use different build settings to interpret the file.
Technically, the watched files notification can change the response of any other request (eg. because a target needs to be re-prepared). But treating it as a `globalConfiguration` inserts a lot of barriers in request handling and significantly prevents parallelism. Since many editors batch file change notifications already, they might have delayed the file change notification even more, which is equivalent to handling the notification a little later inside SourceKit-LSP. Thus, treating it as `freestanding` should be acceptable.
Also, simplify the logic needed in tests to write modified files to disk because we now need to run a barrier request in tests to ensure that the watched file notification has been handled.