Skip to content

Commit d29e71a

Browse files
committed
Convert ManualMainFilesProvider to be an actor
1 parent f265857 commit d29e71a

File tree

3 files changed

+73
-54
lines changed

3 files changed

+73
-54
lines changed

Sources/SKCore/BuildSystemManager.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ extension BuildSystemManager {
151151
for document: DocumentURI,
152152
language: Language
153153
) async -> FileBuildSettings? {
154-
let mainFile = mainFile(for: document)
154+
let mainFile = await mainFile(for: document)
155155
guard var settings = await buildSettings(for: mainFile, language: language) else {
156156
return nil
157157
}
@@ -182,7 +182,7 @@ extension BuildSystemManager {
182182

183183
public func registerForChangeNotifications(for uri: DocumentURI, language: Language) async {
184184
logger.debug("registerForChangeNotifications(\(uri.forLogging))")
185-
let mainFile = mainFile(for: uri)
185+
let mainFile = await mainFile(for: uri)
186186
self.watchedFiles[uri] = (mainFile, language)
187187

188188
// Register for change notifications of the main file in the underlying build
@@ -274,7 +274,7 @@ extension BuildSystemManager: MainFilesDelegate {
274274
public func mainFilesChanged() async {
275275
var changedMainFileAssociations: Set<DocumentURI> = []
276276
for (file, (oldMainFile, language)) in self.watchedFiles {
277-
let newMainFile = self.mainFile(for: file, useCache: false)
277+
let newMainFile = await self.mainFile(for: file, useCache: false)
278278
if newMainFile != oldMainFile {
279279
self.watchedFiles[file] = (newMainFile, language)
280280
changedMainFileAssociations.insert(file)
@@ -303,7 +303,7 @@ extension BuildSystemManager: MainFilesDelegate {
303303
/// For Swift or normal C files, this will be the file itself. For header
304304
/// files, we pick a main file that includes the header since header files
305305
/// don't have build settings by themselves.
306-
private func mainFile(for uri: DocumentURI, useCache: Bool = true) -> DocumentURI {
306+
private func mainFile(for uri: DocumentURI, useCache: Bool = true) async -> DocumentURI {
307307
if useCache, let mainFile = self.watchedFiles[uri]?.mainFile {
308308
// Performance optimization: We did already compute the main file and have
309309
// it cached. We can just return it.
@@ -313,7 +313,7 @@ extension BuildSystemManager: MainFilesDelegate {
313313
return uri
314314
}
315315

316-
let mainFiles = mainFilesProvider.mainFilesContainingFile(uri)
316+
let mainFiles = await mainFilesProvider.mainFilesContainingFile(uri)
317317
if mainFiles.contains(uri) {
318318
// If the main files contain the file itself, prefer to use that one
319319
return uri

Sources/SKCore/MainFilesProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public protocol MainFilesProvider: AnyObject {
2323
/// mainFilesContainingFile("foo.cpp") == Set(["foo.cpp"])
2424
/// mainFilesContainingFile("foo.h") == Set(["foo.cpp", "bar.cpp"])
2525
/// ```
26-
func mainFilesContainingFile(_: DocumentURI) -> Set<DocumentURI>
26+
func mainFilesContainingFile(_: DocumentURI) async -> Set<DocumentURI>
2727
}
2828

2929
/// Delegate that responds to possible main file changes.

Tests/SKCoreTests/BuildSystemManagerTests.swift

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ final class BuildSystemManagerTests: XCTestCase {
2525
let c = DocumentURI(string: "bsm:c")
2626
let d = DocumentURI(string: "bsm:d")
2727

28-
let mainFiles = ManualMainFilesProvider()
29-
mainFiles.mainFiles = [
30-
a: Set([c]),
31-
b: Set([c, d]),
32-
c: Set([c]),
33-
d: Set([d]),
34-
]
28+
let mainFiles = ManualMainFilesProvider(
29+
mainFiles:[
30+
a: Set([c]),
31+
b: Set([c, d]),
32+
c: Set([c]),
33+
d: Set([d]),
34+
]
35+
)
3536

3637
let bsm = await BuildSystemManager(
3738
buildSystem: nil,
@@ -55,13 +56,15 @@ final class BuildSystemManagerTests: XCTestCase {
5556
await assertEqual(bsm._cachedMainFile(for: c), c)
5657
await assertEqual(bsm._cachedMainFile(for: d), d)
5758

58-
mainFiles.mainFiles = [
59-
a: Set([a]),
60-
b: Set([c, d, a]),
61-
c: Set([c]),
62-
d: Set([d]),
63-
]
64-
59+
await mainFiles.setMainFiles(
60+
mainFiles: [
61+
a: Set([a]),
62+
b: Set([c, d, a]),
63+
c: Set([c]),
64+
d: Set([d]),
65+
]
66+
)
67+
6568
await assertEqual(bsm._cachedMainFile(for: a), c)
6669
await assertEqual(bsm._cachedMainFile(for: b), bMain)
6770
await assertEqual(bsm._cachedMainFile(for: c), c)
@@ -92,8 +95,7 @@ final class BuildSystemManagerTests: XCTestCase {
9295

9396
func testSettingsMainFile() async throws {
9497
let a = DocumentURI(string: "bsm:a.swift")
95-
let mainFiles = ManualMainFilesProvider()
96-
mainFiles.mainFiles = [a: Set([a])]
98+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a])])
9799
let bs = ManualBuildSystem()
98100
let bsm = await BuildSystemManager(
99101
buildSystem: bs,
@@ -116,8 +118,7 @@ final class BuildSystemManagerTests: XCTestCase {
116118

117119
func testSettingsMainFileInitialNil() async throws {
118120
let a = DocumentURI(string: "bsm:a.swift")
119-
let mainFiles = ManualMainFilesProvider()
120-
mainFiles.mainFiles = [a: Set([a])]
121+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a])])
121122
let bs = ManualBuildSystem()
122123
let bsm = await BuildSystemManager(
123124
buildSystem: bs,
@@ -138,8 +139,7 @@ final class BuildSystemManagerTests: XCTestCase {
138139

139140
func testSettingsMainFileWithFallback() async throws {
140141
let a = DocumentURI(string: "bsm:a.swift")
141-
let mainFiles = ManualMainFilesProvider()
142-
mainFiles.mainFiles = [a: Set([a])]
142+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a])])
143143
let bs = ManualBuildSystem()
144144
let fallback = FallbackBuildSystem(buildSetup: .default)
145145
let bsm = await BuildSystemManager(
@@ -169,8 +169,7 @@ final class BuildSystemManagerTests: XCTestCase {
169169
func testSettingsMainFileInitialIntersect() async throws {
170170
let a = DocumentURI(string: "bsm:a.swift")
171171
let b = DocumentURI(string: "bsm:b.swift")
172-
let mainFiles = ManualMainFilesProvider()
173-
mainFiles.mainFiles = [a: Set([a]), b: Set([b])]
172+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a]), b: Set([b])])
174173
let bs = ManualBuildSystem()
175174
let bsm = await BuildSystemManager(
176175
buildSystem: bs,
@@ -210,8 +209,7 @@ final class BuildSystemManagerTests: XCTestCase {
210209
func testSettingsMainFileUnchanged() async throws {
211210
let a = DocumentURI(string: "bsm:a.swift")
212211
let b = DocumentURI(string: "bsm:b.swift")
213-
let mainFiles = ManualMainFilesProvider()
214-
mainFiles.mainFiles = [a: Set([a]), b: Set([b])]
212+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a]), b: Set([b])])
215213
let bs = ManualBuildSystem()
216214
let bsm = await BuildSystemManager(
217215
buildSystem: bs,
@@ -242,12 +240,13 @@ final class BuildSystemManagerTests: XCTestCase {
242240
let h = DocumentURI(string: "bsm:header.h")
243241
let cpp1 = DocumentURI(string: "bsm:main.cpp")
244242
let cpp2 = DocumentURI(string: "bsm:other.cpp")
245-
let mainFiles = ManualMainFilesProvider()
246-
mainFiles.mainFiles = [
243+
let mainFiles = ManualMainFilesProvider(
244+
mainFiles: [
247245
h: Set([cpp1]),
248-
cpp1: Set([cpp1]),
249-
cpp2: Set([cpp2]),
250-
]
246+
cpp1: Set([cpp1]),
247+
cpp2: Set([cpp2]),
248+
]
249+
)
251250

252251
let bs = ManualBuildSystem()
253252
let bsm = await BuildSystemManager(
@@ -264,7 +263,13 @@ final class BuildSystemManagerTests: XCTestCase {
264263
await bsm.registerForChangeNotifications(for: h, language: .c)
265264
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h, language: .c), bs.map[cpp1]!)
266265

267-
mainFiles.mainFiles[h] = Set([cpp2])
266+
await mainFiles.setMainFiles(
267+
mainFiles: [
268+
h: Set([cpp2]),
269+
cpp1: Set([cpp1]),
270+
cpp2: Set([cpp2]),
271+
]
272+
)
268273

269274
let changed = expectation(description: "changed settings to cpp2")
270275
await del.setExpected([(h, .c, bs.map[cpp2]!, changed, #file, #line)])
@@ -277,14 +282,26 @@ final class BuildSystemManagerTests: XCTestCase {
277282
await bsm.mainFilesChanged()
278283
try await fulfillmentOfOrThrow([changed2], timeout: 1)
279284

280-
mainFiles.mainFiles[h] = Set([cpp1, cpp2])
285+
await mainFiles.setMainFiles(
286+
mainFiles: [
287+
h: Set([cpp1, cpp2]),
288+
cpp1: Set([cpp1]),
289+
cpp2: Set([cpp2]),
290+
]
291+
)
281292

282293
let changed3 = expectation(description: "added lexicographically earlier main file")
283294
await del.setExpected([(h, .c, bs.map[cpp1]!, changed3, #file, #line)])
284295
await bsm.mainFilesChanged()
285296
try await fulfillmentOfOrThrow([changed3], timeout: 1)
286297

287-
mainFiles.mainFiles[h] = Set([])
298+
await mainFiles.setMainFiles(
299+
mainFiles: [
300+
h: Set([]),
301+
cpp1: Set([cpp1]),
302+
cpp2: Set([cpp2]),
303+
]
304+
)
288305

289306
let changed4 = expectation(description: "changed settings to []")
290307
await del.setExpected([(h, .c, nil, changed4, #file, #line)])
@@ -296,11 +313,12 @@ final class BuildSystemManagerTests: XCTestCase {
296313
let h1 = DocumentURI(string: "bsm:header1.h")
297314
let h2 = DocumentURI(string: "bsm:header2.h")
298315
let cpp = DocumentURI(string: "bsm:main.cpp")
299-
let mainFiles = ManualMainFilesProvider()
300-
mainFiles.mainFiles = [
301-
h1: Set([cpp]),
302-
h2: Set([cpp]),
303-
]
316+
let mainFiles = ManualMainFilesProvider(
317+
mainFiles: [
318+
h1: Set([cpp]),
319+
h2: Set([cpp]),
320+
]
321+
)
304322

305323
let bs = ManualBuildSystem()
306324
let bsm = await BuildSystemManager(
@@ -342,8 +360,7 @@ final class BuildSystemManagerTests: XCTestCase {
342360
let a = DocumentURI(string: "bsm:a.swift")
343361
let b = DocumentURI(string: "bsm:b.swift")
344362
let c = DocumentURI(string: "bsm:c.swift")
345-
let mainFiles = ManualMainFilesProvider()
346-
mainFiles.mainFiles = [a: Set([a]), b: Set([b]), c: Set([c])]
363+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a]), b: Set([b]), c: Set([c])])
347364
let bs = ManualBuildSystem()
348365
let bsm = await BuildSystemManager(
349366
buildSystem: bs,
@@ -384,8 +401,7 @@ final class BuildSystemManagerTests: XCTestCase {
384401

385402
func testDependenciesUpdated() async throws {
386403
let a = DocumentURI(string: "bsm:a.swift")
387-
let mainFiles = ManualMainFilesProvider()
388-
mainFiles.mainFiles = [a: Set([a])]
404+
let mainFiles = ManualMainFilesProvider(mainFiles: [a: Set([a])])
389405

390406
let bs = ManualBuildSystem()
391407
let bsm = await BuildSystemManager(
@@ -412,15 +428,18 @@ final class BuildSystemManagerTests: XCTestCase {
412428
// MARK: Helper Classes for Testing
413429

414430
/// A simple `MainFilesProvider` that wraps a dictionary, for testing.
415-
private final class ManualMainFilesProvider: MainFilesProvider {
416-
let lock: DispatchQueue = DispatchQueue(label: "\(ManualMainFilesProvider.self)-lock")
417-
private var _mainFiles: [DocumentURI: Set<DocumentURI>] = [:]
418-
var mainFiles: [DocumentURI: Set<DocumentURI>] {
419-
get { lock.sync { _mainFiles } }
420-
set { lock.sync { _mainFiles = newValue } }
431+
private final actor ManualMainFilesProvider: MainFilesProvider {
432+
private var mainFiles: [DocumentURI: Set<DocumentURI>]
433+
434+
init(mainFiles: [DocumentURI: Set<DocumentURI>]) {
435+
self.mainFiles = mainFiles
436+
}
437+
438+
func setMainFiles(mainFiles: [DocumentURI: Set<DocumentURI>]) async {
439+
self.mainFiles = mainFiles
421440
}
422441

423-
func mainFilesContainingFile(_ file: DocumentURI) -> Set<DocumentURI> {
442+
func mainFilesContainingFile(_ file: DocumentURI) async -> Set<DocumentURI> {
424443
if let result = mainFiles[file] {
425444
return result
426445
}

0 commit comments

Comments
 (0)