mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Make CompilationDatabase use DocumentURI instead of URL
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
import Foundation
|
||||
import LSPLogging
|
||||
import LanguageServerProtocol
|
||||
import SKSupport
|
||||
|
||||
import struct TSCBasic.AbsolutePath
|
||||
@@ -47,15 +48,15 @@ public struct CompilationDatabaseCompileCommand: Equatable {
|
||||
|
||||
extension CompilationDatabase.Command {
|
||||
|
||||
/// The `URL` for this file. If `filename` is relative and `directory` is
|
||||
/// The `DocumentURI` for this file. If `filename` is relative and `directory` is
|
||||
/// absolute, returns the concatenation. However, if both paths are relative,
|
||||
/// it falls back to `filename`, which is more likely to be the identifier
|
||||
/// that a caller will be looking for.
|
||||
public var url: URL {
|
||||
public var uri: DocumentURI {
|
||||
if filename.hasPrefix("/") || !directory.hasPrefix("/") {
|
||||
return URL(fileURLWithPath: filename)
|
||||
return DocumentURI(filePath: filename, isDirectory: false)
|
||||
} else {
|
||||
return URL(fileURLWithPath: directory).appendingPathComponent(filename, isDirectory: false)
|
||||
return DocumentURI(URL(fileURLWithPath: directory).appendingPathComponent(filename, isDirectory: false))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +66,7 @@ extension CompilationDatabase.Command {
|
||||
/// See https://clang.llvm.org/docs/JSONCompilationDatabase.html
|
||||
public protocol CompilationDatabase {
|
||||
typealias Command = CompilationDatabaseCompileCommand
|
||||
subscript(_ path: URL) -> [Command] { get }
|
||||
subscript(_ uri: DocumentURI) -> [Command] { get }
|
||||
var allCommands: AnySequence<Command> { get }
|
||||
}
|
||||
|
||||
@@ -110,13 +111,13 @@ public func tryLoadCompilationDatabase(
|
||||
///
|
||||
/// See https://clang.llvm.org/docs/JSONCompilationDatabase.html under Alternatives
|
||||
public struct FixedCompilationDatabase: CompilationDatabase, Equatable {
|
||||
public var allCommands: AnySequence<Command> { AnySequence([]) }
|
||||
public var allCommands: AnySequence<CompilationDatabaseCompileCommand> { AnySequence([]) }
|
||||
|
||||
private let fixedArgs: [String]
|
||||
private let directory: String
|
||||
|
||||
public subscript(path: URL) -> [Command] {
|
||||
[Command(directory: directory, filename: path.path, commandLine: fixedArgs + [path.path])]
|
||||
public subscript(path: DocumentURI) -> [CompilationDatabaseCompileCommand] {
|
||||
[Command(directory: directory, filename: path.pseudoPath, commandLine: fixedArgs + [path.pseudoPath])]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,32 +169,38 @@ extension FixedCompilationDatabase {
|
||||
///
|
||||
/// See https://clang.llvm.org/docs/JSONCompilationDatabase.html
|
||||
public struct JSONCompilationDatabase: CompilationDatabase, Equatable {
|
||||
var pathToCommands: [URL: [Int]] = [:]
|
||||
var commands: [Command] = []
|
||||
var pathToCommands: [DocumentURI: [Int]] = [:]
|
||||
var commands: [CompilationDatabaseCompileCommand] = []
|
||||
|
||||
public init(_ commands: [Command] = []) {
|
||||
commands.forEach { try! add($0) }
|
||||
public init(_ commands: [CompilationDatabaseCompileCommand] = []) {
|
||||
for command in commands {
|
||||
add(command)
|
||||
}
|
||||
}
|
||||
|
||||
public subscript(_ url: URL) -> [Command] {
|
||||
if let indices = pathToCommands[url] {
|
||||
public subscript(_ uri: DocumentURI) -> [CompilationDatabaseCompileCommand] {
|
||||
if let indices = pathToCommands[uri] {
|
||||
return indices.map { commands[$0] }
|
||||
}
|
||||
if let indices = pathToCommands[url.resolvingSymlinksInPath()] {
|
||||
if let fileURL = uri.fileURL, let indices = pathToCommands[DocumentURI(fileURL.resolvingSymlinksInPath())] {
|
||||
return indices.map { commands[$0] }
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
public var allCommands: AnySequence<Command> { AnySequence(commands) }
|
||||
public var allCommands: AnySequence<CompilationDatabaseCompileCommand> { AnySequence(commands) }
|
||||
|
||||
public mutating func add(_ command: Command) throws {
|
||||
let url = command.url
|
||||
pathToCommands[url, default: []].append(commands.count)
|
||||
public mutating func add(_ command: CompilationDatabaseCompileCommand) {
|
||||
let uri = command.uri
|
||||
pathToCommands[uri, default: []].append(commands.count)
|
||||
|
||||
let canonical = URL(fileURLWithPath: try resolveSymlinks(AbsolutePath(validating: url.path)).pathString)
|
||||
if canonical != url {
|
||||
pathToCommands[canonical, default: []].append(commands.count)
|
||||
if let fileURL = uri.fileURL,
|
||||
let symlinksResolved = try? resolveSymlinks(AbsolutePath(validating: fileURL.path))
|
||||
{
|
||||
let canonical = DocumentURI(filePath: symlinksResolved.pathString, isDirectory: false)
|
||||
if canonical != uri {
|
||||
pathToCommands[canonical, default: []].append(commands.count)
|
||||
}
|
||||
}
|
||||
|
||||
commands.append(command)
|
||||
@@ -204,7 +211,7 @@ extension JSONCompilationDatabase: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
var container = try decoder.unkeyedContainer()
|
||||
while !container.isAtEnd {
|
||||
try self.add(try container.decode(Command.self))
|
||||
self.add(try container.decode(Command.self))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -106,12 +106,8 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
|
||||
in buildTarget: ConfiguredTarget,
|
||||
language: Language
|
||||
) async -> FileBuildSettings? {
|
||||
guard let url = document.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
|
||||
guard let db = database(for: document),
|
||||
let cmd = db[document].first
|
||||
else { return nil }
|
||||
return FileBuildSettings(
|
||||
compilerArguments: Array(cmd.commandLine.dropFirst()),
|
||||
@@ -153,8 +149,8 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
|
||||
self.watchedFiles.remove(uri)
|
||||
}
|
||||
|
||||
private func database(for url: URL) -> CompilationDatabase? {
|
||||
if let path = try? AbsolutePath(validating: url.path) {
|
||||
private func database(for uri: DocumentURI) -> CompilationDatabase? {
|
||||
if let url = uri.fileURL, let path = try? AbsolutePath(validating: url.path) {
|
||||
return database(for: path)
|
||||
}
|
||||
return compdb
|
||||
@@ -212,10 +208,7 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
|
||||
}
|
||||
|
||||
public func fileHandlingCapability(for uri: DocumentURI) -> FileHandlingCapability {
|
||||
guard let fileUrl = uri.fileURL else {
|
||||
return .unhandled
|
||||
}
|
||||
if database(for: fileUrl) != nil {
|
||||
if database(for: uri) != nil {
|
||||
return .handled
|
||||
} else {
|
||||
return .unhandled
|
||||
@@ -227,7 +220,7 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
|
||||
return []
|
||||
}
|
||||
return compdb.allCommands.map {
|
||||
SourceFileInfo(uri: DocumentURI($0.url), isPartOfRootProject: true, mayContainTests: true)
|
||||
SourceFileInfo(uri: $0.uri, isPartOfRootProject: true, mayContainTests: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,9 +157,9 @@ final class CompilationDatabaseTests: XCTestCase {
|
||||
|
||||
let db = JSONCompilationDatabase([cmd1, cmd2, cmd3])
|
||||
|
||||
XCTAssertEqual(db[URL(fileURLWithPath: "b")], [cmd1])
|
||||
XCTAssertEqual(db[URL(fileURLWithPath: "/c/b")], [cmd2])
|
||||
XCTAssertEqual(db[URL(fileURLWithPath: "/b")], [cmd3])
|
||||
XCTAssertEqual(db[DocumentURI(filePath: "b", isDirectory: false)], [cmd1])
|
||||
XCTAssertEqual(db[DocumentURI(filePath: "/c/b", isDirectory: false)], [cmd2])
|
||||
XCTAssertEqual(db[DocumentURI(filePath: "/b", isDirectory: false)], [cmd3])
|
||||
}
|
||||
|
||||
func testJSONCompilationDatabaseFromDirectory() throws {
|
||||
@@ -255,7 +255,7 @@ final class CompilationDatabaseTests: XCTestCase {
|
||||
XCTAssertNotNil(db)
|
||||
|
||||
XCTAssertEqual(
|
||||
db![URL(fileURLWithPath: "/a/b")],
|
||||
db![DocumentURI(filePath: "/a/b", isDirectory: false)],
|
||||
[
|
||||
CompilationDatabase.Command(
|
||||
directory: try AbsolutePath(validating: "/a").pathString,
|
||||
|
||||
Reference in New Issue
Block a user