blob: 3bc2eb2185be6707dae08a0b9de40063c12bab3c [file] [log] [blame]
// Copyright (c) 2022, 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.assertNotNull;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestParameters;
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.RetraceFrameElement;
import com.android.tools.r8.retrace.RetraceStackTraceContext;
import com.android.tools.r8.retrace.Retracer;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class RetracePartitionRoundTripInlineTest extends RetraceApiTestBase {
public RetracePartitionRoundTripInlineTest(TestParameters parameters) {
super(parameters);
}
@Override
protected Class<? extends RetraceApiBinaryTest> binaryTestClass() {
return ApiTest.class;
}
public static class ApiTest implements RetraceApiBinaryTest {
private final ClassReference callerOriginal = Reference.classFromTypeName("some.Class");
private final ClassReference callerRenamed = Reference.classFromTypeName("b");
private final String mapping =
"# { id: 'com.android.tools.r8.mapping', version: '2.0' }\n"
+ "inlinee.Class -> inlinee.Class:\n"
+ " # {'id':'sourceFile','fileName':'InlineeClass.kt'}\n"
+ callerOriginal.getTypeName()
+ " -> "
+ callerRenamed.getTypeName()
+ ":\n"
+ " # {'id':'sourceFile','fileName':'CallerClass.kt'}\n"
+ " 1:1:void inlinee.Class.bar():42:42 -> a\n"
+ " 1:1:void foo():43 -> a\n";
private int prepareCounter = 0;
@Test
public void test() throws IOException {
ProguardMapProducer proguardMapProducer = ProguardMapProducer.fromString(mapping);
Map<String, byte[]> partitions = new HashMap<>();
MappingPartitionMetadata metadataData =
ProguardMapPartitioner.builder(new DiagnosticsHandler() {})
.setProguardMapProducer(proguardMapProducer)
.setPartitionConsumer(
partition -> partitions.put(partition.getKey(), partition.getPayload()))
.build()
.run();
assertNotNull(metadataData);
assertEquals(2, partitions.size());
Set<String> preFetchedKeys = new LinkedHashSet<>();
PartitionMappingSupplier mappingSupplier =
PartitionMappingSupplier.builder()
.setMetadata(metadataData.getBytes())
.setRegisterMappingPartitionCallback(preFetchedKeys::add)
.setPrepareMappingPartitionsCallback(() -> prepareCounter++)
.setMappingPartitionFromKeySupplier(
key -> {
assertTrue(preFetchedKeys.contains(key));
assertTrue(partitions.containsKey(key));
return partitions.get(key);
})
.build();
assertEquals(0, prepareCounter);
Retracer retracer = Retracer.builder().setMappingSupplier(mappingSupplier).build();
List<RetraceFrameElement> callerRetraced =
retracer
.retraceFrame(
RetraceStackTraceContext.empty(),
OptionalInt.of(1),
Reference.methodFromDescriptor(callerRenamed, "a", "()V"))
.stream()
.collect(Collectors.toList());
// The retrace result should not be ambiguous or empty.
assertEquals(1, callerRetraced.size());
assertEquals(1, preFetchedKeys.size());
assertEquals(1, prepareCounter);
RetraceFrameElement retraceFrameElement = callerRetraced.get(0);
// Check that visiting all frames report all source files.
List<String> allSourceFiles =
retraceFrameElement.stream()
.map(x -> x.getSourceFile().getOrInferSourceFile())
.collect(Collectors.toList());
assertEquals(Arrays.asList("InlineeClass.kt", "CallerClass.kt"), allSourceFiles);
}
}
}