Skip to content

Commit b5860b3

Browse files
authored
Fix ViewAlias Body Accessor crash (#582)
1 parent d4a825d commit b5860b3

File tree

3 files changed

+110
-39
lines changed

3 files changed

+110
-39
lines changed

Sources/OpenSwiftUI/View/Configuration/ViewAlias.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,36 @@ protocol ViewAlias: PrimitiveView {
2525
init()
2626
}
2727

28+
// Audited for 6.5.4
29+
30+
extension ViewAlias {
31+
nonisolated public static func _makeView(view: _GraphValue<Self>, inputs: _ViewInputs) -> _ViewOutputs {
32+
var inputs = inputs
33+
guard let source = inputs.popLast(SourceInput<Self>.self) else {
34+
return .init()
35+
}
36+
inputs.base.resetCurrentStyleableView()
37+
return source.formula.makeView(view: view, source: source, inputs: inputs)
38+
}
39+
40+
nonisolated public static func _makeViewList(view: _GraphValue<Self>, inputs: _ViewListInputs) -> _ViewListOutputs {
41+
var inputs = inputs
42+
guard let source = inputs.base.popLast(SourceInput<Self>.self) else {
43+
return .emptyViewList(inputs: inputs)
44+
}
45+
inputs.base.resetCurrentStyleableView()
46+
return source.formula.makeViewList(view: view, source: source, inputs: inputs)
47+
}
48+
49+
nonisolated public static func _viewListCount(inputs: _ViewListCountInputs) -> Int? {
50+
var inputs = inputs
51+
guard let source = inputs.popLast(SourceInput<Self>.self) else {
52+
return 0
53+
}
54+
return source.formula.viewListCount(source: source, inputs: inputs)
55+
}
56+
}
57+
2858
// MARK: - View + ViewAlias Extension
2959

3060
extension View {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//
2+
// ViewAliasTests.swift
3+
// OpenSwiftUITests
4+
5+
import Foundation
6+
import Testing
7+
@testable import OpenSwiftUI
8+
@_spi(ForOpenSwiftUIOnly)
9+
import OpenSwiftUICore
10+
import OpenSwiftUITestsSupport
11+
12+
@MainActor
13+
struct ViewAliasTests {
14+
#if canImport(Darwin)
15+
@Test
16+
func optionalViewAliasDynamicProperty() async throws {
17+
struct ContentView: View {
18+
var confirmation: Confirmation?
19+
20+
@OptionalViewAlias
21+
private var alias: ChildView.Alias?
22+
23+
var body: some View {
24+
ChildView(confirmation: confirmation)
25+
.viewAlias(ChildView.Alias.self) { Color.red }
26+
.onAppear {
27+
#expect(alias == nil)
28+
confirmation?()
29+
}
30+
}
31+
}
32+
33+
struct ChildView: View {
34+
var confirmation: Confirmation?
35+
36+
struct Alias: ViewAlias {}
37+
38+
@OptionalViewAlias
39+
private var alias: Alias?
40+
41+
var body: some View {
42+
Alias()
43+
.onAppear {
44+
#expect(alias != nil)
45+
confirmation?()
46+
}
47+
}
48+
}
49+
try await triggerLayoutWithWindow(expectedCount: 2) { confirmation in
50+
PlatformHostingController(
51+
rootView: ContentView(
52+
confirmation: confirmation
53+
)
54+
)
55+
}
56+
57+
// DisplayList expectation
58+
let graph = ViewGraph(
59+
rootViewType: ContentView.self,
60+
requestedOutputs: [.displayList]
61+
)
62+
graph.instantiateOutputs()
63+
graph.setRootView(ContentView())
64+
graph.setProposedSize(CGSize(width: 100, height: 100))
65+
let (displayList, _) = graph.displayList()
66+
print(displayList.description)
67+
let expectRegex = try! Regex(#"""
68+
\(display-list
69+
\(item #:identity \d+ #:version \d+
70+
\(frame \([^)]+\)\)
71+
\(effect
72+
\(item #:identity \d+ #:version \d+
73+
\(frame \([^)]+\)\)
74+
\(content-seed \d+\)
75+
\(color #[0-9A-F]{8}\)\)\)\)\)
76+
"""#)
77+
#expect(displayList.description.contains(expectRegex))
78+
}
79+
#endif
80+
}

Tests/OpenSwiftUITests/View/ViewAliasTests.swift

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)