Version 2.2.29
Cherry-pick: [Retrace] Print waiting message on std-in
CL: https://r8-review.googlesource.com/54982
Cherry-pick: Remove ClassNameMapper from the public api of Retrace
CL: https://r8-review.googlesource.com/54841
Cherry-pick: [Retrace] Print an error message on invalid input file
CL: https://r8-review.googlesource.com/54986
Cherry-pick: [Retrace] Print usage on errors and version on help
CL: https://r8-review.googlesource.com/54987
Cherry-pick: Remove unused catches
CL: https://r8-review.googlesource.com/54989
Cherry-pick: [Retrace] Adjust testHelp test expectation
CL: https://r8-review.googlesource.com/54994
Bug: 169671295
Bug: 169672210
Bug: 163981284
Bug: 169552658
Bug: 169552039
Change-Id: I69e22c11f36934872f60070beda7a5a7341f63ff
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 781a82b..b1da4e4 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.2.28";
+ public static final String LABEL = "2.2.29";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/retrace/DirectClassNameMapperProguardMapProducer.java b/src/main/java/com/android/tools/r8/retrace/DirectClassNameMapperProguardMapProducer.java
new file mode 100644
index 0000000..8efe05a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/DirectClassNameMapperProguardMapProducer.java
@@ -0,0 +1,18 @@
+// 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;
+
+import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.retrace.RetraceCommand.ProguardMapProducer;
+
+public interface DirectClassNameMapperProguardMapProducer extends ProguardMapProducer {
+
+ ClassNameMapper getClassNameMapper();
+
+ @Override
+ default String get() {
+ throw new RuntimeException("Should not be called for DirectClassNameMapperProguardMapProducer");
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java b/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java
new file mode 100644
index 0000000..86e81e1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/InvalidMappingFileException.java
@@ -0,0 +1,20 @@
+// 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;
+
+import com.android.tools.r8.Keep;
+
+@Keep
+public final class InvalidMappingFileException extends RuntimeException {
+
+ public InvalidMappingFileException(Throwable throwable) {
+ super(throwable);
+ }
+
+ @Override
+ public String getMessage() {
+ return "Unable to parse mapping file";
+ }
+}
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 f34a5aa..adf9583 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retrace.java
@@ -10,9 +10,9 @@
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.Version;
-import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.retrace.RetraceCommand.Builder;
import com.android.tools.r8.retrace.RetraceCommand.ProguardMapProducer;
+import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.OptionsParsing;
import com.android.tools.r8.utils.OptionsParsing.ParseContext;
import com.android.tools.r8.utils.StringDiagnostic;
@@ -120,7 +120,15 @@
new StringDiagnostic(String.format("Could not find mapping file '%s'.", mappingPath)));
throw new RetraceAbortException();
}
- return () -> new String(Files.readAllBytes(path));
+ return () -> {
+ try {
+ return new String(Files.readAllBytes(path));
+ } catch (IOException e) {
+ diagnosticsHandler.error(
+ new StringDiagnostic(String.format("Could not open mapping file '%s'.", mappingPath)));
+ throw new RuntimeException(e);
+ }
+ };
}
private static List<String> getStackTraceFromFile(
@@ -142,11 +150,9 @@
try {
Timing timing = Timing.create("R8 retrace", command.printMemory());
timing.begin("Read proguard map");
- ClassNameMapper classNameMapper =
- ClassNameMapper.mapperFromString(
- command.proguardMapProducer.get(), command.diagnosticsHandler);
+ RetraceApi retracer =
+ Retracer.create(command.proguardMapProducer, command.diagnosticsHandler);
timing.end();
- RetraceApi retracer = Retracer.create(classNameMapper);
RetraceCommandLineResult result;
timing.begin("Parse and Retrace");
if (command.regularExpression != null) {
@@ -171,10 +177,9 @@
if (command.printTimes()) {
timing.report();
}
- } catch (IOException ex) {
- command.diagnosticsHandler.error(
- new StringDiagnostic("Could not open mapping input stream: " + ex.getMessage()));
- throw new RetraceAbortException();
+ } catch (InvalidMappingFileException e) {
+ command.diagnosticsHandler.error(new ExceptionDiagnostic(e));
+ throw e;
}
}
@@ -207,6 +212,7 @@
return;
}
assert Arrays.asList(mappedArgs).contains("--help");
+ System.out.println("Retrace " + Version.getVersionString());
System.out.print(USAGE_MESSAGE);
return;
}
@@ -233,6 +239,7 @@
}
private static List<String> getStackTraceFromStandardInput() {
+ System.out.println("Waiting for stack-trace input...");
Scanner sc = new Scanner(new InputStreamReader(System.in, Charsets.UTF_8));
List<String> readLines = new ArrayList<>();
while (sc.hasNext()) {
@@ -252,9 +259,11 @@
action.run();
} catch (RetraceAbortException e) {
// Detail of the errors were already reported
+ System.err.println(StringUtils.LINE_SEPARATOR + USAGE_MESSAGE + StringUtils.LINE_SEPARATOR);
System.exit(STATUS_ERROR);
} catch (RuntimeException e) {
System.err.println("Retrace failed with an internal error.");
+ System.err.println(StringUtils.LINE_SEPARATOR + USAGE_MESSAGE + StringUtils.LINE_SEPARATOR);
Throwable cause = e.getCause() == null ? e : e.getCause();
cause.printStackTrace();
System.exit(STATUS_ERROR);
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java b/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
index 64cf59a..3ead933 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceCommand.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.utils.StringDiagnostic;
-import java.io.IOException;
import java.util.List;
import java.util.function.Consumer;
@@ -153,6 +152,6 @@
@Keep
public interface ProguardMapProducer {
- String get() throws IOException;
+ String get();
}
}
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 0f7d547..62add05 100644
--- a/src/main/java/com/android/tools/r8/retrace/Retracer.java
+++ b/src/main/java/com/android/tools/r8/retrace/Retracer.java
@@ -4,12 +4,14 @@
package com.android.tools.r8.retrace;
+import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.Keep;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.retrace.RetraceCommand.ProguardMapProducer;
/** A default implementation for the retrace api using the ClassNameMapper defined in R8. */
@Keep
@@ -21,8 +23,19 @@
this.classNameMapper = classNameMapper;
}
- public static RetraceApi create(ClassNameMapper classNameMapper) {
- return new Retracer(classNameMapper);
+ public static RetraceApi create(
+ ProguardMapProducer proguardMapProducer, DiagnosticsHandler diagnosticsHandler) {
+ if (proguardMapProducer instanceof DirectClassNameMapperProguardMapProducer) {
+ return new Retracer(
+ ((DirectClassNameMapperProguardMapProducer) proguardMapProducer).getClassNameMapper());
+ }
+ try {
+ ClassNameMapper classNameMapper =
+ ClassNameMapper.mapperFromString(proguardMapProducer.get(), diagnosticsHandler);
+ return new Retracer(classNameMapper);
+ } catch (Throwable throwable) {
+ throw new InvalidMappingFileException(throwable);
+ }
}
@Override
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java b/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
index 15ed0d9..85e6cbc 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceCommandLineTests.java
@@ -7,6 +7,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
@@ -38,6 +39,8 @@
public class RetraceCommandLineTests {
private static final boolean testExternal = false;
+ private static final String WAITING_MESSAGE =
+ "Waiting for stack-trace input..." + StringUtils.LINE_SEPARATOR;
@Rule public TemporaryFolder folder = new TemporaryFolder();
@@ -64,6 +67,18 @@
}
@Test
+ public void testInvalidMappingFile() throws IOException {
+ Path mappingFile = folder.newFile("mapping.txt").toPath();
+ Files.write(mappingFile, "foo.bar.baz <- is invalid mapping".getBytes());
+ Path stackTraceFile = folder.newFile("stacktrace.txt").toPath();
+ Files.write(stackTraceFile, new byte[0]);
+ runAbortTest(
+ containsString("Unable to parse mapping file"),
+ mappingFile.toString(),
+ stackTraceFile.toString());
+ }
+
+ @Test
public void testVerbose() throws IOException {
FoundMethodVerboseStackTrace stackTrace = new FoundMethodVerboseStackTrace();
runTest(
@@ -135,7 +150,7 @@
public void testHelp() throws IOException {
ProcessResult processResult = runRetraceCommandLine(null, Arrays.asList("--help"));
assertEquals(0, processResult.exitCode);
- assertEquals(Retrace.USAGE_MESSAGE, processResult.stdout);
+ assertThat(processResult.stdout, containsString(Retrace.USAGE_MESSAGE));
}
@Test
@@ -155,6 +170,12 @@
runTest("", SMILEY_EMOJI, true, SMILEY_EMOJI + StringUtils.LINE_SEPARATOR);
}
+ @Test
+ public void testHelpMessageOnStdIn() throws IOException {
+ ProcessResult processResult = runRetrace("", "", true);
+ assertTrue(processResult.stdout.startsWith(WAITING_MESSAGE));
+ }
+
private final String nonMappableStackTrace =
StringUtils.lines(
"com.android.r8.R8Exception: Problem when compiling program",
@@ -171,7 +192,12 @@
throws IOException {
ProcessResult result = runRetrace(mapping, stackTrace, stacktraceStdIn, args);
assertEquals(0, result.exitCode);
- assertEquals(expected, result.stdout);
+ String stdOut = result.stdout;
+ if (stacktraceStdIn) {
+ assertTrue(result.stdout.startsWith(WAITING_MESSAGE));
+ stdOut = result.stdout.substring(WAITING_MESSAGE.length());
+ }
+ assertEquals(expected, stdOut);
}
private void runAbortTest(Matcher<String> errorMatch, String... args) throws IOException {
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 731e807..bffcd14 100644
--- a/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceTests.java
@@ -14,7 +14,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.retrace.Retrace.RetraceAbortException;
import com.android.tools.r8.retrace.stacktraces.ActualBotStackTraceBase;
import com.android.tools.r8.retrace.stacktraces.ActualIdentityStackTrace;
@@ -203,11 +202,8 @@
private void inspectRetraceTest(
StackTraceForTest stackTraceForTest, Consumer<RetraceApi> inspection) throws Exception {
- TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
- ClassNameMapper classNameMapper =
- ClassNameMapper.mapperFromString(stackTraceForTest.mapping(), diagnosticsHandler);
- RetraceApi retracer = Retracer.create(classNameMapper);
- inspection.accept(retracer);
+ inspection.accept(
+ Retracer.create(stackTraceForTest::mapping, new TestDiagnosticMessagesImpl()));
}
private TestDiagnosticMessagesImpl runRetraceTest(StackTraceForTest stackTraceForTest) {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 6a5b949..522109a 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.StringResource;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.code.Instruction;
@@ -38,6 +39,7 @@
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.retrace.DirectClassNameMapperProguardMapProducer;
import com.android.tools.r8.retrace.RetraceApi;
import com.android.tools.r8.retrace.Retracer;
import com.android.tools.r8.utils.AndroidApp;
@@ -486,6 +488,24 @@
}
public RetraceApi retrace() {
- return Retracer.create(mapping);
+ return Retracer.create(
+ new InternalProguardMapProducer(
+ mapping == null ? ClassNameMapper.builder().build() : mapping),
+ new TestDiagnosticMessagesImpl());
+ }
+
+ public static class InternalProguardMapProducer
+ implements DirectClassNameMapperProguardMapProducer {
+
+ public final ClassNameMapper prebuiltMapper;
+
+ public InternalProguardMapProducer(ClassNameMapper prebuiltMapper) {
+ this.prebuiltMapper = prebuiltMapper;
+ }
+
+ @Override
+ public ClassNameMapper getClassNameMapper() {
+ return prebuiltMapper;
+ }
}
}