mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Find the index store path by searching through the command-line arguments, and if found, also provide a default database path next to the index store. Also add command-line arguments so that either of these can be overridden. We could also easily add these as initialization options if an LSP client wanted to provide them in the future.
121 lines
3.8 KiB
Swift
121 lines
3.8 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 BuildServerProtocol
|
|
import LanguageServerProtocol
|
|
import LSPLogging
|
|
import SKSupport
|
|
import TSCBasic
|
|
import struct Foundation.URL
|
|
|
|
/// 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 lazy var indexStorePath: AbsolutePath? = {
|
|
if let allCommands = self.compdb?.allCommands {
|
|
for command in allCommands {
|
|
let args = command.commandLine
|
|
for i in args.indices.reversed() {
|
|
if args[i] == "-index-store-path" && i != args.endIndex - 1 {
|
|
return try? AbsolutePath(validating: args[i+1])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}()
|
|
|
|
public init(projectRoot: AbsolutePath? = nil, fileSystem: FileSystem = localFileSystem) {
|
|
self.fileSystem = fileSystem
|
|
if let path = projectRoot {
|
|
self.compdb = tryLoadCompilationDatabase(directory: path, fileSystem)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension CompilationDatabaseBuildSystem: BuildSystem {
|
|
|
|
public var indexDatabasePath: AbsolutePath? {
|
|
indexStorePath?.parentDirectory.appending(component: "IndexDatabase")
|
|
}
|
|
|
|
public func settings(for uri: DocumentURI, _ language: Language) -> FileBuildSettings? {
|
|
guard let url = uri.fileURL else {
|
|
// We can't determine build settings for non-file URIs.
|
|
return nil
|
|
}
|
|
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: DocumentURI, _ language: Language) -> Toolchain? { return nil }
|
|
|
|
/// We don't support change watching.
|
|
public func registerForChangeNotifications(for: DocumentURI) {}
|
|
|
|
/// We don't support change watching.
|
|
public func unregisterForChangeNotifications(for: DocumentURI) {}
|
|
|
|
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
|
|
reply(.failure(buildTargetsNotSupported))
|
|
}
|
|
|
|
public func buildTargetSources(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
|
|
reply(.failure(buildTargetsNotSupported))
|
|
}
|
|
|
|
public func buildTargetOutputPaths(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
|
|
reply(.failure(buildTargetsNotSupported))
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|