The idea here is to unify the different ways in which we can currently set options on SourceKit-LSP in a scalable way: Environment variables, command line arguments to `sourcekit-lsp` and initialization options.
The idea is that a user can define a `~/.sourcekit-lsp/.sourcekit-lsp` file (we store logs in `~/.sourcekit-lsp/logs` on non-Darwin platforms), which will be used as the default configuration for all SourceKit-LSP instances. They can also place a `.sourcekit-lsp` file in the root of a workspace to configure SourceKit-LSP for that project specifically, eg. setting arguments that need to be passed to `swift build` for that project and which thus also need to be set on SourceKit-LSP.
For compatibility reasons, I’m mapping the existing command line options into the new options structure for now. I hope to delete the command line arguments in the future and solely rely on `.sourcekit-lsp` configuration files.
Environment variable will be migrated to `.sourcekit-lsp` in a follow-up commit.
# Conflicts:
# Sources/SourceKitLSP/SourceKitLSPServer+Options.swift
# Sources/SourceKitLSP/Swift/SwiftLanguageService.swift
# Sources/sourcekit-lsp/SourceKitLSP.swift
# Tests/SourceKitLSPTests/BackgroundIndexingTests.swift
# Tests/SourceKitLSPTests/ExecuteCommandTests.swift
This would have caught a race condition in background indexing that was caused by accessing `CheckedIndex` from multiple threads despite it not being thread-safe.
Add `.swift-format` to the repo and format the repo with `swift-format`.
This commit does not add any automation to enforce formatting of sourcekit-lsp in CI. The goal of this commit is to get the majority of source changes out of the way so that the diff of actually enforcing formatting will have fewer changes or conflicts.
The core idea here is that the toolchain language servers always call into `BuildSystemManager` and `BuildSystemManager` will always reply with build settings. If it hasn’t computed them yet, it will reply with fallback settings.
With that assumption, we can remove the `documentToPendingQueue` from `SourceKitServer` since there are no longer any documents that are pending – everything has a build settings immediately.
Similarly, `BuildSystemManager.mainFileStatuses` also isn’t needed anymore.
And lastly, since we know that `BuildSystemManager.buildSettings` will always return a value `registerForChangeNotifications` is changed not call `fileBuildSettingsChanged` immediately. Instead, it will only cause `fileBuildSettingsChanged` to be called when the file’s build settings change after the `registerForChangeNotifications` call.
This defines away an entire class of data races if delegate callbacks are delivered out-of-order. If we aren’t providing the new build settings in the delegate callback, then it doesn’t matter if two `fileBuildSettingsChanged` calls change order since they don’t carry any state.
Instead of storing build settings inside the language servers based on update notifications from the build system, always call into the `BuildSystemManager` to get the build settings.
Overall, I think this is a much clearer separation of concerns and will allow us to remove `SourceKitServer.documentToPendingQueue` in a follow-up commit as `SwiftLanguageServer` can always directly call into `BuildSystemManager` to get build settings and we don’t need to wait for the initial notification to receive the first build settings.
This requies `BuildServerBuildSystem` to keep track of the build settings it has received from the BSP server.
`ClangLanguageServer` still caches build settings locally. `ClangLanguageServer` will change to the same pull-based model in a follow-up commit.
The asyncification changes caused some non-deterministic test failures. I believe that some of these are due to race conditions that are the result of the partial transition to actors.
Instead of merging the asyncification piece by piece, I will collect the changes asyncification changes in a branch and then qualify that branch througougly (running CI multiple times) before merging it into `main`.
Instead of storing build settings inside the language servers based on update notifications from the build system, always call into the `BuildSystemManager` to get the build settings.
Overall, I think this is a much clearer separation of concerns and will allow us to remove `SourceKitServer.documentToPendingQueue` in a follow-up commit as `SwiftLanguageServer` can always directly call into `BuildSystemManager` to get build settings and we don’t need to wait for the initial notification to receive the first build settings.
This requies `BuildServerBuildSystem` to keep track of the build settings it has received from the BSP server.
`ClangLanguageServer` still caches build settings locally. `ClangLanguageServer` will change to the same pull-based model in a follow-up commit.
Instead of storing build settings inside the language servers based on update notifications from the build system, always call into the `BuildSystemManager` to get the build settings.
Overall, I think this is a much clearer separation of concerns and will allow us to remove `SourceKitServer.documentToPendingQueue` in a follow-up commit as `SwiftLanguageServer` can always directly call into `BuildSystemManager` to get build settings and we don’t need to wait for the initial notification to receive the first build settings.
This requies `BuildServerBuildSystem` to keep track of the build settings it has received from the BSP server.
`ClangLanguageServer` still caches build settings locally. `ClangLanguageServer` will change to the same pull-based model in a follow-up commit.
The dependency on `TSCUtility` was strictly for identifying the platform
of execution. This logic is relatively self-contained and effectively an
extension over an enumeration. Replicate this logic with updates for new
syntactic improvements. This allows us to partially reduce dependency on
swift-tools-support-core. The dependency on TSCBasic is more complicated
to remove due to the extensive use of `AbsolutePath`.
Co-authored-by: Alex Hoppen <alex@alexhoppen.de>
Explicitly import interfaces from TSCBasic which now allows us to
identify all the swift-tools-support-core interfaces which are in
use in SourceKit-LSP.
This allows sourcekit-lsp to make use of the path remappings recently added to
the index store and IndexStoreDB to remap remote paths into local paths
when loading index data locally.
These remappings can be provided via the `-index-prefix-map` command line flag to sourcekit-lsp or via the `BuildSystem` integration point.
This sets the stage for multi-workspace support. Everything should be handled internally, we are just missing the API to actually open multiple workspaces at this point.
This sets the stage for multi-workspace support. Everything should be handled internally, we are just missing the API to actually open multiple workspaces at this point.
Implement rudementary support for `DidChangeWatchedFileNotification` for SwiftPM projects: When a file is added, reload the Swift package to compute build settings for it.
This enables proper semantic functionality added to the project after the LSP server was started.
Resolves SR-15633
Remove `settings(for:)` from the BuildSystem API in favor of the change callback
- With the `settings(for:)` method removed, we instead block on a
callback from the `BuildSystemManager` which itself handles
the primary build system callback in conjunction with the fallback
system
- We queue up notifications / requests that reference documents
until we receive the callback.
- Remove language from FileBuildSettings as it is no longer needed,
Swift-specific working dir fixes are now in SwiftCompileCommand
- registerForChangeNotifications should inform its delegate
asynchronously instead of immediately
In preparation for injecting doing more during registration, pass
through the same parameters (add language) so that we can call settings
as necessary.
In the fallback build system use the URIs pseudo path to construct
compiler arguments. For non-file URIs this means passing the raw URI as
the filename. We were already testing non-existing file-URLs like /a.txt
and arbitrary URIs seem to allow semantic functionality as well.
According to the LSP specification, arbitrary URIs can be used as
document identifiers. Instead of internally assuming that all URIs are
URLs, use a DocumentURI enum to represent URIs. These can either be file
URLs or other URIs whose value as treated as an opaque string.
Introduce a `BuildSystemDelegate` to handle notifications from the build system
* `SourceKitServer` is the main delegate to process these notifications
* Currently limited to changes in `FileBuildSettings`
* Delegate informs the `BuildSystem` of files to watch via `registerChangeWatching(for: URL)` and `unregisterChangeWatching(for: URL)`
* In the future we could have more integration for handling changes in dependencies
Handling changes in `FileBuildSettings`
* `SourceKitServer` sends notifications to the internal LSPs informing them of any opened documents that have changes in their compiler flags
* For clangd, we send a notification to update the compilation database
* For SourceKit/sourcekitd we must close and reopen the file to force a new AST with the new compiler flags