Commit Graph

235 Commits

Author SHA1 Message Date
Rintaro Ishizaki a6c926fa34 Relax atomic memory orderings; switch semaphore to release/acquire
For ID counters and standalone flags (most sites), drop to .relaxed
since nothing reads other memory based on the atomic's value.

MultiEntrySemaphore.signaled is the exception: it is used as a
signal/wait primitive where waiters proceed to use state set up
before signal(). Use .releasing on store and .acquiring on load so
that pre-signal writes are visible to waiters that observe `true`.
.relaxed there would be incorrect on weakly-ordered architectures.
2026-05-21 11:16:17 -07:00
Rintaro Ishizaki 83de30d29f Migrate atomic call sites to Synchronization.Atomic and ThreadSafeBox
Replace AtomicBool/UInt8/UInt32/Int32 from
ToolsProtocolsSwiftExtensions with Synchronization.Atomic<T> where
the storage is a static, module-level let, or class stored property.
For local lets captured by @Sendable closures (where Atomic's
~Copyable nature prevents capture), use ThreadSafeBox<T> instead.
2026-05-21 10:58:34 -07:00
Alex Hoppen 0cacc26db3 Merge pull request #2591 from ahoppen/require-6.3
Require Swift 6.3
2026-05-18 15:27:18 +02:00
Rintaro Ishizaki 223a88cb8c Add workspace/symbolNames and workspace/symbolInfo LSP extensions (#2619)
- **`sourcekit/workspace/symbolNames`** — returns a flat, deduplicated
list of every symbol name in the workspace index (source and indexed
system modules). Clients use this to drive their search UI locally.

- **`sourcekit/workspace/symbolInfo`** — given a list of exact symbol
names, returns `WorkspaceSymbolItem` for each occurrence across all
workspaces, for display in the search result list. Source-file symbols
get `SymbolInformation` with a `file://` location. SDK/stdlib symbols
get a `WorkspaceSymbol` with `location: .uri(…)` The client must call
`workspaceSymbol/resolve` after the user selects an SDK/stdlib symbol to
obtain the concrete interface location.

- **`workspaceSymbol/resolve`** — resolves the deferred
`WorkspaceSymbol` location from `sourcekit/workspace/symbolInfo`. Parses
the `?module=` value into `moduleName`/`groupName`, finds a real source
file via `mainFiles(containing:)`, calls `openGeneratedInterface`, and
returns the symbol with `location` replaced by a full
`sourcekit-lsp://generated-swift-interface/` URI + range (or a temp
`file://` path for clients without `workspace/getReferenceDocument`
support).
2026-05-12 22:21:17 -07:00
Alex Hoppen 448164aae4 Require Swift 6.3
Swift 6.3 has been released and we no longer need to support building or testing SourceKit-LSP with Swift 6.2.
2026-04-03 08:14:13 +02:00
Alex Hoppen 07a7be294f Query containerNamesCache when looking up container name of an extension
This improves performance of the `workspace/symbols` request in one project from 29s to 11s. Still not amazing, but a very measurable improvement.
2026-04-02 11:12:01 +02:00
Rintaro Ishizaki 26f8efed5f [TestDiscovery] Use file modification time to filter semantic index
Instead of querying the index twice (once for up-to-date files, once for
outdated ones), collect file modification timestamps during the syntactic
scan phase and use them to filter a single semantic index query.
For files that don't support syntactic scans, use the semantic index
results even if outdated.

Also extracts symlink-aware mtime resolution into URL.fileModificationDate
and exposes snapshotHasInMemoryModifications(_:) on DocumentManager.
2026-03-06 15:33:19 -08:00
Alex Hoppen 425e1322a1 Explicitly close the index when shutting down SourceKit-LSP
`IndexStoreDB` moves its index to the `saved` directory when it is deallocated. Because `IndexStoreDB` is primarily owned by `UncheckedIndex`, we rely on deallocating this object to save the index store. This is fairly brittle because various parts of the codebase may hold transient references to that object as reported in https://github.com/swiftlang/sourcekit-lsp/issues/2455#issuecomment-3873561003.

Explicitly remove the reference from `UncheckedIndex` to `IndexStoreDB`. While this still isn’t perfect because other parts of the code base may hold references to `IndexStoreDB` but those should be a lot rarer, resulting in a more consistent closing of the index.
2026-02-15 18:02:53 +01:00
Bruno Rocha 282e7745ee Fix inverted log check when updating the index store 2026-02-04 11:21:56 +01:00
Alex Hoppen d449cb78be Merge pull request #2294 from josh-arnold-1/preparation-batch-size 2025-12-06 10:04:55 +01:00
Ben Barham 9c145fd9a2 Merge pull request #2375 from bnbarham/pass-toolset-through
Pass toolsets through to preparation for the SwiftPM build server
2025-12-04 07:46:36 +10:00
Josh Arnold 668aab32ac Support custom preparationBatchSize defined via SourceKit's options 2025-12-03 13:37:25 -06:00
Ben Barham 9952a11f4b Pass toolsets through to preparation for the SwiftPM build server
Also adds some logging to the synchronize request so that it's obvious
when background indexing is being skipped.

Fixes #2373
Resolves rdar://165519940
2025-12-03 10:19:49 +10:00
Anthony Latsis d1b9c27b95 Merge pull request #2366 from AnthonyLatsis/jepa
Enable some Swift 7 mode features
2025-12-02 17:37:01 +00:00
Anthony Latsis 6b19657739 Enable ExistentialAny 2025-12-02 12:27:27 +00:00
Alex Hoppen f9f13a4105 Don’t use Optional.map or Optional.flatMap
Replace usages of `Optional.map` and `Optional.flatMap` by if expressions or other expressions.

I personally find `Optional.map` to be hard to read because `map` implies mapping a collection to me. Usually the alternative constructs seem clearer to me.
2025-11-20 09:47:21 +01:00
Mishal Shah 0876b7d403 Merge pull request #2324 from owenv/owenv/adopt-swift-tools-protocols
Adopt swift-tools-protocols
2025-11-05 09:02:00 -08:00
Michael Gottesman 43dd488d00 Add [weak self] in two places.
The reason why I am making the first change is because in a separate PR in
swiftlang I am fixing a bug that caused certain captured parameters to be
treated as sending parameters incorrectly. This allowed for parameters to
incorrectly be allowed to be sent from one isolation domain to another.

The specific problem here can be seen with the following swift code:

```swift
actor B {
  init(callback: @escaping @Sendable () -> Void) async {}
}

actor A {
  private func poke() {}
  func schedule() async {
    _ = await B(
      callback: { [weak self] in // closure 1
        Task.detached { // closure 2
          await self?.poke()
        }
      })
  }
}
```

When we capture the weak self from closure 1 in closure 2, we are not actually
capturing self directly. Instead we are capturing the var box which contains the
weak self. The box (unlike self) is actually non-Sendable. Since closure 2 is
not call(once), the compiler must assume semantically that the closure can be
invoked potentially multiple times meaning that it cannot allow for self to be
used in Task.detached. The fix for this is to perform an inner [weak self]
capture. As follows:

```swift
actor A {
  private func poke() {}
  func schedule() async {
    _ = await B(
      callback: { [weak self] in // closure 1
        Task.detached { [weak self] // closure 2
          await self?.poke()
        }
      })
  }
}
```

The reason why this works is that when we form the second weak self binding, we
perform a load from the outer weak self giving us an Optional<A>. Then we store
that optional value back into a new weak box. Since Optional<A> is Sendable, we
know that the two non-Sendable weak var boxes are completely unrelated, so we
can send that new var box into the new Task.detached safely.

The second `[weak self]` is just something I noticed later in the function. The
`[weak self]` just makes the detached function safer.
2025-10-31 14:52:37 -07:00
Owen Voorhees f04b971726 Adopt swift-tools-protocols 2025-10-31 14:11:11 -07:00
Alex Hoppen 95538e7de9 Migrate appendingPathComponent to appending(component:)
`appending(component:)` is the more modern API and can take multiple path components at the same time.
2025-09-23 16:57:56 +02:00
Alex Hoppen 32e919c0cd Merge pull request #2302 from ahoppen/multi-file-indexing-batch-size
Match the batch size for multi-file indexing to the driver's batch size
2025-09-23 16:53:57 +02:00
Alex Hoppen 05c04decf2 Match the batch size for multi-file indexing to the driver's batch size
Until we have better measurements that would motivate a different batching strategy, copying the driver’s batch size seems like the most reasonable thing to do.
2025-09-22 09:52:44 +02:00
Alex Hoppen 4fe68eebfb Use activeProcessorCount instead of processorCount in short-lived use-cases
According to https://developer.apple.com/documentation/foundation/processinfo/activeprocessorcount

> Whereas the processorCount property reports the number of advertised processing cores, the activeProcessorCount property reflects the actual number of active processing cores on the system. There are a number of different factors that may cause a core to not be active, including boot arguments, thermal throttling, or a manufacturing defect.

For short-lived workloads like `concurrentMap` we want to parallelize across the number of cores that are currently active, so use `activeProcessorCount` instead. The only case where we want to continue using `processorCount` is the computation of concurrent tasks for `TaskScheduler` because the value is stored for the lifetime of the SourceKit-LSP process and we don’t want to limit parallelism if SourceKit-LSP was launched during a time of thermal throttling.

I stumbled across this while working on #2302
2025-09-22 09:51:41 +02:00
Alex Hoppen 078a996dac Merge pull request #2293 from ahoppen/multi-file-indexing
Support indexing of mulitple Swift files within the same compiler invocation
2025-09-22 09:02:03 +02:00
Alex Hoppen d1981debec Do not cancel update index store tasks in favor of a task with fewer files
We should not take the number of files in an `UpdateIndexStoreTaskDescription` as an indication on how important the task is. If we do need this functionality, eg. because we want to update the index of files with syntactic matches for a rename term, this should be communicated using a specific purpose similar to `TargetPreparationPurpose`. Since the only reason we update the index store for a file right now is background indexing, such a check is not needed.
2025-09-20 16:26:26 +02:00
Alex Hoppen a005021666 Support indexing of mulitple Swift files within the same compiler invocation
Fixes #1268
2025-09-20 16:26:26 +02:00
Alex Hoppen fa67c22235 Merge pull request #2277 from ahoppen/bsp-timeouts
Add a timeout for `workspace/buildTargets` and `buildTarget/sources` requests
2025-09-20 13:13:40 +02:00
Alex Hoppen e60894c482 Pass multiple URIs to updateIndexStore(forSwiftFiles:) 2025-09-13 12:44:05 +02:00
Alex Hoppen 78608933ba Guarantee that all files in a UpdateIndexStoreTaskDescription have the same language
It doesn’t make sense to try and index files with different langauges in a single compiler invocation.
2025-09-03 17:51:18 +02:00
Alex Hoppen 5c4f1ca93c Make UpdateIndexStoreTaskDescription.updateIndexStore handle mulitple files
This pushes multi-file indexing one level closer to the actual compiler invocation.
2025-09-03 08:58:01 +02:00
Alex Hoppen 690fd9288f Extract target out of the FileIndexInfo used by UpdateIndexStoreTaskDescription
This way we can guarantee that all files passed to `UpdateIndexStoreTaskDescription` belong to the same target, which will simplify multi-file indexing.
2025-09-03 08:45:04 +02:00
Alex Hoppen dddc983dd2 Make BuildServerManager.toolchain only take a target, no document
The document wasn’t used in here.
2025-09-03 08:39:59 +02:00
Alex Hoppen d73433128d Make the build/logMessage conform to the BSP spec
When I added the log structure to `build/logMessage` in #2022 I must have assumed that the entire BSP notifciation was an extension defined by SourceKit-LSP and didn’t realized that this was actually a change that made the notification non-compliant with BSP. Change it up a little bit to make it compliant again.
2025-09-02 20:41:40 +02:00
Alex Hoppen 56fa14a687 Merge pull request #2274 from ahoppen/empty-target
Fix issue that caused the index progress indicator to get stuck if there are no sources in a target
2025-09-01 17:16:29 +02:00
Alex Hoppen 8b20ce734e Merge pull request #2273 from ahoppen/determining-files
Improve `Indexing: Scheduling tasks` message
2025-09-01 17:16:19 +02:00
Alex Hoppen c142b601ff Add a timeout for workspace/buildTargets and buildTarget/sources requests
This allows us to provide functionality based on fallback settings for unresponsive BSP servers.

Fixes #2252
2025-09-01 16:12:41 +02:00
Alex Hoppen e758b5711b Fix issue that caused the index progress indicator to get stuck if there are no sources in a target 2025-08-31 08:54:36 +02:00
Alex Hoppen 131dc69c79 Improve Indexing: Scheduling tasks message
The majority of the work here is getting the list of files to index from the build server. Let’s rename the message to reflect that.
2025-08-31 08:21:54 +02:00
Alex Hoppen d9046e4737 Fix issue that caused targets to be sorted top-down instead of bottom-up for background indexing
This sign flip slipped in with https://github.com/swiftlang/sourcekit-lsp/pull/1674.

There was also a non-determinism in the prepration schedule order.
2025-08-30 20:49:55 +02:00
Alex Hoppen 3762e7a2a4 Fix all warnings
Fixes all warnings when building on macOS and Linux using Swift 6.1, Swift 6.2 and SDKs from Xcode 16.2 and Xcode 16.3
2025-08-25 14:40:16 +02:00
Alex Hoppen 98cd30bb1c Apply exhaustive swift-format configuration from swift-syntax
Apply the exhaustive swift-format configuration from https://github.com/swiftlang/swift-syntax/pull/3117 to sourcekit-lsp. Also apply all automatic formattings.
2025-08-11 09:23:39 +02:00
Alex Hoppen 7f4f92e5bd Rename build system to build server in most cases
The term *build system* predated our wide-spread adoption of BSP for communicating between SourceKit-LSP to the build system and was never really the correct term anyway – ie. a `JSONCompilationDatabaseBuildSystem` never really sounded right. We now have a correct term for the communication layer between SourceKit-LSP: A build server. Rename most occurrences of *build system* to *build server* to reflect this. There are unfortunately a couple lingering instances of *build system* that we can’t change, most notably: `fallbackBuildSystem` in the config file, the `workspace/waitForBuildSystemUpdates` BSP extension request and the `synchronize-for-build-system-updates` experimental feature.
2025-08-02 08:45:01 +02:00
Ben Barham d5926bf69f Run formatting after swift-format changes 2025-06-30 17:08:05 -07:00
Alex Hoppen be5ae8cf1c Merge pull request #2153 from ahoppen/check-shutdown
Do not schedule any new tasks in `TaskScheduler` if it has been shut down
2025-05-14 19:12:41 +02:00
Alex Hoppen ba1fb5de07 Do not schedule any new tasks in TaskScheduler if it has been shut down
This is what `shutDown()` is documented to do. I also remember having this check before, it might have gotten lost during a rebase when I was working on https://github.com/swiftlang/sourcekit-lsp/pull/2081.

I noticed this while investigating https://github.com/swiftlang/sourcekit-lsp/pull/2152: In this case `buildTarget/prepare` was cancelled because the SourceKit-LSP server was shut down but indexing of a file was still started after the shutdown now that preparation had finished (because it was cancelled).
2025-05-13 17:29:44 +02:00
Alex Hoppen 47a940d8bd Fix race condition that causes task cancellation to be missed in TaskScheduler
A queued task might have been cancelled after the execution ask was started but before the task was yielded to `executionTaskCreatedContinuation`. In that case the result task will simply cancel the await on the `executionTaskCreatedStream` and hence not call `valuePropagatingCancellation` on the execution task. This means that the queued task cancellation wouldn't be propagated to the execution task. To address this, check if `resultTaskCancelled` was  set and, if so, explicitly cancel the execution task here.

Fixes an issue I saw in CI during PR testing.
2025-05-13 17:24:45 +02:00
Matthew Bastien 39bf4852b0 handle Markdown and Tutorial files in textDocument/doccDocumentation 2025-04-16 14:44:11 -04:00
Alex Hoppen e474354bca Merge pull request #2051 from ahoppen/build-graph-generation
Don't wait for build graph generation when file is changed
2025-03-26 14:40:06 -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 e28c460f6d Merge pull request #2079 from ahoppen/dependent-targets
Move `targets(dependingOn:)` call out of the changed files loop
2025-03-24 13:27:41 -07:00