Add CompositionGroup.findParameters to SlotTree

This would allow tools to fetch parameters from a single group
instance which may be found through an anchor.

Bug: 239709530
Test: Added check of findParameters
Relnote: "Add CompositionGroup.findParameters to SlotTree.kt. This
allows tools to retrieve parameters for a CompositionGroup without
having to parse the entire slot table."

Change-Id: I124fee0869556b869a1ed2ee2ce1d90014d1c58e
diff --git a/compose/ui/ui-tooling-data/api/public_plus_experimental_current.txt b/compose/ui/ui-tooling-data/api/public_plus_experimental_current.txt
index 7ff92d0..092a10a 100644
--- a/compose/ui/ui-tooling-data/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-tooling-data/api/public_plus_experimental_current.txt
@@ -78,6 +78,7 @@
 
   public final class SlotTreeKt {
     method @androidx.compose.ui.tooling.data.UiToolingDataApi public static androidx.compose.ui.tooling.data.Group asTree(androidx.compose.runtime.tooling.CompositionData);
+    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> findParameters(androidx.compose.runtime.tooling.CompositionGroup, optional androidx.compose.ui.tooling.data.ContextCache? cache);
     method @androidx.compose.ui.tooling.data.UiToolingDataApi public static String? getPosition(androidx.compose.ui.tooling.data.Group);
     method @androidx.compose.ui.tooling.data.UiToolingDataApi public static <T> T? mapTree(androidx.compose.runtime.tooling.CompositionData, kotlin.jvm.functions.Function3<? super androidx.compose.runtime.tooling.CompositionGroup,? super androidx.compose.ui.tooling.data.SourceContext,? super java.util.List<? extends T>,? extends T> factory, optional androidx.compose.ui.tooling.data.ContextCache cache);
   }
diff --git a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
index eb44e3a..a8d4eee 100644
--- a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
+++ b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
@@ -93,6 +93,7 @@
     @Test
     fun testBoundsWithoutParsingParameters() {
         val lefts = mutableMapOf<String, Dp>()
+        val anchors = mutableMapOf<String, Any?>()
         val slotTableRecord = CompositionDataRecord.create()
         show {
             Inspectable(slotTableRecord) {
@@ -105,10 +106,11 @@
         }
 
         activityTestRule.runOnUiThread {
-            slotTableRecord.store.first().mapTree<Any>({ _, context, _ ->
+            slotTableRecord.store.first().mapTree<Any>({ group, context, _ ->
                 if (context.location?.sourceFile == "BoundsTest.kt") {
                     with(Density(activityTestRule.activity)) {
                         lefts[context.name!!] = context.bounds.left.toDp()
+                        anchors[context.name!!] = group.identity
                     }
                 }
             })
@@ -116,6 +118,11 @@
             assertThat(lefts["Box"]?.value).isWithin(1f).of(0f)
             assertThat(lefts["Column"]?.value).isWithin(1f).of(10f)
             assertThat(lefts["Text"]?.value).isWithin(0.5f).of(15f)
+
+            val textAnchor = anchors["Text"]
+            val textGroup = slotTableRecord.store.first().find(textAnchor!!)!!
+            val textParams = textGroup.findParameters()
+            assertThat(textParams.find { it.name == "text" }?.value).isEqualTo("Hello")
         }
     }
 
diff --git a/compose/ui/ui-tooling-data/src/jvmMain/kotlin/androidx/compose/ui/tooling/data/SlotTree.kt b/compose/ui/ui-tooling-data/src/jvmMain/kotlin/androidx/compose/ui/tooling/data/SlotTree.kt
index 17e2f7c..bd62589 100644
--- a/compose/ui/ui-tooling-data/src/jvmMain/kotlin/androidx/compose/ui/tooling/data/SlotTree.kt
+++ b/compose/ui/ui-tooling-data/src/jvmMain/kotlin/androidx/compose/ui/tooling/data/SlotTree.kt
@@ -712,6 +712,20 @@
 }
 
 /**
+ * Return the parameters found for this [CompositionGroup].
+ */
+@UiToolingDataApi
+fun CompositionGroup.findParameters(cache: ContextCache? = null): List<ParameterInformation> {
+    val information = sourceInfo ?: return emptyList()
+    val context = if (cache == null) sourceInformationContextOf(information) else
+        cache.contexts.getOrPut(information) { sourceInformationContextOf(information) }
+            as? SourceInformationContext
+    val data = mutableListOf<Any?>()
+    data.addAll(this.data)
+    return extractParameterInfo(data, context)
+}
+
+/**
  * Return a group tree for for the slot table that represents the entire content of the slot
  * table.
  */