[Retrace] Extend retrace method arguments to account for spaces
Bug: b/301007957
Change-Id: If7af0e3ed1d7b978955f425254405ed592f92168
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
index 08598e7..263ca19 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
@@ -9,7 +9,9 @@
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
-import java.util.Arrays;
+import com.google.common.base.Splitter;
+import java.util.ArrayList;
+import java.util.List;
@Keep
public abstract class StackTraceElementProxy<T, ST extends StackTraceElementProxy<T, ST>> {
@@ -42,6 +44,17 @@
public abstract String getMethodArguments();
+ public List<TypeReference> getMethodArgumentTypeReferences() {
+ if (!hasMethodArguments()) {
+ return null;
+ }
+ List<TypeReference> typeReferences = new ArrayList<>();
+ for (String typeName : Splitter.onPattern(",\\s*").split(getMethodArguments())) {
+ typeReferences.add(Reference.typeFromTypeName(typeName));
+ }
+ return typeReferences;
+ }
+
public abstract T toRetracedItem(
RetraceStackTraceElementProxy<T, ST> retracedProxy, boolean verbose);
@@ -51,21 +64,21 @@
mappingSupplier.registerClassUse(diagnosticsHandler, getClassReference());
}
if (hasMethodArguments()) {
- Arrays.stream(getMethodArguments().split(","))
+ getMethodArgumentTypeReferences()
.forEach(
- typeName ->
- registerUseFromTypeReference(mappingSupplier, typeName, diagnosticsHandler));
+ typeReference ->
+ registerUseFromTypeReference(mappingSupplier, typeReference, diagnosticsHandler));
}
if (hasFieldOrReturnType() && !getFieldOrReturnType().equals("void")) {
- registerUseFromTypeReference(mappingSupplier, getFieldOrReturnType(), diagnosticsHandler);
+ registerUseFromTypeReference(
+ mappingSupplier, Reference.typeFromTypeName(getFieldOrReturnType()), diagnosticsHandler);
}
}
private static void registerUseFromTypeReference(
MappingSupplierBase<?> mappingSupplier,
- String typeName,
+ TypeReference typeReference,
DiagnosticsHandler diagnosticsHandler) {
- TypeReference typeReference = Reference.typeFromTypeName(typeName);
if (typeReference.isArray()) {
typeReference = typeReference.asArray().getBaseType();
}
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
index 18623af..e8ef899 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
@@ -29,7 +29,6 @@
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.ListUtils;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.OptionalInt;
import java.util.function.Consumer;
@@ -280,8 +279,8 @@
return currentResult;
}
List<RetraceTypeResult> retracedResults =
- Arrays.stream(element.getMethodArguments().split(","))
- .map(typeName -> retracer.retraceType(Reference.typeFromTypeName(typeName)))
+ element.getMethodArgumentTypeReferences().stream()
+ .map(retracer::retraceType)
.collect(Collectors.toList());
List<List<RetracedTypeReference>> initial = new ArrayList<>();
initial.add(new ArrayList<>());
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 b7bdf62..9c8569f 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
@@ -312,8 +312,31 @@
if (!retraced.hasRetracedMethodArguments()) {
return original.getMethodArguments();
}
- return StringUtils.join(
- ",", retraced.getRetracedMethodArguments(), RetracedTypeReference::getTypeName);
+ if (retraced.getRetracedMethodArguments().isEmpty()) {
+ return "";
+ }
+ // Create a new arguments string matching the old one but maintain all spacing.
+ StringBuilder result = new StringBuilder();
+ String originalMethodArguments = original.getMethodArguments();
+ int argumentSeparatorIndex = 0;
+ boolean isNotFirst = false;
+ for (RetracedTypeReference retracedMethodArgument :
+ retraced.getRetracedMethodArguments()) {
+ if (isNotFirst) {
+ result.append(",");
+ }
+ int spacesToInsert =
+ StringUtils.firstNonWhitespaceCharacter(
+ originalMethodArguments, argumentSeparatorIndex)
+ - argumentSeparatorIndex;
+ result.append(" ".repeat(spacesToInsert));
+ result.append(retracedMethodArgument.getTypeName());
+ argumentSeparatorIndex =
+ originalMethodArguments.indexOf(',', argumentSeparatorIndex + spacesToInsert)
+ + 1;
+ isNotFirst = true;
+ }
+ return result.toString();
});
orderedIndices.add(methodArguments);
return this;
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 e75aad4..360621e 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
@@ -389,7 +389,11 @@
@Override
String subExpression() {
- return "((" + JAVA_TYPE_REGULAR_EXPRESSION + "\\,)*" + JAVA_TYPE_REGULAR_EXPRESSION + ")?";
+ return "(("
+ + JAVA_TYPE_REGULAR_EXPRESSION
+ + "\\,\\s*)*"
+ + JAVA_TYPE_REGULAR_EXPRESSION
+ + ")?";
}
@Override
diff --git a/src/main/java/com/android/tools/r8/utils/StringUtils.java b/src/main/java/com/android/tools/r8/utils/StringUtils.java
index 7f22a4b..082fa95 100644
--- a/src/main/java/com/android/tools/r8/utils/StringUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/StringUtils.java
@@ -459,6 +459,15 @@
return string.length();
}
+ public static int firstNonWhitespaceCharacter(String string, int index) {
+ for (int i = index; i < string.length(); i++) {
+ if (!isWhitespace(string.charAt(i))) {
+ return i;
+ }
+ }
+ return string.length();
+ }
+
public static String replaceAll(String subject, Map<String, String> map) {
for (Entry<String, String> entry : map.entrySet()) {
subject = replaceAll(subject, entry.getKey(), entry.getValue());
diff --git a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
index abcf319..27e6084 100644
--- a/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/StackTraceRegularExpressionParserTests.java
@@ -826,6 +826,87 @@
}
@Test
+ public void testArgumentsWithWhitespace() {
+ runRetraceTest(
+ "%c.%m\\(%a\\)",
+ new StackTraceForTest() {
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return ImmutableList.of("a.b.c.a(int, a.a.a[], a.b.c)");
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.lines(
+ "com.android.tools.r8.D8 -> a.a.a:",
+ "com.android.tools.r8.R8 -> a.b.c:",
+ " void foo(int,original.signature) -> a");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return ImmutableList.of(
+ "com.android.tools.r8.R8.foo"
+ + "(int, com.android.tools.r8.D8[], com.android.tools.r8.R8)");
+ }
+
+ @Override
+ public List<String> retraceVerboseStackTrace() {
+ return ImmutableList.of(
+ "com.android.tools.r8.R8.void foo"
+ + "(int,original.signature)"
+ + "(int, com.android.tools.r8.D8[], com.android.tools.r8.R8)");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+ });
+ }
+
+ @Test
+ public void testArgumentsWithDifferentWhitespace() {
+ runRetraceTest(
+ "%c.%m\\(%a\\)",
+ new StackTraceForTest() {
+ @Override
+ public List<String> obfuscatedStackTrace() {
+ return ImmutableList.of("a.b.c.a(int,a.a.a[], a.a.a, a.b.c)");
+ }
+
+ @Override
+ public String mapping() {
+ return StringUtils.lines(
+ "com.android.tools.r8.D8 -> a.a.a:",
+ "com.android.tools.r8.R8 -> a.b.c:",
+ " void foo(int,original.signature) -> a");
+ }
+
+ @Override
+ public List<String> retracedStackTrace() {
+ return ImmutableList.of(
+ "com.android.tools.r8.R8.foo(int,com.android.tools.r8.D8[],"
+ + " com.android.tools.r8.D8, com.android.tools.r8.R8)");
+ }
+
+ @Override
+ public List<String> retraceVerboseStackTrace() {
+ return ImmutableList.of(
+ "com.android.tools.r8.R8.void foo"
+ + "(int,original.signature)"
+ + "(int,com.android.tools.r8.D8[],"
+ + " com.android.tools.r8.D8, com.android.tools.r8.R8)");
+ }
+
+ @Override
+ public int expectedWarnings() {
+ return 0;
+ }
+ });
+ }
+
+ @Test
public void testNoArguments() {
runRetraceTest(
"%c.%m\\(%a\\)",