Skip to content

Commit

Permalink
Merge pull request #183 from rjchrhl/rjc-mainactor
Browse files Browse the repository at this point in the history
Swift Concurrency Part 4 - Weaver --mainactor (command line option)
  • Loading branch information
rjchrhl authored Sep 27, 2024
2 parents 69f50d6 + cfa0abf commit 70d6eab
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 45 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.8
1.1.6
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ SWIFT_BUILD_FLAGS=--configuration release

.PHONY: clean build install package codecov

init:
@swift package generate-xcodeproj

build:
@swift build --disable-sandbox $(SWIFT_BUILD_FLAGS)

Expand Down Expand Up @@ -36,4 +33,4 @@ codecov: build
define install_files
install -d $(1)/bin
install -C .build/release/Weaver $(1)/bin/weaver
endef
endef
44 changes: 13 additions & 31 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,12 @@
"version": "0.9.1"
}
},
{
"package": "CwlCatchException",
"repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
"state": {
"branch": null,
"revision": "7cd2f8cacc4d22f21bc0b2309c3b18acf7957b66",
"version": "1.2.0"
}
},
{
"package": "CwlPreconditionTesting",
"repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
"state": {
"branch": null,
"revision": "c228db5d2ad1b01ebc84435e823e6cca4e3db98b",
"version": "1.2.0"
}
},
{
"package": "Meta",
"repositoryURL": "https://github.com/scribd/Meta.git",
"state": {
"branch": "master",
"revision": "ac1103cdc06d31cee65d8b802f21a45e00271a18",
"revision": "2fe6f60b10363515ac12f166567ed766dc276fcc",
"version": null
}
},
Expand All @@ -51,8 +33,8 @@
"repositoryURL": "https://github.com/Quick/Nimble.git",
"state": {
"branch": null,
"revision": "b02b00b30b6353632aa4a5fb6124f8147f7140c0",
"version": "8.0.5"
"revision": "7a46a5fc86cb917f69e3daf79fcb045283d8f008",
"version": "8.1.2"
}
},
{
Expand All @@ -69,26 +51,26 @@
"repositoryURL": "https://github.com/Quick/Quick.git",
"state": {
"branch": null,
"revision": "33682c2f6230c60614861dfc61df267e11a1602f",
"version": "2.2.0"
"revision": "09b3becb37cb2163919a3842a4c5fa6ec7130792",
"version": "2.2.1"
}
},
{
"package": "Rainbow",
"repositoryURL": "https://github.com/onevcat/Rainbow",
"state": {
"branch": null,
"revision": "9c52c1952e9b2305d4507cf473392ac2d7c9b155",
"version": "3.1.5"
"revision": "626c3d4b6b55354b4af3aa309f998fae9b31a3d9",
"version": "3.2.0"
}
},
{
"package": "ShellOut",
"repositoryURL": "https://github.com/JohnSundell/ShellOut.git",
"state": {
"branch": null,
"revision": "4ebf25863deb9c3c02696704fc3d39736183f258",
"version": "2.2.1"
"revision": "e1577acf2b6e90086d01a6d5e2b8efdaae033568",
"version": "2.3.0"
}
},
{
Expand All @@ -105,17 +87,17 @@
"repositoryURL": "https://github.com/kylef/Spectre.git",
"state": {
"branch": null,
"revision": "f14ff47f45642aa5703900980b014c2e9394b6e5",
"version": "0.9.0"
"revision": "f79d4ecbf8bc4e1579fbd86c3e1d652fb6876c53",
"version": "0.9.2"
}
},
{
"package": "SWXMLHash",
"repositoryURL": "https://github.com/drmohundro/SWXMLHash.git",
"state": {
"branch": null,
"revision": "a4931e5c3bafbedeb1601d3bb76bbe835c6d475a",
"version": "5.0.1"
"revision": "9183170d20857753d4f331b0ca63f73c60764bf3",
"version": "5.0.2"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Sample/API/Generated/Weaver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import UIKit

// swiftlint:disable all
/// This file is generated by Weaver 1.1.5
/// This file is generated by Weaver 1.1.6
/// DO NOT EDIT!

final class MainDependencyContainer {
Expand Down
2 changes: 1 addition & 1 deletion Sample/Sample/Generated/Weaver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
import UIKit

// swiftlint:disable all
/// This file is generated by Weaver 1.1.5
/// This file is generated by Weaver 1.1.6
/// DO NOT EDIT!

@objc(SampleIOSMainDependencyContainer)
Expand Down
144 changes: 138 additions & 6 deletions Sources/WeaverCodeGen/SwiftGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public final class SwiftGenerator {
private let version: String

private let swiftlintDisableAll: Bool


private let mainActor: Bool

public typealias ImportFilter = (String) -> Bool
private let importFilter: ImportFilter

Expand All @@ -36,6 +38,7 @@ public final class SwiftGenerator {
version: String,
testableImports: [String]?,
swiftlintDisableAll: Bool,
mainActor: Bool,
importFilter: @escaping ImportFilter) throws {

self.dependencyGraph = dependencyGraph
Expand All @@ -45,6 +48,7 @@ public final class SwiftGenerator {
self.version = version
self.testableImports = testableImports?.filter(importFilter)
self.swiftlintDisableAll = swiftlintDisableAll
self.mainActor = mainActor
self.importFilter = importFilter
}

Expand All @@ -69,6 +73,7 @@ public final class SwiftGenerator {
dependencyGraph,
inspector,
objcPrefix,
mainActor,
version,
testableImports,
swiftlintDisableAll,
Expand Down Expand Up @@ -208,7 +213,9 @@ private final class MetaWeaverFile {
private let testableImports: [String]?

private let swiftlintDisableAll: Bool


private let mainActor: Bool

private let importFilter: SwiftGenerator.ImportFilter

// Pre computed data
Expand All @@ -233,6 +240,7 @@ private final class MetaWeaverFile {
init(_ dependencyGraph: DependencyGraph,
_ inspector: Inspector,
_ objcPrefix: String?,
_ mainActor: Bool,
_ version: String,
_ testableImports: [String]?,
_ swiftlintDisableAll: Bool,
Expand All @@ -241,6 +249,7 @@ private final class MetaWeaverFile {
self.dependencyGraph = dependencyGraph
self.inspector = inspector
self.objcPrefix = objcPrefix
self.mainActor = mainActor
self.version = version
self.testableImports = testableImports
self.swiftlintDisableAll = swiftlintDisableAll
Expand Down Expand Up @@ -312,7 +321,7 @@ private final class MetaWeaverFile {
dependencyResolverProxies(),
publicDependencyInitExtensions(),
propertyWrappers(),
providerClassAndFunctions()
mainActor == true ? providerClassAndFunctionsMainActor() : providerClassAndFunctions()
].flatMap { $0 }
}

Expand Down Expand Up @@ -345,21 +354,40 @@ private final class MetaWeaverFile {
private extension MetaWeaverFile {

func mainDependencyContainer() throws -> Type {
return Type(identifier: .mainDependencyContainer)
var type = Type(identifier: .mainDependencyContainer)

if self.mainActor == true {
type = type.with(actorName: "MainActor")
}

type = type
.with(objc: doesSupportObjc, prefix: objcPrefix)
.adding(inheritedType: doesSupportObjc ? .nsObject : nil)
.adding(member: EmptyLine())
.adding(member: Property(variable: Variable(name: "provider").with(immutable: true).with(type: .provider)).with(accessLevel: .private))
.adding(member: EmptyLine())
.adding(member: Function(kind: .`init`(convenience: false, optional: false))


if self.mainActor == true {

type = type.adding(member: PlainCode(code: """
fileprivate init(provider: Provider? = nil) {
self.provider = provider ?? Provider()
}
"""))

} else {
type = type.adding(member: Function(kind: .`init`(convenience: false, optional: false))
.with(accessLevel: .fileprivate)
.adding(parameter: FunctionParameter(name: "provider", type: .provider).with(defaultValue: TypeIdentifier.provider.reference | .call()))
.adding(members: [
Assignment(variable: Reference.named(.`self`) + .named("provider"), value: Reference.named("provider")),
(doesSupportObjc ? Reference.named(.super) + .named("init") | .call() : .none)
])
)
.adding(member: dependencyGraph.hasPropertyWrapperAnnotations ? PlainCode(code: """
}

type = type.adding(member: dependencyGraph.hasPropertyWrapperAnnotations ? PlainCode(code: """
private static var _dynamicResolvers = [Any]()
private static var _dynamicResolversLock = NSRecursiveLock()
Expand Down Expand Up @@ -392,6 +420,7 @@ static func _pushDynamicResolver<Resolver>(_ resolver: Resolver) {
.adding(members: try resolversImplementation())
.adding(members: settersImplementation())
.adding(members: try dependencyResolverCopyMethods())
return type
}

func propertyWrappers() throws -> [FileBodyMember] {
Expand Down Expand Up @@ -1305,6 +1334,109 @@ private extension MetaWeaverFile {
}
}

func providerClassAndFunctionsMainActor() throws -> [FileBodyMember] {
return [
EmptyLine(),
PlainCode(code: """
// MARK: - Fatal Error
extension MainDependencyContainer {
static var onFatalError: (String, StaticString, UInt) -> Never = { message, file, line in
Swift.fatalError(message, file: file, line: line)
}
fileprivate static func fatalError(file: StaticString = #file, line: UInt = #line) -> Never {
onFatalError("Invalid memory graph. This is never suppose to happen. Please file a ticket at https://github.com/scribd/Weaver", file, line)
}
}
// MARK: - Provider
@MainActor private final class Provider {
typealias ParametersCopier = (Provider) -> Void
typealias Builder<T> = (ParametersCopier?) -> T
private(set) var builders: Dictionary<String, Any>
init(builders: Dictionary<String, Any> = [:]) {
self.builders = builders
}
}
@MainActor private extension Provider {
func addBuilders(_ builders: Dictionary<String, Any>) {
builders.forEach { key, value in
self.builders[key] = value
}
}
func setBuilder<T>(_ name: String, _ builder: @escaping Builder<T>) {
builders[name] = builder
}
func getBuilder<T>(_ name: String, _ type: T.Type) -> Builder<T> {
guard let builder = builders[name] as? Builder<T> else {
return Provider.fatalBuilder()
}
return builder
}
func copy() -> Provider {
return Provider(builders: builders)
}
}
private extension Provider {
static func valueBuilder<T>(_ value: T) -> Builder<T> {
return { _ in
return value
}
}
static func weakOptionalValueBuilder<T>(_ value: Optional<T>) -> Builder<Optional<T>> where T: AnyObject {
return { [weak value] _ in
return value
}
}
static func lazyBuilder<T>(_ builder: @escaping Builder<T>) -> Builder<T> {
var _value: T?
return { copyParameters in
if let value = _value {
return value
}
let value = builder(copyParameters)
_value = value
return value
}
}
static func weakLazyBuilder<T>(_ builder: @escaping Builder<T>) -> Builder<T> where T: AnyObject {
weak var _value: T?
return { copyParameters in
if let value = _value {
return value
}
let value = builder(copyParameters)
_value = value
return value
}
}
@MainActor static func fatalBuilder<T>() -> Builder<T> {
return { _ in
MainDependencyContainer.fatalError()
}
}
}
""")
]
}

func providerClassAndFunctions() throws -> [FileBodyMember] {
return [
EmptyLine(),
Expand Down
Loading

0 comments on commit 70d6eab

Please sign in to comment.