Files
sourcekit-lsp/Sources/SKCore/CompilationDatabaseBuildSystem.swift
David Goldman e5caf44fda Add a BuildSystemDelegate which supports notifications for build settings changes
Introduce a `BuildSystemDelegate` to handle notifications from the build system

* `SourceKitServer` is the main delegate to process these notifications
* Currently limited to changes in `FileBuildSettings`
* Delegate informs the `BuildSystem` of files to watch via `registerChangeWatching(for: URL)` and `unregisterChangeWatching(for: URL)`
* In the future we could have more integration for handling changes in dependencies

Handling changes in `FileBuildSettings`

* `SourceKitServer` sends notifications to the internal LSPs informing them of any opened documents that have changes in their compiler flags
    * For clangd, we send a notification to update the compilation database
    * For SourceKit/sourcekitd we must close and reopen the file to force a new AST with the new compiler flags
2019-09-06 17:44:36 -04:00

88 lines
2.7 KiB
Swift

//===----------------------------------------------------------------------===//
//
// 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 SKSupport
import TSCBasic
import LanguageServerProtocol
/// A `BuildSystem` based on loading clang-compatible compilation database(s).
///
/// 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 {
/// The compilation database.
var compdb: CompilationDatabase? = nil
/// Delegate to handle any build system events.
public weak var delegate: BuildSystemDelegate? = nil
let fileSystem: FileSystem
public init(projectRoot: AbsolutePath? = nil, fileSystem: FileSystem = localFileSystem) {
self.fileSystem = fileSystem
if let path = projectRoot {
self.compdb = tryLoadCompilationDatabase(directory: path, 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),
let cmd = db[url].first else { return nil }
return FileBuildSettings(
compilerArguments: Array(cmd.commandLine.dropFirst()),
workingDirectory: cmd.directory
)
}
public func toolchain(for: URL, _ language: Language) -> Toolchain? { return nil }
/// We don't support change watching.
public func registerForChangeNotifications(for: URL) {}
/// We don't support change watching.
public func unregisterForChangeNotifications(for: URL) {}
func database(for url: URL) -> CompilationDatabase? {
if let path = try? AbsolutePath(validating: url.path) {
return database(for: path)
}
return compdb
}
func database(for path: AbsolutePath) -> CompilationDatabase? {
if compdb == nil {
var dir = path
while !dir.isRoot {
dir = dir.parentDirectory
if let db = tryLoadCompilationDatabase(directory: dir, fileSystem) {
compdb = db
break
}
}
}
if compdb == nil {
log("could not open compilation database for \(path)", level: .warning)
}
return compdb
}
}