[Retrace] Lookup source file mappings for inline frames
Bug: 160938883
Change-Id: I557e14f0876218057a7937c310a5884efed85f92
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
index f984045..e13c832 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
@@ -26,15 +26,18 @@
private final ClassReference obfuscatedReference;
private final ClassNamingForNameMapper mapper;
+ private final RetraceApi retracer;
- private RetraceClassResult(ClassReference obfuscatedReference, ClassNamingForNameMapper mapper) {
+ private RetraceClassResult(
+ ClassReference obfuscatedReference, ClassNamingForNameMapper mapper, RetraceApi retracer) {
this.obfuscatedReference = obfuscatedReference;
this.mapper = mapper;
+ this.retracer = retracer;
}
static RetraceClassResult create(
- ClassReference obfuscatedReference, ClassNamingForNameMapper mapper) {
- return new RetraceClassResult(obfuscatedReference, mapper);
+ ClassReference obfuscatedReference, ClassNamingForNameMapper mapper, RetraceApi retracer) {
+ return new RetraceClassResult(obfuscatedReference, mapper, retracer);
}
public RetraceFieldResult lookupField(String fieldName) {
@@ -75,12 +78,12 @@
if (element.mapper != null) {
mappedRangesForT = lookupFunction.apply(element.mapper, name);
}
- elementBox.set(constructor.create(element, mappedRangesForT, name));
+ elementBox.set(constructor.create(element, mappedRangesForT, name, retracer));
});
return elementBox.get();
}
- private boolean hasRetraceResult() {
+ boolean hasRetraceResult() {
return mapper != null;
}
@@ -101,7 +104,7 @@
}
private interface ResultConstructor<T, R> {
- R create(Element element, T mappings, String obfuscatedName);
+ R create(Element element, T mappings, String obfuscatedName, RetraceApi retraceApi);
}
public boolean isAmbiguous() {
@@ -186,7 +189,10 @@
BiFunction<ClassNamingForNameMapper, String, T> lookupFunction,
ResultConstructor<T, R> constructor) {
return constructor.create(
- this, mapper != null ? lookupFunction.apply(mapper, name) : null, name);
+ this,
+ mapper != null ? lookupFunction.apply(mapper, name) : null,
+ name,
+ classResult.retracer);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
index 57b5354..5477eaa 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
@@ -23,14 +23,17 @@
private final RetraceClassResult.Element classElement;
private final List<MemberNaming> memberNamings;
private final String obfuscatedName;
+ private final RetraceApi retracer;
RetraceFieldResult(
RetraceClassResult.Element classElement,
List<MemberNaming> memberNamings,
- String obfuscatedName) {
+ String obfuscatedName,
+ RetraceApi retracer) {
this.classElement = classElement;
this.memberNamings = memberNamings;
this.obfuscatedName = obfuscatedName;
+ this.retracer = retracer;
assert classElement != null;
assert memberNamings == null
|| (!memberNamings.isEmpty() && memberNamings.stream().allMatch(Objects::nonNull));
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
index ff1af91..7977858 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
@@ -26,15 +26,18 @@
private final String obfuscatedName;
private final RetraceClassResult.Element classElement;
private final MappedRangesOfName mappedRanges;
+ private final RetraceApi retracer;
private Boolean isAmbiguousCached = null;
RetraceMethodResult(
RetraceClassResult.Element classElement,
MappedRangesOfName mappedRanges,
- String obfuscatedName) {
+ String obfuscatedName,
+ RetraceApi retracer) {
this.classElement = classElement;
this.mappedRanges = mappedRanges;
this.obfuscatedName = obfuscatedName;
+ this.retracer = retracer;
assert classElement != null;
}
@@ -87,7 +90,7 @@
}
}
return new RetraceMethodResult(
- classElement, new MappedRangesOfName(narrowedRanges), obfuscatedName);
+ classElement, new MappedRangesOfName(narrowedRanges), obfuscatedName, retracer);
}
@Override
@@ -182,7 +185,8 @@
}
public RetraceSourceFileResult retraceSourceFile(String sourceFile) {
- return RetraceUtils.getSourceFile(classElement, methodReference.getHolderClass(), sourceFile);
+ return RetraceUtils.getSourceFile(
+ classElement, methodReference.getHolderClass(), sourceFile, retraceMethodResult.retracer);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java b/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
index 15479f9..40b3f41 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceRegularExpression.java
@@ -838,7 +838,8 @@
: RetraceUtils.getSourceFile(
retraceString.getClassContext(),
retraceString.context.qualifiedContext,
- fileName);
+ fileName,
+ retracer);
retracedStrings.add(
retraceString
.updateContext(context -> context.withSource(sourceFileResult.getFilename()))
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceUtils.java b/src/main/java/com/android/tools/r8/retrace/RetraceUtils.java
index fd569b1..77aff7d 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceUtils.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceUtils.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.utils.Box;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import java.util.Set;
@@ -61,21 +62,33 @@
}
static RetraceSourceFileResult getSourceFile(
- RetraceClassResult.Element classElement, ClassReference context, String sourceFile) {
- // For inline frames we do not have the class element associated with it.
+ RetraceClassResult.Element classElement,
+ ClassReference context,
+ String sourceFile,
+ RetraceApi retracer) {
+ // If no context is specified always retrace using the found class element.
if (context == null) {
return classElement.retraceSourceFile(sourceFile);
}
if (context.equals(classElement.getClassReference())) {
return classElement.retraceSourceFile(sourceFile);
} else {
- return new RetraceSourceFileResult(
- synthesizeFileName(
- context.getTypeName(),
- classElement.getClassReference().getTypeName(),
- sourceFile,
- true),
- true);
+ RetraceClassResult contextClassResult = retracer.retrace(context);
+ assert !contextClassResult.isAmbiguous();
+ if (contextClassResult.hasRetraceResult()) {
+ Box<RetraceSourceFileResult> retraceSourceFile = new Box<>();
+ contextClassResult.forEach(
+ element -> retraceSourceFile.set(element.retraceSourceFile(sourceFile)));
+ return retraceSourceFile.get();
+ } else {
+ return new RetraceSourceFileResult(
+ synthesizeFileName(
+ context.getTypeName(),
+ classElement.getClassReference().getTypeName(),
+ sourceFile,
+ true),
+ true);
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/retrace/Retracer.java b/src/main/java/com/android/tools/r8/retrace/Retracer.java
index b2dad89..0f7d547 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retracer.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retracer.java
@@ -38,7 +38,7 @@
@Override
public RetraceClassResult retrace(ClassReference classReference) {
return RetraceClassResult.create(
- classReference, classNameMapper.getClassNaming(classReference.getTypeName()));
+ classReference, classNameMapper.getClassNaming(classReference.getTypeName()), this);
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
index 9af9e28..8bf3b29 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -24,6 +24,7 @@
import com.android.tools.r8.retrace.stacktraces.FileNameExtensionStackTrace;
import com.android.tools.r8.retrace.stacktraces.InlineFileNameStackTrace;
import com.android.tools.r8.retrace.stacktraces.InlineNoLineNumberStackTrace;
+import com.android.tools.r8.retrace.stacktraces.InlineSourceFileContextStackTrace;
import com.android.tools.r8.retrace.stacktraces.InlineWithLineNumbersStackTrace;
import com.android.tools.r8.retrace.stacktraces.InvalidStackTrace;
import com.android.tools.r8.retrace.stacktraces.NamedModuleStackTrace;
@@ -173,6 +174,11 @@
runRetraceTest(new UnknownSourceStackTrace());
}
+ @Test
+ public void testInlineSourceFileContext() {
+ runRetraceTest(new InlineSourceFileContextStackTrace());
+ }
+
private TestDiagnosticMessagesImpl runRetraceTest(StackTraceForTest stackTraceForTest) {
TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
RetraceCommand retraceCommand =
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineSourceFileContextStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineSourceFileContextStackTrace.java
new file mode 100644
index 0000000..3c22097
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineSourceFileContextStackTrace.java
@@ -0,0 +1,54 @@
+// Copyright (c) 2020, 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.stacktraces;
+
+import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
+import java.util.List;
+
+public class InlineSourceFileContextStackTrace implements StackTraceForTest {
+
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return Arrays.asList(
+ " at com.google.appreduce.remapper.KotlinJavaSourceFileTestObject"
+ + ".main(KotlinJavaSourceFileTestObject.java:1)");
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.joinLines(
+ "com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary ->"
+ + " com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary:",
+ "# {\"id\":\"sourceFile\",\"fileName\":\"KotlinJavaSourceFileTestLibrary.kt\"}",
+ " void <init>() -> <init>",
+ "com.google.appreduce.remapper.KotlinJavaSourceFileTestObject ->"
+ + " com.google.appreduce.remapper.KotlinJavaSourceFileTestObject:",
+ " void <init>() -> <init>",
+ " 1:1:void com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary"
+ + ".throwsException():22:22 -> main",
+ " 1:1:void com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary"
+ + ".callsThrowsException():19 -> main",
+ " 1:1:void main(java.lang.String[]):32 -> main",
+ " 2:7:void printStackTraceUpToMain(java.lang.Exception):19:24 -> main",
+ " 2:7:void main(java.lang.String[]):34 -> main");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return Arrays.asList(
+ " at com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary"
+ + ".throwsException(KotlinJavaSourceFileTestLibrary.kt:22)",
+ " at com.google.appreduce.remapper.KotlinJavaSourceFileTestLibrary"
+ + ".callsThrowsException(KotlinJavaSourceFileTestLibrary.kt:19)",
+ " at com.google.appreduce.remapper.KotlinJavaSourceFileTestObject"
+ + ".main(KotlinJavaSourceFileTestObject.java:32)");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+}