Skip to content

Commit 4079238

Browse files
authored
Add support for jump to definition (#95)
* Initial logic, still need to :w so it works * Refactoring the logic * Send request that we finished * Modify Package.swift to point to master of sourcekit-lsp * Revert "Send request that we finished" This reverts commit 65d4159. * More Changes to be able to use latest upstream
1 parent a8e3b5b commit 4079238

File tree

10 files changed

+77
-28
lines changed

10 files changed

+77
-28
lines changed

Example/.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
]
1111
}
1212
}
13-
}
13+
}

Package.swift

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,22 @@ let package = Package(
1616
.macOS(.v15),
1717
],
1818
dependencies: [
19+
.package(
20+
url:
21+
"https://github.com/swiftlang/swift-tools-protocols",
22+
revision: "f86b413a803761408e5e718912c46d75a340801b"
23+
),
24+
1925
.package(
2026
url: "https://github.com/apple/swift-argument-parser",
2127
revision: "1.5.0"
2228
),
2329
.package(
24-
url: "https://github.com/rockbruno/sourcekit-lsp",
25-
revision: "c052baae81ec6532bb2f939a21acc4650fb1dc86"
30+
url: "https://github.com/swiftlang/sourcekit-lsp",
31+
revision: "0e061c5c1075152bc2e6187679a11b81d0c3e326" // latest main commit November 29, 2025
32+
// TODO: Ideally it would be better to upstream these changes to sourceKit-lsp
33+
// url: "https://github.com/rockbruno/sourcekit-lsp",
34+
// revision: "c052baae81ec6532bb2f939a21acc4650fb1dc86"
2635
),
2736
.package(
2837
url: "https://github.com/apple/swift-protobuf.git",
@@ -44,18 +53,22 @@ let package = Package(
4453
name: "SourceKitBazelBSP",
4554
dependencies: [
4655
"BazelProtobufBindings",
56+
.product(
57+
name: "LanguageServerProtocolTransport",
58+
package: "swift-tools-protocols"
59+
),
4760
.product(
4861
name: "BuildServerProtocol",
49-
package: "sourcekit-lsp"
62+
package: "swift-tools-protocols"
5063
),
5164
.product(
52-
name: "LSPBindings",
53-
package: "sourcekit-lsp"
65+
name: "ToolsProtocolsSwiftExtensions",
66+
package: "swift-tools-protocols"
5467
),
5568
.product(
5669
name: "ArgumentParser",
5770
package: "swift-argument-parser"
58-
)
71+
),
5972
],
6073
),
6174
.testTarget(
@@ -71,7 +84,7 @@ let package = Package(
7184
.target(
7285
name: "BazelProtobufBindings",
7386
dependencies: [
74-
.product(name: "SwiftProtobuf", package: "swift-protobuf")
87+
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
7588
],
7689
exclude: [
7790
"README.md",
@@ -87,6 +100,6 @@ let package = Package(
87100
.copy("Resources/actions.pb"),
88101
.copy("Resources/streamdeps.pb"),
89102
],
90-
)
103+
),
91104
]
92105
)

Sources/SourceKitBazelBSP/RequestHandlers/InitializeHandler.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@ final class InitializeHandler {
204204
data: SourceKitInitializeBuildResponseData(
205205
indexDatabasePath: initializedConfig.indexDatabasePath,
206206
indexStorePath: initializedConfig.indexStorePath,
207-
multiTargetPreparation: MultiTargetPreparationSupport(
208-
supported: true,
209-
batchSize: batchSize
210-
),
207+
// multiTargetPreparation: MultiTargetPreparationSupport(
208+
// supported: true,
209+
// batchSize: batchSize
210+
// ),
211211
outputPathsProvider: nil,
212212
prepareProvider: true,
213213
sourceKitOptionsProvider: true,

Sources/SourceKitBazelBSP/RequestHandlers/TargetSourcesHandler.swift

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ private let logger = makeFileLevelBSPLogger()
2727
///
2828
/// Returns the sources for the provided target based on previously gathered information.
2929
final class TargetSourcesHandler {
30-
3130
private let initializedConfig: InitializedServerConfig
3231
private let targetStore: BazelTargetStore
3332

@@ -38,7 +37,7 @@ final class TargetSourcesHandler {
3837

3938
func buildTargetSources(
4039
_ request: BuildTargetSourcesRequest,
41-
_ id: RequestID
40+
_: RequestID
4241
) throws -> BuildTargetSourcesResponse {
4342
let targets = request.targets
4443
logger.info("Fetching sources for \(targets.count, privacy: .public) targets")
@@ -62,10 +61,40 @@ final class TargetSourcesHandler {
6261
return BuildTargetSourcesResponse(items: srcs)
6362
}
6463

64+
private func computeCopyDestinations(for src: URI) -> [DocumentURI]? {
65+
guard let srcPath = src.fileURL?.path else {
66+
return nil
67+
}
68+
69+
var destinations: [DocumentURI] = []
70+
71+
let workspaceRoot = initializedConfig.rootUri
72+
let execRoot = initializedConfig.executionRoot
73+
74+
func trimmedRelativePath(fullPath: String, base: String) -> String {
75+
var relativePath = fullPath.dropFirst(base.count)
76+
if relativePath.first == "/" {
77+
relativePath = relativePath.dropFirst()
78+
}
79+
return String(relativePath)
80+
}
81+
82+
if srcPath.hasPrefix(workspaceRoot) {
83+
// Workspace file -> single execroot location Bazel copies to.
84+
// We need to tell the LSP about the path of each file in execution root to later help it mapping it again to original Workspace path.
85+
let relativePath = trimmedRelativePath(fullPath: srcPath, base: workspaceRoot)
86+
let destination = DocumentURI(filePath: execRoot + "/" + relativePath, isDirectory: false)
87+
destinations.append(destination)
88+
}
89+
90+
return destinations.isEmpty ? nil : destinations
91+
}
92+
6593
func convertToSourceItems(_ targetSrcs: [URI]) -> [SourceItem] {
6694
var result: [SourceItem] = []
6795
for src in targetSrcs {
6896
let srcString = src.stringValue
97+
let copyDestinations = computeCopyDestinations(for: src)
6998
let kind: SourceKitSourceItemKind
7099
if srcString.hasSuffix("h") {
71100
kind = .header
@@ -84,12 +113,13 @@ final class TargetSourcesHandler {
84113
SourceItem(
85114
uri: src,
86115
kind: .file,
87-
generated: false, // FIXME: Need to handle this properly
116+
generated: false, // FIXME: Need to handle this properly
88117
dataKind: .sourceKit,
89118
data: SourceKitSourceItemData(
90119
language: language,
91120
kind: kind,
92-
outputPath: nil // FIXME: Related to the same flag on initialize?
121+
outputPath: nil, // FIXME: Related to the same flag on initialize?
122+
copyDestinations: copyDestinations
93123
).encodeToLSPAny()
94124
)
95125
)

Sources/SourceKitBazelBSP/Server/LSPConnection.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import BuildServerProtocol
2121
import Foundation
2222
import LanguageServerProtocol
23-
import LanguageServerProtocolJSONRPC
23+
import LanguageServerProtocolTransport
2424

2525
package protocol LSPTaskLogger: AnyObject {
2626
func startWorkTask(id: TaskId, title: String)
@@ -30,15 +30,22 @@ package protocol LSPTaskLogger: AnyObject {
3030
/// Extends the original sourcekit-lsp `Connection` type to include JSONRPCConnection's start method
3131
/// and task logging utilities.
3232
package protocol LSPConnection: Connection, LSPTaskLogger, AnyObject {
33-
func start(receiveHandler: MessageHandler, closeHandler: @escaping @Sendable () async -> Void)
33+
func startJSONRPC(receiveHandler: MessageHandler, closeHandler: @escaping @Sendable () async -> Void)
3434
}
3535

3636
extension JSONRPCConnection: LSPConnection {
37+
package func startJSONRPC(
38+
receiveHandler: any LanguageServerProtocol.MessageHandler,
39+
closeHandler: @escaping @Sendable () async -> Void
40+
) {
41+
self.start(receiveHandler: receiveHandler, closeHandler: closeHandler as nonisolated(nonsending) @Sendable () async -> Void)
42+
}
43+
3744
package func startWorkTask(id: TaskId, title: String) {
3845
send(TaskStartNotification(taskId: id, data: WorkDoneProgressTask(title: title).encodeToLSPAny()))
3946
}
4047

4148
package func finishTask(id: TaskId, status: StatusCode) {
42-
send(TaskFinishNotification(taskId: id, status: .ok, ))
49+
send(TaskFinishNotification(taskId: id, status: status))
4350
}
4451
}

Sources/SourceKitBazelBSP/Server/SourceKitBazelBSPServer.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import BuildServerProtocol
2121
import Foundation
2222
import LanguageServerProtocol
23-
import LanguageServerProtocolJSONRPC
23+
import LanguageServerProtocolTransport
2424

2525
private let logger = makeFileLevelBSPLogger()
2626

@@ -130,7 +130,7 @@ package final class SourceKitBazelBSPServer {
130130
package func run(parkThread: Bool = true) {
131131
logger.info("Connecting to sourcekit-lsp...")
132132

133-
connection.start(
133+
connection.startJSONRPC(
134134
receiveHandler: handler,
135135
closeHandler: {
136136
logger.info("Connection closed, exiting.")

Tests/SourceKitBazelBSPTests/BSPMessageHandlerTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import BuildServerProtocol
2121
import Foundation
2222
import LanguageServerProtocol
23-
import LanguageServerProtocolJSONRPC
23+
import LanguageServerProtocolTransport
2424
import Testing
2525

2626
@testable import SourceKitBazelBSP

Tests/SourceKitBazelBSPTests/BazelTargetCompilerArgsExtractorTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import BuildServerProtocol
2121
import Foundation
2222
import LanguageServerProtocol
23-
import LanguageServerProtocolJSONRPC
23+
import LanguageServerProtocolTransport
2424
import Testing
2525

2626
@testable import SourceKitBazelBSP

Tests/SourceKitBazelBSPTests/Fakes/LSPConnectionFake.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@
1919

2020
import BuildServerProtocol
2121
import LanguageServerProtocol
22-
import LanguageServerProtocolJSONRPC
22+
import LanguageServerProtocolTransport
2323

2424
@testable import SourceKitBazelBSP
2525

2626
final class LSPConnectionFake: LSPConnection {
27-
2827
nonisolated(unsafe) private(set) var startCalled = false
2928
nonisolated(unsafe) private(set) var startReceivedHandler: MessageHandler?
3029
nonisolated(unsafe) private(set) var sentNotifications: [any NotificationType] = []
3130

32-
func start(receiveHandler: MessageHandler, closeHandler: @escaping @Sendable () async -> Void) {
31+
func startJSONRPC(receiveHandler: MessageHandler, closeHandler: @escaping @Sendable () async -> Void) {
3332
startCalled = true
3433
startReceivedHandler = receiveHandler
3534
}

Tests/SourceKitBazelBSPTests/SourceKitBazelBSPServerTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import BuildServerProtocol
2121
import LanguageServerProtocol
22-
import LanguageServerProtocolJSONRPC
22+
import LanguageServerProtocolTransport
2323
import Testing
2424

2525
@testable import SourceKitBazelBSP

0 commit comments

Comments
 (0)