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