mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
This allows us to run `sourcekit-lsp index --project /path/to/project` to index a project. Intended to debugging purposes, eg. - Profile the time it takes to index a project - See if the project can be indexed successfully - Look at signposts generated during indexing in Instruments to see whether indexing or preparation is the bottleneck and how well we can parallelize tasks.
82 lines
3.1 KiB
Swift
82 lines
3.1 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import CAtomics
|
|
import LanguageServerProtocol
|
|
import SKCore
|
|
import SourceKitLSP
|
|
|
|
/// Launches a `SourceKitLSPServer` in-process and allows sending messages to it.
|
|
public final class InProcessSourceKitLSPClient: Sendable {
|
|
private let server: SourceKitLSPServer
|
|
|
|
/// `nonisolated(unsafe)` if fine because `nextRequestID` is atomic.
|
|
private nonisolated(unsafe) var nextRequestID = AtomicUInt32(initialValue: 0)
|
|
|
|
/// Create a new `SourceKitLSPServer`. An `InitializeRequest` is automatically sent to the server.
|
|
///
|
|
/// `messageHandler` handles notifications and requests sent from the SourceKit-LSP server to the client.
|
|
public init(
|
|
toolchainRegistry: ToolchainRegistry,
|
|
serverOptions: SourceKitLSPServer.Options = SourceKitLSPServer.Options(),
|
|
capabilities: ClientCapabilities = ClientCapabilities(),
|
|
workspaceFolders: [WorkspaceFolder],
|
|
messageHandler: any MessageHandler
|
|
) async throws {
|
|
let serverToClientConnection = LocalConnection(name: "client")
|
|
self.server = SourceKitLSPServer(
|
|
client: serverToClientConnection,
|
|
toolchainRegistry: toolchainRegistry,
|
|
options: serverOptions,
|
|
onExit: {
|
|
serverToClientConnection.close()
|
|
}
|
|
)
|
|
serverToClientConnection.start(handler: messageHandler)
|
|
_ = try await self.send(
|
|
InitializeRequest(
|
|
processId: nil,
|
|
rootPath: nil,
|
|
rootURI: nil,
|
|
initializationOptions: nil,
|
|
capabilities: capabilities,
|
|
trace: .off,
|
|
workspaceFolders: workspaceFolders
|
|
)
|
|
)
|
|
}
|
|
|
|
/// Send the request to `server` and return the request result.
|
|
///
|
|
/// - Important: Because this is an async function, Swift concurrency makes no guarantees about the execution ordering
|
|
/// of this request with regard to other requests to the server. If execution of requests in a particular order is
|
|
/// necessary and the response of the request is not awaited, use the version of the function that takes a
|
|
/// completion handler
|
|
public func send<R: RequestType>(_ request: R) async throws -> R.Response {
|
|
return try await withCheckedThrowingContinuation { continuation in
|
|
self.send(request) {
|
|
continuation.resume(with: $0)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Send the request to `server` and return the request result via a completion handler.
|
|
public func send<R: RequestType>(_ request: R, reply: @Sendable @escaping (LSPResult<R.Response>) -> Void) {
|
|
server.handle(request, id: .number(Int(nextRequestID.fetchAndIncrement())), reply: reply)
|
|
}
|
|
|
|
/// Send the notification to `server`.
|
|
public func send(_ notification: some NotificationType) {
|
|
server.handle(notification)
|
|
}
|
|
}
|