mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Migrate BuildServerBuildSystem to an actor and make methods in BuildSystemDelegate async
This concludes the migration of the build systems to async.
This commit is contained in:
@@ -43,10 +43,7 @@ func executable(_ name: String) -> String {
|
||||
///
|
||||
/// Provides build settings from a build server launched based on a
|
||||
/// `buildServer.json` configuration file provided in the repo root.
|
||||
public final class BuildServerBuildSystem: MessageHandler {
|
||||
/// The handler's request queue. `delegate` will always be called on this queue.
|
||||
public let queue: DispatchQueue = DispatchQueue(label: "language-server-queue", qos: .userInitiated)
|
||||
|
||||
public actor BuildServerBuildSystem: MessageHandler {
|
||||
let projectRoot: AbsolutePath
|
||||
let buildFolder: AbsolutePath?
|
||||
let serverConfig: BuildServerConfig
|
||||
@@ -73,7 +70,7 @@ public final class BuildServerBuildSystem: MessageHandler {
|
||||
/// The build settings that have been received from the build server.
|
||||
private var buildSettings: [DocumentURI: FileBuildSettings] = [:]
|
||||
|
||||
public init(projectRoot: AbsolutePath, buildFolder: AbsolutePath?, fileSystem: FileSystem = localFileSystem) throws {
|
||||
public init(projectRoot: AbsolutePath, buildFolder: AbsolutePath?, fileSystem: FileSystem = localFileSystem) async throws {
|
||||
let configPath = projectRoot.appending(component: "buildServer.json")
|
||||
let config = try loadBuildServerConfig(path: configPath, fileSystem: fileSystem)
|
||||
#if os(Windows)
|
||||
@@ -95,12 +92,11 @@ public final class BuildServerBuildSystem: MessageHandler {
|
||||
/// Creates a build system using the Build Server Protocol config.
|
||||
///
|
||||
/// - Returns: nil if `projectRoot` has no config or there is an error parsing it.
|
||||
public convenience init?(projectRoot: AbsolutePath?, buildSetup: BuildSetup)
|
||||
{
|
||||
public init?(projectRoot: AbsolutePath?, buildSetup: BuildSetup) async {
|
||||
if projectRoot == nil { return nil }
|
||||
|
||||
do {
|
||||
try self.init(projectRoot: projectRoot!, buildFolder: buildSetup.path)
|
||||
try await self.init(projectRoot: projectRoot!, buildFolder: buildSetup.path)
|
||||
} catch _ as FileSystemError {
|
||||
// config file was missing, no build server for this workspace
|
||||
return nil
|
||||
@@ -171,13 +167,11 @@ public final class BuildServerBuildSystem: MessageHandler {
|
||||
/// the build server has sent us a notification.
|
||||
///
|
||||
/// We need to notify the delegate about any updated build settings.
|
||||
public func handle(_ params: some NotificationType, from clientID: ObjectIdentifier) {
|
||||
queue.async {
|
||||
if let params = params as? BuildTargetsChangedNotification {
|
||||
self.handleBuildTargetsChanged(Notification(params, clientID: clientID))
|
||||
} else if let params = params as? FileOptionsChangedNotification {
|
||||
self.handleFileOptionsChanged(Notification(params, clientID: clientID))
|
||||
}
|
||||
public func handle(_ params: some NotificationType, from clientID: ObjectIdentifier) async {
|
||||
if let params = params as? BuildTargetsChangedNotification {
|
||||
await self.handleBuildTargetsChanged(Notification(params, clientID: clientID))
|
||||
} else if let params = params as? FileOptionsChangedNotification {
|
||||
await self.handleFileOptionsChanged(Notification(params, clientID: clientID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,30 +184,28 @@ public final class BuildServerBuildSystem: MessageHandler {
|
||||
from clientID: ObjectIdentifier,
|
||||
reply: @escaping (LSPResult<R.Response>) -> Void
|
||||
) {
|
||||
queue.async {
|
||||
reply(.failure(ResponseError.methodNotFound(R.method)))
|
||||
}
|
||||
reply(.failure(ResponseError.methodNotFound(R.method)))
|
||||
}
|
||||
|
||||
func handleBuildTargetsChanged(_ notification: LanguageServerProtocol.Notification<BuildTargetsChangedNotification>) {
|
||||
self.delegate?.buildTargetsChanged(notification.params.changes)
|
||||
func handleBuildTargetsChanged(_ notification: LanguageServerProtocol.Notification<BuildTargetsChangedNotification>) async {
|
||||
await self.delegate?.buildTargetsChanged(notification.params.changes)
|
||||
}
|
||||
|
||||
func handleFileOptionsChanged(_ notification: LanguageServerProtocol.Notification<FileOptionsChangedNotification>) {
|
||||
func handleFileOptionsChanged(_ notification: LanguageServerProtocol.Notification<FileOptionsChangedNotification>) async {
|
||||
let result = notification.params.updatedOptions
|
||||
let settings = FileBuildSettings(
|
||||
compilerArguments: result.options, workingDirectory: result.workingDirectory)
|
||||
self.buildSettingsChanged(for: notification.params.uri, settings: settings)
|
||||
await self.buildSettingsChanged(for: notification.params.uri, settings: settings)
|
||||
}
|
||||
|
||||
/// Record the new build settings for the given document and inform the delegate
|
||||
/// about the changed build settings.
|
||||
private func buildSettingsChanged(for document: DocumentURI, settings: FileBuildSettings?) {
|
||||
private func buildSettingsChanged(for document: DocumentURI, settings: FileBuildSettings?) async {
|
||||
buildSettings[document] = settings
|
||||
if let settings {
|
||||
self.delegate?.fileBuildSettingsChanged([document: .modified(settings)])
|
||||
await self.delegate?.fileBuildSettingsChanged([document: .modified(settings)])
|
||||
} else {
|
||||
self.delegate?.fileBuildSettingsChanged([document: .removedOrUnavailable])
|
||||
await self.delegate?.fileBuildSettingsChanged([document: .removedOrUnavailable])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -239,12 +231,14 @@ extension BuildServerBuildSystem: BuildSystem {
|
||||
public func registerForChangeNotifications(for uri: DocumentURI, language: Language) {
|
||||
let request = RegisterForChanges(uri: uri, action: .register)
|
||||
_ = self.buildServer?.send(request, queue: requestQueue, reply: { result in
|
||||
if let error = result.failure {
|
||||
log("error registering \(uri): \(error)", level: .error)
|
||||
|
||||
// BuildServer registration failed, so tell our delegate that no build
|
||||
// settings are available.
|
||||
self.buildSettingsChanged(for: uri, settings: nil)
|
||||
Task {
|
||||
if let error = result.failure {
|
||||
log("error registering \(uri): \(error)", level: .error)
|
||||
|
||||
// BuildServer registration failed, so tell our delegate that no build
|
||||
// settings are available.
|
||||
await self.buildSettingsChanged(for: uri, settings: nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user