Skip to content

Commit 698102f

Browse files
committed
Enumerate supported code lens commands
1 parent f48dec7 commit 698102f

File tree

6 files changed

+52
-32
lines changed

6 files changed

+52
-32
lines changed

Sources/LanguageServerProtocol/SupportTypes/ClientCapabilities.swift

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -470,24 +470,18 @@ public struct TextDocumentClientCapabilities: Hashable, Codable, Sendable {
470470
/// Whether the client supports dynamic registration of this request.
471471
public var dynamicRegistration: Bool?
472472

473-
public var supportedCommands: [String: String]
473+
/// Dictionary of supported commands announced by the client.
474+
/// The key is the CodeLens name recognized by SourceKit-LSP and the
475+
/// value is the command as recognized by the client.
476+
public var supportedCommands: [SupportedCodeLensCommand: String]?
474477

475-
public init(dynamicRegistration: Bool? = nil, supportedCommands: [String: String] = [:]) {
478+
public init(
479+
dynamicRegistration: Bool? = nil,
480+
supportedCommands: [SupportedCodeLensCommand: String] = [:]
481+
) {
476482
self.dynamicRegistration = dynamicRegistration
477483
self.supportedCommands = supportedCommands
478484
}
479-
480-
public init(from decoder: any Decoder) throws {
481-
let registration = try DynamicRegistrationCapability(from: decoder)
482-
self = CodeLens(
483-
dynamicRegistration: registration.dynamicRegistration
484-
)
485-
}
486-
487-
public func encode(to encoder: any Encoder) throws {
488-
let registration = DynamicRegistrationCapability(dynamicRegistration: self.dynamicRegistration)
489-
try registration.encode(to: encoder)
490-
}
491485
}
492486

493487
/// Capabilities specific to `textDocument/rename`.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 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+
/// Code lenses that LSP can annotate code with.
14+
///
15+
/// Clients provide these as keys to the `supportedCommands` dictionary supplied
16+
/// in the client's `InitializeRequest`.
17+
public struct SupportedCodeLensCommand: Codable, Hashable, RawRepresentable, Sendable {
18+
public var rawValue: String
19+
20+
public init(rawValue: String) {
21+
self.rawValue = rawValue
22+
}
23+
24+
/// Lens to run the application
25+
public static let run: Self = Self(rawValue: "swift.run")
26+
27+
/// Lens to debug the application
28+
public static let debug: Self = Self(rawValue: "swift.debug")
29+
}

Sources/SourceKitLSP/CapabilityRegistry.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ public final actor CapabilityRegistry {
3838
/// Dynamically registered pull diagnostics options.
3939
private var pullDiagnostics: [CapabilityRegistration: DiagnosticRegistrationOptions] = [:]
4040

41-
/// Dynamically registered code lens options.
42-
private var codeLens: [CapabilityRegistration: CodeLensRegistrationOptions] = [:]
43-
4441
/// Dynamically registered file watchers.
4542
private var didChangeWatchedFiles: DidChangeWatchedFilesRegistrationOptions?
4643

@@ -83,7 +80,7 @@ public final actor CapabilityRegistry {
8380
clientCapabilities.textDocument?.publishDiagnostics?.codeDescriptionSupport == true
8481
}
8582

86-
public var supportedCodeLensCommands: [String: String] {
83+
public var supportedCodeLensCommands: [SupportedCodeLensCommand: String] {
8784
clientCapabilities.textDocument?.codeLens?.supportedCommands ?? [:]
8885
}
8986

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -980,14 +980,14 @@ extension SourceKitLSPServer {
980980
case let .dictionary(codeLensConfig) = codeLens,
981981
case let .dictionary(supportedCommands) = codeLensConfig["supportedCommands"]
982982
{
983-
let commandMap = supportedCommands.compactMapValues({
984-
if case let .string(val) = $0 {
985-
return val
983+
let commandMap = supportedCommands.compactMap { (key, value) in
984+
if case let .string(clientCommand) = value {
985+
return (SupportedCodeLensCommand(rawValue: key), clientCommand)
986986
}
987987
return nil
988-
})
988+
}
989989

990-
clientCapabilities.textDocument?.codeLens?.supportedCommands = commandMap
990+
clientCapabilities.textDocument?.codeLens?.supportedCommands = Dictionary(uniqueKeysWithValues: commandMap)
991991
}
992992
}
993993

Sources/SourceKitLSP/Swift/SwiftCodeLensScanner.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ final class SwiftCodeLensScanner: SyntaxVisitor {
2222
private var result: [CodeLens] = []
2323

2424
/// The map of supported commands and their client side command names
25-
private let supportedCommands: [String: String]
25+
private let supportedCommands: [SupportedCodeLensCommand: String]
2626

27-
private init(snapshot: DocumentSnapshot, supportedCommands: [String: String]) {
27+
private init(snapshot: DocumentSnapshot, supportedCommands: [SupportedCodeLensCommand: String]) {
2828
self.snapshot = snapshot
2929
self.supportedCommands = supportedCommands
3030
super.init(viewMode: .fixedUp)
@@ -35,7 +35,7 @@ final class SwiftCodeLensScanner: SyntaxVisitor {
3535
public static func findCodeLenses(
3636
in snapshot: DocumentSnapshot,
3737
syntaxTreeManager: SyntaxTreeManager,
38-
supportedCommands: [String: String]
38+
supportedCommands: [SupportedCodeLensCommand: String]
3939
) async -> [CodeLens] {
4040
guard snapshot.text.contains("@main") && !supportedCommands.isEmpty else {
4141
// This is intended to filter out files that obviously do not contain an entry point.
@@ -62,7 +62,7 @@ final class SwiftCodeLensScanner: SyntaxVisitor {
6262
if attribute.trimmedDescription == "@main" {
6363
let range = self.snapshot.absolutePositionRange(of: attribute.trimmedRange)
6464

65-
if let runCommand = supportedCommands["swift.run"] {
65+
if let runCommand = supportedCommands[SupportedCodeLensCommand.run] {
6666
// Return commands for running/debugging the executable.
6767
// These command names must be recognized by the client and so should not be chosen arbitrarily.
6868
self.result.append(
@@ -73,7 +73,7 @@ final class SwiftCodeLensScanner: SyntaxVisitor {
7373
)
7474
}
7575

76-
if let debugCommand = supportedCommands["swift.debug"] {
76+
if let debugCommand = supportedCommands[SupportedCodeLensCommand.debug] {
7777
self.result.append(
7878
CodeLens(
7979
range: range,

Tests/SourceKitLSPTests/CodeLensTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ final class CodeLensTests: XCTestCase {
1919
func testNoLenses() async throws {
2020
var codeLensCapabilities = TextDocumentClientCapabilities.CodeLens()
2121
codeLensCapabilities.supportedCommands = [
22-
"swift.run": "swift.run",
23-
"swift.debug": "swift.debug"
22+
SupportedCodeLensCommand.run: "swift.run",
23+
SupportedCodeLensCommand.debug: "swift.debug",
2424
]
2525
let capabilities = ClientCapabilities(textDocument: TextDocumentClientCapabilities(codeLens: codeLensCapabilities))
2626

@@ -67,8 +67,8 @@ final class CodeLensTests: XCTestCase {
6767
func testSuccessfulCodeLensRequest() async throws {
6868
var codeLensCapabilities = TextDocumentClientCapabilities.CodeLens()
6969
codeLensCapabilities.supportedCommands = [
70-
"swift.run": "swift.run",
71-
"swift.debug": "swift.debug"
70+
SupportedCodeLensCommand.run: "swift.run",
71+
SupportedCodeLensCommand.debug: "swift.debug",
7272
]
7373
let capabilities = ClientCapabilities(textDocument: TextDocumentClientCapabilities(codeLens: codeLensCapabilities))
7474

0 commit comments

Comments
 (0)