From 7f74d4a25f4ff2dcfaffca7a4aa81526fabe3ac1 Mon Sep 17 00:00:00 2001 From: Ben Langmuir Date: Mon, 3 Dec 2018 22:54:35 -0800 Subject: [PATCH] [build-system] Fold ExternalWorkspace into BuildSystem Simplifies clients to only need to care about one thing, and makes it easier for BuildSystems to grow new functionality. --- .../SKCore/BuildSettingsProviderList.swift | 10 ++++++- Sources/SKCore/BuildSystem.swift | 16 +++++++++- .../CompilationDatabaseBuildSystem.swift | 9 +++++- Sources/SKCore/ExternalWorkspace.swift | 29 ------------------- .../FallbackBuildSettingsProvider.swift | 4 +++ .../SKSwiftPMWorkspace/SwiftPMWorkspace.swift | 4 +-- Sources/SourceKit/SourceKitServer.swift | 1 - Sources/SourceKit/Workspace.swift | 24 ++++----------- 8 files changed, 42 insertions(+), 55 deletions(-) delete mode 100644 Sources/SKCore/ExternalWorkspace.swift diff --git a/Sources/SKCore/BuildSettingsProviderList.swift b/Sources/SKCore/BuildSettingsProviderList.swift index 7ac02608..d22850ee 100644 --- a/Sources/SKCore/BuildSettingsProviderList.swift +++ b/Sources/SKCore/BuildSettingsProviderList.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// +import Basic import LanguageServerProtocol /// Provides build settings from a list of providers in priority order. -public final class BuildSettingsProviderList: BuildSystem { +public final class BuildSettingsProviderList { /// The build settings providers to try (in order). public var providers: [BuildSystem] = [ @@ -21,6 +22,13 @@ public final class BuildSettingsProviderList: BuildSystem { ] public init() {} +} + +extension BuildSettingsProviderList: BuildSystem { + + public var indexStorePath: AbsolutePath? { return providers.first?.indexStorePath } + + public var indexDatabasePath: AbsolutePath? { return providers.first?.indexDatabasePath } public func settings(for url: URL, _ language: Language) -> FileBuildSettings? { for provider in providers { diff --git a/Sources/SKCore/BuildSystem.swift b/Sources/SKCore/BuildSystem.swift index 8c67d6c0..0e693c5c 100644 --- a/Sources/SKCore/BuildSystem.swift +++ b/Sources/SKCore/BuildSystem.swift @@ -11,10 +11,24 @@ //===----------------------------------------------------------------------===// import LanguageServerProtocol +import Basic -/// Provider of build settings. +/// Provider of FileBuildSettings and other build-related information. +/// +/// The primary role of the build system is to answer queries for FileBuildSettings and (TODO) to +/// notify clients when they change. The BuildSystem is also the source of related informatino, +/// such as where the index datastore is located. +/// +/// For example, a SwiftPMWorkspace provides compiler arguments for the files contained in a +/// SwiftPM package root directory. public protocol BuildSystem { + /// The path to the raw index store data, if any. + var indexStorePath: AbsolutePath? { get } + + /// The path to put the index database, if any. + var indexDatabasePath: AbsolutePath? { get } + /// Returns the settings for the given url and language mode, if known. func settings(for: URL, _ language: Language) -> FileBuildSettings? diff --git a/Sources/SKCore/CompilationDatabaseBuildSystem.swift b/Sources/SKCore/CompilationDatabaseBuildSystem.swift index 44837711..ed3a03ab 100644 --- a/Sources/SKCore/CompilationDatabaseBuildSystem.swift +++ b/Sources/SKCore/CompilationDatabaseBuildSystem.swift @@ -17,7 +17,7 @@ import LanguageServerProtocol /// /// Provides build settings from a `CompilationDatabase` found by searching a project. For now, only /// one compilation database, located at the project root. -public final class CompilationDatabaseBuildSystem: BuildSystem { +public final class CompilationDatabaseBuildSystem { /// The compilation database. var compdb: CompilationDatabase? = nil @@ -30,6 +30,13 @@ public final class CompilationDatabaseBuildSystem: BuildSystem { self.compdb = tryLoadCompilationDatabase(directory: path, fileSystem: fileSystem) } } +} + +extension CompilationDatabaseBuildSystem: BuildSystem { + + // FIXME: derive from the compiler arguments. + public var indexStorePath: AbsolutePath? { return nil } + public var indexDatabasePath: AbsolutePath? { return nil } public func settings(for url: URL, _ language: Language) -> FileBuildSettings? { guard let db = database(for: url), diff --git a/Sources/SKCore/ExternalWorkspace.swift b/Sources/SKCore/ExternalWorkspace.swift deleted file mode 100644 index f0f63e68..00000000 --- a/Sources/SKCore/ExternalWorkspace.swift +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 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 Basic - -/// Connection to an external workspace/project, providing access to settings, etc. -/// -/// For example, a swiftpm package loaded from disk can provide command-line arguments for the files -/// contained in its package root directory. -public protocol ExternalWorkspace { - - /// The build system, providing access to compiler arguments. - var buildSystem: BuildSystem { get } - - /// The path to the raw index store data, if any. - var indexStorePath: AbsolutePath? { get } - - /// The path to put the index database, if any. - var indexDatabasePath: AbsolutePath? { get } -} diff --git a/Sources/SKCore/FallbackBuildSettingsProvider.swift b/Sources/SKCore/FallbackBuildSettingsProvider.swift index f738cbe6..82148ee7 100644 --- a/Sources/SKCore/FallbackBuildSettingsProvider.swift +++ b/Sources/SKCore/FallbackBuildSettingsProvider.swift @@ -26,6 +26,10 @@ public final class FallbackBuildSettingsProvider: BuildSystem { return nil }() + public var indexStorePath: AbsolutePath? { return nil } + + public var indexDatabasePath: AbsolutePath? { return nil } + public func settings(for url: URL, _ language: Language) -> FileBuildSettings? { guard let path = try? AbsolutePath(validating: url.path) else { return nil diff --git a/Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift b/Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift index 2809fa53..d3c3a668 100644 --- a/Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift +++ b/Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift @@ -162,9 +162,7 @@ public final class SwiftPMWorkspace { } } -extension SwiftPMWorkspace: ExternalWorkspace, BuildSystem { - - public var buildSystem: BuildSystem { return self } +extension SwiftPMWorkspace: BuildSystem { public var buildPath: AbsolutePath { return buildParameters.buildPath diff --git a/Sources/SourceKit/SourceKitServer.swift b/Sources/SourceKit/SourceKitServer.swift index b78f1d63..a901c42e 100644 --- a/Sources/SourceKit/SourceKitServer.swift +++ b/Sources/SourceKit/SourceKitServer.swift @@ -228,7 +228,6 @@ extension SourceKitServer { self.workspace = Workspace( rootPath: nil, clientCapabilities: req.params.capabilities, - external: nil, buildSettings: BuildSettingsProviderList(), index: nil ) diff --git a/Sources/SourceKit/Workspace.swift b/Sources/SourceKit/Workspace.swift index 39e711fb..5cea6e3f 100644 --- a/Sources/SourceKit/Workspace.swift +++ b/Sources/SourceKit/Workspace.swift @@ -23,9 +23,7 @@ import SKSwiftPMWorkspace /// In LSP, this represents the per-workspace state that is typically only available after the /// "initialize" request has been made. /// -/// Typically a workspace is contained in a root directory, and may be represented by an -/// `ExternalWorkspace` if this workspace is part of a workspace in another tool such as a swiftpm -/// package. +/// Typically a workspace is contained in a root directory. public final class Workspace { /// The root directory of the workspace. @@ -33,13 +31,7 @@ public final class Workspace { public let clientCapabilities: ClientCapabilities - /// The external workspace connection, if any. - public let external: ExternalWorkspace? - /// The build settings provider to use for documents in this workspace. - /// - /// If `external` is not `nil`, this will typically include `external.buildSystem`. It may also - /// provide settings for files outside the workspace using additional providers. public let buildSettings: BuildSystem /// The source code index, if available. @@ -54,13 +46,11 @@ public final class Workspace { public init( rootPath: AbsolutePath?, clientCapabilities: ClientCapabilities, - external: ExternalWorkspace?, buildSettings: BuildSystem, index: IndexStoreDB?) { self.rootPath = rootPath self.clientCapabilities = clientCapabilities - self.external = external self.buildSettings = buildSettings self.index = index } @@ -79,21 +69,17 @@ public final class Workspace { self.rootPath = try AbsolutePath(validating: url.path) self.clientCapabilities = clientCapabilities - self.external = SwiftPMWorkspace(url: url, toolchainRegistry: toolchainRegistry) - let settings = BuildSettingsProviderList() self.buildSettings = settings settings.providers.insert(CompilationDatabaseBuildSystem(projectRoot: rootPath), at: 0) - guard let external = self.external else { - return + if let swiftpm = SwiftPMWorkspace(url: url, toolchainRegistry: toolchainRegistry) { + settings.providers.insert(swiftpm, at: 0) } - settings.providers.insert(external.buildSystem, at: 0) - - if let storePath = external.indexStorePath, - let dbPath = external.indexDatabasePath, + if let storePath = buildSettings.indexStorePath, + let dbPath = buildSettings.indexDatabasePath, let libPath = toolchainRegistry.default?.libIndexStore { do {