From b317441fcfc2f12620e30bc9632800d92ac73090 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 8 Oct 2025 03:03:22 +0800 Subject: [PATCH 1/2] Fix ViewAlias BodyAccessor crash issue --- .../View/Configuration/ViewAlias.swift | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Sources/OpenSwiftUI/View/Configuration/ViewAlias.swift b/Sources/OpenSwiftUI/View/Configuration/ViewAlias.swift index f395c1118..34200146b 100644 --- a/Sources/OpenSwiftUI/View/Configuration/ViewAlias.swift +++ b/Sources/OpenSwiftUI/View/Configuration/ViewAlias.swift @@ -25,6 +25,36 @@ protocol ViewAlias: PrimitiveView { init() } +// Audited for 6.5.4 + +extension ViewAlias { + nonisolated public static func _makeView(view: _GraphValue, inputs: _ViewInputs) -> _ViewOutputs { + var inputs = inputs + guard let source = inputs.popLast(SourceInput.self) else { + return .init() + } + inputs.base.resetCurrentStyleableView() + return source.formula.makeView(view: view, source: source, inputs: inputs) + } + + nonisolated public static func _makeViewList(view: _GraphValue, inputs: _ViewListInputs) -> _ViewListOutputs { + var inputs = inputs + guard let source = inputs.base.popLast(SourceInput.self) else { + return .emptyViewList(inputs: inputs) + } + inputs.base.resetCurrentStyleableView() + return source.formula.makeViewList(view: view, source: source, inputs: inputs) + } + + nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? { + var inputs = inputs + guard let source = inputs.popLast(SourceInput.self) else { + return 0 + } + return source.formula.viewListCount(source: source, inputs: inputs) + } +} + // MARK: - View + ViewAlias Extension extension View { From ea441f2c9a591b3e284860ff75353ebcda059e93 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 19 Oct 2025 00:20:18 +0800 Subject: [PATCH 2/2] Add ViewAliasTests --- .../View/Configuration/ViewAliasTests.swift | 80 +++++++++++++++++++ .../View/ViewAliasTests.swift | 39 --------- 2 files changed, 80 insertions(+), 39 deletions(-) create mode 100644 Tests/OpenSwiftUITests/View/Configuration/ViewAliasTests.swift delete mode 100644 Tests/OpenSwiftUITests/View/ViewAliasTests.swift diff --git a/Tests/OpenSwiftUITests/View/Configuration/ViewAliasTests.swift b/Tests/OpenSwiftUITests/View/Configuration/ViewAliasTests.swift new file mode 100644 index 000000000..19efd8ec1 --- /dev/null +++ b/Tests/OpenSwiftUITests/View/Configuration/ViewAliasTests.swift @@ -0,0 +1,80 @@ +// +// ViewAliasTests.swift +// OpenSwiftUITests + +import Foundation +import Testing +@testable import OpenSwiftUI +@_spi(ForOpenSwiftUIOnly) +import OpenSwiftUICore +import OpenSwiftUITestsSupport + +@MainActor +struct ViewAliasTests { + #if canImport(Darwin) + @Test + func optionalViewAliasDynamicProperty() async throws { + struct ContentView: View { + var confirmation: Confirmation? + + @OptionalViewAlias + private var alias: ChildView.Alias? + + var body: some View { + ChildView(confirmation: confirmation) + .viewAlias(ChildView.Alias.self) { Color.red } + .onAppear { + #expect(alias == nil) + confirmation?() + } + } + } + + struct ChildView: View { + var confirmation: Confirmation? + + struct Alias: ViewAlias {} + + @OptionalViewAlias + private var alias: Alias? + + var body: some View { + Alias() + .onAppear { + #expect(alias != nil) + confirmation?() + } + } + } + try await triggerLayoutWithWindow(expectedCount: 2) { confirmation in + PlatformHostingController( + rootView: ContentView( + confirmation: confirmation + ) + ) + } + + // DisplayList expectation + let graph = ViewGraph( + rootViewType: ContentView.self, + requestedOutputs: [.displayList] + ) + graph.instantiateOutputs() + graph.setRootView(ContentView()) + graph.setProposedSize(CGSize(width: 100, height: 100)) + let (displayList, _) = graph.displayList() + print(displayList.description) + let expectRegex = try! Regex(#""" + \(display-list + \(item #:identity \d+ #:version \d+ + \(frame \([^)]+\)\) + \(effect + \(item #:identity \d+ #:version \d+ + \(frame \([^)]+\)\) + \(content-seed \d+\) + \(color #[0-9A-F]{8}\)\)\)\)\) + """#) + #expect(displayList.description.contains(expectRegex)) + } + #endif +} diff --git a/Tests/OpenSwiftUITests/View/ViewAliasTests.swift b/Tests/OpenSwiftUITests/View/ViewAliasTests.swift deleted file mode 100644 index cf9b7058f..000000000 --- a/Tests/OpenSwiftUITests/View/ViewAliasTests.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// ViewAliasTests.swift -// OpenSwiftUITests - -import Testing -@testable import OpenSwiftUI -@_spi(ForOpenSwiftUIOnly) -import OpenSwiftUICore -#if os(iOS) || os(visionOS) -import UIKit -#endif - -// TODO: Add viewAlias related test after style are implemented -@MainActor -struct ViewAliasTests { -// struct CustomView: View { -// struct Alias: ViewAlias { -// init() {} -// } -// } -// @Test -// func optionalViewAliasDynamicProperty() { -// struct ContentView: View { -// @OptionalViewAlias -// private var alias: CustomView.Alias? -// -// var body: some View { -// CustomView() -// .viewAlias(CustomView.Alias.self) { -// Color.red -// } -// } -// } -// #if os(iOS) || os(visionOS) -// let hostingView = _UIHostingView(rootView: ContentView()) -// hostingView.render() -// #endif -// } -}