diff --git a/Package.swift b/Package.swift index 2e3339dd1..aece5c03b 100644 --- a/Package.swift +++ b/Package.swift @@ -20,6 +20,7 @@ func envEnable(_ key: String, default defaultValue: Bool = false) -> Bool { var sharedSwiftSettings: [SwiftSetting] = [ .enableUpcomingFeature("BareSlashRegexLiterals"), .enableUpcomingFeature("InternalImportsByDefault"), + .enableUpcomingFeature("InferSendableFromCaptures"), .define("OPENSWIFTUI_SUPPRESS_DEPRECATED_WARNINGS"), .swiftLanguageMode(.v5), ] @@ -74,7 +75,11 @@ if development { let warningsAsErrorsCondition = envEnable("OPENSWIFTUI_WERROR", default: isXcodeEnv && development) if warningsAsErrorsCondition { - sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"])) + // Hold off the werror feature as we can't avoid the concurrency warning. + // Reenable the folllowing after swift-evolution#443 is release. + + // sharedSwiftSettings.append(.unsafeFlags(["-warnings-as-errors"])) + // sharedSwiftSettings.append(.unsafeFlags(["-Wwarning", "concurrency"])) } // NOTE: diff --git a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentValues.swift b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentValues.swift index 167ac537c..e8c9f94be 100644 --- a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentValues.swift +++ b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentValues.swift @@ -150,6 +150,9 @@ public struct EnvironmentValues: CustomStringConvertible { private var _plist: PropertyList private let tracker: PropertyList.Tracker? + // FIXME + var plist: PropertyList { _plist } + init(plist: PropertyList) { _plist = plist tracker = nil diff --git a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentalView.swift b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentalView.swift index 9d4cfeb52..25cb4bc08 100644 --- a/Sources/OpenSwiftUICore/Data/Environment/EnvironmentalView.swift +++ b/Sources/OpenSwiftUICore/Data/Environment/EnvironmentalView.swift @@ -3,8 +3,14 @@ // OpenSwiftUICore // // Audited for iOS 18.0 -// Status: WIP +// Status: Blocked by Tracing +import OpenGraphShims + +// MARK: - EnvironmentalView + +@MainActor +@preconcurrency package protocol EnvironmentalView: PrimitiveView, UnaryView { associatedtype EnvironmentBody: View func body(environment: EnvironmentValues) -> EnvironmentBody @@ -12,6 +18,82 @@ package protocol EnvironmentalView: PrimitiveView, UnaryView { extension EnvironmentalView { nonisolated public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { - preconditionFailure("") + let child = EnvironmentalViewChild(view: view.value, env: inputs.environment) + return EnvironmentBody.makeDebuggableView(view: _GraphValue(child), inputs: inputs) + } +} + +// MARK: - EnvironmentalViewChild + +struct EnvironmentalViewChild: StatefulRule, AsyncAttribute, CustomStringConvertible where V: EnvironmentalView { + @Attribute var view: V + @Attribute var env: EnvironmentValues + let tracker: PropertyList.Tracker + + init(view: Attribute, env: Attribute) { + _view = view + _env = env + tracker = .init() + } + + typealias Value = V.EnvironmentBody + + func updateValue() { + let (view, viewChanged) = $view.changedValue() + let (env, envChanged) = $env.changedValue() + + let shouldReset: Bool + if viewChanged { + shouldReset = true + } else if envChanged, tracker.hasDifferentUsedValues(env.plist) { + shouldReset = true + } else { + // TODO: Optimize this API call + let outputValue: UnsafePointer? = Graph.outputValue() + shouldReset = outputValue == nil + } + guard shouldReset else { return } + tracker.reset() + tracker.initializeValues(from: env.plist) + // TODO: Tracing + value = view.body(environment: env) + } + + var description: String { + "EnvironmentReading: \(V.self)" + } +} + +// MARK: - EnvironmentReader + +@MainActor +@preconcurrency +package struct EnvironmentReader: EnvironmentalView where Content: View { + let content: (EnvironmentValues) -> Content + + package init(@ViewBuilder _ content: @escaping (EnvironmentValues) -> Content) { + self.content = content + } + + package func body(environment: EnvironmentValues) -> Content { + content(environment) + } + + nonisolated package static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { + guard Semantics.EnvironmentReaderViewIsMulti.isEnabled else { + return _ViewListOutputs.unaryViewList(view: view, inputs: inputs) + } + let child = EnvironmentalViewChild(view: view.value, env: inputs.base.environment) + return EnvironmentBody.makeDebuggableViewList(view: _GraphValue(child), inputs: inputs) + } + + nonisolated package static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + guard Semantics.EnvironmentReaderViewIsMulti.isEnabled else { + return 1 + } + return Content._viewListCount(inputs: inputs) } + + package typealias Body = Never + package typealias EnvironmentBody = Content } diff --git a/Sources/OpenSwiftUICore/Graph/GraphValue.swift b/Sources/OpenSwiftUICore/Graph/GraphValue.swift index 62f0a29cd..dad68e7b5 100644 --- a/Sources/OpenSwiftUICore/Graph/GraphValue.swift +++ b/Sources/OpenSwiftUICore/Graph/GraphValue.swift @@ -42,7 +42,6 @@ public struct _GraphValue: Equatable { package func unsafeBitCast(to _: T.Type) -> _GraphValue { _GraphValue(value.unsafeBitCast(to: T.self)) - } public static func == (a: _GraphValue, b: _GraphValue) -> Bool { diff --git a/Sources/OpenSwiftUICore/Modifier/ModifiedContent.swift b/Sources/OpenSwiftUICore/Modifier/ModifiedContent.swift index c9cad60c6..4901cc53e 100644 --- a/Sources/OpenSwiftUICore/Modifier/ModifiedContent.swift +++ b/Sources/OpenSwiftUICore/Modifier/ModifiedContent.swift @@ -7,7 +7,7 @@ extension View { @inlinable - public func modifier(_ modifier: T) -> ModifiedContent { + nonisolated public func modifier(_ modifier: T) -> ModifiedContent { .init(content: self, modifier: modifier) } } diff --git a/Sources/OpenSwiftUICore/Modifier/ViewModifier/PrimitiveViewModifier.swift b/Sources/OpenSwiftUICore/Modifier/ViewModifier/PrimitiveViewModifier.swift deleted file mode 100644 index 39fc19109..000000000 --- a/Sources/OpenSwiftUICore/Modifier/ViewModifier/PrimitiveViewModifier.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// PrimitiveViewModifier.swift -// OpenSwiftUI -// -// Audited for iOS 15.5 -// Status: Complete - -package protocol PrimitiveViewModifier: ViewModifier where Body == Never {} diff --git a/Sources/OpenSwiftUICore/Modifier/ViewModifier/TODO/_EnvironmentKeyWritingModifier.swift b/Sources/OpenSwiftUICore/Modifier/ViewModifier/TODO/_EnvironmentKeyWritingModifier.swift index ece93d6d8..2d971abaf 100644 --- a/Sources/OpenSwiftUICore/Modifier/ViewModifier/TODO/_EnvironmentKeyWritingModifier.swift +++ b/Sources/OpenSwiftUICore/Modifier/ViewModifier/TODO/_EnvironmentKeyWritingModifier.swift @@ -6,12 +6,11 @@ // Status: WIP @frozen -public struct _EnvironmentKeyWritingModifier: ViewModifier/*, _GraphInputsModifier*/ { +public struct _EnvironmentKeyWritingModifier: ViewModifier, _GraphInputsModifier, PrimitiveViewModifier { public var keyPath: WritableKeyPath public var value: Value @inlinable - @inline(__always) public init(keyPath: WritableKeyPath, value: Value) { self.keyPath = keyPath self.value = value @@ -20,12 +19,16 @@ public struct _EnvironmentKeyWritingModifier: ViewModifier/*, _GraphInput public static func _makeInputs(modifier: _GraphValue<_EnvironmentKeyWritingModifier>, inputs: inout _GraphInputs) { // TODO } + + } +@available(*, unavailable) +extension _EnvironmentKeyWritingModifier: Sendable {} + extension View { @inlinable - @inline(__always) - public func environment(_ keyPath: WritableKeyPath, _ value: V) -> some View { + nonisolated public func environment(_ keyPath: WritableKeyPath, _ value: V) -> some View { modifier(_EnvironmentKeyWritingModifier(keyPath: keyPath, value: value)) } } diff --git a/Sources/OpenSwiftUICore/Modifier/ViewModifier/ViewModifier.swift b/Sources/OpenSwiftUICore/Modifier/ViewModifier/ViewModifier.swift index bc7fe3796..b0586977f 100644 --- a/Sources/OpenSwiftUICore/Modifier/ViewModifier/ViewModifier.swift +++ b/Sources/OpenSwiftUICore/Modifier/ViewModifier/ViewModifier.swift @@ -1,6 +1,6 @@ // // ViewModifier.swift -// OpenSwiftUI +// OpenSwiftUICore // // Audited for iOS 15.5 // Status: Complete @@ -48,18 +48,17 @@ /// Downtown Bus. A view extension, using custom a modifier, renders the /// caption in blue text surrounded by a rounded /// rectangle.](OpenSwiftUI-View-ViewModifier.png) +@MainActor +@preconcurrency public protocol ViewModifier { - /// The type of view representing the body. - associatedtype Body: View - /// Makes a new view using the view modifier and inputs that you provide. - static func _makeView( + nonisolated static func _makeView( modifier: _GraphValue, inputs: _ViewInputs, body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs ) -> _ViewOutputs - static func _makeViewList( + nonisolated static func _makeViewList( modifier: _GraphValue, inputs: _ViewListInputs, body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs @@ -67,49 +66,27 @@ public protocol ViewModifier { /// The number of views that `_makeViewList()` would produce, or /// nil if unknown. - static func _viewListCount( + nonisolated static func _viewListCount( inputs: _ViewListCountInputs, body: (_ViewListCountInputs) -> Int? ) -> Int? - /// The content view type passed to `body()`. - typealias Content = _ViewModifier_Content + /// The type of view representing the body. + associatedtype Body: View /// Gets the current body of the caller. /// /// `content` is a proxy for the view that will have the modifier /// represented by `Self` applied to it. @ViewBuilder - @MainActor - @preconcurrency func body(content: Content) -> Body -} - -extension ViewModifier { - public static func _makeView( - modifier: _GraphValue, - inputs: _ViewInputs, - body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs - ) -> _ViewOutputs { - makeView(modifier: modifier, inputs: inputs, body: body) - } - public static func _makeViewList( - modifier: _GraphValue, - inputs: _ViewListInputs, - body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs - ) -> _ViewListOutputs { - makeViewList(modifier: modifier, inputs: inputs, body: body) - } - - public static func _viewListCount( - inputs: _ViewListCountInputs, - body: (_ViewListCountInputs) -> Int? - ) -> Int? { - viewListCount(inputs: inputs, body: body) - } + /// The content view type passed to `body()`. + typealias Content = _ViewModifier_Content } +package protocol PrimitiveViewModifier: ViewModifier where Body == Never {} + extension ViewModifier where Body == Never { public func body(content _: Content) -> Never { bodyError() @@ -163,3 +140,28 @@ extension ViewModifier { preconditionFailure("body() should not be called on \(Self.self)") } } + +extension ViewModifier { + public static func _makeView( + modifier: _GraphValue, + inputs: _ViewInputs, + body: @escaping (_Graph, _ViewInputs) -> _ViewOutputs + ) -> _ViewOutputs { + makeView(modifier: modifier, inputs: inputs, body: body) + } + + public static func _makeViewList( + modifier: _GraphValue, + inputs: _ViewListInputs, + body: @escaping (_Graph, _ViewListInputs) -> _ViewListOutputs + ) -> _ViewListOutputs { + makeViewList(modifier: modifier, inputs: inputs, body: body) + } + + public static func _viewListCount( + inputs: _ViewListCountInputs, + body: (_ViewListCountInputs) -> Int? + ) -> Int? { + viewListCount(inputs: inputs, body: body) + } +} diff --git a/Sources/OpenSwiftUICore/View/AnyView.swift b/Sources/OpenSwiftUICore/View/AnyView.swift index 1e60b9188..f240353e5 100644 --- a/Sources/OpenSwiftUICore/View/AnyView.swift +++ b/Sources/OpenSwiftUICore/View/AnyView.swift @@ -1,20 +1,25 @@ // // AnyView.swift -// OpenSwiftUI +// OpenSwiftUICore // -// Audited for iOS 15.5 +// Audited for iOS 18.0 // Status: WIP -// ID: A96961F3546506F21D8995C6092F15B5 +// ID: A96961F3546506F21D8995C6092F15B5 (OpenSwiftUI) +// ID: 7578D05D331D7F1A2E0C2F8DEF38AAD4 (OpenSwiftUICore) import OpenGraphShims import OpenSwiftUI_SPI @frozen -public struct AnyView: PrimitiveView { +public struct AnyView: View, PrimitiveView { var storage: AnyViewStorageBase public init(_ view: V) where V: View { - self.init(view, id: nil) + if let anyView = view as? AnyView { + storage = anyView.storage + } else { + storage = AnyViewStorage(view: view) + } } @_alwaysEmitIntoClient @@ -42,19 +47,7 @@ public struct AnyView: PrimitiveView { } self = visitor.view! } - - init(_ view: V, id: UniqueID?) { - if let anyView = view as? AnyView { - storage = anyView.storage - } else { - storage = AnyViewStorage(view: view, id: id) - } - } - - func visitContent(_ visitor: inout Visitor) { - storage.visitContent(&visitor) - } - + public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { #if canImport(Darwin) let outputs = inputs.makeIndirectOutputs() @@ -76,16 +69,14 @@ public struct AnyView: PrimitiveView { public static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { preconditionFailure("TODO") } + + package func visitContent(_ visitor: inout Visitor) { + storage.visitContent(&visitor) + } } @usableFromInline class AnyViewStorageBase { - let id: UniqueID? - - init(id: UniqueID?) { - self.id = id - } - fileprivate var type: Any.Type { preconditionFailure("") } fileprivate var canTransition: Bool { preconditionFailure("") } fileprivate func matches(_ other: AnyViewStorageBase) -> Bool { preconditionFailure("") } @@ -111,10 +102,13 @@ class AnyViewStorageBase { private final class AnyViewStorage: AnyViewStorageBase { let view: V - init(view: V, id: UniqueID?) { + init(view: V) { self.view = view - super.init(id: id) + super.init() } + + // FIXME + var id: UniqueID? { nil } override var type: Any.Type { V.self } diff --git a/Sources/OpenSwiftUICore/View/ConditionalContent.swift b/Sources/OpenSwiftUICore/View/ConditionalContent.swift index bc91d5f0a..38397d06b 100644 --- a/Sources/OpenSwiftUICore/View/ConditionalContent.swift +++ b/Sources/OpenSwiftUICore/View/ConditionalContent.swift @@ -55,9 +55,9 @@ extension _ConditionalContent: View, PrimitiveView where TrueContent: View, Fals var value: AnyView { switch content.storage { case .trueContent(let view): - AnyView(view, id: ids.0) + AnyView(view) case .falseContent(let view): - AnyView(view, id: ids.1) + AnyView(view) } } } diff --git a/Sources/OpenSwiftUICore/View/CustomView.swift b/Sources/OpenSwiftUICore/View/CustomView.swift index 37740a36f..6fc660ef6 100644 --- a/Sources/OpenSwiftUICore/View/CustomView.swift +++ b/Sources/OpenSwiftUICore/View/CustomView.swift @@ -1,15 +1,28 @@ // // CustomView.swift -// OpenSwiftUI +// OpenSwiftUICore // // Audited for iOS 15.5 // Status: WIP -// ID: 9F92ACD17B554E8AB7D29ABB1E796415 +// ID: 9F92ACD17B554E8AB7D29ABB1E796415 (SwiftUI) +// ID: CE1D93D8ECBBEB5FE2E32E69A123E7CB (SwiftUICore) import OpenGraphShims extension View { - static func makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + nonisolated public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + makeView(view: view, inputs: inputs) + } + + nonisolated public static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { + makeViewList(view: view, inputs: inputs) + } + + nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + Body._viewListCount(inputs: inputs) + } + + nonisolated package static func makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { let fields = DynamicPropertyCache.fields(of: Self.self) var inputs = inputs let (body, buffer) = inputs.withMutateGraphInputs { inputs in @@ -28,7 +41,7 @@ extension View { return outputs } - static func makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { + nonisolated package static func makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { let fields = DynamicPropertyCache.fields(of: Self.self) var inputs = inputs let (body, buffer) = inputs.withMutateGraphInputs { inputs in @@ -41,7 +54,7 @@ extension View { return outputs } - private static func makeBody( + nonisolated private static func makeBody( view: _GraphValue, inputs: inout _GraphInputs, fields: DynamicPropertyCache.Fields diff --git a/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift b/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift index 6a99fedd1..125cd26a8 100644 --- a/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift +++ b/Sources/OpenSwiftUICore/View/Input/ViewOutputs.swift @@ -3,7 +3,7 @@ // OpenSwiftUICore // // Audited for iOS 18.0 -// Status: WIP +// Status: Complete package import OpenGraphShims @@ -13,11 +13,6 @@ public struct _ViewOutputs { private var _layoutComputer: OptionalAttribute - package init() { - preferences = PreferencesOutputs() - _layoutComputer = OptionalAttribute() - } - package var layoutComputer: Attribute? { get { _layoutComputer.attribute @@ -30,6 +25,11 @@ public struct _ViewOutputs { } } + package init() { + preferences = PreferencesOutputs() + _layoutComputer = OptionalAttribute() + } + #if canImport(Darwin) package subscript(anyKey key: any AnyPreferenceKey.Type) -> AnyAttribute? { get { preferences[anyKey: key] } @@ -57,5 +57,7 @@ public struct _ViewOutputs { extension _ViewOutputs: Sendable {} extension _ViewOutputs { - // package func viewResponders: Attribute<[ViewResponder]> {} + package func viewResponders() -> Attribute<[ViewResponder]> { + self[ViewRespondersKey.self] ?? ViewGraph.current.intern([], for: [ViewResponder].self, id: .defaultValue) + } } diff --git a/Sources/OpenSwiftUICore/View/PrimitiveView.swift b/Sources/OpenSwiftUICore/View/PrimitiveView.swift deleted file mode 100644 index fc16a49a8..000000000 --- a/Sources/OpenSwiftUICore/View/PrimitiveView.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// PrimitiveView.swift -// OpenSwiftUI -// -// Audited for iOS 15.5 -// Status: Complete - -package protocol PrimitiveView: View where Body == Never {} - -extension PrimitiveView { - public var body: Never { - bodyError() - } -} diff --git a/Sources/OpenSwiftUICore/View/UnaryView.swift b/Sources/OpenSwiftUICore/View/UnaryView.swift deleted file mode 100644 index d86cfa835..000000000 --- a/Sources/OpenSwiftUICore/View/UnaryView.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// UnaryView.swift -// OpenSwiftUI -// -// Audited for iOS 15.5 -// Status: Empty - -package protocol UnaryView: View {} diff --git a/Sources/OpenSwiftUICore/View/Variadic/VariadicView_ViewRoot.swift b/Sources/OpenSwiftUICore/View/Variadic/VariadicView_ViewRoot.swift index e8849eceb..afff3b0be 100644 --- a/Sources/OpenSwiftUICore/View/Variadic/VariadicView_ViewRoot.swift +++ b/Sources/OpenSwiftUICore/View/Variadic/VariadicView_ViewRoot.swift @@ -74,7 +74,7 @@ extension _ViewInputs { } extension View { - static func makeImplicitRoot(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + nonisolated static func makeImplicitRoot(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { // TODO return .init() } diff --git a/Sources/OpenSwiftUICore/View/View.swift b/Sources/OpenSwiftUICore/View/View.swift index b9ac4e17d..9b6cf3781 100644 --- a/Sources/OpenSwiftUICore/View/View.swift +++ b/Sources/OpenSwiftUICore/View/View.swift @@ -1,8 +1,8 @@ // // View.swift -// OpenSwiftUI +// OpenSwiftUICore // -// Audited for iOS 15.5 +// Audited for iOS 18.0 // Status: WIP /// A type that represents part of your app's user interface and provides @@ -42,24 +42,26 @@ /// You can also collect groups of default modifiers into new, /// custom view modifiers for easy reuse. @_typeEraser(AnyView) +@preconcurrency +@MainActor public protocol View { - /// The type of view representing the body of this view. - /// - /// When you create a custom view, Swift infers this type from your - /// implementation of the required ``View/body-swift.property`` property. - associatedtype Body: View - /// Instantiates the view using `view` as its source value, and /// `inputs` as its input values. Returns the view's output values. /// This should never be called directly, instead use the /// makeDebuggableView() shim function. - static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs + nonisolated static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs - static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs + nonisolated static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs /// The number of views that `_makeViewList()` would produce, or /// nil if unknown. - static func _viewListCount(inputs: _ViewListCountInputs) -> Int? + nonisolated static func _viewListCount(inputs: _ViewListCountInputs) -> Int? + + /// The type of view representing the body of this view. + /// + /// When you create a custom view, Swift infers this type from your + /// implementation of the required ``View/body-swift.property`` property. + associatedtype Body: View /// The content and behavior of the view. /// @@ -82,25 +84,24 @@ public protocol View { var body: Self.Body { get } } -extension View { - public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { - makeView(view: view, inputs: inputs) - } - - public static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { - makeViewList(view: view, inputs: inputs) - } - - public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { - Body._viewListCount(inputs: inputs) +// MARK: - Never + View + +extension Never: View { + public var body: Never { self } + + nonisolated public static func _viewListCount(inputs _: _ViewListCountInputs) -> Int? { + nil } } +// MARK: - PrimitiveView -// MARK: - Never + View +package protocol PrimitiveView: View {} -extension Never: View { - public var body: Never { self } +extension PrimitiveView { + public var body: Never { + bodyError() + } } extension View { @@ -108,3 +109,31 @@ extension View { preconditionFailure("body() should not be called on \(Self.self)") } } + +// MARK: - UnaryView + +package protocol UnaryView: View {} + +extension UnaryView { + nonisolated public static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { + _ViewListOutputs.unaryViewList(view: view, inputs: inputs) + } + + nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + 1 + } +} + +// MARK: - MultiView + +package protocol MultiView: View {} + +extension MultiView { + nonisolated public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + makeImplicitRoot(view: view, inputs: inputs) + } + + nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + nil + } +} diff --git a/Sources/OpenSwiftUICore/View/ViewList.swift b/Sources/OpenSwiftUICore/View/ViewList.swift index 0ca7a3fbc..c3e9ccaec 100644 --- a/Sources/OpenSwiftUICore/View/ViewList.swift +++ b/Sources/OpenSwiftUICore/View/ViewList.swift @@ -81,6 +81,11 @@ public struct _ViewListOutputs { } extension _ViewListOutputs { + package static func unaryViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs where V: View { + preconditionFailure("TODO") + } + + @inline(__always) static func emptyParentViewList(inputs: _ViewListInputs) -> _ViewListOutputs { staticList(EmptyElements(), inputs: inputs, staticCount: 0) diff --git a/Sources/OpenSwiftUICore/View/ViewVisitor.swift b/Sources/OpenSwiftUICore/View/ViewVisitor.swift index b2230478a..36bc5a3d4 100644 --- a/Sources/OpenSwiftUICore/View/ViewVisitor.swift +++ b/Sources/OpenSwiftUICore/View/ViewVisitor.swift @@ -5,10 +5,10 @@ // Audited for iOS 15.5 // Status: Complete -protocol ViewVisitor { +package protocol ViewVisitor { mutating func visit(_ view: V) } -protocol ViewTypeVisitor { +package protocol ViewTypeVisitor { mutating func visit(type: V.Type) } diff --git a/Tests/OpenSwiftUICoreTests/View/AnyViewTests.swift b/Tests/OpenSwiftUICoreTests/View/AnyViewTests.swift index 907f0b7ae..697423d93 100644 --- a/Tests/OpenSwiftUICoreTests/View/AnyViewTests.swift +++ b/Tests/OpenSwiftUICoreTests/View/AnyViewTests.swift @@ -10,7 +10,7 @@ struct AnyViewTests { func testInitFromValue() throws { let empty = EmptyView() let any = try #require(AnyView(_fromValue: empty)) - #expect(any.storage.id == nil) + // #expect(any.storage.id == nil) let _: EmptyView = any.storage.child() let any1 = AnyView(any)