Commit Graph

65 Commits

Author SHA1 Message Date
Alex Hoppen
14cfd50582 If sourcekitd or clangd don’t respond to a request for 5 minutes, terminate them and use crash recovery to restore behavior
This should be a last stop-gap measure in case sourcekitd or clangd get stuck, don’t respond to any requests anymore and don’t honor cancellation either. In that case we can restore SourceKit-LSP behavior by killing them and using the crash recovery logic to restore functionality.

rdar://149492159
2025-05-07 13:43:28 +02:00
Alex Hoppen
250081ec58 Fix theoretical issue in withTaskPriorityChangedHandler that could always report a priority change to high
We were launching the task that watches for the priority change with `high` priority. If the base priority was `medium`, this should immediately report a priority change to `high`. It appears the only reason why this doesn’t happen right now is due to rdar://147868544.
2025-03-27 15:07:45 -07:00
Alex Hoppen
3fb72cddb6 Merge pull request #2089 from ahoppen/async-fixes
Be a little more pedantic about making sure that we cancel  `bodyTask` and `timeoutTask` in `withTimeout` and `withTaskPriorityChangedHandler`
2025-03-27 15:04:03 -07:00
Alex Hoppen
a691ee3440 Be a little more pedantic about making sure that we cancel bodyTask and timeoutTask in withTimeout and withTaskPriorityChangedHandler
I have not been able to reason out any concrete issues that this might fix but these are my best guesses to fix the underlying issue of https://github.com/swiftlang/sourcekit-lsp/pull/2088
2025-03-25 14:13:52 -07:00
Alex Hoppen
3bb4690db4 Terminate pending background indexing and preparation tasks when shutting down SourceKit-LSP
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.
2025-03-25 14:10:38 -07:00
Alex Hoppen
dd2d2aff49 Fix some more quadratic performance issues in AsyncQueue
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.
2025-03-21 17:33:55 -07:00
Alex Hoppen
d10c868497 Support indexing a file in the context of multiple targets
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.
2025-03-14 15:49:59 -07:00
Alex Hoppen
1cfa8db1d8 Require Swift 6 to build SourceKit-LSP
This significantly cleans up our `import` statements
2025-03-07 08:05:49 -08:00
Alex Hoppen
58bce8225f Add a concurrentForEach method to start a concurrent task for each element in a collection
This is simpler to reason about than creating a `TaskGroup`.
2025-02-26 16:27:56 -08:00
Alex Hoppen
c67c06e7b1 Merge pull request #1950 from ahoppen/gardening
Gardening
2025-01-24 22:33:51 -08:00
Alex Hoppen
64f2aef446 Fix build warnings
Quite a few of these were reminders to clean things up once we no longer need to support testing using compilers and sourcekitd from older toolchains.
2025-01-23 21:11:08 -08:00
Alex Hoppen
15b9670888 Split build systems for JSON compilation database and fixed compilation database
I feel like the implementations are actually simpler if we split them. This will also allow us to add more advanced logic to the JSON compilation database build system in the future, such as inferring the toolchain from the compile command.
2025-01-17 14:38:37 -08:00
Alex Hoppen
69121eed95 Merge pull request #1906 from ahoppen/add-sourcekit-plugin
Add a SourceKit plugin to handle code completion requests
2025-01-15 12:42:18 -08:00
Alex Hoppen
16f897aefa Make the SourceKit plugins work on Windows 2025-01-11 06:57:03 +01:00
Alex Hoppen
718c0ee809 Remove imports of SwiftPM modules that are not strictly necessary 2025-01-08 12:43:43 +01:00
Alex Hoppen
03d58e8415 Normalize Windows drive letter to be uppercase
VS Code spells file paths with a lowercase drive letter, while the rest of Windows APIs use an uppercase drive letter. Normalize the drive letter spelling to be uppercase.

Fixes #1855
rdar://141001203
2024-12-10 16:16:27 -08:00
Alex Hoppen
87af5b06f1 Merge pull request #1857 from ahoppen/no-implicit-completion-cancellation 2024-12-07 08:56:38 -08:00
Alex Hoppen
1c1a1cf5f6 Cached transformed results in Cache
The transform to get the transformed result might be expensive, so we should cache its result.
2024-12-06 11:59:25 -08:00
Alex Hoppen
990ec7fc2a Don’t implicitly cancel code completion requests on document edits
As the user types, we filter the code completion results. Cancelling the completion request on every keystroke means that we will never build the initial list of completion results for this code completion session if building that list takes longer than the user's typing cadence (eg. for global completions) and we will thus not show any completions.
2024-12-05 14:43:56 -08:00
Alex Hoppen
eb982d5b1e Fix quadratic performance issue in AsyncQueue<Serial>
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
2024-11-22 15:33:57 +01:00
Alex Hoppen
be546308ca Use URL in many cases where we used AbsolutePath
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.
2024-11-18 18:19:48 -08:00
Alex Hoppen
9c84a344c8 Merge pull request #1817 from ahoppen/bsp-review 2024-11-14 08:10:02 -08:00
Alex Hoppen
bb6f4b4a47 Allow waiting for the next notification from SourceKit-LSP when the previous wait timed out
When `TestSourceKitLSPClient.nextNotification` timed out, it would cancel `AsyncSequence.Iterator.next()` and thus also cancel the underlying `AsyncStream` (which I only now found out). This means that calling `nextNotification` again would never return any notification. Hence, if we didn’t receive a `PublishDiagnosticsNotification` within the first timeout, we would never get one.
2024-11-13 16:53:08 -08:00
Alex Hoppen
c1e090ef33 Address minor review comments 2024-11-13 10:09:31 -08:00
Alex Hoppen
820b454994 Merge pull request #1780 from ahoppen/withtimeout-priority-escalation
Fix a race condition that caused `withTimeout` to not escalate the priority of the body
2024-10-29 13:02:18 -07:00
Alex Hoppen
0b7b565783 Fix a race condition that caused withTimeout to not escalate the priority of the body
rdar://137678566
2024-10-24 16:24:07 -07:00
Alex Hoppen
5d47358236 Merge pull request #1762 from ahoppen/build-settings-timeout 2024-10-23 23:50:58 -07:00
Alex Hoppen
cbc8aed404 Guard access-level import by compiler(>=6)
This allows us to build SourceKit-LSP using Swift 5.10 again.
2024-10-23 09:34:40 -07:00
Alex Hoppen
951e923245 Use withUnsafeFileSystemRepresentation to get the path of a URL on disk
`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
2024-10-21 11:12:30 -07:00
Alex Hoppen
5bae73fca8 Use fallback build settings if build system doesn’t provide build settings within a timeout
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
2024-10-16 10:55:29 -07:00
Alex Hoppen
17b13a935a Merge pull request #1751 from ahoppen/windows-fixes 2024-10-11 11:31:44 -07:00
Alex Hoppen
aa0aa927ca Stop using TSCBasic.resolveSymlinks and URL.resolvingSymlinksInPath 2024-10-09 13:16:57 -07:00
Alex Hoppen
77f02fc706 Yield TimeoutError before cancelling body task in withTimeout
Otherwise, the body task might finish before we yield the `TimeoutError` and thus `withTimeout` would not actually throw a `TimeoutError`.

rdar://137171114
2024-10-08 15:26:02 -07:00
Alex Hoppen
dff72f1807 In withTaskPriorityChangedHandler execute the task that watches for priority changes with high priority
I saw a nondeterministic test failure of `AsyncUtilsTests.testWithTimeoutEscalatesPriority` and I believe this was the cause.

Also refactor a few test helper functions on the way.
2024-10-04 09:57:52 -07:00
Alex Hoppen
86653b3c45 When withTimeout hits a timeout, don’t wait for cooperative cancellation before returning
Previously, when we hit the timeout in `withTimeout`, we just cancelled `body` but relied on cooperative cancellation before the caller could continue. Since the caller is obviously no longer interested in the operation, we can return with `CancellationError` immediately.

Fixes #883
rdar://116705684
2024-09-30 15:55:09 -07:00
Alex Hoppen
431a1c7e4f Merge pull request #1710 from ahoppen/internal-imports
Adopt `InternalImportsByDefault`
2024-09-30 02:43:14 -07:00
Alex Hoppen
794d4936fe Revert "Use fallback build settings if build system doesn’t provide build settings within a timeout"
This reverts commit 78217ec6a6.
2024-09-27 12:32:47 -07:00
Alex Hoppen
9b4a9b04bc Merge pull request #1720 from ahoppen/atomic-instead-of-queue
Use an `AtomicInt32` to count `pendingUnitCount` instead of using `AsyncQueue`
2024-09-27 10:30:43 -07:00
Alex Hoppen
b91f72f1d4 Merge pull request #1700 from ahoppen/build-settings-timeout
Use fallback build settings if build system doesn’t provide build settings within a timeout
2024-09-27 10:28:50 -07:00
Alex Hoppen
8cd831b55d Adopt InternalImportsByDefault 2024-09-27 09:17:13 -07:00
Alex Hoppen
2c9436b08c Use an AtomicInt32 to count pendingUnitCount instead of using AsyncQueue
Adding an item to `AsyncQueue<Serial>` is 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.

`SourceKitIndexDelegate` was also using `AsyncQueue` to track the number of pending units to be processed and eg. after indexing SourceKit-LSP, I have seen this grow up to ~20,000. With the quadratic behavior, this explodes time-wise.

Turns out that we don’t actually need to use a queue here at all, an atomic is sufficient and much faster.

Independently, we should consider mitigating the quadratic behavior of `AsyncQueue<Serial>` or `AsyncQueue` in general.
2024-09-26 21:51:28 -07:00
Alex Hoppen
fb5ee8e9c7 Miscellaneous adjustments to allow SourceKit-LSP to build using Swift 5.10 2024-09-26 18:23:59 -07:00
Alex Hoppen
78217ec6a6 Use fallback build settings if build system doesn’t provide build settings within a timeout
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
2024-09-26 17:50:58 -07:00
Alex Hoppen
120bd8688b Only scan test targets for tests
Don’t run the syntactic test scanner on files that we know are only part of non-test targets.

rdar://126493903
2024-09-19 13:42:40 -07:00
Alex Hoppen
d8b2cb2a82 Mark all transitive dependents of a modified target as being unprepared
We weren’t considering transitive dependencies in `BuildSystemManager.targets(dependingOn:)` before.

rdar://136039234
2024-09-17 14:37:24 -07:00
Alex Hoppen
d155665b73 Review BuildSystemManager 2024-09-16 10:12:18 -07:00
Alex Hoppen
57e933da97 Move Atomics from SKSupport to SwiftExtensions 2024-09-15 16:28:09 -07:00
Alex Hoppen
bb96ff4c68 Migrate targets(dependingOn:) to BSP 2024-09-12 16:59:03 -07:00
Alex Hoppen
236f566977 Instead of having FileHandlingCapability for a source file, check if it belongs to any targets 2024-09-11 08:27:12 -07:00
Alex Hoppen
57055d4135 Make Workspace the delegate of a BuildSystemManager
`Workspace` is responsible for creating the `BuildSystemManager` and responds to most of the delegate calls. It should thus also be the delegate of `BuildSystemManager`.
2024-09-10 15:22:18 -07:00