1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.compose.runtime.tooling
18
19 import androidx.compose.runtime.Composable
20 import androidx.compose.runtime.ComposeNodeLifecycleCallback
21 import androidx.compose.runtime.Composition
22 import androidx.compose.runtime.DisposableEffect
23 import androidx.compose.runtime.NonRestartableComposable
24 import androidx.compose.runtime.ReusableComposeNode
25 import androidx.compose.runtime.key
26 import androidx.compose.runtime.mock.View
27 import androidx.compose.runtime.mock.ViewApplier
28 import androidx.compose.runtime.remember
29 import androidx.compose.runtime.rememberCompositionContext
30 import androidx.compose.runtime.rememberUpdatedState
31
32 /**
33 * These composables are kept in a separate file to test line offsets in traces. When adding new
34 * composables, add to the end of the file to avoid breaking existing expectations.
35 */
36
37 /*
38 ┌─ reserved in case more imports will be added (╯°□°)╯︵ ┻━┻
39 │
40 │
41 │
42 │
43 │
44 │
45 │
46 │
47 │
48 │
49 │
50 │
51 │
52 └─
53 */
54
55 @Composable
56 inline fun InlineWrapper(block: @Composable () -> Unit) {
57 block()
58 }
59
60 @Composable
Subcomposenull61 fun Subcompose(content: @Composable () -> Unit) {
62 val context = rememberCompositionContext()
63 val composition = remember(context) { Composition(ViewApplier(View()), context) }
64 val currentContent = rememberUpdatedState(content)
65 DisposableEffect(composition) {
66 composition.setContent { currentContent.value() }
67 onDispose { composition.dispose() }
68 }
69 }
70
71 @Composable
Linearnull72 fun Linear(content: @Composable () -> Unit) {
73 ReusableComposeNode<View, ViewApplier>(
74 factory = { View().also { it.name = "linear" } },
75 update = {}
76 ) {
77 content()
78 }
79 }
80
81 @Composable
82 inline fun InlineLinear(content: @Composable () -> Unit) {
83 ReusableComposeNode<View, ViewApplier>(
<lambda>null84 factory = { View().also { it.name = "linear" } },
<lambda>null85 update = {}
<lambda>null86 ) {
87 content()
88 }
89 }
90
91 @Composable
Repeatednull92 fun <T : Any> Repeated(of: Iterable<T>, block: @Composable (value: T) -> Unit) {
93 for (value in of) {
94 key(value) { block(value) }
95 }
96 }
97
98 @Composable
99 @NonRestartableComposable
Textnull100 fun Text(value: String) {
101 ReusableComposeNode<View, ViewApplier>(
102 factory = { View().also { it.name = "text" } },
103 update = { set(value) { text = it } }
104 )
105 }
106
107 @Composable
ComposableWithDefaultsnull108 fun ComposableWithDefaults(value: String = remember { "" }, block: @Composable (String) -> Unit) {
109 block(value)
110 }
111
112 @Composable
NodeWithCallbacksnull113 fun NodeWithCallbacks(
114 onAttach: () -> Unit = {},
<lambda>null115 onDetach: () -> Unit = {},
<lambda>null116 onUpdate: () -> Unit = {},
<lambda>null117 onReuse: () -> Unit = {},
<lambda>null118 onDeactivate: () -> Unit = {},
<lambda>null119 onRelease: () -> Unit = {}
120 ) {
121 ReusableComposeNode<View, ViewApplier>(
<lambda>null122 factory = {
123 object : View(), ComposeNodeLifecycleCallback {
124 init {
125 this.name = "node_w_callbacks"
126 this.onAttach = onAttach
127 this.onDetach = onDetach
128 }
129
130 override fun onReuse() {
131 onReuse()
132 }
133
134 override fun onDeactivate() {
135 onDeactivate()
136 }
137
138 override fun onRelease() {
139 onRelease()
140 }
141 }
142 },
<lambda>null143 update = { onUpdate() }
144 )
145 }
146
147 @Composable
Wrappernull148 fun Wrapper(content: @Composable () -> Unit) {
149 content()
150 }
151