[Retrace] Add test for using MappingSupplier in Retrace
Bug: b/277673018
Change-Id: Ifb3feb975a120e18f97d74dc7d48f97bc787e7bc
diff --git a/src/main/java/com/android/tools/r8/retrace/Retrace.java b/src/main/java/com/android/tools/r8/retrace/Retrace.java
index 3d2740a..75d03af 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -160,16 +160,19 @@
private final StackTraceLineParser<T, ST> stackTraceLineParser;
private final StackTraceElementProxyRetracer<T, ST> proxyRetracer;
+ private final MappingSupplier<?> mappingSupplier;
private final DiagnosticsHandler diagnosticsHandler;
protected final boolean isVerbose;
Retrace(
StackTraceLineParser<T, ST> stackTraceLineParser,
StackTraceElementProxyRetracer<T, ST> proxyRetracer,
+ MappingSupplier<?> mappingSupplier,
DiagnosticsHandler diagnosticsHandler,
boolean isVerbose) {
this.stackTraceLineParser = stackTraceLineParser;
this.proxyRetracer = proxyRetracer;
+ this.mappingSupplier = mappingSupplier;
this.diagnosticsHandler = diagnosticsHandler;
this.isVerbose = isVerbose;
}
@@ -503,6 +506,7 @@
private StackTraceLineParser<T, ST> stackTraceLineParser;
private StackTraceElementProxyRetracer<T, ST> proxyRetracer;
+ private MappingSupplier<?> mappingSupplier;
private DiagnosticsHandler diagnosticsHandler;
protected boolean isVerbose;
@@ -512,15 +516,30 @@
return this;
}
+ /***
+ * Set a final constructed retracer where discovery of keys has been done.
+ */
public Builder<T, ST> setRetracer(Retracer retracer) {
return setProxyRetracer(StackTraceElementProxyRetracer.createDefault(retracer));
}
+ /***
+ * Set a final constructed proxy retracer where discovery of keys has been done.
+ */
public Builder<T, ST> setProxyRetracer(StackTraceElementProxyRetracer<T, ST> proxyRetracer) {
this.proxyRetracer = proxyRetracer;
return this;
}
+ /***
+ * Set a mapping supplier to be used for retracing where keys needed will be discovered when
+ * performing the actual retracing.
+ */
+ public Builder<T, ST> setMappingSupplier(MappingSupplier<?> mappingSupplier) {
+ this.mappingSupplier = mappingSupplier;
+ return this;
+ }
+
public Builder<T, ST> setDiagnosticsHandler(DiagnosticsHandler diagnosticsHandler) {
this.diagnosticsHandler = diagnosticsHandler;
return this;
@@ -532,7 +551,8 @@
}
public Retrace<T, ST> build() {
- return new Retrace<>(stackTraceLineParser, proxyRetracer, diagnosticsHandler, isVerbose);
+ return new Retrace<>(
+ stackTraceLineParser, proxyRetracer, mappingSupplier, diagnosticsHandler, isVerbose);
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
index 5a7a797..4cbe9e7 100644
--- a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
@@ -30,7 +30,7 @@
StackTraceElementProxyRetracer<String, StackTraceElementStringProxy> proxyRetracer,
DiagnosticsHandler diagnosticsHandler,
boolean isVerbose) {
- super(stackTraceLineParser, proxyRetracer, diagnosticsHandler, isVerbose);
+ super(stackTraceLineParser, proxyRetracer, null, diagnosticsHandler, isVerbose);
}
/**
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionStackTraceTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionStackTraceTest.java
new file mode 100644
index 0000000..801a369
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetracePartitionStackTraceTest.java
@@ -0,0 +1,211 @@
+// Copyright (c) 2023, 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.
+
+package com.android.tools.r8.retrace.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.naming.retrace.StackTrace;
+import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.retrace.MappingPartitionMetadata;
+import com.android.tools.r8.retrace.PartitionMappingSupplier;
+import com.android.tools.r8.retrace.ProguardMapPartitioner;
+import com.android.tools.r8.retrace.ProguardMapProducer;
+import com.android.tools.r8.retrace.Retrace;
+import com.android.tools.r8.retrace.RetraceStackTraceContext;
+import com.android.tools.r8.retrace.RetraceStackTraceElementProxy;
+import com.android.tools.r8.retrace.RetracedMethodReference.KnownRetracedMethodReference;
+import com.android.tools.r8.retrace.StackTraceElementProxy;
+import com.android.tools.r8.retrace.StackTraceLineParser;
+import com.android.tools.r8.utils.BooleanBox;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class RetracePartitionStackTraceTest extends TestBase {
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ public RetracePartitionStackTraceTest(TestParameters parameters) {
+ parameters.assertNoneRuntime();
+ }
+
+ private final String MAPPING =
+ StringUtils.unixLines(
+ "com.Foo -> a:",
+ " 1:1:void m1():42:42 -> a",
+ "com.Bar -> b:",
+ " 2:2:void m2():43:43 -> b",
+ "com.Baz -> c:",
+ " 3:3:void m3():44:44 -> c");
+
+ @Test
+ public void testRetrace() throws Exception {
+ TestDiagnosticMessagesImpl diagnosticMessages = new TestDiagnosticMessagesImpl();
+ Map<String, byte[]> partitions = new HashMap<>();
+ MappingPartitionMetadata metadata =
+ ProguardMapPartitioner.builder(diagnosticMessages)
+ .setProguardMapProducer(ProguardMapProducer.fromString(MAPPING))
+ .setPartitionConsumer(
+ partition -> partitions.put(partition.getKey(), partition.getPayload()))
+ .build()
+ .run();
+
+ Set<String> requestedKeys = new HashSet<>();
+ BooleanBox setPartitionCallBack = new BooleanBox();
+ PartitionMappingSupplier mappingSupplier =
+ PartitionMappingSupplier.builder()
+ .setMetadata(metadata.getBytes())
+ .setRegisterMappingPartitionCallback(requestedKeys::add)
+ .setPrepareMappingPartitionsCallback(setPartitionCallBack::set)
+ .setMappingPartitionFromKeySupplier(partitions::get)
+ .build();
+
+ Retrace<StackTraceLine, StackTraceLineProxy> retrace =
+ Retrace.<StackTraceLine, StackTraceLineProxy>builder()
+ .setMappingSupplier(mappingSupplier)
+ .setStackTraceLineParser(StackTraceLineProxy::new)
+ .setDiagnosticsHandler(diagnosticMessages)
+ .build();
+
+ List<StackTraceLine> minifiedStackTrace = new ArrayList<>();
+ minifiedStackTrace.add(StackTraceLine.parse("at a.a(SourceFile:1)"));
+ minifiedStackTrace.add(StackTraceLine.parse("at b.b(SourceFile:2)"));
+ minifiedStackTrace.add(StackTraceLine.parse("at c.c(SourceFile:3)"));
+ StackTrace.Builder retraceStackTraceBuilder = StackTrace.builder();
+ // TODO(b/277673018): Ensure that we can use a mapping supplier directly.
+ assertThrows(
+ NullPointerException.class,
+ () ->
+ retrace
+ .retraceStackTrace(minifiedStackTrace, RetraceStackTraceContext.empty())
+ .forEach(
+ stackTraceLines -> {
+ assertEquals(1, stackTraceLines.size());
+ stackTraceLines.get(0).forEach(retraceStackTraceBuilder::add);
+ }));
+ }
+
+ public static class IdentityStackTraceLineParser
+ implements StackTraceLineParser<StackTraceLine, StackTraceLineProxy> {
+
+ @Override
+ public StackTraceLineProxy parse(StackTraceLine stackTraceLine) {
+ return new StackTraceLineProxy(stackTraceLine);
+ }
+ }
+
+ public static class StackTraceLineProxy
+ extends StackTraceElementProxy<StackTraceLine, StackTraceLineProxy> {
+
+ private final StackTraceLine stackTraceLine;
+
+ public StackTraceLineProxy(StackTraceLine stackTraceLine) {
+ this.stackTraceLine = stackTraceLine;
+ }
+
+ @Override
+ public boolean hasClassName() {
+ return true;
+ }
+
+ @Override
+ public boolean hasMethodName() {
+ return true;
+ }
+
+ @Override
+ public boolean hasSourceFile() {
+ return true;
+ }
+
+ @Override
+ public boolean hasLineNumber() {
+ return true;
+ }
+
+ @Override
+ public boolean hasFieldName() {
+ return false;
+ }
+
+ @Override
+ public boolean hasFieldOrReturnType() {
+ return false;
+ }
+
+ @Override
+ public boolean hasMethodArguments() {
+ return false;
+ }
+
+ @Override
+ public ClassReference getClassReference() {
+ return Reference.classFromTypeName(stackTraceLine.className);
+ }
+
+ @Override
+ public String getMethodName() {
+ return stackTraceLine.methodName;
+ }
+
+ @Override
+ public String getSourceFile() {
+ return stackTraceLine.fileName;
+ }
+
+ @Override
+ public int getLineNumber() {
+ return stackTraceLine.lineNumber;
+ }
+
+ @Override
+ public String getFieldName() {
+ return null;
+ }
+
+ @Override
+ public String getFieldOrReturnType() {
+ return null;
+ }
+
+ @Override
+ public String getMethodArguments() {
+ return null;
+ }
+
+ @Override
+ public StackTraceLine toRetracedItem(
+ RetraceStackTraceElementProxy<StackTraceLine, StackTraceLineProxy> retracedProxy,
+ boolean verbose) {
+ KnownRetracedMethodReference knownRetracedMethodReference =
+ retracedProxy.getRetracedMethod().asKnown();
+ return new StackTraceLine(
+ stackTraceLine.toString(),
+ knownRetracedMethodReference.getMethodReference().getHolderClass().getTypeName(),
+ knownRetracedMethodReference.getMethodName(),
+ retracedProxy.getSourceFile(),
+ knownRetracedMethodReference.getOriginalPositionOrDefault(0));
+ }
+ }
+}