Skip to content

Commit 70d6eab

Browse files
authored
Merge pull request #183 from rjchrhl/rjc-mainactor
Swift Concurrency Part 4 - Weaver --mainactor (command line option)
2 parents 69f50d6 + cfa0abf commit 70d6eab

File tree

7 files changed

+160
-45
lines changed

7 files changed

+160
-45
lines changed

.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.8
1+
1.1.6

Makefile

+1-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ SWIFT_BUILD_FLAGS=--configuration release
44

55
.PHONY: clean build install package codecov
66

7-
init:
8-
@swift package generate-xcodeproj
9-
107
build:
118
@swift build --disable-sandbox $(SWIFT_BUILD_FLAGS)
129

@@ -36,4 +33,4 @@ codecov: build
3633
define install_files
3734
install -d $(1)/bin
3835
install -C .build/release/Weaver $(1)/bin/weaver
39-
endef
36+
endef

Package.resolved

+13-31
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,12 @@
1919
"version": "0.9.1"
2020
}
2121
},
22-
{
23-
"package": "CwlCatchException",
24-
"repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
25-
"state": {
26-
"branch": null,
27-
"revision": "7cd2f8cacc4d22f21bc0b2309c3b18acf7957b66",
28-
"version": "1.2.0"
29-
}
30-
},
31-
{
32-
"package": "CwlPreconditionTesting",
33-
"repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
34-
"state": {
35-
"branch": null,
36-
"revision": "c228db5d2ad1b01ebc84435e823e6cca4e3db98b",
37-
"version": "1.2.0"
38-
}
39-
},
4022
{
4123
"package": "Meta",
4224
"repositoryURL": "https://github.com/scribd/Meta.git",
4325
"state": {
4426
"branch": "master",
45-
"revision": "ac1103cdc06d31cee65d8b802f21a45e00271a18",
27+
"revision": "2fe6f60b10363515ac12f166567ed766dc276fcc",
4628
"version": null
4729
}
4830
},
@@ -51,8 +33,8 @@
5133
"repositoryURL": "https://github.com/Quick/Nimble.git",
5234
"state": {
5335
"branch": null,
54-
"revision": "b02b00b30b6353632aa4a5fb6124f8147f7140c0",
55-
"version": "8.0.5"
36+
"revision": "7a46a5fc86cb917f69e3daf79fcb045283d8f008",
37+
"version": "8.1.2"
5638
}
5739
},
5840
{
@@ -69,26 +51,26 @@
6951
"repositoryURL": "https://github.com/Quick/Quick.git",
7052
"state": {
7153
"branch": null,
72-
"revision": "33682c2f6230c60614861dfc61df267e11a1602f",
73-
"version": "2.2.0"
54+
"revision": "09b3becb37cb2163919a3842a4c5fa6ec7130792",
55+
"version": "2.2.1"
7456
}
7557
},
7658
{
7759
"package": "Rainbow",
7860
"repositoryURL": "https://github.com/onevcat/Rainbow",
7961
"state": {
8062
"branch": null,
81-
"revision": "9c52c1952e9b2305d4507cf473392ac2d7c9b155",
82-
"version": "3.1.5"
63+
"revision": "626c3d4b6b55354b4af3aa309f998fae9b31a3d9",
64+
"version": "3.2.0"
8365
}
8466
},
8567
{
8668
"package": "ShellOut",
8769
"repositoryURL": "https://github.com/JohnSundell/ShellOut.git",
8870
"state": {
8971
"branch": null,
90-
"revision": "4ebf25863deb9c3c02696704fc3d39736183f258",
91-
"version": "2.2.1"
72+
"revision": "e1577acf2b6e90086d01a6d5e2b8efdaae033568",
73+
"version": "2.3.0"
9274
}
9375
},
9476
{
@@ -105,17 +87,17 @@
10587
"repositoryURL": "https://github.com/kylef/Spectre.git",
10688
"state": {
10789
"branch": null,
108-
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
109-
"version": "0.9.0"
90+
"revision": "f79d4ecbf8bc4e1579fbd86c3e1d652fb6876c53",
91+
"version": "0.9.2"
11092
}
11193
},
11294
{
11395
"package": "SWXMLHash",
11496
"repositoryURL": "https://github.com/drmohundro/SWXMLHash.git",
11597
"state": {
11698
"branch": null,
117-
"revision": "a4931e5c3bafbedeb1601d3bb76bbe835c6d475a",
118-
"version": "5.0.1"
99+
"revision": "9183170d20857753d4f331b0ca63f73c60764bf3",
100+
"version": "5.0.2"
119101
}
120102
},
121103
{

Sample/API/Generated/Weaver.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22
import UIKit
33

44
// swiftlint:disable all
5-
/// This file is generated by Weaver 1.1.5
5+
/// This file is generated by Weaver 1.1.6
66
/// DO NOT EDIT!
77

88
final class MainDependencyContainer {

Sample/Sample/Generated/Weaver.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Foundation
33
import UIKit
44

55
// swiftlint:disable all
6-
/// This file is generated by Weaver 1.1.5
6+
/// This file is generated by Weaver 1.1.6
77
/// DO NOT EDIT!
88

99
@objc(SampleIOSMainDependencyContainer)

Sources/WeaverCodeGen/SwiftGenerator.swift

+138-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ public final class SwiftGenerator {
2525
private let version: String
2626

2727
private let swiftlintDisableAll: Bool
28-
28+
29+
private let mainActor: Bool
30+
2931
public typealias ImportFilter = (String) -> Bool
3032
private let importFilter: ImportFilter
3133

@@ -36,6 +38,7 @@ public final class SwiftGenerator {
3638
version: String,
3739
testableImports: [String]?,
3840
swiftlintDisableAll: Bool,
41+
mainActor: Bool,
3942
importFilter: @escaping ImportFilter) throws {
4043

4144
self.dependencyGraph = dependencyGraph
@@ -45,6 +48,7 @@ public final class SwiftGenerator {
4548
self.version = version
4649
self.testableImports = testableImports?.filter(importFilter)
4750
self.swiftlintDisableAll = swiftlintDisableAll
51+
self.mainActor = mainActor
4852
self.importFilter = importFilter
4953
}
5054

@@ -69,6 +73,7 @@ public final class SwiftGenerator {
6973
dependencyGraph,
7074
inspector,
7175
objcPrefix,
76+
mainActor,
7277
version,
7378
testableImports,
7479
swiftlintDisableAll,
@@ -208,7 +213,9 @@ private final class MetaWeaverFile {
208213
private let testableImports: [String]?
209214

210215
private let swiftlintDisableAll: Bool
211-
216+
217+
private let mainActor: Bool
218+
212219
private let importFilter: SwiftGenerator.ImportFilter
213220

214221
// Pre computed data
@@ -233,6 +240,7 @@ private final class MetaWeaverFile {
233240
init(_ dependencyGraph: DependencyGraph,
234241
_ inspector: Inspector,
235242
_ objcPrefix: String?,
243+
_ mainActor: Bool,
236244
_ version: String,
237245
_ testableImports: [String]?,
238246
_ swiftlintDisableAll: Bool,
@@ -241,6 +249,7 @@ private final class MetaWeaverFile {
241249
self.dependencyGraph = dependencyGraph
242250
self.inspector = inspector
243251
self.objcPrefix = objcPrefix
252+
self.mainActor = mainActor
244253
self.version = version
245254
self.testableImports = testableImports
246255
self.swiftlintDisableAll = swiftlintDisableAll
@@ -312,7 +321,7 @@ private final class MetaWeaverFile {
312321
dependencyResolverProxies(),
313322
publicDependencyInitExtensions(),
314323
propertyWrappers(),
315-
providerClassAndFunctions()
324+
mainActor == true ? providerClassAndFunctionsMainActor() : providerClassAndFunctions()
316325
].flatMap { $0 }
317326
}
318327

@@ -345,21 +354,40 @@ private final class MetaWeaverFile {
345354
private extension MetaWeaverFile {
346355

347356
func mainDependencyContainer() throws -> Type {
348-
return Type(identifier: .mainDependencyContainer)
357+
var type = Type(identifier: .mainDependencyContainer)
358+
359+
if self.mainActor == true {
360+
type = type.with(actorName: "MainActor")
361+
}
362+
363+
type = type
349364
.with(objc: doesSupportObjc, prefix: objcPrefix)
350365
.adding(inheritedType: doesSupportObjc ? .nsObject : nil)
351366
.adding(member: EmptyLine())
352367
.adding(member: Property(variable: Variable(name: "provider").with(immutable: true).with(type: .provider)).with(accessLevel: .private))
353368
.adding(member: EmptyLine())
354-
.adding(member: Function(kind: .`init`(convenience: false, optional: false))
369+
370+
371+
if self.mainActor == true {
372+
373+
type = type.adding(member: PlainCode(code: """
374+
fileprivate init(provider: Provider? = nil) {
375+
self.provider = provider ?? Provider()
376+
}
377+
"""))
378+
379+
} else {
380+
type = type.adding(member: Function(kind: .`init`(convenience: false, optional: false))
355381
.with(accessLevel: .fileprivate)
356382
.adding(parameter: FunctionParameter(name: "provider", type: .provider).with(defaultValue: TypeIdentifier.provider.reference | .call()))
357383
.adding(members: [
358384
Assignment(variable: Reference.named(.`self`) + .named("provider"), value: Reference.named("provider")),
359385
(doesSupportObjc ? Reference.named(.super) + .named("init") | .call() : .none)
360386
])
361387
)
362-
.adding(member: dependencyGraph.hasPropertyWrapperAnnotations ? PlainCode(code: """
388+
}
389+
390+
type = type.adding(member: dependencyGraph.hasPropertyWrapperAnnotations ? PlainCode(code: """
363391
364392
private static var _dynamicResolvers = [Any]()
365393
private static var _dynamicResolversLock = NSRecursiveLock()
@@ -392,6 +420,7 @@ static func _pushDynamicResolver<Resolver>(_ resolver: Resolver) {
392420
.adding(members: try resolversImplementation())
393421
.adding(members: settersImplementation())
394422
.adding(members: try dependencyResolverCopyMethods())
423+
return type
395424
}
396425

397426
func propertyWrappers() throws -> [FileBodyMember] {
@@ -1305,6 +1334,109 @@ private extension MetaWeaverFile {
13051334
}
13061335
}
13071336

1337+
func providerClassAndFunctionsMainActor() throws -> [FileBodyMember] {
1338+
return [
1339+
EmptyLine(),
1340+
PlainCode(code: """
1341+
// MARK: - Fatal Error
1342+
1343+
extension MainDependencyContainer {
1344+
1345+
static var onFatalError: (String, StaticString, UInt) -> Never = { message, file, line in
1346+
Swift.fatalError(message, file: file, line: line)
1347+
}
1348+
1349+
fileprivate static func fatalError(file: StaticString = #file, line: UInt = #line) -> Never {
1350+
onFatalError("Invalid memory graph. This is never suppose to happen. Please file a ticket at https://github.com/scribd/Weaver", file, line)
1351+
}
1352+
}
1353+
1354+
// MARK: - Provider
1355+
1356+
@MainActor private final class Provider {
1357+
1358+
typealias ParametersCopier = (Provider) -> Void
1359+
typealias Builder<T> = (ParametersCopier?) -> T
1360+
1361+
private(set) var builders: Dictionary<String, Any>
1362+
1363+
init(builders: Dictionary<String, Any> = [:]) {
1364+
self.builders = builders
1365+
}
1366+
}
1367+
1368+
@MainActor private extension Provider {
1369+
1370+
func addBuilders(_ builders: Dictionary<String, Any>) {
1371+
builders.forEach { key, value in
1372+
self.builders[key] = value
1373+
}
1374+
}
1375+
1376+
func setBuilder<T>(_ name: String, _ builder: @escaping Builder<T>) {
1377+
builders[name] = builder
1378+
}
1379+
1380+
func getBuilder<T>(_ name: String, _ type: T.Type) -> Builder<T> {
1381+
guard let builder = builders[name] as? Builder<T> else {
1382+
return Provider.fatalBuilder()
1383+
}
1384+
return builder
1385+
}
1386+
1387+
func copy() -> Provider {
1388+
return Provider(builders: builders)
1389+
}
1390+
}
1391+
1392+
private extension Provider {
1393+
1394+
static func valueBuilder<T>(_ value: T) -> Builder<T> {
1395+
return { _ in
1396+
return value
1397+
}
1398+
}
1399+
1400+
static func weakOptionalValueBuilder<T>(_ value: Optional<T>) -> Builder<Optional<T>> where T: AnyObject {
1401+
return { [weak value] _ in
1402+
return value
1403+
}
1404+
}
1405+
1406+
static func lazyBuilder<T>(_ builder: @escaping Builder<T>) -> Builder<T> {
1407+
var _value: T?
1408+
return { copyParameters in
1409+
if let value = _value {
1410+
return value
1411+
}
1412+
let value = builder(copyParameters)
1413+
_value = value
1414+
return value
1415+
}
1416+
}
1417+
1418+
static func weakLazyBuilder<T>(_ builder: @escaping Builder<T>) -> Builder<T> where T: AnyObject {
1419+
weak var _value: T?
1420+
return { copyParameters in
1421+
if let value = _value {
1422+
return value
1423+
}
1424+
let value = builder(copyParameters)
1425+
_value = value
1426+
return value
1427+
}
1428+
}
1429+
1430+
@MainActor static func fatalBuilder<T>() -> Builder<T> {
1431+
return { _ in
1432+
MainDependencyContainer.fatalError()
1433+
}
1434+
}
1435+
}
1436+
""")
1437+
]
1438+
}
1439+
13081440
func providerClassAndFunctions() throws -> [FileBodyMember] {
13091441
return [
13101442
EmptyLine(),

0 commit comments

Comments
 (0)