Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Example/.sourcekit-lsp/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"backgroundIndexing": true,
"backgroundPreparationMode": "build",
"defaultWorkspaceType": "buildServer"
"defaultWorkspaceType": "buildServer",
"logging": {
"level": "error",
"privacyLevel": "sensitive"
}
}
16 changes: 13 additions & 3 deletions Sources/SourceKitBazelBSP/RequestHandlers/PrepareHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ private let logger = makeFileLevelBSPLogger()
///
/// Builds the provided list of targets upon request.
final class PrepareHandler {

private let initializedConfig: InitializedServerConfig
private let targetStore: BazelTargetStore
private let commandRunner: CommandRunner
private weak var connection: LSPConnection?

// Prevent redundant builds of the same targets
private var didRun = false

init(
initializedConfig: InitializedServerConfig,
targetStore: BazelTargetStore,
Expand All @@ -46,9 +48,15 @@ final class PrepareHandler {
}

func prepareTarget(
_ request: BuildTargetPrepareRequest,
_: BuildTargetPrepareRequest,
_ id: RequestID
) throws -> VoidResponse {
// FIXME: Invalidate on changes
guard !didRun else {
logger.info("Build already completed, skipping redundant build")
return VoidResponse()
}

let taskId = TaskId(id: "buildPrepare-\(id.description)")
connection?.startWorkTask(id: taskId, title: "Indexing: Building targets")
do {
Expand All @@ -58,6 +66,7 @@ final class PrepareHandler {
// and these are lost if you build the libs directly. We need those transitions here too.
try build(bazelLabels: initializedConfig.baseConfig.targets)
connection?.finishTask(id: taskId, status: .ok)
didRun = true
return VoidResponse()
} catch {
connection?.finishTask(id: taskId, status: .error)
Expand All @@ -78,6 +87,7 @@ final class PrepareHandler {
bazelLabels labelsToBuild: [String]
) throws {
logger.info("Will build \(labelsToBuild.count) targets")
logger.info("Target to build: \(labelsToBuild)")

// Build the provided targets, on our special output base and taking into account special index flags.
_ = try commandRunner.bazelIndexAction(
Expand All @@ -86,7 +96,7 @@ final class PrepareHandler {
)

// FIXME: This might not be necessary anymore
_ = try commandRunner.run("chmod -R 777 \(initializedConfig.outputBase)")
// _ = try commandRunner.run("chmod -R 777 \(initializedConfig.outputBase)")

logger.info("Finished building targets!")
}
Expand Down
24 changes: 18 additions & 6 deletions Sources/SourceKitBazelBSP/Server/SourceKitBazelBSPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ private let logger = makeFileLevelBSPLogger()

/// The higher-level class that bootstraps and manages the BSP server.
package final class SourceKitBazelBSPServer {

let connection: LSPConnection
let handler: MessageHandler

Expand Down Expand Up @@ -62,16 +61,16 @@ package final class SourceKitBazelBSPServer {
connection: JSONRPCConnection
) {
// First, deal with the no-op handlers we cannot or do not want to handle directly.
registry.register(notificationHandler: { (notification: OnBuildInitializedNotification) in
registry.register(notificationHandler: { (_: OnBuildInitializedNotification) in
// no-op
})
registry.register(notificationHandler: { (notification: CancelRequestNotification) in
registry.register(notificationHandler: { (_: CancelRequestNotification) in
// no-op, no request canceling since the code today is not async
})
registry.register(requestHandler: {
(request: WorkspaceWaitForBuildSystemUpdatesRequest, id: RequestID) in
(_: WorkspaceWaitForBuildSystemUpdatesRequest, _: RequestID) in
// FIXME: no-op, no special handling since the code today is not async, but I might be wrong here.
return VoidResponse()
VoidResponse()
})

// Then, register the things we are interested in.
Expand All @@ -96,7 +95,20 @@ package final class SourceKitBazelBSPServer {
targetStore: targetStore,
connection: connection
)
registry.register(requestHandler: skOptionsHandler.textDocumentSourceKitOptions)
registry.register(requestHandler: { (request: TextDocumentSourceKitOptionsRequest, id: RequestID) in
// Handle the optional response type properly - if nil is returned for valid reasons
// (like missing module entries), return an empty response instead of nil to prevent connection closure
if let response = try skOptionsHandler.textDocumentSourceKitOptions(request, id) {
return response
} else {
// Return an empty response with no compiler arguments rather than nil
// This prevents SourceKit LSP from closing the connection
return TextDocumentSourceKitOptionsResponse(
compilerArguments: [],
workingDirectory: initializedConfig.rootUri
)
}
})

// buildTarget/prepare
let prepareHandler = PrepareHandler(
Expand Down
Loading