Lets BSP servers know which SourceKit extension methods SourceKit-LSP
supports, so they can choose between the current sourcekit/-prefixed
names and the legacy names.
Rename all SourceKit-LSP–specific LSP and BSP extension requests and
notifications to use the `sourcekit/` prefix (e.g. `workspace/tests`
→ `sourcekit/workspace/tests`).
* Register the legacy name alias in `MessageRegistry` so incoming
messages from existing clients are still dispatched correctly.
* Advertise both the new and legacy method names in the `experimental`
capability dict so old clients can still discover the capabilities
they know.
* Accept legacy names advertised by old clients in `CapabilityRegistry`.
* Use `LegacyNameFallbackConnection` to retry requests with the legacy
method name when the peer returns `methodNotFound` for a
`sourcekit/`-prefixed request. Used in:
* `SourceKitLSPServer.client` (server→client) to keep old editors working
* `ExternalBuildServerAdapter.connectionToBuildServer` (SourceKit-LSP→BSP)
to keep old build servers working
Delete `Collection+Only.swift`, `Duration+Seconds.swift`,
`FileManagerExtensions.swift`, `PipeAsStringHandler.swift`, and
`URLExtensions.swift` from `Sources/SwiftExtensions/`. The same
APIs now live in swift-tools-protocols as `@_spi(SourceKitLSP)
public` declarations.
Update each call site to add `@_spi(SourceKitLSP) import
ToolsProtocolsSwiftExtensions` next to the existing
`import SwiftExtensions`. Add the
`_ToolsProtocolsSwiftExtensionsForPlugin` dependency and the
`ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin`
module alias to the `SwiftSourceKitClientPlugin` target in both
`Package.swift` and the corresponding `CMakeLists.txt`.
Wrap each `task.waitToFinish()` in `TaskScheduler.shutDown()` with a
10s `withTimeout` so a stuck QueuedTask cannot block sourcekit-lsp's
shutdown indefinitely; on timeout, log the task description so the
offender is identifiable. The QueuedTask is already cancelled via
`task.cancel()` and continues winding down in the background.
Add debug logs after `Process.waitUntilExit()` returns and after
`Process.run` returns inside `prepare(singleTarget:)`, so a future
shutdown hang can be triaged: did the swift build process actually
exit, did `Process.run` propagate the result, or is the stall higher
up in the prepare chain.
Motivated by a recurring Windows CI hang in
BackgroundIndexingTests.testSymlinkedTargetReferringToSameSourceFile
where prepareForExit stalls for the full test timeout with no log
output during shutdown.
The `WorkspaceConfiguration.default` was being used to populate
the `Workspace`; there was an extra step here needed to assure that
we are propagating the trait configuration to the workspace.
The added test assures that non-default traits that are enabled are
indeed processed as enabled.
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.
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.
`CopiedFileMap` previously held methods like
`workspaceEditAdjustedForCopiedFiles`,
`callHierarchyItemAdjustedForCopiedFiles`, etc. that encoded knowledge
of high-level LSP message types into `BuildServerIntegration`.
Replace them with `adjusted(for:)` methods on each LSP type
(`Location`, `[Location]`, `LocationsOrLocationLinksResponse`,
`WorkspaceEdit`, `CallHierarchyItem`, `TypeHierarchyItem`) in a new
`LSP+CopiedFileMap.swift` in the SourceKitLSP module. The primitive
URI remapping is extracted into `CopiedFileMap.adjustedURI(for:)`
which remains in `BuildServerIntegration`.
`CallHierarchyItem.adjusted(for:)` also drops manual `LSPAny`
dictionary construction in favour of `HierarchyItemData`.
Extract the copied-file adjustment logic from BuildServerManager into a
Sendable value type CopiedFileMap. Call sites snapshot cachedCopiedFileMap
once per request (hoisted before loops) instead of awaiting the actor on
every iteration.
SwiftPM PR #9985 introduce files in the scratch path whose contents
indicate which build system was used to build artifact for a given build
configuration. if this file exist, use it's contents to infer the build
system. Otherwise, fallback to the existing behaviour.
Fixes: #2576
Binary targets backed by remote `.artifactbundleindex` URLs cause
SwiftPM to re-extract the artifact bundle into the scratch directory
on every package load. The resulting file-change events (delete +
create) for the extracted files triggered another reload, causing an
infinite loop.
Add `isInScratchDirectory` to `fileEventShouldTriggerPackageReload`
to filter out events before the build-settings check. It covers
both the configured scratch directory and the default `.build/`
directory (which receives regular `swift build` output even when
a custom scratch path is configured).
Also add tests using local zip-based binary targets to cover both
the default and custom-scratch-path scenarios. Local zips are used
in the tests to avoid a network dependency; they exercise the same
`isInScratchDirectory` code path even though the infinite loop in
practice requires a remote `.artifactbundleindex` target (where
SwiftPM's checksum mismatch causes re-extraction on every load).
https://github.com/swiftlang/sourcekit-lsp/issues/2615
If we have a source item `include/Test.h` that gets copied to `build/Test.h`, we currently don’t provide any semantic functionality for `build/Test.h`. Improve the build settings fallback logic to construct fallback build settings for `build/Test.h` based on `include/Test.h`.
If the original file does not exist, it is preferable to jump to a file generated by the build system instead of trying to jump to a file that the editor can’t open. This will become important when using the copied file logic to jump to files in `.build/checkouts` instead of `.build/index-build/checkouts` in a follow-up PR.
- Remove async from workspaceEditAdjustedForCopiedFiles
- Refactor to use uriAdjustedForCopiedFiles helper
- Update dictionary update logic with +=
- Adjust LocationLink creation to use adjusted ranges
- Ensure selectionRange adjustment in prepareCallHierarchy
- Provide default WorkspaceEdit in ClangLanguageService
- Revert asyncMap to map and remove await in SourceKitLSPServer
- Chain workspace and index retrieval in incomingCalls
- Use indexToLSPCallHierarchyItem and shared helper for CallHierarchyItem
- Fix indentation and remove duplicated detail setting
- Use shared helper for TypeHierarchyItem
- Remove .sort() from expected array in tests
- Enable testFindImplementationInCopiedHeader
- Add await for actor-isolated BuildServerManager calls
This addresses issue #2276 by ensuring that all LSP requests that return source file locations
map copied header files back to their original locations, not just jump-to-definition.
Previously, only the definition request applied this mapping. Now, the following requests
also adjust locations for copied files:
- textDocument/references
- textDocument/implementation
- workspace/symbol
- callHierarchy/prepare
- callHierarchy/incomingCalls
- callHierarchy/outgoingCalls
- typeHierarchy/prepare
- typeHierarchy/supertypes
- typeHierarchy/subtypes
This provides consistent navigation behavior, ensuring users are always taken to the original
source files instead of build artifacts when possible.