Commit Graph

38 Commits

Author SHA1 Message Date
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
25harsh f185bc404f [SwiftSyntaxCodeActions] Moved syntactic code actions into a new module 2026-05-11 11:10:40 +05:30
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 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 caa4b97c57 Merge pull request #2597 from Steffeeen/inlay-hint-performance
Cache inlay hints to avoid flickering
2026-04-30 15:37:42 +02:00
Steffeeen c5593c09c6 Cache inlay hints to avoid flickering
Previously, we always recomputed the inlay hints by calling into
SourceKit. If the document that we compute inlay hints for has recently
changed, SourceKit may need a bit of time to recompute the semantic
analysis. The inlay hints may thus need roughly 200-700ms to be
computed. This causes flickering in VSCode as it removes the old inlay
hints immediately and only displays them again when SourceKit-LSP
returned them.

With this commit we cache the inlay hints and recompute them in the
background. After the recompute is finished we use
`workspace/inlayHint/refresh` request to tell the client to refresh its
inlay hints. On each textDocument/didChange request the cached inlay
hints are shifted according to the text edits to ensure their positions
are still correct. This avoids the flickering as we can always return
the cached inlay hints immediately. The returned hints may however
temporarily show outdated type information until the background
recompute is finished.
2026-04-29 20:45:23 +02: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 aa3497e96c Rename DocumentSnapshot.absolutePositionRange() to positionRange()
This matches the naming of the `position` and `absolutePosition`
methods.
2026-04-07 10:47:59 +02:00
Rintaro Ishizaki 894496e9be Merge pull request #2549 from Tabonx/feature/codeAction-resolve-support 2026-03-22 06:11:21 -07:00
Pavel Kroupa 8639c19347 Add codeAction/resolve support 2026-03-21 10:38:44 +01:00
Rintaro Ishizaki 955a400f6f Merge pull request #2501 from loveucifer/fix/pass-experimental-features-to-swift-parser
Pass experimental features to SwiftParser once we have build settings
2026-03-06 15:28:40 -08:00
loveucifer d2736c130e minor fix 2026-03-01 00:33:17 +05:30
loveucifer 091e802f1c Pass experimental features to SwiftParser using build settings
This commit adds support for passing experimental features to SwiftParser through build settings. It includes:
- Changes to SwiftLanguageService.swift to handle experimental features
- Updates to SyntaxTreeManager.swift to pass these features to the parser
- E2E tests verifying experimental features work with the SyntaxTreeManager
2026-02-28 09:19:43 +05:30
Steffeeen d748f80896 Implement support for textDocument/selectionRange
This enables hierarchical selection expansion in supported editors.

Selection ranges are computed from the AST by walking upward from the
smallest enclosing node to the root. This is implemented by AST nodes
conforming to the `SelectionRangeProvider` protocol. Most nodes use a
default implementation which returns the node's `trimmedRange`.
Other nodes are special-cased to adjust the returned selection ranges
based on other factors.
2026-02-26 09:15:01 +01:00
loveucifer 2a360c046e address comments 2026-01-17 16:17:59 +05:30
Alex Hoppen 61ba0c92a4 Merge pull request #2436 from loveucifer/inlay-hint-go-to-definition 2026-01-16 13:16:45 +01:00
Ahmad Ayman Mansour 80c9e43250 Skip jump-to-definition for literal values
Return empty response when cursor is on literal tokens (strings,
integers, floats, booleans, nil) since they have no declaration.

Resolves #2368

Co-Authored-By: clemo97 <lumumbaclement@gmail.com>
2026-01-10 18:21:29 +02:00
loveucifer 8e300ee443 add go-to-definition for inlay hints (#2318)
Implements resolveProvider for inlay hints to enable navigating to type
definitions. When an inlay hint showing a type is resolved, the server
looks up the type's definition location using cursorInfo and the index.

- store variable position in InlayHint.data for resolution
- add inlayHintResolve to LanguageService protocol
- implement resolve handler using cursorInfo and index lookup
- enable resolveProvider: true in capabilities
- add test for resolve functionality

Addresses #2318
2026-01-06 19:35:06 +05:30
Alex Hoppen 219428328c Address my own review comments
Apply the following changes:
- Check for the presence of `#Playgrounds` textually before getting the module name in `SwiftPlaygroundsScanner`. This is important because getting the module name requires us to get build settings for the file, which can be expensive. Do the cheaper check first
- Make `syntacticTests` and `syntacticPlaygrounds` closures capture the workspace instead of passing the workspace from the `SwiftSyntacticIndex` back out. I like this better because now we can’t accidentally pass the wrong workspace to a `SwiftSyntacticIndex`, eg. to `buildTargetsChanges`.
- Capture the initialize result in `TestSourceKitLSPClient` instead of using `postInitialization` to capture the result
- Minor cleanup of unnecessary abstractions, likely artifacts of earlier iterations
- Restructure tests so that every test has its own list of source files, allowing for easier local reasoning – turns out some of these tests didn’t even need to open a workspace, just to check the initialize response
2025-12-08 15:16:36 -05:00
Adam Ward 308375a135 Move syntactic index back to Workspace 2025-12-08 15:16:36 -05:00
Adam Ward 9602433d2a Add new workspace/playgrounds request 2025-12-08 15:16:36 -05: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
Adam Ward ddcddded67 Support swift.play in textDocument/codelens request
- New `swift.play` CodeLens support that is an experimental feature while [swift play](https://github.com/apple/swift-play-experimental/) is still experimental
- Add #Playground macro visitor to parse the macro expansions
- File must `import Playgrounds` to record the macro expansion
- The `swift-play` binary must exist in the toolchain to
- TextDocumentPlayground will record the id and optionally label to match detail you get from
```
$ swift play --list
Building for debugging...
Found 1 Playground
* Fibonacci/Fibonacci.swift:23 "Fibonacci"
```
- Add LSP extension documentation for designing pending `workspace/playground` request
- Add new parsing test cases
- Update CMake files

Issue: #2339 #2343

Add column to unnamed label

Update Sources/SwiftLanguageService/SwiftCodeLensScanner.swift

Co-authored-by: Alex Hoppen <alex@alexhoppen.de>

Update Sources/SwiftLanguageService/SwiftPlaygroundsScanner.swift

Co-authored-by: Alex Hoppen <alex@alexhoppen.de>

Update Sources/SwiftLanguageService/SwiftPlaygroundsScanner.swift

Co-authored-by: Alex Hoppen <alex@alexhoppen.de>

Update Tests/SourceKitLSPTests/CodeLensTests.swift

Co-authored-by: Alex Hoppen <alex@alexhoppen.de>

Address review comments

Fix test failures

Fix more review comments

Update for swift-tools-core
2025-11-07 15:51:17 -05:00
Owen Voorhees f04b971726 Adopt swift-tools-protocols 2025-10-31 14:11:11 -07:00
Alex Hoppen 4c957506e8 Add a code action to remove unused imports in a source file
The idea is pretty simple: When `MemberImportVisibility` is enabled, we know that imports can only affect the current source file. So, we can just try and remove every single `import` declaration in the file, check if a new error occurred and if not, we can safely remove it.
2025-10-22 23:56:09 +02:00
Alex Hoppen 2ad02363a3 Show inlay hints of #if conditions at their corresponding #endif directives
Fixes #2221
2025-10-13 16:35:05 +02:00
Alex Hoppen a6c291b84e Do not block SourceKit-LSP functionality when a build server takes long to initialize
We previously waited for the initialization response from the build server during the creation of a `Workspace` so that we could create a `SemanticIndexManager` with the index store path etc. that was returned by the `build/initialize` response. This caused all functionality (including syntactic) of SourceKit-LSP to be blocked until the build server was initialized.

Change the computation of the `SemanticIndexManager` and related types to happen in the background so that we can provide functionality that doesn’t rely on the build server immediately.

Fixes #2304
2025-09-29 13:02:08 +01: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
Ahmed Elrefaey a5854f4ecf Add signature help LSP request support (#2250)
Depends on https://github.com/swiftlang/swift/pull/83378

---

Adds support for the LSP signature help request.

> [!NOTE]
> As of https://github.com/swiftlang/swift/pull/83378, SourceKitD still
doesn't separate parameter documentation from the signature
documentation and thus parameters don't have their own separate
documentation. This should just work once SourceKitD implements this
functionality and we'll only need to modify the tests.
2025-09-05 14:52:56 +01:00
Matthew Bastien 58096eb822 cache snapshots opened in sourcekitd by textDocument/doccDocumentation requests 2025-08-27 15:30:50 +02:00
Alex Hoppen 4040a5e4ac Add default implementations to LanguageService for methods that are not expected to be implemented by all language services
With the introduction of secondary language services, we don’t expect every language service to implement every request anymore. To simplify the addition of language services like `DocumentationLanguageService` add default implementations for methods that satisfy the following criteria:
 - `SourceKitLSPServer` does not expect side effects to happen when they are called
 - The method can throw or there is a reasonable default value
 - It is reasonable to expect that not all language services need to implement it
2025-08-26 16:10:36 +02:00
Alex Hoppen 64fe439f24 Make DocumentationLanguageService the only module that imports DocCDocumentation 2025-08-21 10:10:54 +02:00
Alex Hoppen 08faa197af Make LanguageService initializer non-failable 2025-08-20 00:21:45 +02:00
Alex Hoppen c14f5dd7fd Move SwiftLanguageService into its own module 2025-08-14 11:12:31 +02:00