Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class DependencyProviderFuncSerializer: Serializer {
func serialize() -> String {
return """
/// \(provider.unprocessed.pathString)
@preconcurrency
@MainActor
private func \(funcNameSerializer.serialize())(_ component: NeedleFoundation.Scope) -> AnyObject {
return \(classNameSerializer.serialize())(\(paramsSerializer.serialize()))
}\n
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class OutputSerializer: Serializer {

let traversalHelpers = (1...maxLevel).map { num in
return """
@preconcurrency
@MainActor
private func parent\(num)(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
return component\(String(repeating: ".parent", count: num))
}
Expand Down Expand Up @@ -101,7 +103,10 @@ class OutputSerializer: Serializer {
.trimmingCharacters(in: .whitespacesAndNewlines)
let regNum = ($0 / linesPerHelper) + 1
registrationHelperFuncs.append("""
@inline(never) private func register\(regNum)() {
@inline(never)
@preconcurrency
@MainActor
private func register\(regNum)() {
\(helperBody)
}
""")
Expand Down Expand Up @@ -132,11 +137,15 @@ class OutputSerializer: Serializer {

#endif

@preconcurrency
@MainActor
private func factoryEmptyDependencyProvider(_ component: NeedleFoundation.Scope) -> AnyObject {
return EmptyDependencyProvider(component: component)
}

// MARK: - Registration
@preconcurrency
@MainActor
private func registerProviderFactory(_ componentPath: String, _ factory: @escaping (NeedleFoundation.Scope) -> AnyObject) {
__DependencyProviderRegistry.instance.registerDependencyProviderFactory(for: componentPath, factory)
}
Expand All @@ -146,6 +155,8 @@ class OutputSerializer: Serializer {
\(registrationHelpers)
#endif

@preconcurrency
@MainActor
public func registerProviderFactories() {
#if !NEEDLE_DYNAMIC
\(registrationBody)
Expand Down
Binary file modified Generator/bin/needle
Binary file not shown.
2 changes: 2 additions & 0 deletions Sample/MVC/TicTacToe/Sources/Game/GameComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import NeedleFoundation
import UIKit

@MainActor
protocol GameDependency: Dependency {
var mutableScoreStream: MutableScoreStream { get }
var playersStream: PlayersStream { get }
Expand All @@ -40,6 +41,7 @@ class GameComponent: Component<GameDependency>, GameBuilder {

// Use a builder protocol to allow mocking for unit tests. At the same time,
// this allows GameViewController to be initialized lazily.
@MainActor
protocol GameBuilder {
var gameViewController: UIViewController { get }
}
2 changes: 1 addition & 1 deletion Sample/MVC/TicTacToe/Sources/Game/GameViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import UIKit
private let rowCount = 3
private let colCount = 3
private let sectionCount = 1
private let cellSize: CGFloat = UIScreen.main.bounds.width / CGFloat(colCount)
@MainActor let cellSize: CGFloat = UIScreen.main.bounds.width / CGFloat(colCount)
private let cellIdentifier = "TicTacToeCell"

private enum Players: Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class LoggedInComponent: Component<LoggedInDependency>, LoggedInBuilder {

// Use a builder protocol to allow mocking for unit tests. At the same time,
// this allows LoggedInViewController to be initialized lazily.
@MainActor
protocol LoggedInBuilder {
var loggedInViewController: UIViewController { get }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,8 @@ class LoggedInViewController: UIViewController, ScoreSheetListener {
}

func done() {
dismiss(animated: true)
}

deinit {
gameDisposable?.dispose()
dismiss(animated: true) { [weak self] in
self?.gameDisposable?.dispose()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import NeedleFoundation
import UIKit

@MainActor
protocol LoggedOutDependency: Dependency {
var mutablePlayersStream: MutablePlayersStream { get }
}
Expand All @@ -30,6 +31,7 @@ class LoggedOutComponent: Component<LoggedOutDependency>, LoggedOutBuilder {

// Use a builder protocol to allow mocking for unit tests. At the same time,
// this allows LoggedOutViewController to be initialized lazily.
@MainActor
protocol LoggedOutBuilder {
var loggedOutViewController: UIViewController { get }
}
28 changes: 25 additions & 3 deletions Sample/MVC/TicTacToe/Sources/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ private let needleDependenciesHash : String? = nil

// MARK: - Traversal Helpers

@preconcurrency
@MainActor
private func parent1(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
return component.parent
}

@preconcurrency
@MainActor
private func parent2(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
return component.parent.parent
}
Expand All @@ -50,6 +54,8 @@ private class GameDependency1ab5926a977f706d3195Provider: GameDependency {
}
}
/// ^->RootComponent->LoggedInComponent->GameComponent
@preconcurrency
@MainActor
private func factorycf9c02c4def4e3d508816cd03d3cf415b70dfb0e(_ component: NeedleFoundation.Scope) -> AnyObject {
return GameDependency1ab5926a977f706d3195Provider(loggedInComponent: parent1(component) as! LoggedInComponent, rootComponent: parent2(component) as! RootComponent)
}
Expand All @@ -63,10 +69,14 @@ private class ScoreSheetDependency97f2595a691a56781aaaProvider: ScoreSheetDepend
}
}
/// ^->RootComponent->LoggedInComponent->GameComponent->ScoreSheetComponent
@preconcurrency
@MainActor
private func factory3f7d60e2119708f293bac0d8c882e1e0d9b5eda1(_ component: NeedleFoundation.Scope) -> AnyObject {
return ScoreSheetDependency97f2595a691a56781aaaProvider(loggedInComponent: parent2(component) as! LoggedInComponent)
}
/// ^->RootComponent->LoggedInComponent->ScoreSheetComponent
@preconcurrency
@MainActor
private func factory3f7d60e2119708f293ba0b20504d5a9e5588d7b3(_ component: NeedleFoundation.Scope) -> AnyObject {
return ScoreSheetDependency97f2595a691a56781aaaProvider(loggedInComponent: parent1(component) as! LoggedInComponent)
}
Expand All @@ -80,6 +90,8 @@ private class LoggedOutDependencyacada53ea78d270efa2fProvider: LoggedOutDependen
}
}
/// ^->RootComponent->LoggedOutComponent
@preconcurrency
@MainActor
private func factory1434ff4463106e5c4f1bb3a8f24c1d289f2c0f2e(_ component: NeedleFoundation.Scope) -> AnyObject {
return LoggedOutDependencyacada53ea78d270efa2fProvider(rootComponent: parent1(component) as! RootComponent)
}
Expand All @@ -105,31 +117,39 @@ extension LoggedOutComponent: Registration {
extension LoggedInComponent: Registration {
public func registerItems() {


localTable["scoreStream-ScoreStream"] = { [unowned self] in self.scoreStream as Any }
}
}
extension RootComponent: Registration {
public func registerItems() {


localTable["playersStream-PlayersStream"] = { [unowned self] in self.playersStream as Any }
localTable["mutablePlayersStream-MutablePlayersStream"] = { [unowned self] in self.mutablePlayersStream as Any }
}
}


#endif

@preconcurrency
@MainActor
private func factoryEmptyDependencyProvider(_ component: NeedleFoundation.Scope) -> AnyObject {
return EmptyDependencyProvider(component: component)
}

// MARK: - Registration
@preconcurrency
@MainActor
private func registerProviderFactory(_ componentPath: String, _ factory: @escaping (NeedleFoundation.Scope) -> AnyObject) {
__DependencyProviderRegistry.instance.registerDependencyProviderFactory(for: componentPath, factory)
}

#if !NEEDLE_DYNAMIC

@inline(never) private func register1() {
@inline(never)
@preconcurrency
@MainActor
private func register1() {
registerProviderFactory("^->RootComponent->LoggedInComponent->GameComponent", factorycf9c02c4def4e3d508816cd03d3cf415b70dfb0e)
registerProviderFactory("^->RootComponent->LoggedInComponent->GameComponent->ScoreSheetComponent", factory3f7d60e2119708f293bac0d8c882e1e0d9b5eda1)
registerProviderFactory("^->RootComponent->LoggedInComponent->ScoreSheetComponent", factory3f7d60e2119708f293ba0b20504d5a9e5588d7b3)
Expand All @@ -139,6 +159,8 @@ private func registerProviderFactory(_ componentPath: String, _ factory: @escapi
}
#endif

@preconcurrency
@MainActor
public func registerProviderFactories() {
#if !NEEDLE_DYNAMIC
register1()
Expand Down
9 changes: 5 additions & 4 deletions Sample/MVC/TicTacToe/Sources/Root/RootViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class RootViewController: UIViewController {
updateChildViewController()
}

override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
playersStreamDisposable?.dispose()
}

private func updateChildViewController() {
if playersStreamDisposable != nil {
return
Expand Down Expand Up @@ -89,8 +94,4 @@ class RootViewController: UIViewController {
present(viewController, animated: true, completion: nil)
}
}

deinit {
playersStreamDisposable?.dispose()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import NeedleFoundation
import RxSwift
import UIKit

@MainActor
protocol ScoreSheetDependency: Dependency {
var scoreStream: ScoreStream { get }
}
Expand All @@ -30,6 +31,7 @@ class ScoreSheetComponent: Component<ScoreSheetDependency>, ScoreSheetBuilder {
}

// Use a builder protocol to allow mocking for unit tests
@MainActor
protocol ScoreSheetBuilder {
var scoreSheetViewController: UIViewController { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import RxSwift
import SnapKit
import UIKit

@MainActor
protocol ScoreSheetListener {
func done()
}
Expand Down
1 change: 1 addition & 0 deletions Sample/MVC/TicTacToe/Tests/RootViewControllerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import RxSwift
import XCTest

@MainActor
class RootViewControllerTests: XCTestCase {

private var playersStream: PlayersStreamMock!
Expand Down
4 changes: 3 additions & 1 deletion Sample/MVC/TicTacToe/TicTacToe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -567,6 +567,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.uber.needle.tictactoe.TicTacToe;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand All @@ -587,6 +588,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.uber.needle.tictactoe.TicTacToe;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import NeedleFoundation
import RxSwift
import UIKit

@MainActor
public protocol ScoreSheetDependency: Dependency {
var scoreStream: ScoreStream { get }
}
Expand All @@ -30,6 +31,7 @@ public class ScoreSheetComponent: Component<ScoreSheetDependency>, ScoreSheetBui
}

// Use a builder protocol to allow mocking for unit tests
@MainActor
public protocol ScoreSheetBuilder {
var scoreSheetViewController: UIViewController { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import RxSwift
import SnapKit
import UIKit

@MainActor
public protocol ScoreSheetListener {
func done()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -987,6 +987,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_STRICT_CONCURRENCY = complete;
};
name = Debug;
};
Expand Down Expand Up @@ -1041,6 +1042,7 @@
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_STRICT_CONCURRENCY = complete;
VALIDATE_PRODUCT = YES;
};
name = Release;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import ScoreSheet
import TicTacToeIntegrations
import UIKit

@MainActor
protocol GameDependency: Dependency {
var mutableScoreStream: MutableScoreStream { get }
var playersStream: PlayersStream { get }
}

@MainActor
protocol GamePluginExtension: PluginExtension {
var scoreSheetBuilder: ScoreSheetBuilder { get }
}
Expand Down Expand Up @@ -62,6 +64,7 @@ class GameComponent: UberPluginizedComponent<GameDependency, GamePluginExtension

// Use a builder protocol to allow mocking for unit tests. At the same time,
// this allows GameViewController to be initialized lazily.
@MainActor
protocol GameBuilder {
var gameViewController: UIViewController { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import UIKit
private let rowCount = 3
private let colCount = 3
private let sectionCount = 1
private let cellSize: CGFloat = UIScreen.main.bounds.width / CGFloat(colCount)
@MainActor private let cellSize: CGFloat = UIScreen.main.bounds.width / CGFloat(colCount)
private let cellIdentifier = "TicTacToeCell"

private enum Players: Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import ScoreSheet
import TicTacToeIntegrations
import UIKit

@MainActor
protocol LoggedInPluginExtension: PluginExtension {
var scoreSheetBuilder: ScoreSheetBuilder { get }
var mutableScoreStream: MutableScoreStream { get }
Expand Down Expand Up @@ -50,6 +51,7 @@ class LoggedInComponent: PluginizedComponent<EmptyDependency, LoggedInPluginExte

// Use a builder protocol to allow mocking for unit tests. At the same time,
// this allows LoggedInViewController to be initialized lazily.
@MainActor
protocol LoggedInBuilder {
var loggedInViewController: UIViewController { get }
}
Loading