@@ -25,7 +25,9 @@ public final class SwiftGenerator {
25
25
private let version : String
26
26
27
27
private let swiftlintDisableAll : Bool
28
-
28
+
29
+ private let mainActor : Bool
30
+
29
31
public typealias ImportFilter = ( String ) -> Bool
30
32
private let importFilter : ImportFilter
31
33
@@ -36,6 +38,7 @@ public final class SwiftGenerator {
36
38
version: String ,
37
39
testableImports: [ String ] ? ,
38
40
swiftlintDisableAll: Bool ,
41
+ mainActor: Bool ,
39
42
importFilter: @escaping ImportFilter ) throws {
40
43
41
44
self . dependencyGraph = dependencyGraph
@@ -45,6 +48,7 @@ public final class SwiftGenerator {
45
48
self . version = version
46
49
self . testableImports = testableImports? . filter ( importFilter)
47
50
self . swiftlintDisableAll = swiftlintDisableAll
51
+ self . mainActor = mainActor
48
52
self . importFilter = importFilter
49
53
}
50
54
@@ -69,6 +73,7 @@ public final class SwiftGenerator {
69
73
dependencyGraph,
70
74
inspector,
71
75
objcPrefix,
76
+ mainActor,
72
77
version,
73
78
testableImports,
74
79
swiftlintDisableAll,
@@ -208,7 +213,9 @@ private final class MetaWeaverFile {
208
213
private let testableImports : [ String ] ?
209
214
210
215
private let swiftlintDisableAll : Bool
211
-
216
+
217
+ private let mainActor : Bool
218
+
212
219
private let importFilter : SwiftGenerator . ImportFilter
213
220
214
221
// Pre computed data
@@ -233,6 +240,7 @@ private final class MetaWeaverFile {
233
240
init ( _ dependencyGraph: DependencyGraph ,
234
241
_ inspector: Inspector ,
235
242
_ objcPrefix: String ? ,
243
+ _ mainActor: Bool ,
236
244
_ version: String ,
237
245
_ testableImports: [ String ] ? ,
238
246
_ swiftlintDisableAll: Bool ,
@@ -241,6 +249,7 @@ private final class MetaWeaverFile {
241
249
self . dependencyGraph = dependencyGraph
242
250
self . inspector = inspector
243
251
self . objcPrefix = objcPrefix
252
+ self . mainActor = mainActor
244
253
self . version = version
245
254
self . testableImports = testableImports
246
255
self . swiftlintDisableAll = swiftlintDisableAll
@@ -312,7 +321,7 @@ private final class MetaWeaverFile {
312
321
dependencyResolverProxies ( ) ,
313
322
publicDependencyInitExtensions ( ) ,
314
323
propertyWrappers ( ) ,
315
- providerClassAndFunctions ( )
324
+ mainActor == true ? providerClassAndFunctionsMainActor ( ) : providerClassAndFunctions ( )
316
325
] . flatMap { $0 }
317
326
}
318
327
@@ -345,21 +354,40 @@ private final class MetaWeaverFile {
345
354
private extension MetaWeaverFile {
346
355
347
356
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
349
364
. with ( objc: doesSupportObjc, prefix: objcPrefix)
350
365
. adding ( inheritedType: doesSupportObjc ? . nsObject : nil )
351
366
. adding ( member: EmptyLine ( ) )
352
367
. adding ( member: Property ( variable: Variable ( name: " provider " ) . with ( immutable: true ) . with ( type: . provider) ) . with ( accessLevel: . private) )
353
368
. 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 ) )
355
381
. with ( accessLevel: . fileprivate)
356
382
. adding ( parameter: FunctionParameter ( name: " provider " , type: . provider) . with ( defaultValue: TypeIdentifier . provider. reference | . call( ) ) )
357
383
. adding ( members: [
358
384
Assignment ( variable: Reference . named ( . `self`) + . named( " provider " ) , value: Reference . named ( " provider " ) ) ,
359
385
( doesSupportObjc ? Reference . named ( . super) + . named( " init " ) | . call( ) : . none)
360
386
] )
361
387
)
362
- . adding ( member: dependencyGraph. hasPropertyWrapperAnnotations ? PlainCode ( code: """
388
+ }
389
+
390
+ type = type. adding ( member: dependencyGraph. hasPropertyWrapperAnnotations ? PlainCode ( code: """
363
391
364
392
private static var _dynamicResolvers = [Any]()
365
393
private static var _dynamicResolversLock = NSRecursiveLock()
@@ -392,6 +420,7 @@ static func _pushDynamicResolver<Resolver>(_ resolver: Resolver) {
392
420
. adding ( members: try resolversImplementation ( ) )
393
421
. adding ( members: settersImplementation ( ) )
394
422
. adding ( members: try dependencyResolverCopyMethods ( ) )
423
+ return type
395
424
}
396
425
397
426
func propertyWrappers( ) throws -> [ FileBodyMember ] {
@@ -1305,6 +1334,109 @@ private extension MetaWeaverFile {
1305
1334
}
1306
1335
}
1307
1336
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
+
1308
1440
func providerClassAndFunctions( ) throws -> [ FileBodyMember ] {
1309
1441
return [
1310
1442
EmptyLine ( ) ,
0 commit comments