Add a script for extracting @Composable size
Change-Id: I7bc335ae240196bd3b5b353f40da7fffe1562183
diff --git a/scripts/ComposableSizeInApk.java b/scripts/ComposableSizeInApk.java
new file mode 100644
index 0000000..04b8017
--- /dev/null
+++ b/scripts/ComposableSizeInApk.java
@@ -0,0 +1,48 @@
+// Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.optimize.compose.ComposeReferences;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.timing.Timing;
+import com.google.common.collect.Streams;
+import java.io.IOException;
+import java.nio.file.Paths;
+
+public class ComposableSizeInApk {
+
+ public static void main(String[] args) throws IOException {
+ AndroidApp androidApp = AndroidApp.builder().addProgramFile(Paths.get(args[0])).build();
+ InternalOptions options = new InternalOptions();
+ ComposeReferences composeReferences = new ComposeReferences(options.dexItemFactory());
+ int size =
+ new ApplicationReader(androidApp, options, Timing.empty())
+ .read().classes().stream()
+ .flatMap(c -> Streams.stream(c.programMethods()))
+ .filter(m -> m.getAnnotations().hasAnnotation(composeReferences.composableType))
+ .filter(m -> m.getDefinition().hasCode())
+ .mapToInt(m -> m.getDefinition().getCode().asDexCode().codeSizeInBytes())
+ .sum();
+ if (size == 0) {
+ String name = "androidx.compose.runtime.Composable";
+ System.err.println("Warning: To collect the size of @Composable functions, ");
+ System.err.println("all @Composable annotations must be retained.");
+ System.err.println("");
+ System.err.println("This can be achieved using the following keep annotation:");
+ System.err.println("");
+ System.err.println("@KeepEdge(");
+ System.err.println("consequences =");
+ System.err.println(" @KeepTarget(");
+ System.err.println(" kind = KeepItemKind.ONLY_METHODS,");
+ System.err.println(" methodAnnotatedByClassName = \"" + name + "\",");
+ System.err.println(" constraints = {},");
+ System.err.println(" constrainAnnotations =");
+ System.err.println(" @AnnotationPattern(");
+ System.err.println(" name = \"" + name + "\",");
+ System.err.println(" retention = RetentionPolicy.CLASS)))");
+ }
+ System.out.println(size);
+ }
+}
diff --git a/scripts/composable-size-in-apk.sh b/scripts/composable-size-in-apk.sh
new file mode 100755
index 0000000..6e0fc08
--- /dev/null
+++ b/scripts/composable-size-in-apk.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Copyright (c) 2025, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+SCRIPTS_DIR=$(dirname "$0")
+BUILD_DIR=$(realpath "$SCRIPTS_DIR/../build")
+
+java -cp $BUILD_DIR/libs/r8.jar:$BUILD_DIR/libs/test_deps_all.jar \
+ $SCRIPTS_DIR/ComposableSizeInApk.java $1