Skip to content

Commit 5a32f95

Browse files
committed
Migrate CompilationDatabaseBuildSystem to be an actor
1 parent fccbc39 commit 5a32f95

File tree

2 files changed

+52
-86
lines changed

2 files changed

+52
-86
lines changed

Sources/SKCore/CompilationDatabaseBuildSystem.swift

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,10 @@ import var TSCBasic.localFileSystem
2525
///
2626
/// Provides build settings from a `CompilationDatabase` found by searching a project. For now, only
2727
/// one compilation database, located at the project root.
28-
public final class CompilationDatabaseBuildSystem {
29-
30-
/// Queue guarding the following properties:
31-
/// - `compdb`
32-
/// - `watchedFiles`
33-
/// - `_indexStorePath`
34-
let queue: DispatchQueue = .init(label: "CompilationDatabaseBuildSystem.queue", qos: .userInitiated)
35-
28+
public actor CompilationDatabaseBuildSystem {
3629
/// The compilation database.
3730
var compdb: CompilationDatabase? = nil {
3831
didSet {
39-
dispatchPrecondition(condition: .onQueue(queue))
4032
// Build settings have changed and thus the index store path might have changed.
4133
// Recompute it on demand.
4234
_indexStorePath = nil
@@ -60,24 +52,22 @@ public final class CompilationDatabaseBuildSystem {
6052

6153
private var _indexStorePath: AbsolutePath?
6254
public var indexStorePath: AbsolutePath? {
63-
return queue.sync {
64-
if let indexStorePath = _indexStorePath {
65-
return indexStorePath
66-
}
55+
if let indexStorePath = _indexStorePath {
56+
return indexStorePath
57+
}
6758

68-
if let allCommands = self.compdb?.allCommands {
69-
for command in allCommands {
70-
let args = command.commandLine
71-
for i in args.indices.reversed() {
72-
if args[i] == "-index-store-path" && i != args.endIndex - 1 {
73-
_indexStorePath = try? AbsolutePath(validating: args[i+1])
74-
return _indexStorePath
75-
}
59+
if let allCommands = self.compdb?.allCommands {
60+
for command in allCommands {
61+
let args = command.commandLine
62+
for i in args.indices.reversed() {
63+
if args[i] == "-index-store-path" && i != args.endIndex - 1 {
64+
_indexStorePath = try? AbsolutePath(validating: args[i+1])
65+
return _indexStorePath
7666
}
7767
}
7868
}
79-
return nil
8069
}
70+
return nil
8171
}
8272

8373
public init(projectRoot: AbsolutePath? = nil, fileSystem: FileSystem = localFileSystem) {
@@ -98,44 +88,31 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
9888
public var indexPrefixMappings: [PathPrefixMapping] { return [] }
9989

10090
public func buildSettings(for document: DocumentURI, language: Language) async throws -> FileBuildSettings? {
101-
// FIXME: (async) Convert this to an async function once `CompilationDatabaseBuildSystem` is an actor.
102-
return await withCheckedContinuation { continuation in
103-
self.queue.async {
104-
continuation.resume(returning: self.settings(for: document))
105-
}
106-
}
91+
return self.settings(for: document)
10792
}
10893

10994
public func registerForChangeNotifications(for uri: DocumentURI, language: Language) {
110-
queue.async {
111-
self.watchedFiles[uri] = language
95+
self.watchedFiles[uri] = language
11296

113-
guard let delegate = self.delegate else { return }
97+
guard let delegate = self.delegate else { return }
11498

115-
let settings = self.settings(for: uri)
116-
delegate.fileBuildSettingsChanged([uri: FileBuildSettingsChange(settings)])
117-
}
99+
let settings = self.settings(for: uri)
100+
delegate.fileBuildSettingsChanged([uri: FileBuildSettingsChange(settings)])
118101
}
119102

120103
/// We don't support change watching.
121104
public func unregisterForChangeNotifications(for uri: DocumentURI) {
122-
queue.async {
123-
self.watchedFiles[uri] = nil
124-
}
105+
self.watchedFiles[uri] = nil
125106
}
126107

127-
/// Must be invoked on `queue`.
128108
private func database(for url: URL) -> CompilationDatabase? {
129-
dispatchPrecondition(condition: .onQueue(queue))
130109
if let path = try? AbsolutePath(validating: url.path) {
131110
return database(for: path)
132111
}
133112
return compdb
134113
}
135114

136-
/// Must be invoked on `queue`.
137115
private func database(for path: AbsolutePath) -> CompilationDatabase? {
138-
dispatchPrecondition(condition: .onQueue(queue))
139116
if compdb == nil {
140117
var dir = path
141118
while !dir.isRoot {
@@ -165,10 +142,7 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
165142

166143
/// The compilation database has been changed on disk.
167144
/// Reload it and notify the delegate about build setting changes.
168-
/// Must be called on `queue`.
169145
private func reloadCompilationDatabase() {
170-
dispatchPrecondition(condition: .onQueue(queue))
171-
172146
guard let projectRoot = self.projectRoot else { return }
173147

174148
self.compdb = tryLoadCompilationDatabase(directory: projectRoot, self.fileSystem)
@@ -187,31 +161,25 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
187161
}
188162

189163
public func filesDidChange(_ events: [FileEvent]) {
190-
queue.async {
191-
if events.contains(where: { self.fileEventShouldTriggerCompilationDatabaseReload(event: $0) }) {
192-
self.reloadCompilationDatabase()
193-
}
164+
if events.contains(where: { self.fileEventShouldTriggerCompilationDatabaseReload(event: $0) }) {
165+
self.reloadCompilationDatabase()
194166
}
195167
}
196168

197169
public func fileHandlingCapability(for uri: DocumentURI) -> FileHandlingCapability {
198170
guard let fileUrl = uri.fileURL else {
199171
return .unhandled
200172
}
201-
return queue.sync {
202-
if database(for: fileUrl) != nil {
203-
return .handled
204-
} else {
205-
return .unhandled
206-
}
173+
if database(for: fileUrl) != nil {
174+
return .handled
175+
} else {
176+
return .unhandled
207177
}
208178
}
209179
}
210180

211181
extension CompilationDatabaseBuildSystem {
212-
/// Must be invoked on `queue`.
213182
private func settings(for uri: DocumentURI) -> FileBuildSettings? {
214-
dispatchPrecondition(condition: .onQueue(queue))
215183
guard let url = uri.fileURL else {
216184
// We can't determine build settings for non-file URIs.
217185
return nil
@@ -225,8 +193,6 @@ extension CompilationDatabaseBuildSystem {
225193

226194
/// Exposed for *testing*.
227195
public func _settings(for uri: DocumentURI) -> FileBuildSettings? {
228-
return queue.sync {
229-
return self.settings(for: uri)
230-
}
196+
return self.settings(for: uri)
231197
}
232198
}

Tests/SKCoreTests/CompilationDatabaseTests.swift

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ final class CompilationDatabaseTests: XCTestCase {
207207
])
208208
}
209209

210-
func testCompilationDatabaseBuildSystem() throws {
211-
try checkCompilationDatabaseBuildSystem("""
210+
func testCompilationDatabaseBuildSystem() async throws {
211+
try await checkCompilationDatabaseBuildSystem("""
212212
[
213213
{
214214
"file": "/a/a.swift",
@@ -217,23 +217,23 @@ final class CompilationDatabaseTests: XCTestCase {
217217
}
218218
]
219219
""") { buildSystem in
220-
let settings = buildSystem._settings(for: DocumentURI(URL(fileURLWithPath: "/a/a.swift")))
220+
let settings = await buildSystem._settings(for: DocumentURI(URL(fileURLWithPath: "/a/a.swift")))
221221
XCTAssertNotNil(settings)
222222
XCTAssertEqual(settings?.workingDirectory, "/a")
223223
XCTAssertEqual(settings?.compilerArguments, ["-swift-version", "4", "/a/a.swift"])
224-
XCTAssertNil(buildSystem.indexStorePath)
225-
XCTAssertNil(buildSystem.indexDatabasePath)
224+
assertNil(await buildSystem.indexStorePath)
225+
assertNil(await buildSystem.indexDatabasePath)
226226
}
227227
}
228228

229-
func testCompilationDatabaseBuildSystemIndexStoreSwift0() throws {
230-
try checkCompilationDatabaseBuildSystem("[]") { buildSystem in
231-
XCTAssertNil(buildSystem.indexStorePath)
229+
func testCompilationDatabaseBuildSystemIndexStoreSwift0() async throws {
230+
try await checkCompilationDatabaseBuildSystem("[]") { buildSystem in
231+
assertNil(await buildSystem.indexStorePath)
232232
}
233233
}
234234

235-
func testCompilationDatabaseBuildSystemIndexStoreSwift1() throws {
236-
try checkCompilationDatabaseBuildSystem("""
235+
func testCompilationDatabaseBuildSystemIndexStoreSwift1() async throws {
236+
try await checkCompilationDatabaseBuildSystem("""
237237
[
238238
{
239239
"file": "/a/a.swift",
@@ -242,13 +242,13 @@ final class CompilationDatabaseTests: XCTestCase {
242242
}
243243
]
244244
""") { buildSystem in
245-
XCTAssertEqual(URL(fileURLWithPath: buildSystem.indexStorePath?.pathString ?? "").path, "/b")
246-
XCTAssertEqual(URL(fileURLWithPath: buildSystem.indexDatabasePath?.pathString ?? "").path, "/IndexDatabase")
245+
assertEqual(URL(fileURLWithPath: await buildSystem.indexStorePath?.pathString ?? "").path, "/b")
246+
assertEqual(URL(fileURLWithPath: await buildSystem.indexDatabasePath?.pathString ?? "").path, "/IndexDatabase")
247247
}
248248
}
249249

250-
func testCompilationDatabaseBuildSystemIndexStoreSwift2() throws {
251-
try checkCompilationDatabaseBuildSystem("""
250+
func testCompilationDatabaseBuildSystemIndexStoreSwift2() async throws {
251+
try await checkCompilationDatabaseBuildSystem("""
252252
[
253253
{
254254
"file": "/a/a.swift",
@@ -267,12 +267,12 @@ final class CompilationDatabaseTests: XCTestCase {
267267
}
268268
]
269269
""") { buildSystem in
270-
XCTAssertEqual(buildSystem.indexStorePath, try AbsolutePath(validating: "/b"))
270+
await assertEqual(buildSystem.indexStorePath, try AbsolutePath(validating: "/b"))
271271
}
272272
}
273273

274-
func testCompilationDatabaseBuildSystemIndexStoreSwift3() throws {
275-
try checkCompilationDatabaseBuildSystem("""
274+
func testCompilationDatabaseBuildSystemIndexStoreSwift3() async throws {
275+
try await checkCompilationDatabaseBuildSystem("""
276276
[
277277
{
278278
"file": "/a/a.swift",
@@ -281,12 +281,12 @@ final class CompilationDatabaseTests: XCTestCase {
281281
}
282282
]
283283
""") { buildSystem in
284-
XCTAssertEqual(buildSystem.indexStorePath, try AbsolutePath(validating: "/b"))
284+
assertEqual(await buildSystem.indexStorePath, try AbsolutePath(validating: "/b"))
285285
}
286286
}
287287

288-
func testCompilationDatabaseBuildSystemIndexStoreSwift4() throws {
289-
try checkCompilationDatabaseBuildSystem("""
288+
func testCompilationDatabaseBuildSystemIndexStoreSwift4() async throws {
289+
try await checkCompilationDatabaseBuildSystem("""
290290
[
291291
{
292292
"file": "/a/a.swift",
@@ -295,12 +295,12 @@ final class CompilationDatabaseTests: XCTestCase {
295295
}
296296
]
297297
""") { buildSystem in
298-
XCTAssertNil(buildSystem.indexStorePath)
298+
assertNil(await buildSystem.indexStorePath)
299299
}
300300
}
301301

302-
func testCompilationDatabaseBuildSystemIndexStoreClang() throws {
303-
try checkCompilationDatabaseBuildSystem("""
302+
func testCompilationDatabaseBuildSystemIndexStoreClang() async throws {
303+
try await checkCompilationDatabaseBuildSystem("""
304304
[
305305
{
306306
"file": "/a/a.cpp",
@@ -319,16 +319,16 @@ final class CompilationDatabaseTests: XCTestCase {
319319
}
320320
]
321321
""") { buildSystem in
322-
XCTAssertEqual(URL(fileURLWithPath: buildSystem.indexStorePath?.pathString ?? "").path, "/b")
323-
XCTAssertEqual(URL(fileURLWithPath: buildSystem.indexDatabasePath?.pathString ?? "").path, "/IndexDatabase")
322+
assertEqual(URL(fileURLWithPath: await buildSystem.indexStorePath?.pathString ?? "").path, "/b")
323+
assertEqual(URL(fileURLWithPath: await buildSystem.indexDatabasePath?.pathString ?? "").path, "/IndexDatabase")
324324
}
325325
}
326326
}
327327

328-
private func checkCompilationDatabaseBuildSystem(_ compdb: ByteString, block: (CompilationDatabaseBuildSystem) throws -> ()) throws {
328+
private func checkCompilationDatabaseBuildSystem(_ compdb: ByteString, block: (CompilationDatabaseBuildSystem) async throws -> ()) async throws {
329329
let fs = InMemoryFileSystem()
330330
try fs.createDirectory(AbsolutePath(validating: "/a"))
331331
try fs.writeFileContents(AbsolutePath(validating: "/a/compile_commands.json"), bytes: compdb)
332332
let buildSystem = CompilationDatabaseBuildSystem(projectRoot: try AbsolutePath(validating: "/a"), fileSystem: fs)
333-
try block(buildSystem)
333+
try await block(buildSystem)
334334
}

0 commit comments

Comments
 (0)