Skip to content

Commit 78e69f7

Browse files
authored
Merge pull request swiftlang#375 from hashemi/fixed-compilation-database
Add support for fixed compilation database (compile_flags.txt)
2 parents cb01f2f + 08c9d40 commit 78e69f7

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

Sources/SKCore/CompilationDatabase.swift

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,57 @@ public func tryLoadCompilationDatabase(
6868
directory: AbsolutePath,
6969
_ fileSystem: FileSystem = localFileSystem
7070
) -> CompilationDatabase? {
71-
// TODO: Support fixed compilation database (compile_flags.txt).
72-
return try? JSONCompilationDatabase(directory: directory, fileSystem)
71+
return
72+
(try? JSONCompilationDatabase(directory: directory, fileSystem))
73+
?? (try? FixedCompilationDatabase(directory: directory, fileSystem))
7374
}
7475

76+
/// Fixed clang-compatible compilation database (compile_flags.txt).
77+
///
78+
/// Each line in the file becomes a command line argument. Example:
79+
/// ```
80+
/// -xc++
81+
/// -I
82+
/// libwidget/include/
83+
/// ```
84+
///
85+
/// See https://clang.llvm.org/docs/JSONCompilationDatabase.html under Alternatives
86+
public struct FixedCompilationDatabase: CompilationDatabase, Equatable {
87+
public var allCommands: AnySequence<Command> { AnySequence([]) }
88+
89+
private let fixedArgs: [String]
90+
private let directory: String
91+
92+
public subscript(path: URL) -> [Command] {
93+
[Command(directory: directory, filename: path.path, commandLine: fixedArgs + [path.path])]
94+
}
95+
}
96+
97+
extension FixedCompilationDatabase {
98+
public init(directory: AbsolutePath, _ fileSystem: FileSystem = localFileSystem) throws {
99+
let path = directory.appending(component: "compile_flags.txt")
100+
try self.init(file: path, fileSystem)
101+
}
102+
103+
public init(file: AbsolutePath, _ fileSystem: FileSystem = localFileSystem) throws {
104+
self.directory = file.dirname
105+
let bytes = try fileSystem.readFileContents(file)
106+
107+
var fixedArgs: [String] = ["clang"]
108+
try bytes.withUnsafeData { data in
109+
guard let fileContents = String(data: data, encoding: .utf8) else {
110+
throw CompilationDatabaseDecodingError.fixedDatabaseDecordingError
111+
}
112+
113+
fileContents.enumerateLines { line, _ in
114+
fixedArgs.append(line.trimmingCharacters(in: .whitespacesAndNewlines))
115+
}
116+
}
117+
self.fixedArgs = fixedArgs
118+
}
119+
}
120+
121+
75122
/// The JSON clang-compatible compilation database.
76123
///
77124
/// Example:
@@ -150,6 +197,7 @@ extension JSONCompilationDatabase {
150197

151198
enum CompilationDatabaseDecodingError: Error {
152199
case missingCommandOrArguments
200+
case fixedDatabaseDecordingError
153201
}
154202

155203
extension CompilationDatabase.Command: Codable {

Tests/SKCoreTests/CompilationDatabaseTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,25 @@ final class CompilationDatabaseTests: XCTestCase {
187187
XCTAssertNotNil(tryLoadCompilationDatabase(directory: AbsolutePath("/a"), fs))
188188
}
189189

190+
func testFixedCompilationDatabase() {
191+
let fs = InMemoryFileSystem()
192+
try! fs.createDirectory(AbsolutePath("/a"))
193+
XCTAssertNil(tryLoadCompilationDatabase(directory: AbsolutePath("/a"), fs))
194+
195+
try! fs.writeFileContents(AbsolutePath("/a/compile_flags.txt"), bytes: """
196+
-xc++
197+
-I
198+
libwidget/include/
199+
""")
200+
201+
let db = tryLoadCompilationDatabase(directory: AbsolutePath("/a"), fs)
202+
XCTAssertNotNil(db)
203+
204+
XCTAssertEqual(db![URL(fileURLWithPath: "/a/b")], [
205+
CompilationDatabase.Command(directory: "/a", filename: "/a/b", commandLine: ["clang", "-xc++", "-I", "libwidget/include/", "/a/b"], output: nil)
206+
])
207+
}
208+
190209
func testCompilationDatabaseBuildSystem() {
191210
checkCompilationDatabaseBuildSystem("""
192211
[

Tests/SKCoreTests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ extension CompilationDatabaseTests {
5757
("testCompilationDatabaseBuildSystemIndexStoreSwift4", testCompilationDatabaseBuildSystemIndexStoreSwift4),
5858
("testDecodeCompDBCommand", testDecodeCompDBCommand),
5959
("testEncodeCompDBCommand", testEncodeCompDBCommand),
60+
("testFixedCompilationDatabase", testFixedCompilationDatabase),
6061
("testJSONCompilationDatabaseCoding", testJSONCompilationDatabaseCoding),
6162
("testJSONCompilationDatabaseFromDirectory", testJSONCompilationDatabaseFromDirectory),
6263
("testJSONCompilationDatabaseLookup", testJSONCompilationDatabaseLookup),

0 commit comments

Comments
 (0)