Test retracing R8-processed R8.
Change-Id: Id8257d84073c1ea55155bb1b83a51ee41f6e66fd
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 0bad20c..4397db9 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -59,6 +59,7 @@
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.LineNumberOptimizer;
import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.SelfRetraceTest;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
@@ -586,6 +587,7 @@
private static void run(String[] args) throws CompilationFailedException {
R8Command command = R8Command.parse(args, CommandLineOrigin.INSTANCE).build();
if (command.isPrintHelp()) {
+ SelfRetraceTest.test();
System.out.println(USAGE_MESSAGE);
return;
}
diff --git a/src/main/java/com/android/tools/r8/utils/SelfRetraceTest.java b/src/main/java/com/android/tools/r8/utils/SelfRetraceTest.java
new file mode 100644
index 0000000..ab891e8
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/SelfRetraceTest.java
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, 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.utils;
+
+// NOTE: If you change this file you may need to update the expected line numbers in
+// tools/test_self_retrace.py
+public class SelfRetraceTest {
+ private static String SELFRETRACETEST_ENVIRONMENT_VAR = "R8_THROW_EXCEPTION_FOR_TESTING_RETRACE";
+
+ private void foo3() {
+ throw new RuntimeException("Intentional exception for testing retrace.");
+ }
+
+ private void foo2() {
+ foo3();
+ }
+
+ private void foo1() {
+ foo2();
+ }
+
+ public static void test() {
+ if (System.getenv(SELFRETRACETEST_ENVIRONMENT_VAR) != null) {
+ new SelfRetraceTest().foo1();
+ }
+ }
+}
diff --git a/src/main/keep-compatdx.txt b/src/main/keep-compatdx.txt
index 51b401c..75a8012 100644
--- a/src/main/keep-compatdx.txt
+++ b/src/main/keep-compatdx.txt
@@ -3,3 +3,4 @@
# BSD-style license that can be found in the LICENSE file.
-keep public class com.android.tools.r8.compatdx.CompatDx { public static void main(java.lang.String[]); }
+-keepattributes LineNumberTable
diff --git a/src/main/keep-compatproguard.txt b/src/main/keep-compatproguard.txt
index f508bea..e29d13e 100644
--- a/src/main/keep-compatproguard.txt
+++ b/src/main/keep-compatproguard.txt
@@ -3,3 +3,4 @@
# BSD-style license that can be found in the LICENSE file.
-keep public class com.android.tools.r8.compatproguard.CompatProguard { public static void main(java.lang.String[]); }
+-keepattributes LineNumberTable
diff --git a/src/main/keep.txt b/src/main/keep.txt
index 0d3812c..7642a71 100644
--- a/src/main/keep.txt
+++ b/src/main/keep.txt
@@ -12,3 +12,5 @@
-keep public class com.android.tools.r8.compatdx.CompatDx { public static void main(java.lang.String[]); }
-keep public class com.android.tools.r8.dexfilemerger.DexFileMerger { public static void main(java.lang.String[]); }
-keep public class com.android.tools.r8.dexsplitter.DexSplitter { public static void main(java.lang.String[]); }
+
+-keepattributes LineNumberTable
diff --git a/tools/test_self_retrace.py b/tools/test_self_retrace.py
new file mode 100755
index 0000000..08b97db
--- /dev/null
+++ b/tools/test_self_retrace.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+import gradle
+import os
+import subprocess
+import sys
+import utils
+
+RETRACE_JAR = os.path.join(
+ utils.THIRD_PARTY,
+ 'proguard',
+ 'proguard6.0.1',
+ 'lib',
+ 'retrace.jar')
+
+EXCEPTION_LINE = 'Intentional exception for testing retrace.'
+EXPECTED_LINES = [
+ 'com.android.tools.r8.utils.SelfRetraceTest.foo3(SelfRetraceTest.java:13)',
+ 'com.android.tools.r8.utils.SelfRetraceTest.foo2(SelfRetraceTest.java:17)',
+ 'com.android.tools.r8.utils.SelfRetraceTest.foo1(SelfRetraceTest.java:21)',
+ 'com.android.tools.r8.utils.SelfRetraceTest.test(SelfRetraceTest.java:26)',
+ 'com.android.tools.r8.R8.run(R8.java:',
+]
+
+def main():
+ gradle.RunGradle(['r8lib'])
+
+ # Run 'r8 --help' which throws an exception.
+ cmd = ['java','-cp', utils.R8LIB_JAR, 'com.android.tools.r8.R8', '--help']
+ os.environ["R8_THROW_EXCEPTION_FOR_TESTING_RETRACE"] = "1"
+ utils.PrintCmd(cmd)
+ p = subprocess.Popen(cmd, stderr=subprocess.PIPE)
+ _, stacktrace = p.communicate()
+ assert(p.returncode != 0)
+ assert(EXCEPTION_LINE in stacktrace)
+ # r8lib must be minified, original class names must not be present.
+ assert('SelfRetraceTest' not in stacktrace)
+
+ # Run the retrace tool.
+ cmd = ['java', '-jar', RETRACE_JAR, utils.R8LIB_JAR + ".map"]
+ utils.PrintCmd(cmd)
+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ retrace_stdout, _ = p.communicate(stacktrace)
+ assert p.returncode == 0
+ retrace_lines = retrace_stdout.splitlines()
+ line_index = -1
+ for line in retrace_lines:
+ if line_index < 0:
+ if 'java.lang.RuntimeException' in line:
+ assert(EXCEPTION_LINE in line)
+ line_index = 0;
+ else:
+ assert EXPECTED_LINES[line_index] in line
+ line_index += 1
+ if line_index >= len(EXPECTED_LINES):
+ break
+ assert(line_index >= 0)
+
+if __name__ == '__main__':
+ sys.exit(main())