[Retrace] Treat retraced position 0 as no line
Bug: b/232212653
Bug: b/255705077
Change-Id: I008f1c4405def576891df613863ba94aca602935
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
index f82327a..2deef6f 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -228,24 +228,28 @@
OptionalInt originalPosition = mappedRangeForFrame.position;
if (!isAmbiguous()
&& (mappedRange.minifiedRange == null || obfuscatedPosition.orElse(-1) == -1)) {
- int originalLineNumber = mappedRange.getFirstPositionOfOriginalRange(0);
- if (originalLineNumber > 0) {
- return RetracedMethodReferenceImpl.create(
- methodReference, OptionalUtils.orElse(originalPosition, originalLineNumber));
- } else {
- return RetracedMethodReferenceImpl.create(methodReference, originalPosition);
- }
+ return RetracedMethodReferenceImpl.create(
+ methodReference,
+ OptionalUtils.map(
+ originalPosition,
+ () -> {
+ int originalLineNumber = mappedRange.getFirstPositionOfOriginalRange(0);
+ return originalLineNumber > 0
+ ? OptionalInt.of(originalLineNumber)
+ : OptionalInt.empty();
+ }));
}
- if (!obfuscatedPosition.isPresent()
+ if (obfuscatedPosition.isEmpty()
|| mappedRange.minifiedRange == null
|| !mappedRange.minifiedRange.contains(obfuscatedPosition.getAsInt())) {
return RetracedMethodReferenceImpl.create(methodReference, originalPosition);
}
return RetracedMethodReferenceImpl.create(
methodReference,
- OptionalUtils.orElseGet(
+ OptionalUtils.map(
originalPosition,
- () -> mappedRange.getOriginalLineNumber(obfuscatedPosition.getAsInt())));
+ () ->
+ OptionalInt.of(mappedRange.getOriginalLineNumber(obfuscatedPosition.getAsInt()))));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
index 761a124..b88958e 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
@@ -115,6 +115,9 @@
}
try {
String lineNumberString = getEntryInLine(lineNumber);
+ if (lineNumberString.startsWith(":")) {
+ lineNumberString = lineNumberString.substring(1);
+ }
if (lineNumberString.isEmpty()) {
return -1;
}
@@ -238,14 +241,15 @@
startIndex,
endIndex,
(retraced, original, verbose) -> {
- boolean printLineNumber =
- retraced.hasLineNumber()
- && ((original.hasLineNumber() && original.getLineNumber() > -1)
- || !retraced.isAmbiguous()
- || verbose);
- return printLineNumber
- ? ((insertSeparatorForRetraced ? ":" : "") + retraced.getLineNumber())
- : original.lineNumberAsString();
+ if (retraced.hasLineNumber()
+ && ((original.hasLineNumber() && original.getLineNumber() > -1)
+ || !retraced.isAmbiguous()
+ || verbose)) {
+ return retraced.getLineNumber() <= 0
+ ? ""
+ : ((insertSeparatorForRetraced ? ":" : "") + retraced.getLineNumber());
+ }
+ return original.lineNumberAsString();
});
orderedIndices.add(lineNumber);
return this;
@@ -326,6 +330,10 @@
}
lastSeenStartIndex = newStartIndex;
}
+
+ public String getLine() {
+ return line;
+ }
}
static class StringIndex {
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
index bf9123e..b73c9bc 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceRegularExpressionParser.java
@@ -297,7 +297,15 @@
if (startOfGroup == NO_MATCH) {
return false;
}
- builder.registerLineNumber(startOfGroup, matcher.end(captureGroup), false);
+ boolean insertSeparatorForRetraced = false;
+ // We need to include ':' in the group since we may want to rewrite '(SourceFile:0)` into
+ // (SourceFile) and not (SourceFile:)
+ if (startOfGroup > 0 && builder.getLine().charAt(startOfGroup + -1) == ':') {
+ startOfGroup = startOfGroup - 1;
+ insertSeparatorForRetraced = true;
+ }
+ int end = matcher.end(captureGroup);
+ builder.registerLineNumber(startOfGroup, end, insertSeparatorForRetraced);
return true;
};
}
@@ -321,9 +329,10 @@
int sourceFileEnd = startOfGroup + endOfSourceFileInGroup;
builder.registerSourceFile(startOfGroup, sourceFileEnd);
int endOfMatch = matcher.end(captureGroup);
- int lineNumberStart = sourceFileEnd + 1;
- builder.registerLineNumber(
- Integer.min(lineNumberStart, endOfMatch), endOfMatch, lineNumberStart > endOfMatch);
+ // We need to include ':' in the group since we may want to rewrite '(SourceFile:0)` into
+ // (SourceFile) and not (SourceFile:). We fix this by setting the start of the linenumber
+ // group to the end of the SourceFile group and then force inserting ':'.
+ builder.registerLineNumber(Integer.min(sourceFileEnd, endOfMatch), endOfMatch, true);
return true;
};
}
diff --git a/src/main/java/com/android/tools/r8/utils/OptionalUtils.java b/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
index 974bf0c..925ca07 100644
--- a/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/OptionalUtils.java
@@ -9,11 +9,8 @@
public class OptionalUtils {
- public static OptionalInt orElse(OptionalInt optional, int orElse) {
- return optional.isPresent() ? optional : OptionalInt.of(orElse);
+ public static OptionalInt map(OptionalInt optional, Supplier<OptionalInt> orElse) {
+ return optional.isPresent() ? optional : orElse.get();
}
- public static OptionalInt orElseGet(OptionalInt optional, Supplier<Integer> orElse) {
- return optional.isPresent() ? optional : OptionalInt.of(orElse.get());
- }
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
index c39d3ef..655e6a8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
@@ -60,7 +60,8 @@
// TODO(b/124483578): Stack trace lines from the merging of equivalent
// constructors should retrace to the set of lines from each of the
// individual source constructors.
- .map(1, stackTraceLine -> stackTraceLine.builderOf().setLineNumber(0).build())
+ .map(
+ 1, stackTraceLine -> stackTraceLine.builderOf().setLineNumber(-1).build())
.build();
assertThat(stackTrace, isSame(expectedStackTraceWithMergedConstructor));
assertThat(codeInspector.clazz(B.class), not(isPresent()));
diff --git a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
index c164fa7..ba0dba3 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
@@ -150,7 +150,7 @@
.setClassName(TEST_CLASS)
.setFileName(TEST_FILE)
.setMethodName(methodName)
- .setLineNumber(hasPosition ? location.line : 0)
+ .setLineNumber(hasPosition ? location.line : -1)
.build();
}
}
diff --git a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
index f0d4c89..3831e44 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/NoLineInfoTest.java
@@ -207,17 +207,16 @@
private StackTrace getUnexpectedRetracedStacktrace() {
assertFalse(parameters.isCfRuntime());
StackTraceLine fooLine;
- if (customSourceFile) {
- // TODO(b/232212653): Should retrace convert out of "0" and represent it as <noline>/-1?
- fooLine = inputLine("foo", 0);
- } else if (isRuntimeWithPcAsLineNumberSupport()) {
+ if (isRuntimeWithPcAsLineNumberSupport() && !customSourceFile) {
// TODO(b/232212653): Retrace should convert PC 1 to line <noline>/-1/0.
fooLine = inputLine("foo", 1);
} else {
fooLine = inputLine("foo", -1);
}
- StackTraceLine barLine = inputLine("bar", getPcEncoding(0));
- StackTraceLine bazLine = inputLine("baz", getPcEncoding(0));
+ int position =
+ isCompileWithPcAsLineNumberSupport() && !customSourceFile ? -1 : getPcEncoding(0);
+ StackTraceLine barLine = inputLine("bar", position);
+ StackTraceLine bazLine = inputLine("baz", position);
return StackTrace.builder()
.add(fooLine)
.add(barLine)
diff --git a/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java b/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
index 3695c0e..d0a41c5 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/OverloadWithNoLineNumberTest.java
@@ -65,8 +65,8 @@
String className = typeName(SimpleCallChainClassWithOverloads.class);
assertEquals(
StringUtils.joinLines(
- "\tat " + className + ".void test(long)(" + SOURCE_FILE_NAME + ":0)",
- "\tat " + className + ".void test()(" + SOURCE_FILE_NAME + ":0)",
+ "\tat " + className + ".void test(long)(" + SOURCE_FILE_NAME + ")",
+ "\tat " + className + ".void test()(" + SOURCE_FILE_NAME + ")",
"\tat "
+ className
+ ".void main(java.lang.String[])("
diff --git a/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java b/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
index cbe2680..b1c1b96 100644
--- a/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/OverloadsWithoutLineNumberTest.java
@@ -66,7 +66,7 @@
assertEquals(
"\tat "
+ typeName(ClassWithOverload.class)
- + ".void test(int)(OverloadsWithoutLineNumberTest.java:0)",
+ + ".void test(int)(OverloadsWithoutLineNumberTest.java)",
box.get().get(1));
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
index 048b941..b8243aa 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameStackTrace.java
@@ -21,7 +21,7 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz.baz(Bar.java:0)",
+ "\tat foo.Bar$Baz.baz(Bar.java)",
"\tat Foo$Bar.bar(Foo.java:2)",
"\tat com.android.tools.r8.naming.retrace.Main$Foo.method1(Main.java:8)",
"\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:7)");
@@ -31,7 +31,7 @@
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz.void baz(long)(Bar.java:0)",
+ "\tat foo.Bar$Baz.void baz(long)(Bar.java)",
"\tat Foo$Bar.void bar(int)(Foo.java:2)",
"\tat com.android.tools.r8.naming.retrace.Main$Foo"
+ ".void method1(java.lang.String)(Main.java:8)",
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
index 177eb8a..1c53b40 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineFileNameWithInnerClassesStackTrace.java
@@ -21,7 +21,7 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz$Qux.baz(Bar.java:0)",
+ "\tat foo.Bar$Baz$Qux.baz(Bar.java)",
"\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:7)");
}
@@ -29,7 +29,7 @@
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat foo.Bar$Baz$Qux.void baz(long)(Bar.java:0)",
+ "\tat foo.Bar$Baz$Qux.void baz(long)(Bar.java)",
"\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:7)");
}
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
index 763ec80..28e94c5 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/InlineNoLineNumberStackTrace.java
@@ -21,20 +21,20 @@
public List<String> retracedStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat com.android.tools.r8.naming.retrace.Main.method3(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.method3(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.method2(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.method1(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)");
}
@Override
public List<String> retraceVerboseStackTrace() {
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
- "\tat com.android.tools.r8.naming.retrace.Main.void method3(long)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void method2(int)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void method1(java.lang.String)(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.void method3(long)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void method2(int)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void method1(java.lang.String)(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
index 8ec36a8..67a0d43 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/NoObfuscationRangeMappingWithStackTrace.java
@@ -26,8 +26,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
"\tat com.android.tools.r8.naming.retrace.Main.foo(Main.java:1)",
"\tat com.android.tools.r8.naming.retrace.Main.bar(Main.java:3)",
- "\tat com.android.tools.r8.naming.retrace.Main.baz(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.baz(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.main(Main.java)");
}
@Override
@@ -36,8 +36,8 @@
"Exception in thread \"main\" java.lang.NullPointerException",
"\tat com.android.tools.r8.naming.retrace.Main.void foo(long)(Main.java:1)",
"\tat com.android.tools.r8.naming.retrace.Main.void bar(int)(Main.java:3)",
- "\tat com.android.tools.r8.naming.retrace.Main.void baz()(Main.java:0)",
- "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java:0)");
+ "\tat com.android.tools.r8.naming.retrace.Main.void baz()(Main.java)",
+ "\tat com.android.tools.r8.naming.retrace.Main.void main(java.lang.String[])(Main.java)");
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java b/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
index 98a6ed6..bbd72bd 100644
--- a/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
+++ b/src/test/java/com/android/tools/r8/retrace/stacktraces/PreambleLineNumberStackTrace.java
@@ -33,7 +33,7 @@
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
" at kotlin.ResultKt.createFailure(Result.kt)",
- " at kotlin.ResultKt.createFailure(Result.kt:0)",
+ " at kotlin.ResultKt.createFailure(Result.kt)",
" at kotlin.ResultKt.createFailure(Result.kt:122)",
" at kotlin.ResultKt.createFailure(Result.kt:124)");
}
@@ -43,7 +43,7 @@
return Arrays.asList(
"Exception in thread \"main\" java.lang.NullPointerException",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt)",
- " at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:0)",
+ " at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt)",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:122)",
" at kotlin.ResultKt.void createFailure(java.lang.Throwable)(Result.kt:124)");
}