Adding an item to `AsyncQueue` was linear in the number of pending queue items, thus adding n items to an `AsyncQueue` before any can execute is in O(n^2). This decision was made intentionally because the primary use case for `AsyncQueue` was to track pending LSP requests, of which we don’t expect to have too many pending requests at any given time.
While we can't fix the quadratic performance issue in general, we can resolve the quadratic issue of `AsyncQueue<Serial>` by making a new task only depend on the last item in the queue, which then transitively depends on all the previous items. `AsyncQueue<Serial>` are the queues that are most likely to contain many items.
Fixes#1725
rdar://137886469
We made quite a few fixes recently to make sure that path handling works correctly using `URL` on Windows. Use `URL` in most places to have a single type that represents file paths instead of sometimes using `AbsolutePath`.
While doing so, also remove usages of `TSCBasic.FileSystem` an `InMemoryFileSystem`. The pattern of using `InMemoryFileSystem` for tests was never consistently used and it was a little confusing that some types took a `FileSystem` parameter while other always assumed to work on the local file system.
`LineTable.replace` did not actually validate that the edit is in range. This could cause crashes of SourceKit-LSP if the editor is sending us bogus edits. Validate the position, like we do in all the other position conversions and log a fault if the edit is out-of-range.
While fixing this, I found a couple more places where line table accesses were not properly guarded. I migrated them to safe alternatives as well.
rdar://138962353
`URL.path` returns forward slashes in the path on Windows (https://github.com/swiftlang/swift-foundation/issues/973) where we expect backslashes. Work around that by defining our own `filePath` property that is backed by `withUnsafeFileSystemRepresentation`, which produces backslashes.
rdar://137963660
When we receive build settings after hitting the timeout, we call `fileBuildSettingsChanged` on the delegate, which should cause the document to get re-opened in sourcekitd and diagnostics to get refreshed.
rdar://136332685
Fixes#1693
Returned code actions are often sorted in a predetermined, preferred
order. For instance, when proposing actions to handle error propagation
on a throwing function the option to handle the error with `try` should
appear before the more dangerous option to disable error propagation
with `try!`.
Fixes#1696
Xcode 16 with Swift 6 has been released, we can drop support for building and testing SourceKit-LSP using a Swift 5.10 toolchain. This allows us to remove a number of workarounds.
Even after sending the `dependencyUpdated` request to sourcekitd, the code completion session has state from before the AST update. Close it and open a new code completion session on the next completion request.
`Workspace` is responsible for creating the `BuildSystemManager` and responds to most of the delegate calls. It should thus also be the delegate of `BuildSystemManager`.
The basic idea is that a `sourcekit-lsp://swift-macro-expansion` URL should have sufficient information to reconstruct the contents of that macro buffer without relying on any state in SourceKit-LSP. The benefit of not having any cross-request state in SourceKit-LSP is that an editor might can send the `workspace/getReferenceDocument` request at any time and it will succeed independent of the previous requests. Furthermore, we can always get the contents of the macro expansion to form a `DocumentSnapshot`, which can be used to provide semantic functionality inside macro expansion buffers.
To do that, the `sourcekit-lsp:` URL scheme was changed to have a parent instead of a `primary`, which is the URI of the document that the buffer was expanded from. For nested macro expansions, this will be a `sourcekit-lsp://swift-macro-expansion` URL itself.
With that parent, we can reconstruct the macro expansion chain all the way from the primary source file. To avoid sending the same expand macro request to sourcekitd all the time, we introduce `MacroExpansionManager`, which caches the last 10 macro expansions.
`SwiftLanguageService` now has a `latestSnapshot` method that returns the contents of the reference document when asked for a reference document URL and only consults the document manager for other URIs. To support semantic functionality in macro expansion buffers, we need to call that `latestSnapshot` method so we have a document snapshot of the macro expansion buffer for position conversions and pass the following to the sourcekitd requests.
```
keys.sourceFile: snapshot.uri.sourcekitdSourceFile,
keys.primaryFile: snapshot.uri.primaryFile?.pseudoPath,
```
We should consider if there’s a way to make the `latestSnapshot` method on `documentManager` less accessible so that the method which also returns snapshots for reference documents is the one being used by default.
Co-Authored-By: Lokesh T R <lokesh.t.r.official@gmail.com>
As a user makes an edit to a file, these requests are most likely no longer relevant. It also makes sure that a long-running sourcekitd request can't block the entire language server if the client does not cancel all requests. For example, consider the following sequence of requests:
- `textDocument/semanticTokens/full` for document A
- `textDocument/didChange` for document A
- `textDocument/formatting` for document A
If the editor is not cancelling the semantic tokens request on edit (like VS Code does), then the `didChange` notification is blocked on the semantic tokens request finishing. Hence, we also can't run the `textDocument/formatting` request. Cancelling the semantic tokens on the edit fixes the issue.
rdar://133987424
Do one of the following for every `FIXME` or `TODO` comment
- Add an issue that tracks the task
- Remove the comment if we are not planning to address it
The CMake build should only be run when building an entire toolchain, which means that we are guaranteed to have a Swift 6 compiler at hand and can unconditionally enable Swift 6 mode.
Fixes all build warnings in SourceKit-LSP so that it builds without any issues using recent Swift development snapshots (`swift-DEVELOPMENT-SNAPSHOT-2024-07-22-a` and `swift-6.0-DEVELOPMENT-SNAPSHOT-2024-07-24-a`)