Skip to content

Commit c148080

Browse files
committed
Have different playground type for workspace and document requests
1 parent bbb17be commit c148080

File tree

9 files changed

+108
-25
lines changed

9 files changed

+108
-25
lines changed

Contributor Documentation/LSP Extensions.md

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ call `workspace/playgrounds` each time a document is changed.
169169
SourceKit-LSP will advertise `textDocument/playgrounds` in its experimental server capabilities if it supports it.
170170
171171
- params: `DocumentPlaygroundParams`
172-
- result: `PlaygroundItem[]`
172+
- result: `DocumentPlayground[]`
173173
174174
```ts
175175
export interface DocumentPlaygroundParams {
@@ -179,14 +179,14 @@ export interface DocumentPlaygroundParams {
179179
textDocument: TextDocumentIdentifier;
180180
}
181181
/**
182-
* A `PlaygroundItem` represents an expansion of the #Playground macro, providing the editor with the
182+
* A `DocumentPlayground` represents an expansion of the #Playground macro, providing the editor with the
183183
* location of the playground and identifiers to allow executing the playground through a "swift play" command.
184184
*/
185-
export interface PlaygroundItem {
185+
export interface DocumentPlayground {
186186
/**
187-
* Unique identifier for the `PlaygroundItem`. Client can run the playground by executing `swift play <id>`.
187+
* Unique identifier for the `DocumentPlayground`. Client can run the playground by executing `swift play <id>`.
188188
*
189-
* This property is always present whether the `PlaygroundItem` has a `label` or not.
189+
* This property is always present whether the `DocumentPlayground` has a `label` or not.
190190
*
191191
* Follows the format output by `swift play --list`.
192192
*/
@@ -199,9 +199,9 @@ export interface PlaygroundItem {
199199
label?: string
200200

201201
/**
202-
* The location of the of where the #Playground macro expansion occured in the source code.
202+
* The range where the #Playground macro expansion occured in the given document.
203203
*/
204-
location: Location
204+
range: Range<Position>
205205
}
206206
```
207207
@@ -742,6 +742,54 @@ export interface PeekDocumentsResult {
742742
}
743743
```
744744
745+
## `workspace/playgrounds`
746+
747+
New request for return the list of all #Playground macro expansions in the workspace.
748+
749+
Primarily designed to allow editors to provide a list of available playgrounds in the project workspace and allow
750+
jumping to the locations where the #Playground macro was expanded.
751+
752+
The request fetches the list of all macro expansions found in the workspace, returning the location, identifier, and optional label
753+
when available for each #Playground macro expansion. The request is intended to be used in combination with the `textDocument/playgrounds`
754+
request where the `workspace/playgrounds` provides the full list of playgrounds in the workspace and `textDocument/playgrounds`
755+
can be called after document changes. This way the editor can itself keep the list of playgrounds up to date without needing to
756+
call `workspace/playgrounds` each time a document is changed.
757+
758+
SourceKit-LSP will advertise `workspace/playgrounds` in its experimental server capabilities if it supports it.
759+
760+
- params: `DocumentPlaygroundParams`
761+
- result: `Playground[]`
762+
763+
```ts
764+
export interface WorkspacePlaygroundParams {}
765+
766+
/**
767+
* A `Playground` represents an expansion of the #Playground macro, providing the editor with the
768+
* location of the playground and identifiers to allow executing the playground through a "swift play" command.
769+
*/
770+
export interface Playground {
771+
/**
772+
* Unique identifier for the `Playground`. Client can run the playground by executing `swift play <id>`.
773+
*
774+
* This property is always present whether the `Playground` has a `label` or not.
775+
*
776+
* Follows the format output by `swift play --list`.
777+
*/
778+
id: string;
779+
780+
/**
781+
* The label that can be used as a display name for the playground. This optional property is only available
782+
* for named playgrounds. For example: `#Playground("hello") { print("Hello!) }` would have a `label` of `"hello"`.
783+
*/
784+
label?: string
785+
786+
/**
787+
* The location of the of where the #Playground macro expansion occured in the source code.
788+
*/
789+
location: Location
790+
}
791+
```
792+
745793
## `workspace/synchronize`
746794
747795
Request from the client to the server to wait for SourceKit-LSP to handle all ongoing requests and, optionally, wait for background activity to finish.

Sources/ClangLanguageService/ClangLanguageService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ extension ClangLanguageService {
647647
return []
648648
}
649649

650-
package func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [PlaygroundItem] {
650+
package func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [TextDocumentPlayground] {
651651
return []
652652
}
653653

Sources/LanguageServerProtocol/Requests/DocumentPlaygroundsRequest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/// **(LSP Extension)**
1616
public struct DocumentPlaygroundsRequest: TextDocumentRequest, Hashable {
1717
public static let method: String = "textDocument/playgrounds"
18-
public typealias Response = [PlaygroundItem]
18+
public typealias Response = [TextDocumentPlayground]
1919

2020
public var textDocument: TextDocumentIdentifier
2121

Sources/LanguageServerProtocol/SupportTypes/PlaygroundItem.swift renamed to Sources/LanguageServerProtocol/SupportTypes/Playground.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
/// A playground item that can be used to identify playgrounds alongside a source file.
14-
public struct PlaygroundItem: ResponseType, Equatable {
14+
public struct Playground: ResponseType, Equatable {
1515
/// Identifier for the `PlaygroundItem`.
1616
///
1717
/// This identifier uniquely identifies the playground. It can be used to run an individual playground with `swift play`.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
/// A playground item that can be used to identify playground. Differs from `PlaygroundItem`
14+
/// by not including location which is given for `textDocument/playgrounds` request
15+
public struct TextDocumentPlayground: ResponseType, Equatable {
16+
/// Identifier for the `PlaygroundItem`.
17+
///
18+
/// This identifier uniquely identifies the playground. It can be used to run an individual playground with `swift play`.
19+
public var id: String
20+
21+
/// Display name describing the playground.
22+
public var label: String?
23+
24+
/// The range of the #Playground macro expansion in the given file.
25+
public var range: Range<Position>
26+
27+
public init(
28+
id: String,
29+
label: String?,
30+
range: Range<Position>
31+
) {
32+
self.id = id
33+
self.label = label
34+
self.range = range
35+
}
36+
}

Sources/SourceKitLSP/LanguageService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ package protocol LanguageService: AnyObject, Sendable {
323323
/// Syntactically scans the file at the given URL for #Playground macro expansions within it.
324324
///
325325
/// Does not write the results to the index.
326-
func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [PlaygroundItem]
326+
func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [TextDocumentPlayground]
327327

328328
/// A position that is canonical for all positions within a declaration. For example, if we have the following
329329
/// declaration, then all `|` markers should return the same canonical position.
@@ -532,7 +532,7 @@ package extension LanguageService {
532532
throw ResponseError.internalError("syntacticDocumentTests not implemented in \(Self.self) for \(uri)")
533533
}
534534

535-
func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [PlaygroundItem] {
535+
func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [TextDocumentPlayground] {
536536
throw ResponseError.requestNotImplemented(DocumentPlaygroundsRequest.self)
537537
}
538538

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1824,7 +1824,7 @@ extension SourceKitLSPServer {
18241824
_ req: DocumentPlaygroundsRequest,
18251825
workspace: Workspace,
18261826
languageService: LanguageService
1827-
) async throws -> [PlaygroundItem] {
1827+
) async throws -> [TextDocumentPlayground] {
18281828
return try await languageService.syntacticDocumentPlaygrounds(for: req.textDocument.uri, in: workspace)
18291829
}
18301830

Sources/SwiftLanguageService/PlaygroundDiscovery.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import SwiftParser
1919
internal import BuildServerIntegration
2020

2121
extension SwiftLanguageService {
22-
package func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [PlaygroundItem] {
22+
package func syntacticDocumentPlaygrounds(for uri: DocumentURI, in workspace: Workspace) async throws -> [TextDocumentPlayground] {
2323
let snapshot = try self.documentManager.latestSnapshot(uri)
2424

2525
let syntaxTree = await syntaxTreeManager.syntaxTree(for: snapshot)
@@ -44,7 +44,7 @@ final class PlaygroundFinder: SyntaxAnyVisitor {
4444
private let snapshot: DocumentSnapshot
4545

4646
/// Accumulating the result in here.
47-
private var result: [PlaygroundItem] = []
47+
private var result: [TextDocumentPlayground] = []
4848

4949
/// Keep track of if "Playgrounds" has been imported
5050
fileprivate var isPlaygroundImported: Bool = false
@@ -60,7 +60,7 @@ final class PlaygroundFinder: SyntaxAnyVisitor {
6060
in node: some SyntaxProtocol,
6161
workspace: Workspace,
6262
snapshot: DocumentSnapshot
63-
) async -> [PlaygroundItem] {
63+
) async -> [TextDocumentPlayground] {
6464
guard let canonicalTarget = await workspace.buildServerManager.canonicalTarget(for: snapshot.uri),
6565
let moduleName = await workspace.buildServerManager.moduleName(for: snapshot.uri, in: canonicalTarget),
6666
let baseName = snapshot.uri.fileURL?.lastPathComponent
@@ -79,13 +79,12 @@ final class PlaygroundFinder: SyntaxAnyVisitor {
7979
range: Range<AbsolutePosition>
8080
) {
8181
let positionRange = snapshot.absolutePositionRange(of: range)
82-
let location = Location(uri: snapshot.uri, range: positionRange)
8382

8483
result.append(
85-
PlaygroundItem(
84+
TextDocumentPlayground(
8685
id: id,
8786
label: label,
88-
location: location,
87+
range: positionRange,
8988
)
9089
)
9190
}

Tests/SourceKitLSPTests/DocumentPlaygroundDiscoveryTests.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,20 @@ final class DocumentPlaygroundDiscoveryTests: XCTestCase {
5454
XCTAssertEqual(
5555
playgrounds,
5656
[
57-
PlaygroundItem(
57+
TextDocumentPlayground(
5858
id: "MyLibrary/MyLib.swift:7",
5959
label: "foo",
60-
location: Location(uri: uri, range: positions["1️⃣"]..<positions["2️⃣"]),
60+
range: positions["1️⃣"]..<positions["2️⃣"],
6161
),
62-
PlaygroundItem(
62+
TextDocumentPlayground(
6363
id: "MyLibrary/MyLib.swift:11",
6464
label: nil,
65-
location: Location(uri: uri, range: positions["3️⃣"]..<positions["4️⃣"]),
65+
range: positions["3️⃣"]..<positions["4️⃣"],
6666
),
67-
PlaygroundItem(
67+
TextDocumentPlayground(
6868
id: "MyLibrary/MyLib.swift:19",
6969
label: "bar",
70-
location: Location(uri: uri, range: positions["5️⃣"]..<positions["6️⃣"]),
70+
range: positions["5️⃣"]..<positions["6️⃣"],
7171
),
7272
]
7373
)

0 commit comments

Comments
 (0)