1355 Commits

Author SHA1 Message Date
Rintaro Ishizaki 04118be02d Prefix SourceKit-LSP extension methods with sourcekit/
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
2026-06-22 11:16:37 -07:00
Rintaro Ishizaki 1b652de1f0 Use Mutex directly for class/actor stored properties
ThreadSafeBox is a `class` wrapping a `Mutex<Value>`. When stored as
a property of another class or actor, the outer reference type already
provides identity, so the extra ThreadSafeBox class indirection is just a
redundant heap allocation. Replace `ThreadSafeBox<T>` with `Mutex<T>` at
those sites.

Function-local ThreadSafeBox uses are unchanged since they need class
identity to be capturable in `@Sendable` closures.

CustomBuildServerTestProject.buildServerBox is also unchanged: it is
value-captured into a closure stored before `super.init`, which a
~Copyable Mutex can't support without a class wrapper.

Port SourceKitD's fileprivate `computeIfNil` extension from ThreadSafeBox
to Mutex (now `borrowing`).
2026-06-18 15:11:53 -07:00
Alex Hoppen 3522158207 Merge pull request #2679 from somiljain2006/Local-variable-refrence
Fix references for local variables and parameters
2026-06-15 10:15:28 -07:00
Rintaro Ishizaki b9e4c67793 Delete SwiftExtensions duplicates of swift-tools-protocols APIs
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`.
2026-06-08 21:08:24 -07:00
somiljain2006 56d63fa798 Fix sklogging issue 2026-06-06 03:51:48 +05:30
somiljain2006 81fcf25be4 Updated documentation 2026-06-05 07:46:10 +05:30
somiljain2006 0fd40073f3 Use localReferences as fallback for non-indexed symbols 2026-06-05 07:43:02 +05:30
Rintaro Ishizaki f0231e287f Workspace: explicit weak captures in semanticIndexManager callbacks
Inner closures captured `sourceKitLSPServer` implicitly. The outer
`Task` already captures it weakly, making it a `var` in scope; inner
@Sendable closures that capture this `var` implicitly trigger the
`SendableClosureCaptures` diagnostic on compiler configurations
without `ImmutableWeakCaptures`.

Add explicit `[weak sourceKitLSPServer]` to each inner closure so the
capture binds cleanly to a fresh weak local.
2026-06-02 11:06:52 -07:00
somiljain2006 359e422dcb Fix formatting 2026-06-02 23:19:21 +05:30
somiljain2006 3834952983 Improve code organisation 2026-06-02 23:18:33 +05:30
somiljain2006 b715835c3b Changed the index check back to .deletedFiles. 2026-06-02 22:00:40 +05:30
somiljain2006 39be8e4661 Improve reference lookup for local symbols and in-memory edits 2026-06-02 13:02:51 +05:30
somiljain2006 f26f220236 Added doc comment aand remove redundant set() wrapper 2026-06-02 11:47:30 +05:30
somiljain2006 5b47421f8b Fix the filtering logic 2026-06-02 01:04:38 +05:30
somiljain2006 ee42692b08 Fix formatting 2026-05-30 22:03:04 +05:30
somiljain2006 477d33c89c Fix references for local variables and parameters 2026-05-30 21:55:01 +05:30
Rintaro Ishizaki 7c99f4f0e7 Use swift-tools-protocols's ThreadSafeBox
Delete sourcekit-lsp's `Sources/SwiftExtensions/ThreadSafeBox.swift`
and the now-unused `NSLock+WithLock.swift`.
Use the `Mutex`-backed `ThreadSafeBox` from swift-tools-protocols'

Adjust call sites for the new API: e.g.
`foo.value.mutate()` with `foo.withLock { $0.mutate() }` because it
doesn't provide `_modify` accessor.
2026-05-27 12:01:07 -07:00
Rintaro Ishizaki a39c92022f Add forOpenDocument label to language service lookup methods
Rename languageServices(for:), primaryLanguageService(for:), and their
internal counterparts to use the `forOpenDocument` label, so the
precondition that the document must already be open is visible at call
sites.

Also make primaryLanguageService(forOpenDocument:) throw instead of
returning an optional, and switch several resolve-style handlers from
the find-or-create primaryLanguageService(for:_:) to
primaryLanguageService(forOpenDocument:), since those call sites already
have an open document in hand.
2026-05-20 10:31:44 -07:00
Rintaro Ishizaki f56a27b996 Fix build warnings 2026-05-18 18:04:44 -07:00
Rintaro Ishizaki 626861d316 Merge pull request #2654 from rintaro/per-workspace-language-services
Scope language service lifetime to workspace
2026-05-18 14:59:47 -07:00
Rintaro Ishizaki f84abc1eb2 Use 'weak let' for immutable weak references (SE-0481)
Replace 'weak var' with 'weak let' for weak reference properties that are
set in init and never reassigned, using the Swift 6.3 feature introduced
by SE-0481.
2026-05-18 09:28:10 -07:00
Rintaro Ishizaki f2a121453d Scope language service instances per workspace
Previously, language services were held in a global registry on
SourceKitLSPServer and shared across workspaces, requiring complex
lifetime tracking (isImmortal, shutdownOrphanedLanguageServices) to
decide when to tear them down. In practice, every language service
already stored workspace-specific properties (buildServerManager,
semanticIndexManagerTask), so sharing them across workspaces was never
truly safe. Giving each Workspace its own service instances simplifies
lifetime management: services are created when needed and shut down
with their workspace.

Remove LanguageService.isImmortal, the workspace parameter from
canHandle(toolchain:), and the initialize/clientInitialized protocol
requirements.
2026-05-18 09:21:01 -07:00
Rintaro Ishizaki a559d60451 Merge pull request #2648 from rintaro/language-service-close
Preserve language service when closing generated interface
2026-05-14 16:26:50 -07:00
Rintaro Ishizaki 1d20e3f32e Merge pull request #2647 from rintaro/open-quickly-revise
Move Open Quickly and Jump to Definition docs to Contributor Documentation
2026-05-14 06:41:48 -07:00
Rintaro Ishizaki b60b9582ac Move language-service retention check into Workspace
The buildSettingsFile key is an implementation detail of Workspace's
language-service dictionary, so the guard that prevents removing a
still-needed service belongs there rather than in SourceKitLSPServer.
2026-05-13 20:59:29 -07:00
Edward Lee ca91f5ff4f Preserve language service when closing generated interface documents
Closing a generated interface document (sourcekit-lsp:// URI) was
removing the language service for the originating source file because
both share the same buildSettingsFile key. Guard the removal so it
only happens when no other open document shares that key.

Relates to #2209
2026-05-13 15:56:27 -07:00
Rintaro Ishizaki 292985e7dd Remove redundant fragment-clearing when constructing moduleFileURI 2026-05-13 10:25:09 -07:00
25harsh 90ceac197d Use ExpressibleByLiteral conformances for LSPAny 2026-05-13 16:19:42 +05:30
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
Rintaro Ishizaki eab4f58f32 Simplify adjusted(for:) implementations in LSP+CopiedFileMap
The range is never changed by URI adjustment, so there's no need to
construct intermediate Location values just to extract the URI.
2026-05-10 17:12:15 -07:00
Rintaro Ishizaki 2d320b288c Fix missing CopiedFileMap adjustments for WorkspaceEdit and TypeHierarchyItem
- WorkspaceEdit.adjusted(for:) was using originalURI(for:) ?? uri, which
  skips the file-existence check; switch to adjustedURI(for:)
- TypeHierarchyItem.adjusted(for:) was not adjusting the URI stored in
  data, unlike CallHierarchyItem
2026-05-10 17:12:12 -07:00
Rintaro Ishizaki 01b793dab4 Merge pull request #2637 from rintaro/lsp-messsage-metadata-structs
Replace manual LSPAny data handling with typed structs
2026-05-10 11:22:35 -07:00
Rintaro Ishizaki 2773bcdfa2 Merge pull request #2633 from rintaro/sourcekitd-inject
Allow injection of a pre-initialized sourcekitd connection
2026-05-07 19:57:41 -07:00
Rintaro Ishizaki 83afc9d1e1 Move CopiedFileMap LSP adjustments to extensions on LSP types
`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`.
2026-05-07 16:10:02 -07:00
Rintaro Ishizaki 070bc52b8c Use typed structs for LSP item data fields instead of manual LSPAny 2026-05-07 15:25:18 -07:00
Rintaro Ishizaki 4b2fa3193a Allow injection of a pre-initialized sourcekitd connection
Introduce `SourceKitDCore` as the protocol boundary between dylib
lifecycle management and the high-level `SourceKitD` API. Its single
lifecycle entry point, `initializeService(api:notificationCallback:)`,
receives the already-loaded `sourcekitd_api_functions_t` from
`SourceKitD.init(core:)`.

`SourceKitDCoreImpl` is the standard implementation: `init` opens the
dylib; `initializeService` registers any plugin paths, calls
`api.initialize()`, and wires the notification handler; `deinit` calls
`shutdown()` and closes the handle. Pre-initialized conformances
implement `initializeService` as a no-op.

Wire a `sourcekitdCoreInjector` hook through `Hooks` so an embedding
host can return a pre-initialized `SourceKitDCore` for a given toolchain
path, preventing `sourcekitd_initialize()` from being called a second
time.

Declare `SourceKitDCoreForPlugin` at its use sites so each call site
can express the exact deinit behavior it needs: `dlclose` for handles
acquired via `RTLD_NOLOAD`, and `leak` for externally-owned handles.
2026-05-07 09:58:47 -07:00
Alex Hoppen 234890c484 Merge pull request #2607 from DeeSee/fix-duplicate-rename-edits
Make RenameLocation unique
2026-05-04 19:23:37 +02:00
Alexander Skvortsov 0b1a2cb372 Make RenameLocation unique 2026-04-30 17:27:19 +03:00
Alex Hoppen caa4b97c57 Merge pull request #2597 from Steffeeen/inlay-hint-performance
Cache inlay hints to avoid flickering
2026-04-30 15:37:42 +02:00
Rintaro Ishizaki 3d7ebf7f20 Factor out CopiedFileMap as a Sendable value type
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.
2026-04-28 12:12:40 -07:00
Rintaro Ishizaki 4fa1b30d52 Add SymbolLocation.lspPosition, lspLocation, and make documentUri optional
Add computed properties to `SymbolLocation` that centralise the
index-to-LSP coordinate conversion:

- `uri: DocumentURI?` — returns nil when `path` is empty.
- `lspPosition: Position` — converts the 1-based line/utf8Column to a
  0-based LSP Position, using UTF-8 column as a UTF-16 approximation.
- `lspLocation: Location?` — wraps `documentUri` + `lspPosition` into
  an LSP Location, returning nil when `path` is empty.

Update all call sites.
2026-04-28 06:56:55 -07:00
Alex Hoppen b4fafb64b3 Fix build warnings
Fix all build warnings except those caused by using old DocC request/response types, which are a little harder to resolve.
2026-04-12 16:11:11 +10:00
Steffeeen a2ea03c53f Add DocoumentSnapshot.absolutePositionRange() 2026-04-07 10:47:59 +02:00
Steffeeen aa3497e96c Rename DocumentSnapshot.absolutePositionRange() to positionRange()
This matches the naming of the `position` and `absolutePosition`
methods.
2026-04-07 10:47:59 +02:00
Alex Hoppen facfb28d39 Don’t implicitly cancel requests when an edit is detected
Instead, use `staleRequestSupport.retryOnContentModified` as an indicator which requests should return a `ContentModified` error when the document is modified. This fixes https://github.com/swiftlang/sourcekit-lsp/issues/2136 by no longer implicitly cancelling inlayHints in Helix while still implicitly cancelling semantic tokens request, which was the motivation for https://github.com/swiftlang/sourcekit-lsp/pull/1629.

Fixes #2136
2026-04-03 13:38:40 +02:00
Kavon Farvardin e45119ea18 Merge pull request #2416 from ahoppen/any-error
Allow `QueueBasedMessageHandler.handle` to return `any Error` instead of `ResponseError`
2026-04-02 08:55:26 -07:00
Rintaro Ishizaki f54f5c9ad0 Fix build errors and warnings in 6.2 toolchain 2026-03-30 14:57:07 -07:00
Rintaro Ishizaki 64aa354caf [TestDiscovery] "/refresh" style tests/playgrounds requests
When the client opts in to `workspace/tests/refresh` or
`workspace/playgrounds/refresh` via experimental client capabilities,
SourceKit-LSP now maintains a proactive cache of the current test and
playground lists and sends the corresponding `workspace/.../refresh`
notification whenever the cache changes. `workspaceTests()` /
`workspacePlaygrounds()` then serve subsequent fetch requests directly
from the cache.

Add `EntryPointManager`: runs background scans, stores the results,
fires callbacks on changes:
 - Start scanning when build targets are updated including initial
   updates, any watched files are changed, and index is updated.
 - Send '/refresh' server initiated requests when the cache has changed.
 - Coalesces rapid invalidations by cancelling any in-flight refresh task.

Also:
- Simplify `SourceKitIndexDelegate` from an `actor` with `AtomicInt32`
  to a plain `class`, since it is only called from IndexStoreDB's
  internal serial dispatch queue.
2026-03-27 09:32:59 -07:00
Paul LeMarquand 9af9441d59 Merge pull request #2575 from plemarquand/dup-test-discovery-fix
When semantic test discovery encounters XCTest methods in an extension it adds the extension definition to the root items list for each child test method. With N test methods, the same extension root appears N times, each copy receiving all N children. After merging, this produces N*N test items instead of N.

The bug is normally masked by the syntactic index, which provides correct results that take priority via combineTests(). This bug was exposed while I was debugging why tests generated by build plugins would appear multiple times. Turns out because they don't exist on disk at the time of the syntatic scan only the semantic results are used, which surfaced the issue.

The fix is to track already-added extension USRs to ensure each extension added once as a root item.
2026-03-25 12:26:14 -04:00
Paul LeMarquand de2500e032 Simplify insertion check by using existing testSymbolUsrs 2026-03-24 10:01:44 -04:00