Skip to content

Commit

Permalink
Expose ServerInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
FastestMolasses committed Jan 27, 2024
1 parent f8fdeae commit 19dc4c7
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 43 deletions.
111 changes: 69 additions & 42 deletions Sources/LanguageClient/InitializingServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,43 @@ enum InitializingServerError: Error {
public actor InitializingServer {
public typealias InitializeParamsProvider = @Sendable () async throws -> InitializeParams

private enum State {
case uninitialized
case initialized(ServerCapabilities)
case shutdown

var capabilities: ServerCapabilities? {
get {
switch self {
case .initialized(let capabilities):
return capabilities
case .uninitialized, .shutdown:
return nil
}
}
set {
guard let caps = newValue else {
fatalError()
}

switch self {
case .initialized:
self = .initialized(caps)
case .uninitialized, .shutdown:
break
}
}
}
}
private enum State {
case uninitialized
case initialized(capabilities: ServerCapabilities, info: ServerInfo?)
case shutdown

var capabilities: ServerCapabilities? {
get {
switch self {
case .initialized(let capabilities, _):
return capabilities
case .uninitialized, .shutdown:
return nil
}
}
set {
guard let caps = newValue else {
fatalError()
}

switch self {
case .initialized(_, let info):
self = .initialized(capabilities: caps, info: info)
case .uninitialized, .shutdown:
break
}
}
}

var serverInfo: ServerInfo? {
switch self {
case .initialized(_, let info):
return info
case .uninitialized, .shutdown:
return nil
}
}
}

private let channel: ServerConnection
private var state = State.uninitialized
Expand Down Expand Up @@ -94,6 +103,23 @@ public actor InitializingServer {
return state.capabilities
}
}

/// Return the server's info.
///
/// This will not start the server if it isn't already running.
public var serverInfo: ServerInfo? {
get async {
do {
try await semaphore.waitUnlessCancelled()
} catch {
return nil
}

defer { semaphore.signal() }

return state.serverInfo
}
}
}

extension InitializingServer: StatefulServer {
Expand Down Expand Up @@ -158,10 +184,10 @@ extension InitializingServer: StatefulServer {

extension InitializingServer {
/// Run the initialization sequence with the server, if it has not already happened.
public func initializeIfNeeded() async throws -> ServerCapabilities {
public func initializeIfNeeded() async throws -> (ServerCapabilities, ServerInfo?) {
switch state {
case .initialized(let caps):
return caps
case .initialized(let caps, let info):
return (caps, info)
case .uninitialized, .shutdown:
try await semaphore.waitUnlessCancelled()
}
Expand All @@ -172,27 +198,28 @@ extension InitializingServer {

let initResponse = try await channel.initialize(params)
let caps = initResponse.capabilities
let info = initResponse.serverInfo

try await channel.initialized(InitializedParams())

self.state = .initialized(caps)
self.state = .initialized(capabilities: caps, info: info)

capabilitiesContinuation.yield(caps)

return caps
return (caps, info)
}

private func handleEvent(_ event: ServerEvent) {
switch event {
case let .request(_, request):
handleRequest(request)
default:
break
private func handleEvent(_ event: ServerEvent) {
switch event {
case let .request(_, request):
handleRequest(request)
default:
break
}
}
}

private func handleRequest(_ request: ServerRequest) {
guard case .initialized(let caps) = self.state else {
guard case .initialized(let caps, let info) = self.state else {
fatalError("received a request without being initialized")
}

Expand All @@ -212,7 +239,7 @@ extension InitializingServer {
}

if caps != newCaps {
self.state = .initialized(newCaps)
self.state = .initialized(capabilities: newCaps, info: info)

capabilitiesContinuation.yield(newCaps)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/LanguageClient/RestartingServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public actor RestartingServer<WrappedServer: ServerConnection & Sendable> {
}

/// Run the initialization sequence with the server, if it has not already happened.
public func initializeIfNeeded() async throws -> ServerCapabilities {
public func initializeIfNeeded() async throws -> (ServerCapabilities, ServerInfo?) {
try await startServerIfNeeded().initializeIfNeeded()
}

Expand Down

0 comments on commit 19dc4c7

Please sign in to comment.