From e073a01bbc91bd117d3ee6a054cec5dc794bbca1 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Fri, 22 Nov 2024 15:52:27 +0100 Subject: [PATCH] Reply with `null` to `shutdown` request The LSP spec says the result of `shutdown` is `null`, not an empty object. Fixes #1733 rdar://137886488 --- .../Requests/ShutdownRequest.swift | 15 +++++++++++---- Sources/SourceKitLSP/SourceKitLSPServer.swift | 4 ++-- .../LanguageServerProtocolTests/CodingTests.swift | 4 ++++ Tests/SourceKitLSPTests/IndexTests.swift | 2 +- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift b/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift index aca90bcfa..036aa020f 100644 --- a/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift +++ b/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift @@ -18,10 +18,17 @@ /// - Returns: Void. public struct ShutdownRequest: RequestType, Hashable { public static let method: String = "shutdown" - public typealias Response = VoidResponse + + public struct Response: ResponseType, Equatable { + public init() {} + + public init(from decoder: any Decoder) throws {} + + public func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + try container.encodeNil() + } + } public init() {} } - -@available(*, deprecated, renamed: "ShutdownRequest") -public typealias Shutdown = ShutdownRequest diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index 6cedb6c50..c2af608e8 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -1128,7 +1128,7 @@ extension SourceKitLSPServer { } } - func shutdown(_ request: ShutdownRequest) async throws -> VoidResponse { + func shutdown(_ request: ShutdownRequest) async throws -> ShutdownRequest.Response { await prepareForExit() await withTaskGroup(of: Void.self) { taskGroup in @@ -1159,7 +1159,7 @@ extension SourceKitLSPServer { // Otherwise we might terminate sourcekit-lsp while it still has open // connections to the toolchain servers, which could send messages to // sourcekit-lsp while it is being deallocated, causing crashes. - return VoidResponse() + return ShutdownRequest.Response() } func exit(_ notification: ExitNotification) async { diff --git a/Tests/LanguageServerProtocolTests/CodingTests.swift b/Tests/LanguageServerProtocolTests/CodingTests.swift index ee81ec2b0..72b0e13e1 100644 --- a/Tests/LanguageServerProtocolTests/CodingTests.swift +++ b/Tests/LanguageServerProtocolTests/CodingTests.swift @@ -1343,6 +1343,10 @@ final class CodingTests: XCTestCase { """ ) } + + func testShutdownResponse() { + checkCoding(ShutdownRequest.Response(), json: "null") + } } func with(_ value: T, mutate: (inout T) -> Void) -> T { diff --git a/Tests/SourceKitLSPTests/IndexTests.swift b/Tests/SourceKitLSPTests/IndexTests.swift index 76450db37..2452e8cf5 100644 --- a/Tests/SourceKitLSPTests/IndexTests.swift +++ b/Tests/SourceKitLSPTests/IndexTests.swift @@ -141,7 +141,7 @@ final class IndexTests: XCTestCase { "Received unexpected version: \(versionContentsBefore.first?.lastPathComponent ?? "")" ) - try await project.testClient.send(ShutdownRequest()) + _ = try await project.testClient.send(ShutdownRequest()) return versionedPath }