Merge "Test verification behavior of dex move instructions."
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index e393f32..799d834 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -37,7 +37,7 @@
programConsumer = null;
mode = null;
minApiLevel = 0;
- reporter = new Reporter(new DefaultDiagnosticsHandler());
+ reporter = new Reporter(new DefaultDiagnosticsHandler(), this);
enableDesugaring = true;
optimizeMultidexForLinearAlloc = false;
}
diff --git a/src/main/java/com/android/tools/r8/CompatDxHelper.java b/src/main/java/com/android/tools/r8/CompatDxHelper.java
index 627f417..f540ed0 100644
--- a/src/main/java/com/android/tools/r8/CompatDxHelper.java
+++ b/src/main/java/com/android/tools/r8/CompatDxHelper.java
@@ -9,8 +9,7 @@
import java.io.IOException;
public class CompatDxHelper {
- public static void run(D8Command command, Boolean minimalMainDex)
- throws IOException, CompilationException {
+ public static void run(D8Command command, Boolean minimalMainDex) throws IOException {
AndroidApp app = command.getInputApp();
InternalOptions options = command.getInternalOptions();
// DX does not desugar.
diff --git a/src/main/java/com/android/tools/r8/CompilationException.java b/src/main/java/com/android/tools/r8/CompilationException.java
deleted file mode 100644
index 8e1e56c..0000000
--- a/src/main/java/com/android/tools/r8/CompilationException.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2017, 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;
-
-/**
- * Exception to signal an compilation error.
- *
- * This is always an expected error and considered a user input issue.
- * A user-understandable message must be provided.
- */
-public class CompilationException extends Exception {
- private static final long serialVersionUID = 1L;
-
- /**
- * Construct the exception with a {@link String} message.
- * @param message the message
- */
- public CompilationException(String message) {
- super(message);
- }
-
- /**
- * Construct the exception with a {@link String} message and a {@link Throwable} cause.
- * @param message the message
- * @param cause the cause
- */
- public CompilationException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Construct the exception with a {@link Throwable} cause.
- * @param cause the cause
- */
- public CompilationException(Throwable cause) {
- super(cause.getMessage(), cause);
- }
-
- protected CompilationException() {
- super();
- }
-
- public String getMessageForD8() {
- return super.getMessage();
- }
-
- public String getMessageForR8() {
- return super.getMessage();
- }
-}
-
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 250f2e9..06cf0bb 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -17,7 +17,6 @@
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.ExceptionUtils;
-import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
@@ -94,9 +93,8 @@
});
}
- private static void run(String[] args) throws CompilationFailedException, IOException {
- String[] expandedArgs = FlagFile.expandFlagFiles(args);
- D8Command command = D8Command.parse(expandedArgs, CommandLineOrigin.INSTANCE).build();
+ private static void run(String[] args) throws CompilationFailedException {
+ D8Command command = D8Command.parse(args, CommandLineOrigin.INSTANCE).build();
if (command.isPrintHelp()) {
System.out.println(USAGE_MESSAGE);
return;
@@ -123,8 +121,7 @@
ExceptionUtils.withMainProgramHandler(() -> run(args));
}
- static void runForTesting(AndroidApp inputApp, InternalOptions options)
- throws IOException, CompilationException {
+ static void runForTesting(AndroidApp inputApp, InternalOptions options) throws IOException {
ExecutorService executor = ThreadUtils.getExecutorService(options);
try {
run(inputApp, options, executor);
@@ -151,7 +148,7 @@
}
private static void run(AndroidApp inputApp, InternalOptions options, ExecutorService executor)
- throws IOException, CompilationException {
+ throws IOException {
Timing timing = new Timing("D8");
try {
// Disable global optimizations.
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 4c65134..6f956db 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
@@ -215,9 +216,10 @@
Path outputPath = null;
OutputMode outputMode = null;
boolean hasDefinedApiLevel = false;
+ String[] expandedArgs = FlagFile.expandFlagFiles(args, builder.getReporter());
try {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i].trim();
+ for (int i = 0; i < expandedArgs.length; i++) {
+ String arg = expandedArgs[i].trim();
if (arg.length() == 0) {
continue;
} else if (arg.equals("--help")) {
@@ -243,7 +245,7 @@
} else if (arg.equals("--file-per-class")) {
outputMode = OutputMode.DexFilePerClassFile;
} else if (arg.equals("--output")) {
- String output = args[++i];
+ String output = expandedArgs[++i];
if (outputPath != null) {
builder.getReporter().error(new StringDiagnostic(
"Cannot output both to '" + outputPath.toString() + "' and '" + output + "'",
@@ -252,15 +254,15 @@
}
outputPath = Paths.get(output);
} else if (arg.equals("--lib")) {
- builder.addLibraryFiles(Paths.get(args[++i]));
+ builder.addLibraryFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--classpath")) {
- builder.addClasspathFiles(Paths.get(args[++i]));
+ builder.addClasspathFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--main-dex-list")) {
- builder.addMainDexListFiles(Paths.get(args[++i]));
+ builder.addMainDexListFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--optimize-multidex-for-linearalloc")) {
builder.setOptimizeMultidexForLinearAlloc(true);
} else if (arg.equals("--min-api")) {
- hasDefinedApiLevel = parseMinApi(builder, args[++i], hasDefinedApiLevel, origin);
+ hasDefinedApiLevel = parseMinApi(builder, expandedArgs[++i], hasDefinedApiLevel, origin);
} else if (arg.equals("--intermediate")) {
builder.setIntermediate(true);
} else if (arg.equals("--no-desugaring")) {
diff --git a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
index 9c76484..5987b99 100644
--- a/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
+++ b/src/main/java/com/android/tools/r8/DexFileMergerHelper.java
@@ -67,7 +67,7 @@
InternalOptions options,
Boolean minimalMainDex,
Map<String, Integer> inputOrdering)
- throws IOException, CompilationException {
+ throws IOException {
options.enableDesugaring = false;
options.enableMainDexListCheck = false;
options.minimalMainDex = minimalMainDex;
@@ -106,7 +106,7 @@
}
public static void runD8ForTesting(D8Command command, boolean dontCreateMarkerInD8)
- throws IOException, CompilationException {
+ throws IOException {
InternalOptions options = command.getInternalOptions();
options.testing.dontCreateMarkerInD8 = dontCreateMarkerInD8;
D8.runForTesting(command.getInputApp(), options);
diff --git a/src/main/java/com/android/tools/r8/DexSplitterHelper.java b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
index 1fcd70a..2d52ec9 100644
--- a/src/main/java/com/android/tools/r8/DexSplitterHelper.java
+++ b/src/main/java/com/android/tools/r8/DexSplitterHelper.java
@@ -40,8 +40,7 @@
try {
ExceptionUtils.withCompilationHandler(
command.getReporter(),
- () -> run(command, featureClassMapping, output, proguardMap, executor),
- CompilationException::getMessage);
+ () -> run(command, featureClassMapping, output, proguardMap, executor));
} finally {
executor.shutdown();
}
@@ -53,7 +52,7 @@
String output,
String proguardMap,
ExecutorService executor)
- throws IOException, CompilationException {
+ throws IOException {
InternalOptions options = command.getInternalOptions();
options.enableDesugaring = false;
options.enableMainDexListCheck = false;
@@ -135,7 +134,7 @@
}
public static void runD8ForTesting(D8Command command, boolean dontCreateMarkerInD8)
- throws IOException, CompilationException {
+ throws IOException {
InternalOptions options = command.getInternalOptions();
options.testing.dontCreateMarkerInD8 = dontCreateMarkerInD8;
D8.runForTesting(command.getInputApp(), options);
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index ced0b4c..734dc4a 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -94,7 +94,7 @@
}
public static void main(String[] args)
- throws IOException, CompilationException, ExecutionException, ResourceException {
+ throws IOException, ExecutionException, ResourceException {
ExtractMarkerCommand.Builder builder = ExtractMarkerCommand.parse(args);
ExtractMarkerCommand command = builder.build();
if (command.isPrintHelp()) {
diff --git a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
index 9555d3b..598d8e0 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import com.android.tools.r8.errors.CompilationError;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.file.Path;
@@ -54,7 +55,7 @@
return this;
}
- public ExtractMarkerCommand build() throws CompilationException, IOException {
+ public ExtractMarkerCommand build() throws IOException {
// If printing versions ignore everything else.
if (isPrintHelp()) {
return new ExtractMarkerCommand(isPrintHelp());
@@ -76,15 +77,13 @@
return new Builder();
}
- public static Builder parse(String[] args)
- throws CompilationException, IOException {
+ public static Builder parse(String[] args) throws IOException {
Builder builder = builder();
parse(args, builder);
return builder;
}
- private static void parse(String[] args, Builder builder)
- throws CompilationException, IOException {
+ private static void parse(String[] args, Builder builder) throws IOException {
for (int i = 0; i < args.length; i++) {
String arg = args[i].trim();
if (arg.length() == 0) {
@@ -101,7 +100,7 @@
builder.setPrintHelp(true);
} else {
if (arg.startsWith("--")) {
- throw new CompilationException("Unknown option: " + arg);
+ throw new CompilationError("Unknown option: " + arg);
}
builder.addProgramFile(Paths.get(arg));
}
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 8e1722e..5d29d90 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.ClassAndMemberPublicizer;
import com.android.tools.r8.graph.DexApplication;
@@ -51,7 +50,6 @@
import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.LineNumberOptimizer;
@@ -180,7 +178,7 @@
String proguardSeedsData,
InternalOptions options,
ProguardMapSupplier proguardMapSupplier)
- throws ExecutionException, DexOverflowException {
+ throws ExecutionException {
try {
Marker marker = getMarker(options);
if (options.isGeneratingClassFiles()) {
@@ -215,8 +213,7 @@
return result;
}
- static void runForTesting(AndroidApp app, InternalOptions options)
- throws IOException, CompilationException {
+ static void runForTesting(AndroidApp app, InternalOptions options) throws IOException {
ExecutorService executor = ThreadUtils.getExecutorService(options);
try {
run(app, options, executor);
@@ -225,16 +222,12 @@
}
}
- private static void run(
- AndroidApp app,
- InternalOptions options,
- ExecutorService executor)
- throws IOException, CompilationException {
+ private static void run(AndroidApp app, InternalOptions options, ExecutorService executor)
+ throws IOException {
new R8(options).run(app, executor);
}
- private void run(AndroidApp inputApp, ExecutorService executorService)
- throws IOException, CompilationException {
+ private void run(AndroidApp inputApp, ExecutorService executorService) throws IOException {
assert options.programConsumer != null;
if (options.quiet) {
System.setOut(new PrintStream(ByteStreams.nullOutputStream()));
@@ -504,39 +497,22 @@
}
}
- static void unwrapExecutionException(ExecutionException executionException)
- throws CompilationException {
+ static void unwrapExecutionException(ExecutionException executionException) {
Throwable cause = executionException.getCause();
if (cause instanceof CompilationError) {
// add original exception as suppressed exception to provide the original stack trace
cause.addSuppressed(executionException);
throw (CompilationError) cause;
- } else if (cause instanceof CompilationException) {
- cause.addSuppressed(executionException);
- throw (CompilationException) cause;
} else if (cause instanceof RuntimeException) {
- // ForkJoinPool wraps checked exceptions in RuntimeExceptions
- if (cause.getCause() != null
- && cause.getCause() instanceof CompilationException) {
- cause.addSuppressed(executionException);
- throw (CompilationException) cause.getCause();
- // ForkJoinPool sometimes uses 2 levels of RuntimeExceptions, to provide accurate stack traces
- } else if (cause.getCause() != null && cause.getCause().getCause() != null
- && cause.getCause().getCause() instanceof CompilationException) {
- cause.addSuppressed(executionException);
- throw (CompilationException) cause.getCause().getCause();
- } else {
- cause.addSuppressed(executionException);
- throw (RuntimeException) cause;
- }
+ cause.addSuppressed(executionException);
+ throw (RuntimeException) cause;
} else {
throw new RuntimeException(executionException.getMessage(), cause);
}
}
- private static void run(String[] args) throws CompilationFailedException, IOException {
- String[] expandedArgs = FlagFile.expandFlagFiles(args);
- R8Command command = R8Command.parse(expandedArgs, CommandLineOrigin.INSTANCE).build();
+ private static void run(String[] args) throws CompilationFailedException {
+ R8Command command = R8Command.parse(args, CommandLineOrigin.INSTANCE).build();
if (command.isPrintHelp()) {
System.out.println(USAGE_MESSAGE);
return;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index ced17d4..573f6df 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionDiagnostic;
import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.FlagFile;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
import com.android.tools.r8.utils.Reporter;
@@ -65,6 +66,8 @@
// Internal compatibility mode for use from CompatProguard tool.
Path proguardCompatibilityRulesOutput = null;
+ private boolean allowPartiallyImplementedProguardOptions = false;
+
private StringConsumer mainDexListConsumer = null;
// TODO(zerny): Consider refactoring CompatProguardCommandBuilder to avoid subclassing.
@@ -285,7 +288,8 @@
mainDexKeepRules = parser.getConfig().getRules();
}
- ProguardConfigurationParser parser = new ProguardConfigurationParser(factory, reporter);
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(
+ factory, reporter, !allowPartiallyImplementedProguardOptions);
if (!proguardConfigs.isEmpty()) {
parser.parse(proguardConfigs);
}
@@ -383,6 +387,11 @@
c.accept(builder);
};
}
+
+ // Internal for-testing method to add post-processors of the proguard configuration.
+ void allowPartiallyImplementedProguardOptions() {
+ allowPartiallyImplementedProguardOptions = true;
+ }
}
// Wrapper class to ensure that R8 does not allow DEX as program inputs.
@@ -513,8 +522,9 @@
Origin argsOrigin,
Builder builder,
ParseState state) {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i].trim();
+ String[] expandedArgs = FlagFile.expandFlagFiles(args, builder.getReporter());
+ for (int i = 0; i < expandedArgs.length; i++) {
+ String arg = expandedArgs[i].trim();
if (arg.length() == 0) {
continue;
} else if (arg.equals("--help")) {
@@ -546,7 +556,7 @@
}
state.outputMode = OutputMode.ClassFile;
} else if (arg.equals("--output")) {
- String outputPath = args[++i];
+ String outputPath = expandedArgs[++i];
if (state.outputPath != null) {
builder.getReporter().error(new StringDiagnostic(
"Cannot output both to '"
@@ -558,10 +568,10 @@
}
state.outputPath = Paths.get(outputPath);
} else if (arg.equals("--lib")) {
- builder.addLibraryFiles(Paths.get(args[++i]));
+ builder.addLibraryFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--min-api")) {
state.hasDefinedApiLevel =
- parseMinApi(builder, args[++i], state.hasDefinedApiLevel, argsOrigin);
+ parseMinApi(builder, expandedArgs[++i], state.hasDefinedApiLevel, argsOrigin);
} else if (arg.equals("--no-tree-shaking")) {
builder.setDisableTreeShaking(true);
} else if (arg.equals("--no-minification")) {
@@ -569,17 +579,17 @@
} else if (arg.equals("--no-desugaring")) {
builder.setDisableDesugaring(true);
} else if (arg.equals("--main-dex-rules")) {
- builder.addMainDexRulesFiles(Paths.get(args[++i]));
+ builder.addMainDexRulesFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--main-dex-list")) {
- builder.addMainDexListFiles(Paths.get(args[++i]));
+ builder.addMainDexListFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--main-dex-list-output")) {
- builder.setMainDexListOutputPath(Paths.get(args[++i]));
+ builder.setMainDexListOutputPath(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--optimize-multidex-for-linearalloc")) {
builder.setOptimizeMultidexForLinearAlloc(true);
} else if (arg.equals("--pg-conf")) {
- builder.addProguardConfigurationFiles(Paths.get(args[++i]));
+ builder.addProguardConfigurationFiles(Paths.get(expandedArgs[++i]));
} else if (arg.equals("--pg-map-output")) {
- builder.setProguardMapOutputPath(Paths.get(args[++i]));
+ builder.setProguardMapOutputPath(Paths.get(expandedArgs[++i]));
} else {
if (arg.startsWith("--")) {
builder.getReporter().error(new StringDiagnostic("Unknown option: " + arg, argsOrigin));
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 98ed5e9..24b2cc9 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 = "1.2.17-dev";
+ public static final String LABEL = "1.2.19-dev";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java b/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
index 250ca3b..1336f95 100644
--- a/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
+++ b/src/main/java/com/android/tools/r8/benchmarks/FrameworkIncrementalDexingBenchmark.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.benchmarks.BenchmarkUtils.printRuntimeNanoseconds;
import com.android.tools.r8.ClassFileResourceProvider;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -112,7 +111,7 @@
boolean desugar,
Map<String, ProgramResource> outputs,
ExecutorService executor)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
ProgramConsumer consumer =
new DexFilePerClassFileConsumer.ForwardingConsumer(null) {
@@ -155,7 +154,7 @@
boolean desugar,
Map<String, ProgramResource> outputs,
ExecutorService executor)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
ProgramConsumer consumer =
new ForwardingConsumer(null) {
@Override
@@ -199,7 +198,7 @@
private static void merge(
boolean desugar, Map<String, ProgramResource> outputs, ExecutorService executor)
- throws IOException, CompilationException, CompilationFailedException, ResourceException {
+ throws IOException, CompilationFailedException, ResourceException {
Builder builder =
D8Command.builder()
.setMinApiLevel(API)
@@ -221,7 +220,7 @@
}
public static void main(String[] args)
- throws IOException, CompilationException, CompilationFailedException, ResourceException {
+ throws IOException, CompilationFailedException, ResourceException {
boolean desugar = Arrays.asList(args).contains("--desugar");
Path input = desugar ? JAR_NOT_DESUGARED : JAR_DESUGARED;
InMemoryClassPathProvider provider = new InMemoryClassPathProvider(input);
diff --git a/src/main/java/com/android/tools/r8/benchmarks/IncrementalDexingBenchmark.java b/src/main/java/com/android/tools/r8/benchmarks/IncrementalDexingBenchmark.java
index 0aaefd9..3f241a0 100644
--- a/src/main/java/com/android/tools/r8/benchmarks/IncrementalDexingBenchmark.java
+++ b/src/main/java/com/android/tools/r8/benchmarks/IncrementalDexingBenchmark.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.benchmarks;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -20,7 +19,7 @@
private static final int ITERATIONS = 1000;
public static void compile(ExecutorService executor)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
D8.run(
D8Command.builder()
.addProgramFiles(Paths.get("build/test/examples/arithmetic.jar"))
@@ -43,8 +42,7 @@
executor);
}
- public static void main(String[] args)
- throws IOException, CompilationException, CompilationFailedException {
+ public static void main(String[] args) throws IOException, CompilationFailedException {
int threads = Integer.min(Runtime.getRuntime().availableProcessors(), 16) / 2;
ExecutorService executor = ThreadUtils.getExecutorService(threads);
try {
diff --git a/src/main/java/com/android/tools/r8/bisect/Bisect.java b/src/main/java/com/android/tools/r8/bisect/Bisect.java
index dcc89c6..7ef43a3 100644
--- a/src/main/java/com/android/tools/r8/bisect/Bisect.java
+++ b/src/main/java/com/android/tools/r8/bisect/Bisect.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.utils.AndroidApp;
@@ -175,7 +174,7 @@
}
private static void writeApp(DexApplication app, Path output, ExecutorService executor)
- throws IOException, ExecutionException, DexOverflowException {
+ throws IOException, ExecutionException {
InternalOptions options = new InternalOptions();
AndroidAppConsumers compatSink = new AndroidAppConsumers(options);
ApplicationWriter writer = new ApplicationWriter(app, options, null, null, null, null, null);
diff --git a/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java b/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java
index b270200..6599591 100644
--- a/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java
+++ b/src/main/java/com/android/tools/r8/compatdexbuilder/CompatDexBuilder.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.compatdexbuilder;
import com.android.tools.r8.CompatDxHelper;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -154,7 +153,7 @@
}
private DexConsumer dexEntry(ZipFile zipFile, ZipEntry classEntry, ExecutorService executor)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
DexConsumer consumer = new DexConsumer();
D8Command.Builder builder = D8Command.builder();
CompatDxHelper.ignoreDexInArchive(builder);
diff --git a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
index b9131e5..f512a34 100644
--- a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
+++ b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
@@ -11,7 +11,6 @@
import static com.android.tools.r8.utils.FileUtils.isZipFile;
import com.android.tools.r8.CompatDxHelper;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8Command;
@@ -312,9 +311,6 @@
public static void main(String[] args) throws IOException {
try {
run(args);
- } catch (CompilationException e) {
- System.err.println(e.getMessage());
- System.exit(1);
} catch (DxUsageMessage e) {
System.err.println(USAGE_HEADER);
e.printHelpOn(System.err);
@@ -325,7 +321,7 @@
}
private static void run(String[] args)
- throws DxUsageMessage, IOException, CompilationException, CompilationFailedException {
+ throws DxUsageMessage, IOException, CompilationFailedException {
DxCompatOptions dexArgs = DxCompatOptions.parse(args);
if (dexArgs.help) {
printHelpOn(System.out);
diff --git a/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java b/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
index 66931e3..615a3e2 100644
--- a/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
+++ b/src/main/java/com/android/tools/r8/compatproguard/CompatProguard.java
@@ -5,12 +5,12 @@
package com.android.tools.r8.compatproguard;
import com.android.tools.r8.CompatProguardCommandBuilder;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.Version;
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.origin.CommandLineOrigin;
import com.android.tools.r8.utils.AbortException;
import com.google.common.collect.ImmutableList;
@@ -58,7 +58,7 @@
this.printHelpAndExit = printHelpAndExit;
}
- public static CompatProguardOptions parse(String[] args) throws CompilationException {
+ public static CompatProguardOptions parse(String[] args) {
String output = null;
int minApi = 1;
boolean forceProguardCompatibility = false;
@@ -97,7 +97,7 @@
} else if (arg.equals("--no-locals")) {
noLocals = true;
} else if (arg.equals("-outjars")) {
- throw new CompilationException(
+ throw new CompilationError(
"Proguard argument -outjar is not supported. Use R8 compatible --output flag");
} else {
if (currentLine.length() > 0) {
@@ -150,8 +150,7 @@
CompatProguardOptions.print();
}
- private static void run(String[] args)
- throws IOException, CompilationException, CompilationFailedException {
+ private static void run(String[] args) throws IOException, CompilationFailedException {
// Run R8 passing all the options from the command line as a Proguard configuration.
CompatProguardOptions options = CompatProguardOptions.parse(args);
if (options.printHelpAndExit || options.output == null) {
@@ -175,9 +174,6 @@
public static void main(String[] args) throws IOException {
try {
run(args);
- } catch (CompilationException e) {
- System.err.println(e.getMessage());
- System.exit(1);
} catch (CompilationFailedException | AbortException e) {
// Detail of the errors were already reported
System.err.println("Compilation failed");
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 9721d3b..e1905ff 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.ProgramResourceProvider;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationDirectory;
import com.android.tools.r8.graph.DexAnnotationSet;
@@ -162,7 +161,7 @@
}
private Iterable<VirtualFile> distribute(ExecutorService executorService)
- throws ExecutionException, IOException, DexOverflowException {
+ throws ExecutionException, IOException {
// Distribute classes into dex files.
VirtualFile.Distributor distributor;
if (options.isGeneratingDexFilePerClassFile()) {
@@ -179,8 +178,7 @@
return distributor.run();
}
- public void write(ExecutorService executorService)
- throws IOException, ExecutionException, DexOverflowException {
+ public void write(ExecutorService executorService) throws IOException, ExecutionException {
application.timing.begin("DexApplication.write");
try {
insertAttributeAnnotations();
diff --git a/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java b/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
index 3d0b01c..9e75e45 100644
--- a/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
+++ b/src/main/java/com/android/tools/r8/dex/InheritanceClassInDexDistributor.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.dex;
import com.android.tools.r8.dex.VirtualFile.VirtualFileCycler;
-import com.android.tools.r8.errors.DexOverflowException;
+import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
@@ -306,7 +306,7 @@
directSubClasses = new DirectSubClassesInfo(app, classes);
}
- public void distribute() throws DexOverflowException {
+ public void distribute() {
List<ClassGroup> remainingInheritanceGroups = collectInheritanceGroups();
// Sort to ensure reproducible allocation
remainingInheritanceGroups.sort(null);
@@ -369,8 +369,7 @@
return groupClassNumber;
}
- private Collection<VirtualFile> assignGroup(ClassGroup group,
- List<VirtualFile> dexBlackList) throws DexOverflowException {
+ private Collection<VirtualFile> assignGroup(ClassGroup group, List<VirtualFile> dexBlackList) {
VirtualFileCycler cycler = new VirtualFileCycler(dexes, namingLens, dexIndexOffset);
if (group.members.isEmpty()) {
return Collections.emptyList();
@@ -411,8 +410,8 @@
* They will fail to link during DexOpt but they will be loaded only once.
* @param classes set of classes to assign, the set will be destroyed during assignment.
*/
- private Collection<VirtualFile> assignClassesWithLinkingError(Set<DexProgramClass> classes,
- Collection<VirtualFile> dexBlackList) throws DexOverflowException {
+ private Collection<VirtualFile> assignClassesWithLinkingError(
+ Set<DexProgramClass> classes, Collection<VirtualFile> dexBlackList) {
List<ClassGroup> layers = collectNoDirectInheritanceGroups(classes);
@@ -440,7 +439,7 @@
dexForLayer.abortTransaction();
if (dexForLayer.isEmpty()) {
// The class is too big to fit in one dex
- throw new DexOverflowException("Class '" + dexProgramClass.toSourceString()
+ throw new CompilationError("Class '" + dexProgramClass.toSourceString()
+ "' from " + dexProgramClass.getOrigin().toString()
+ " is too big to fit in a dex.");
}
@@ -614,8 +613,8 @@
* Assign as many classes as possible by layer starting by roots.
* @return the list of classes that were not assigned.
*/
- private Set<DexProgramClass> assignFromRoot(VirtualFile dex,
- Collection<DexProgramClass> classes) throws DexOverflowException {
+ private Set<DexProgramClass> assignFromRoot(
+ VirtualFile dex, Collection<DexProgramClass> classes) {
int totalClasses = classes.size();
int assignedClasses = 0;
@@ -635,7 +634,7 @@
dex.abortTransaction();
if (dex.isEmpty()) {
// The class is too big to fit in one dex
- throw new DexOverflowException("Class '" + clazz.toSourceString() + "' from "
+ throw new CompilationError("Class '" + clazz.toSourceString() + "' from "
+ clazz.getOrigin().toString() + " is too big to fit in a dex.");
}
isLayerFullyAssigned = false;
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index 7f55b19..9ac752a 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -3,9 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.dex;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.InternalCompilerError;
-import com.android.tools.r8.errors.MainDexOverflowException;
+import com.android.tools.r8.errors.MainDexOverflow;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
@@ -24,6 +23,7 @@
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
@@ -185,15 +185,16 @@
return transaction.getNumberOfFields();
}
- void throwIfFull(boolean hasMainDexList) throws DexOverflowException {
+ void throwIfFull(boolean hasMainDexList, Reporter reporter) {
if (!isFull()) {
return;
}
- throw new MainDexOverflowException(
- hasMainDexList,
- transaction.getNumberOfMethods(),
- transaction.getNumberOfFields(),
- MAX_ENTRIES);
+ throw reporter.fatalError(
+ new MainDexOverflow(
+ hasMainDexList,
+ transaction.getNumberOfMethods(),
+ transaction.getNumberOfFields(),
+ MAX_ENTRIES));
}
private boolean isFilledEnough(FillStrategy fillStrategy) {
@@ -226,8 +227,7 @@
this.writer = writer;
}
- public abstract Collection<VirtualFile> run()
- throws ExecutionException, IOException, DexOverflowException;
+ public abstract Collection<VirtualFile> run() throws ExecutionException, IOException;
}
/**
@@ -296,7 +296,7 @@
originalNames = computeOriginalNameMapping(classes, application.getProguardMap());
}
- protected void fillForMainDexList(Set<DexProgramClass> classes) throws DexOverflowException {
+ protected void fillForMainDexList(Set<DexProgramClass> classes) {
if (!application.mainDexList.isEmpty()) {
VirtualFile mainDexFile = virtualFiles.get(0);
for (DexType type : application.mainDexList) {
@@ -314,7 +314,7 @@
}
mainDexFile.commitTransaction();
}
- mainDexFile.throwIfFull(true);
+ mainDexFile.throwIfFull(true, options.reporter);
}
}
@@ -363,7 +363,7 @@
}
@Override
- public Collection<VirtualFile> run() throws IOException, DexOverflowException {
+ public Collection<VirtualFile> run() throws IOException {
int totalClassNumber = classes.size();
// First fill required classes into the main dex file.
fillForMainDexList(classes);
@@ -408,14 +408,13 @@
}
@Override
- public Collection<VirtualFile> run()
- throws ExecutionException, IOException, DexOverflowException {
+ public Collection<VirtualFile> run() throws ExecutionException, IOException {
// Add all classes to the main dex file.
for (DexProgramClass programClass : classes) {
mainDexFile.addClass(programClass);
}
mainDexFile.commitTransaction();
- mainDexFile.throwIfFull(false);
+ mainDexFile.throwIfFull(false, options.reporter);
return virtualFiles;
}
}
diff --git a/src/main/java/com/android/tools/r8/errors/DexOverflowException.java b/src/main/java/com/android/tools/r8/errors/DexOverflowException.java
deleted file mode 100644
index a392080..0000000
--- a/src/main/java/com/android/tools/r8/errors/DexOverflowException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2017, 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.errors;
-
-import com.android.tools.r8.CompilationException;
-
-/**
- * Signals when there were too many items to fit in a given dex file.
- */
-public class DexOverflowException extends CompilationException {
-
- protected DexOverflowException() {
- super();
- }
-
- public DexOverflowException(String message) {
- super(message);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java b/src/main/java/com/android/tools/r8/errors/MainDexOverflow.java
similarity index 89%
rename from src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java
rename to src/main/java/com/android/tools/r8/errors/MainDexOverflow.java
index e570c81..e33cf59 100644
--- a/src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java
+++ b/src/main/java/com/android/tools/r8/errors/MainDexOverflow.java
@@ -4,16 +4,16 @@
package com.android.tools.r8.errors;
/**
- * Thrown when running mono dex and not all classes can fit in a dex or when running for multidex
- * legacy and there are too many classes to fit in the main dex.
+ * Info about error when running mono dex and not all classes can fit in a dex or when running for
+ * multidex legacy and there are too many classes to fit in the main dex.
*/
-public class MainDexOverflowException extends DexOverflowException {
+public class MainDexOverflow {
private final boolean hasMainDexList;
private final long numOfMethods;
private final long numOfFields;
private final long maxNumOfEntries;
- public MainDexOverflowException(
+ public MainDexOverflow(
boolean hasMainDexList, long numOfMethods, long numOfFields, long maxNumOfEntries) {
super();
this.hasMainDexList = hasMainDexList;
@@ -52,7 +52,6 @@
return messageBuilder.toString();
}
- @Override
public String getMessage() {
// Default message
return getGeneralMessage()
@@ -62,7 +61,6 @@
.toString();
}
- @Override
public String getMessageForD8() {
StringBuilder messageBuilder = getGeneralMessage();
if (!hasMainDexList) {
@@ -74,7 +72,6 @@
return messageBuilder.toString();
}
- @Override
public String getMessageForR8() {
StringBuilder messageBuilder = getGeneralMessage();
if (!hasMainDexList) {
@@ -85,5 +82,4 @@
messageBuilder.append(getNumberRelatedMessage());
return messageBuilder.toString();
}
-
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 0914e7b..9f97f88 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -99,6 +99,7 @@
private Code code;
private CompilationState compilationState = CompilationState.NOT_PROCESSED;
private OptimizationInfo optimizationInfo = DefaultOptimizationInfo.DEFAULT;
+ private int classFileVersion = -1;
public DexEncodedMethod(
DexMethod method,
@@ -114,6 +115,17 @@
assert code == null || !accessFlags.isAbstract();
}
+ public DexEncodedMethod(
+ DexMethod method,
+ MethodAccessFlags flags,
+ DexAnnotationSet annotationSet,
+ ParameterAnnotationsList annotationsList,
+ Code code,
+ int classFileVersion) {
+ this(method, flags, annotationSet, annotationsList, code);
+ this.classFileVersion = classFileVersion;
+ }
+
public boolean isProcessed() {
return compilationState != CompilationState.NOT_PROCESSED;
}
@@ -303,6 +315,21 @@
return code.asDexCode().hasDebugPositions();
}
+ public int getClassFileVersion() {
+ assert classFileVersion >= 0;
+ return classFileVersion;
+ }
+
+ public boolean hasClassFileVersion() {
+ return classFileVersion >= 0;
+ }
+
+ public void upgradeClassFileVersion(int version) {
+ assert version >= 0;
+ assert !hasClassFileVersion() || version >= getClassFileVersion();
+ classFileVersion = version;
+ }
+
public String qualifiedName() {
return method.qualifiedName();
}
@@ -753,6 +780,16 @@
return optimizationInfo;
}
+ public void copyMetadataFromInlinee(DexEncodedMethod inlinee) {
+ // Record that the current method uses identifier name string if the inlinee did so.
+ if (inlinee.getOptimizationInfo().useIdentifierNameString()) {
+ markUseIdentifierNameString();
+ }
+ if (inlinee.classFileVersion > classFileVersion) {
+ upgradeClassFileVersion(inlinee.getClassFileVersion());
+ }
+ }
+
private static Builder builder(DexEncodedMethod from) {
return new Builder(from);
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index c1b843f..0a33000 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -356,9 +356,14 @@
}
public void setClassFileVersion(int classFileVersion) {
+ assert classFileVersion >= 0;
this.classFileVersion = classFileVersion;
}
+ public boolean hasClassFileVersion() {
+ return classFileVersion >= 0;
+ }
+
public int getClassFileVersion() {
assert classFileVersion != -1;
return classFileVersion;
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 02f0801..64ba508 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import static org.objectweb.asm.ClassReader.SKIP_CODE;
import static org.objectweb.asm.ClassReader.SKIP_FRAMES;
import static org.objectweb.asm.Opcodes.ACC_DEPRECATED;
import static org.objectweb.asm.Opcodes.ASM6;
@@ -90,7 +91,7 @@
ClassReader reader = new ClassReader(input);
reader.accept(
new CreateDexClassVisitor(origin, classKind, reader.b, application, classConsumer),
- SKIP_FRAMES);
+ SKIP_FRAMES | SKIP_CODE);
}
private static int cleanAccessFlags(int access) {
@@ -560,6 +561,11 @@
@Override
public void visitCode() {
+ throw new Unreachable("visitCode() should not be called when SKIP_CODE is set");
+ }
+
+ @Override
+ public void visitEnd() {
if (!flags.isAbstract() && !flags.isNative() && parent.classKind == ClassKind.PROGRAM) {
if (parent.application.options.enableCfFrontend) {
code = new LazyCfCode(method, parent.origin, parent.context, parent.application);
@@ -567,12 +573,6 @@
code = new JarCode(method, parent.origin, parent.context, parent.application);
}
}
- }
-
- @Override
- public void visitEnd() {
- assert flags.isAbstract() || flags.isNative() || parent.classKind != ClassKind.PROGRAM
- || code != null;
ParameterAnnotationsList annotationsList;
if (parameterAnnotationsLists == null) {
annotationsList = ParameterAnnotationsList.empty();
@@ -595,8 +595,14 @@
parameterFlags.toArray(new DexValue[parameterFlags.size()]),
parent.application.getFactory()));
}
- DexEncodedMethod dexMethod = new DexEncodedMethod(method, flags,
- createAnnotationSet(annotations), annotationsList, code);
+ DexEncodedMethod dexMethod =
+ new DexEncodedMethod(
+ method,
+ flags,
+ createAnnotationSet(annotations),
+ annotationsList,
+ code,
+ parent.version);
if (flags.isStatic() || flags.isConstructor() || flags.isPrivate()) {
parent.directMethods.add(dexMethod);
} else {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index fa00cd1..90a9898 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -6,7 +6,6 @@
import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.Flavor.ExcludeDexResources;
import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.Flavor.IncludeAllResources;
-import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
@@ -253,7 +252,7 @@
}
}
- private void processCovariantReturnTypeAnnotations(Builder<?> builder) throws ApiLevelException {
+ private void processCovariantReturnTypeAnnotations(Builder<?> builder) {
if (covariantReturnTypeAnnotationTransformer != null) {
covariantReturnTypeAnnotationTransformer.process(builder);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
index 526bd9f..5b397e0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.ir.desugar;
-import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
@@ -56,7 +55,7 @@
this.factory = factory;
}
- public void process(DexApplication.Builder<?> builder) throws ApiLevelException {
+ public void process(DexApplication.Builder<?> builder) {
// List of methods that should be added to the next class.
List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation = new LinkedList<>();
List<DexEncodedMethod> covariantReturnTypeMethods = new LinkedList<>();
@@ -114,8 +113,7 @@
private void buildCovariantReturnTypeMethodsForClass(
DexClass clazz,
List<DexEncodedMethod> methodsWithCovariantReturnTypeAnnotation,
- List<DexEncodedMethod> covariantReturnTypeMethods)
- throws ApiLevelException {
+ List<DexEncodedMethod> covariantReturnTypeMethods) {
for (DexEncodedMethod method : clazz.virtualMethods()) {
if (methodHasCovariantReturnTypeAnnotation(method)) {
methodsWithCovariantReturnTypeAnnotation.add(method);
@@ -137,8 +135,7 @@
// variantReturnTypes annotations on the given method. Adds the newly constructed, synthetic
// methods to the list covariantReturnTypeMethods.
private void buildCovariantReturnTypeMethodsForMethod(
- DexClass clazz, DexEncodedMethod method, List<DexEncodedMethod> covariantReturnTypeMethods)
- throws ApiLevelException {
+ DexClass clazz, DexEncodedMethod method, List<DexEncodedMethod> covariantReturnTypeMethods) {
assert methodHasCovariantReturnTypeAnnotation(method);
for (DexType covariantReturnType : getCovariantReturnTypes(clazz, method)) {
DexEncodedMethod covariantReturnTypeMethod =
@@ -153,8 +150,7 @@
//
// Note: any "synchronized" or "strictfp" modifier could be dropped safely.
private DexEncodedMethod buildCovariantReturnTypeMethod(
- DexClass clazz, DexEncodedMethod method, DexType covariantReturnType)
- throws ApiLevelException {
+ DexClass clazz, DexEncodedMethod method, DexType covariantReturnType) {
DexProto newProto =
factory.createProto(
covariantReturnType, method.method.proto.shorty, method.method.proto.parameters);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index d4cb8a8..b75597d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -468,10 +468,7 @@
method.accessFlags.unsetBridge();
}
- // Record that the current method uses identifier name string if the inlinee did so.
- if (target.getOptimizationInfo().useIdentifierNameString()) {
- method.markUseIdentifierNameString();
- }
+ method.copyMetadataFromInlinee(target);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 2e5b703..6cb8f6e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -64,6 +64,7 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;
+import org.objectweb.asm.Opcodes;
/**
* Support class for implementing outlining (i.e. extracting common code patterns as methods).
@@ -872,6 +873,8 @@
Constants.ACC_PUBLIC | Constants.ACC_STATIC, false);
DexString methodName = dexItemFactory.createString(OutlineOptions.METHOD_PREFIX + count);
DexMethod method = outline.buildMethod(type, methodName);
+ List<DexEncodedMethod> sites = outlineSites.get(outline);
+ assert !sites.isEmpty();
direct[count] =
new DexEncodedMethod(
method,
@@ -879,6 +882,9 @@
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
new OutlineCode(outline));
+ if (options.isGeneratingClassFiles()) {
+ direct[count].upgradeClassFileVersion(sites.get(0).getClassFileVersion());
+ }
generatedOutlines.put(outline, method);
count++;
}
@@ -908,10 +914,9 @@
DexEncodedMethod.EMPTY_ARRAY, // Virtual methods.
options.itemFactory.getSkipNameValidationForTesting());
if (options.isGeneratingClassFiles()) {
- // Don't set class file version below 50.0 (JDK release 1.6).
- clazz.setClassFileVersion(Math.max(50, getClassFileVersion(outlines)));
+ // All program classes must have a class-file version. Use Java 6.
+ clazz.setClassFileVersion(Opcodes.V1_6);
}
-
return clazz;
}
@@ -927,26 +932,6 @@
return result;
}
- private int getClassFileVersion(List<Outline> outlines) {
- assert options.isGeneratingClassFiles();
- int classFileVersion = -1;
- Set<DexType> seen = Sets.newIdentityHashSet();
- for (Outline outline : outlines) {
- List<DexEncodedMethod> methods = outlineSites.get(outline);
- for (DexEncodedMethod method : methods) {
- DexType holder = method.method.holder;
- if (seen.add(holder)) {
- DexProgramClass programClass = appInfo.definitionFor(holder).asProgramClass();
- assert programClass != null : "Attempt to outline from library class";
- assert programClass.originatesFromClassResource()
- : "Attempt to outline from non-classfile input to classfile output";
- classFileVersion = Math.max(classFileVersion, programClass.getClassFileVersion());
- }
- }
- }
- return classFileVersion;
- }
-
public void applyOutliningCandidate(IRCode code, DexEncodedMethod method) {
assert !(method.getCode() instanceof OutlineCode);
ListIterator<BasicBlock> blocksIterator = code.blocks.listIterator();
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index bb27c08..ef247a0 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -390,10 +390,14 @@
// Compute the final change in locals and insert it before nextInstruction.
boolean localsChanged = !ending.isEmpty() || !starting.isEmpty();
if (localsChanged) {
- DebugLocalsChange change = createLocalsChange(ending, starting);
- if (change != null) {
- // Insert the DebugLocalsChange instruction before nextInstruction.
- instructionIterator.add(change);
+ boolean skipChange =
+ nextInstruction == nextInstruction.getBlock().exit() && nextInstruction.isGoto();
+ if (!skipChange) {
+ DebugLocalsChange change = createLocalsChange(ending, starting);
+ if (change != null) {
+ // Insert the DebugLocalsChange instruction before nextInstruction.
+ instructionIterator.add(change);
+ }
}
// Create new maps for the next DebugLocalsChange instruction.
ending = new Int2ReferenceOpenHashMap<>();
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 2970fb4..7a25e1a 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -108,7 +108,7 @@
private void writeClass(DexProgramClass clazz, ClassFileConsumer consumer) throws IOException {
ClassWriter writer = new ClassWriter(0);
writer.visitSource(clazz.sourceFile != null ? clazz.sourceFile.toString() : null, null);
- int version = clazz.getClassFileVersion();
+ int version = getClassFileVersion(clazz);
int access = clazz.accessFlags.getAsCfAccessFlags();
String desc = namingLens.lookupDescriptor(clazz.type).toString();
String name = namingLens.lookupInternalName(clazz.type);
@@ -161,6 +161,17 @@
options.reporter, handler -> consumer.accept(result, desc, handler));
}
+ private int getClassFileVersion(DexProgramClass clazz) {
+ int version = clazz.getClassFileVersion();
+ for (DexEncodedMethod method : clazz.directMethods()) {
+ version = Math.max(version, method.getClassFileVersion());
+ }
+ for (DexEncodedMethod method : clazz.virtualMethods()) {
+ version = Math.max(version, method.getClassFileVersion());
+ }
+ return version;
+ }
+
private DexValue getSystemAnnotationValue(DexAnnotationSet annotations, DexType type) {
DexAnnotation annotation = annotations.getFirstMatching(type);
if (annotation == null) {
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
index 9a5baaf..0cc0d53 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureParser.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.naming.signature;
import java.lang.reflect.GenericSignatureFormatError;
+import java.nio.CharBuffer;
/**
* Implements a parser for the generics signature attribute as defined by JVMS 7 $ 4.3.4.
@@ -177,7 +178,7 @@
updateTypeVariableSignature();
break;
default:
- throw new GenericSignatureFormatError();
+ parseError();
}
}
@@ -340,7 +341,7 @@
eof = true;
}
} else {
- throw new GenericSignatureFormatError();
+ parseError("Unexpected end of signature");
}
}
@@ -348,7 +349,7 @@
if (symbol == c) {
scanSymbol();
} else {
- throw new GenericSignatureFormatError();
+ parseError("Expected " + c);
}
}
@@ -395,10 +396,20 @@
// Ident starts with incorrect char.
symbol = 0;
eof = true;
- throw new GenericSignatureFormatError();
+ parseError();
}
} else {
- throw new GenericSignatureFormatError();
+ parseError("Unexpected end of signature");
}
}
+
+ private void parseError() {
+ parseError("Unexpected");
+ }
+
+ private void parseError(String message) {
+ String arrow = CharBuffer.allocate(pos).toString().replace('\0', ' ') + '^';
+ throw new GenericSignatureFormatError(
+ message + " at position " + (pos + 1) + "\n" + String.valueOf(buffer) + "\n" + arrow);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/position/TextRange.java b/src/main/java/com/android/tools/r8/position/TextRange.java
index d7c0f43..5f35aad 100644
--- a/src/main/java/com/android/tools/r8/position/TextRange.java
+++ b/src/main/java/com/android/tools/r8/position/TextRange.java
@@ -45,6 +45,11 @@
}
@Override
+ public String toString() {
+ return "Text range from: '" + getStart() + "', to: '" + getEnd() + "'";
+ }
+
+ @Override
public String getDescription() {
return start.getDescription();
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index d4fcc67..19fe18e 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -460,10 +460,11 @@
DexType baseType = type.toBaseType(appInfo.dexItemFactory);
if (baseType.isClassType()) {
DexClass baseClass = appInfo.definitionFor(baseType);
- if (baseClass != null && !baseClass.isLibraryClass()) {
+ if (baseClass != null && baseClass.isProgramClass()
+ && baseClass.hasDefaultInitializer()) {
markClassAsInstantiatedWithCompatRule(baseClass);
} else {
- // This handles reporting of missing classes.
+ // This also handles reporting of missing classes.
markTypeAsLive(baseType);
}
return true;
@@ -739,7 +740,6 @@
transitionNonAbstractMethodsToLiveAndShadow(
reachableMethods.getItems(), instantiatedType, seen.newNestedScope());
}
- seen = seen.newNestedScope();
for (DexType subInterface : clazz.interfaces.values) {
transitionDefaultMethodsForInstantiatedClass(subInterface, instantiatedType, seen);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index dd82dfd..d4d4bcb 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -305,8 +305,8 @@
// disableOptimization();
}
- if ((keepAttributePatterns.isEmpty()
- && (rulesWasEmpty || (forceProguardCompatibility && !isObfuscating())))
+ if ((keepAttributePatterns.isEmpty() && rulesWasEmpty)
+ || (forceProguardCompatibility && !isObfuscating())
|| !isShrinking()) {
keepAttributePatterns.addAll(ProguardKeepAttributes.KEEP_ALL);
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 4a25e42..ed9cbdb 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -47,6 +47,7 @@
private final DexItemFactory dexItemFactory;
private final Reporter reporter;
+ private final boolean failOnPartiallyImplementedOptions;
private static final List<String> IGNORED_SINGLE_ARG_OPTIONS = ImmutableList.of(
"protomapping",
@@ -96,10 +97,16 @@
public ProguardConfigurationParser(
DexItemFactory dexItemFactory, Reporter reporter) {
+ this(dexItemFactory, reporter, true);
+ }
+
+ public ProguardConfigurationParser(
+ DexItemFactory dexItemFactory, Reporter reporter, boolean failOnPartiallyImplementedOptions) {
this.dexItemFactory = dexItemFactory;
configurationBuilder = ProguardConfiguration.builder(dexItemFactory, reporter);
this.reporter = reporter;
+ this.failOnPartiallyImplementedOptions = failOnPartiallyImplementedOptions;
}
public ProguardConfiguration.Builder getConfigurationBuilder() {
@@ -219,6 +226,10 @@
ProguardCheckDiscardRule rule = parseCheckDiscardRule();
configurationBuilder.addRule(rule);
} else if (acceptString("keepdirectories")) {
+ // TODO(74279367): Report an error until it's fully supported.
+ if (failOnPartiallyImplementedOptions) {
+ failPartiallyImplementedOption("-keepdirectories", optionStart);
+ }
parsePathFilter(configurationBuilder::addKeepDirectories);
} else if (acceptString("keep")) {
ProguardKeepRule rule = parseKeepRule();
@@ -339,11 +350,17 @@
} else if (acceptString("adaptclassstrings")) {
parseClassFilter(configurationBuilder::addAdaptClassStringsPattern);
} else if (acceptString("adaptresourcefilenames")) {
- // TODO(b/76377381): should be report an error until it's fully supported.
+ // TODO(76377381): Report an error until it's fully supported.
+ if (failOnPartiallyImplementedOptions) {
+ failPartiallyImplementedOption("-adaptresourcefilenames", optionStart);
+ }
parsePathFilter(configurationBuilder::addAdaptResourceFilenames);
} else if (acceptString("adaptresourcefilecontents")) {
+ // TODO(36847655): Report an error until it's fully supported.
+ if (failOnPartiallyImplementedOptions) {
+ failPartiallyImplementedOption("-adaptresourcefilecontents", optionStart);
+ }
parsePathFilter(configurationBuilder::addAdaptResourceFilecontents);
- // TODO(b/37139570): should be report an error until it's fully supported.
} else if (acceptString("identifiernamestring")) {
configurationBuilder.addRule(parseIdentifierNameStringRule());
} else if (acceptString("if")) {
@@ -1473,6 +1490,11 @@
"Option -" + optionName + " overrides -" + victim, origin, getPosition(start)));
}
+ private void failPartiallyImplementedOption(String optionName, TextPosition start) {
+ throw reporter.fatalError(new StringDiagnostic(
+ "Option " + optionName + " currently not supported", origin, getPosition(start)));
+ }
+
private Position getPosition(TextPosition start) {
if (start.getOffset() == position) {
return start;
diff --git a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
index 577632a..fe8adfa 100644
--- a/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ExceptionUtils.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ResourceException;
@@ -15,7 +14,6 @@
import java.nio.file.FileSystemException;
import java.nio.file.Paths;
import java.util.function.Consumer;
-import java.util.function.Function;
public abstract class ExceptionUtils {
@@ -37,31 +35,26 @@
}
public interface CompileAction {
- void run() throws IOException, CompilationException, CompilationError, ResourceException;
+ void run() throws IOException, CompilationError, ResourceException;
}
public static void withD8CompilationHandler(Reporter reporter, CompileAction action)
throws CompilationFailedException {
- withCompilationHandler(reporter, action, CompilationException::getMessageForD8);
+ withCompilationHandler(reporter, action);
}
public static void withR8CompilationHandler(Reporter reporter, CompileAction action)
throws CompilationFailedException {
- withCompilationHandler(reporter, action, CompilationException::getMessageForR8);
+ withCompilationHandler(reporter, action);
}
- public static void withCompilationHandler(
- Reporter reporter,
- CompileAction action,
- Function<CompilationException, String> compilerMessage)
+ public static void withCompilationHandler(Reporter reporter, CompileAction action)
throws CompilationFailedException {
try {
try {
action.run();
} catch (IOException e) {
throw reporter.fatalError(new ExceptionDiagnostic(e, extractIOExceptionOrigin(e)));
- } catch (CompilationException e) {
- throw reporter.fatalError(new StringDiagnostic(compilerMessage.apply(e)), e);
} catch (CompilationError e) {
throw reporter.fatalError(e);
} catch (ResourceException e) {
@@ -74,7 +67,7 @@
}
public interface MainAction {
- void run() throws CompilationFailedException, IOException;
+ void run() throws CompilationFailedException;
}
public static void withMainProgramHandler(MainAction action) {
@@ -84,7 +77,7 @@
// Detail of the errors were already reported
System.err.println("Compilation failed");
System.exit(STATUS_ERROR);
- } catch (RuntimeException | IOException e) {
+ } catch (RuntimeException e) {
System.err.println("Compilation failed with an internal error.");
Throwable cause = e.getCause() == null ? e : e.getCause();
cause.printStackTrace();
diff --git a/src/main/java/com/android/tools/r8/utils/FlagFile.java b/src/main/java/com/android/tools/r8/utils/FlagFile.java
index 2354066..4791217 100644
--- a/src/main/java/com/android/tools/r8/utils/FlagFile.java
+++ b/src/main/java/com/android/tools/r8/utils/FlagFile.java
@@ -4,18 +4,41 @@
package com.android.tools.r8.utils;
+import com.android.tools.r8.origin.Origin;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class FlagFile {
- public static String[] expandFlagFiles(String[] args) throws IOException {
+
+ private static class FlagFileOrigin extends Origin {
+ private final Path path;
+
+ protected FlagFileOrigin(Path path) {
+ super(Origin.root());
+ this.path = path;
+ }
+
+ @Override
+ public String part() {
+ return "flag file argument: '@" + path + "'";
+ }
+ }
+
+ public static String[] expandFlagFiles(String[] args, Reporter reporter) {
List<String> flags = new ArrayList<>(args.length);
for (String arg : args) {
if (arg.startsWith("@")) {
- flags.addAll(Files.readAllLines(Paths.get(arg.substring(1))));
+ Path flagFilePath = Paths.get(arg.substring(1));
+ try {
+ flags.addAll(Files.readAllLines(flagFilePath));
+ } catch (IOException e) {
+ Origin origin = new FlagFileOrigin(flagFilePath);
+ reporter.error(new ExceptionDiagnostic(e, origin));
+ }
} else {
flags.add(arg);
}
diff --git a/src/main/java/com/android/tools/r8/utils/Reporter.java b/src/main/java/com/android/tools/r8/utils/Reporter.java
index ebb7ce6..b09f164 100644
--- a/src/main/java/com/android/tools/r8/utils/Reporter.java
+++ b/src/main/java/com/android/tools/r8/utils/Reporter.java
@@ -3,10 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.utils;
+import com.android.tools.r8.BaseCompilerCommand;
import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.D8Command;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.R8Command;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.MainDexOverflow;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
@@ -16,12 +20,18 @@
public class Reporter implements DiagnosticsHandler {
private final DiagnosticsHandler clientHandler;
+ private final BaseCompilerCommand command;
private int errorCount = 0;
private Diagnostic lastError;
private final Collection<Throwable> suppressedExceptions = new ArrayList<>();
public Reporter(DiagnosticsHandler clientHandler) {
+ this(clientHandler, null);
+ }
+
+ public Reporter(DiagnosticsHandler clientHandler, BaseCompilerCommand command) {
this.clientHandler = clientHandler;
+ this.command = command;
}
@Override
@@ -75,6 +85,19 @@
}
/**
+ * @throws AbortException always.
+ */
+ public RuntimeException fatalError(MainDexOverflow e) {
+ if (command instanceof R8Command) {
+ return fatalError(new StringDiagnostic(e.getMessageForR8()));
+ } else if (command instanceof D8Command) {
+ return fatalError(new StringDiagnostic(e.getMessageForD8()));
+ } else {
+ return fatalError(new StringDiagnostic(e.getMessage()));
+ }
+ }
+
+ /**
* @throws AbortException if any error was reported.
*/
public void failIfPendingErrors() {
diff --git a/src/test/java/com/android/tools/r8/AsmTestBase.java b/src/test/java/com/android/tools/r8/AsmTestBase.java
index db26fe6..9cc2b48 100644
--- a/src/test/java/com/android/tools/r8/AsmTestBase.java
+++ b/src/test/java/com/android/tools/r8/AsmTestBase.java
@@ -54,8 +54,8 @@
}
private void ensureSameOutput(String main, AndroidApp app, byte[]... classes)
- throws IOException, CompilationException, ExecutionException, CompilationFailedException,
- ProguardRuleParserException {
+ throws IOException, ExecutionException, CompilationFailedException,
+ ProguardRuleParserException {
ProcessResult javaResult = runOnJava(main, classes);
ProcessResult d8Result = runOnArtRaw(compileWithD8(app), main);
ProcessResult r8Result = runOnArtRaw(compileWithR8(app), main);
@@ -88,8 +88,8 @@
}
protected void ensureSameOutputAfterMerging(String main, byte[]... classes)
- throws IOException, CompilationException, ExecutionException,
- CompilationFailedException, ProguardRuleParserException {
+ throws IOException, ExecutionException, CompilationFailedException,
+ ProguardRuleParserException {
AndroidApp app = buildAndroidApp(classes);
// Compile to dex files with D8.
AndroidApp dexApp = compileWithD8(app);
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index 5576058..1b846a5 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -9,6 +9,7 @@
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import com.android.sdklib.AndroidVersion;
@@ -99,7 +100,7 @@
FileUtils.writeTextFile(
flagsFile,
"--output",
- output.toString(),
+ "output.zip",
"--min-api",
"24",
input.toString());
@@ -110,6 +111,19 @@
assertEquals(Tool.D8, marker.getTool());
}
+ @Test(expected=CompilationFailedException.class)
+ public void nonExistingFlagsFile() throws Throwable {
+ Path working = temp.getRoot().toPath();
+ Path flags = working.resolve("flags.txt").toAbsolutePath();
+ assertNotEquals(0, ToolHelper.forkR8(working, "@flags.txt").exitCode);
+ DiagnosticsChecker.checkErrorsContains("File not found", handler ->
+ D8.run(
+ D8Command.parse(
+ new String[] { "@" + flags.toString() },
+ EmbeddedOrigin.INSTANCE,
+ handler).build()));
+ }
+
@Test
public void printsHelpOnNoInput() throws Throwable {
ProcessResult result = ToolHelper.forkD8(temp.getRoot().toPath());
diff --git a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
index dc4a9b4..1d9ec50 100644
--- a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
@@ -119,7 +119,7 @@
}
private AndroidApp mergeDexResources(int minAPILevel, List<ProgramResource> individalDexes)
- throws IOException, CompilationException, CompilationFailedException, ResourceException {
+ throws IOException, CompilationFailedException, ResourceException {
D8Command.Builder builder = D8Command.builder()
.setMinApiLevel(minAPILevel);
for (ProgramResource resource : individalDexes) {
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
index 77959d9..ede7e53 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
@@ -76,7 +76,7 @@
// compilation should have failed on CompilationError since A is declaring a default method.
Assert.fail();
- } catch (CompilationError | CompilationException e) {
+ } catch (CompilationError e) {
// Expected.
}
}
diff --git a/src/test/java/com/android/tools/r8/DiagnosticsChecker.java b/src/test/java/com/android/tools/r8/DiagnosticsChecker.java
index 2265c3e..2f45ae2 100644
--- a/src/test/java/com/android/tools/r8/DiagnosticsChecker.java
+++ b/src/test/java/com/android/tools/r8/DiagnosticsChecker.java
@@ -49,13 +49,14 @@
try {
runner.run(handler);
} catch (CompilationFailedException e) {
+ List<String> messages = ListUtils.map(handler.errors, Diagnostic::getDiagnosticMessage);
System.out.println("Expecting match for '" + snippet + "'");
- System.out.println("StdErr:\n" + handler.errors);
+ System.out.println("StdErr:\n" + messages);
assertTrue(
"Expected to find snippet '"
+ snippet
+ "' in error messages:\n"
- + String.join("\n", ListUtils.map(handler.errors, Diagnostic::getDiagnosticMessage)),
+ + String.join("\n", messages),
handler.errors.stream().anyMatch(d -> d.getDiagnosticMessage().contains(snippet)));
throw e;
}
diff --git a/src/test/java/com/android/tools/r8/R8CommandTest.java b/src/test/java/com/android/tools/r8/R8CommandTest.java
index c1072bd..fbd88be 100644
--- a/src/test/java/com/android/tools/r8/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/R8CommandTest.java
@@ -101,7 +101,7 @@
FileUtils.writeTextFile(
flagsFile,
"--output",
- output.toString(),
+ "output.zip",
"--min-api",
"24",
"--lib",
@@ -114,6 +114,20 @@
assertEquals(Tool.R8, marker.getTool());
}
+
+ @Test(expected=CompilationFailedException.class)
+ public void nonExistingFlagsFile() throws Throwable {
+ Path working = temp.getRoot().toPath();
+ Path flags = working.resolve("flags.txt").toAbsolutePath();
+ assertNotEquals(0, ToolHelper.forkR8(working, "@flags.txt").exitCode);
+ DiagnosticsChecker.checkErrorsContains("File not found", handler ->
+ R8.run(
+ R8Command.parse(
+ new String[] { "@" + flags.toString() },
+ EmbeddedOrigin.INSTANCE,
+ handler).build()));
+ }
+
@Test
public void printsHelpOnNoInput() throws Throwable {
ProcessResult result = ToolHelper.forkR8(temp.getRoot().toPath());
diff --git a/src/test/java/com/android/tools/r8/R8EntryPointTests.java b/src/test/java/com/android/tools/r8/R8EntryPointTests.java
index 6f3473e..edf7f20 100644
--- a/src/test/java/com/android/tools/r8/R8EntryPointTests.java
+++ b/src/test/java/com/android/tools/r8/R8EntryPointTests.java
@@ -131,8 +131,7 @@
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
- private R8Command getCommand(Path out)
- throws CompilationException, IOException, CompilationFailedException {
+ private R8Command getCommand(Path out) throws IOException, CompilationFailedException {
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.addProgramFiles(INPUT_JAR)
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index b27569b..b12eb2d 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -1388,7 +1388,7 @@
boolean disableInlining,
boolean disableClassInlining,
boolean hasMissingClasses)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
executeCompilerUnderTest(compilerUnderTest, fileNames, resultPath, compilationMode, null,
disableInlining, disableClassInlining, hasMissingClasses);
@@ -1403,7 +1403,7 @@
boolean disableInlining,
boolean disableClassInlining,
boolean hasMissingClasses)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
assert mode != null;
switch (compilerUnderTest) {
@@ -1434,7 +1434,7 @@
}
}
} catch (ResourceException e) {
- throw new CompilationException(e);
+ throw new CompilationError("", e);
}
}
}
@@ -1621,7 +1621,7 @@
protected void runJctfTest(CompilerUnderTest compilerUnderTest, String classFilePath,
String fullClassName)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
DexVm dexVm = ToolHelper.getDexVm();
@@ -1751,7 +1751,7 @@
CompilationMode mode,
DexVm dexVm,
File resultDir)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
executeCompilerUnderTest(compilerUnderTest, fileNames, resultDir.getAbsolutePath(), mode,
specification.disableInlining, specification.disableClassInlining,
@@ -1930,7 +1930,7 @@
compilerUnderTest, fileNames, resultDir.getCanonicalPath(), compilationMode,
specification.disableInlining, specification.disableClassInlining,
specification.hasMissingClasses);
- } catch (CompilationException | CompilationFailedException e) {
+ } catch (CompilationFailedException e) {
throw new CompilationError(e.getMessage(), e);
} catch (ExecutionException e) {
throw e.getCause();
diff --git a/src/test/java/com/android/tools/r8/R8UnreachableCodeTest.java b/src/test/java/com/android/tools/r8/R8UnreachableCodeTest.java
index a504c7c..36a4f00 100644
--- a/src/test/java/com/android/tools/r8/R8UnreachableCodeTest.java
+++ b/src/test/java/com/android/tools/r8/R8UnreachableCodeTest.java
@@ -30,7 +30,7 @@
@Ignore
@Test
- public void UnreachableCode() throws IOException, ExecutionException, CompilationException {
+ public void UnreachableCode() throws IOException, ExecutionException {
String name = "unreachable-code-1";
AndroidApp input =
AndroidApp.builder()
diff --git a/src/test/java/com/android/tools/r8/ResourceShrinkerTest.java b/src/test/java/com/android/tools/r8/ResourceShrinkerTest.java
index 301f78f..d21d156 100644
--- a/src/test/java/com/android/tools/r8/ResourceShrinkerTest.java
+++ b/src/test/java/com/android/tools/r8/ResourceShrinkerTest.java
@@ -73,8 +73,7 @@
}
@Test
- public void testEmptyClass()
- throws CompilationFailedException, IOException, ExecutionException, CompilationException {
+ public void testEmptyClass() throws CompilationFailedException, IOException, ExecutionException {
TrackAll analysis = runAnalysis(EmptyClass.class);
assertThat(analysis.integers, is(Sets.newHashSet()));
@@ -95,7 +94,7 @@
@Test
public void testConstsAndFieldAndMethods()
- throws CompilationFailedException, IOException, ExecutionException, CompilationException {
+ throws CompilationFailedException, IOException, ExecutionException {
TrackAll analysis = runAnalysis(ConstInCode.class);
assertThat(analysis.integers, is(Sets.newHashSet(10, 11)));
@@ -125,7 +124,7 @@
@Test
public void testStaticValues()
- throws CompilationFailedException, IOException, ExecutionException, CompilationException {
+ throws CompilationFailedException, IOException, ExecutionException {
TrackAll analysis = runAnalysis(StaticFields.class);
assertThat(analysis.integers, hasItems(10, 11, 12, 13));
@@ -163,8 +162,7 @@
}
@Test
- public void testAnnotations()
- throws CompilationFailedException, IOException, ExecutionException, CompilationException {
+ public void testAnnotations() throws CompilationFailedException, IOException, ExecutionException {
TrackAll analysis = runAnalysis(IntAnnotation.class, OuterAnnotation.class, Annotated.class);
assertThat(analysis.integers, hasItems(10, 11, 12, 13, 14, 15, 42));
@@ -184,7 +182,7 @@
@Test
public void testWithSkippingSome()
- throws ExecutionException, CompilationFailedException, CompilationException, IOException {
+ throws ExecutionException, CompilationFailedException, IOException {
TrackAll analysis = runAnalysis(ResourceClassToSkip.class, ToProcess.class);
assertThat(analysis.integers, hasItems(10, 11, 12));
@@ -222,13 +220,13 @@
}
private TrackAll runAnalysis(Class<?>... classes)
- throws IOException, CompilationException, ExecutionException, CompilationFailedException {
+ throws IOException, ExecutionException, CompilationFailedException {
AndroidApp app = readClasses(classes);
return runOnApp(app);
}
private TrackAll runOnApp(AndroidApp app)
- throws IOException, ExecutionException, CompilationFailedException, CompilationException {
+ throws IOException, ExecutionException, CompilationFailedException {
AndroidApp outputApp = compileWithD8(app);
Path outputDex = tmp.newFolder().toPath().resolve("classes.dex");
outputApp.writeToDirectory(outputDex.getParent(), OutputMode.DexIndexed);
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 96591d8..331af0a 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -215,7 +215,7 @@
* Compile an application with D8.
*/
protected AndroidApp compileWithD8(AndroidApp app)
- throws CompilationException, ExecutionException, IOException, CompilationFailedException {
+ throws ExecutionException, IOException, CompilationFailedException {
D8Command.Builder builder = ToolHelper.prepareD8CommandBuilder(app);
AndroidAppConsumers appSink = new AndroidAppConsumers(builder);
D8.run(builder.build());
@@ -226,7 +226,7 @@
* Compile an application with D8.
*/
protected AndroidApp compileWithD8(AndroidApp app, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ExecutionException, IOException, CompilationFailedException {
+ throws ExecutionException, IOException, CompilationFailedException {
return ToolHelper.runD8(app, optionsConsumer);
}
@@ -234,7 +234,7 @@
* Compile an application with R8.
*/
protected AndroidApp compileWithR8(Class... classes)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
return ToolHelper.runR8(readClasses(classes));
}
@@ -243,7 +243,7 @@
* Compile an application with R8.
*/
protected AndroidApp compileWithR8(List<Class> classes)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command = ToolHelper.prepareR8CommandBuilder(readClasses(classes)).build();
return ToolHelper.runR8(command);
@@ -253,7 +253,7 @@
* Compile an application with R8.
*/
protected AndroidApp compileWithR8(List<Class> classes, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command = ToolHelper.prepareR8CommandBuilder(readClasses(classes)).build();
return ToolHelper.runR8(command, optionsConsumer);
@@ -263,7 +263,7 @@
* Compile an application with R8.
*/
protected AndroidApp compileWithR8(AndroidApp app)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command = ToolHelper.prepareR8CommandBuilder(app).build();
return ToolHelper.runR8(command);
@@ -273,7 +273,7 @@
* Compile an application with R8.
*/
protected AndroidApp compileWithR8(AndroidApp app, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command = ToolHelper.prepareR8CommandBuilder(app).build();
return ToolHelper.runR8(command, optionsConsumer);
@@ -283,7 +283,7 @@
* Compile an application with R8 using the supplied proguard configuration.
*/
protected AndroidApp compileWithR8(List<Class> classes, String proguardConfig)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
return compileWithR8(readClasses(classes), proguardConfig);
}
@@ -293,7 +293,7 @@
*/
protected AndroidApp compileWithR8(
List<Class> classes, String proguardConfig, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
return compileWithR8(readClasses(classes), proguardConfig, optionsConsumer);
}
@@ -302,7 +302,7 @@
* Compile an application with R8 using the supplied proguard configuration.
*/
protected AndroidApp compileWithR8(List<Class> classes, Path proguardConfig)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
return compileWithR8(readClasses(classes), proguardConfig);
}
@@ -311,7 +311,7 @@
* Compile an application with R8 using the supplied proguard configuration.
*/
protected AndroidApp compileWithR8(AndroidApp app, Path proguardConfig)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command =
ToolHelper.prepareR8CommandBuilder(app)
@@ -324,7 +324,7 @@
* Compile an application with R8 using the supplied proguard configuration.
*/
protected AndroidApp compileWithR8(AndroidApp app, String proguardConfig)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
return compileWithR8(app, proguardConfig, null);
}
@@ -334,7 +334,7 @@
*/
protected AndroidApp compileWithR8(
AndroidApp app, String proguardConfig, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command =
ToolHelper.prepareR8CommandBuilder(app)
@@ -348,7 +348,7 @@
*/
protected AndroidApp compileWithR8(
AndroidApp app, Path proguardConfig, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, ProguardRuleParserException, ExecutionException, IOException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
R8Command command =
ToolHelper.prepareR8CommandBuilder(app)
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index afa8c12..45ec280 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -11,7 +11,6 @@
import com.android.tools.r8.DeviceRunner.DeviceRunnerConfigurationException;
import com.android.tools.r8.ToolHelper.DexVm.Kind;
import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexItemFactory;
@@ -768,7 +767,7 @@
public static ProguardConfiguration loadProguardConfiguration(
DexItemFactory factory, List<Path> configPaths)
- throws IOException, ProguardRuleParserException, CompilationException {
+ throws IOException, ProguardRuleParserException {
Reporter reporter = new Reporter(new DefaultDiagnosticsHandler());
if (configPaths.isEmpty()) {
return ProguardConfiguration.defaultConfiguration(factory, reporter);
@@ -789,7 +788,7 @@
return R8Command.builder(app).setProgramConsumer(DexIndexedConsumer.emptyConsumer());
}
- public static AndroidApp runR8(AndroidApp app) throws IOException, CompilationException {
+ public static AndroidApp runR8(AndroidApp app) throws IOException {
try {
return runR8(prepareR8CommandBuilder(app).build());
} catch (CompilationFailedException e) {
@@ -798,7 +797,7 @@
}
public static AndroidApp runR8(AndroidApp app, Consumer<InternalOptions> optionsConsumer)
- throws IOException, CompilationException {
+ throws IOException {
try {
return runR8(prepareR8CommandBuilder(app).build(), optionsConsumer);
} catch (CompilationFailedException e) {
@@ -806,18 +805,17 @@
}
}
- public static AndroidApp runR8(R8Command command) throws IOException, CompilationException {
+ public static AndroidApp runR8(R8Command command) throws IOException {
return runR8(command, null);
}
public static AndroidApp runR8(R8Command command, Consumer<InternalOptions> optionsConsumer)
- throws IOException, CompilationException {
+ throws IOException {
return runR8WithFullResult(command, optionsConsumer);
}
public static AndroidApp runR8WithFullResult(
- R8Command command, Consumer<InternalOptions> optionsConsumer)
- throws IOException, CompilationException {
+ R8Command command, Consumer<InternalOptions> optionsConsumer) throws IOException {
// TODO(zerny): Should we really be adding the android library in ToolHelper?
AndroidApp app = command.getInputApp();
if (app.getLibraryResourceProviders().isEmpty()) {
@@ -848,12 +846,12 @@
ImmutableList.of("!junit/**", "!android/test/**"))));
}
- public static AndroidApp runD8(AndroidApp app) throws CompilationException, IOException {
+ public static AndroidApp runD8(AndroidApp app) throws IOException {
return runD8(app, null);
}
public static AndroidApp runD8(AndroidApp app, Consumer<InternalOptions> optionsConsumer)
- throws CompilationException, IOException {
+ throws IOException {
try {
return runD8(D8Command.builder(app), optionsConsumer);
} catch (CompilationFailedException e) {
@@ -862,13 +860,13 @@
}
public static AndroidApp runD8(D8Command.Builder builder)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
return runD8(builder, null);
}
public static AndroidApp runD8(
D8Command.Builder builder, Consumer<InternalOptions> optionsConsumer)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
AndroidAppConsumers compatSink = new AndroidAppConsumers(builder);
D8Command command = builder.build();
InternalOptions options = command.getInternalOptions();
@@ -1328,6 +1326,12 @@
return builder;
}
+ public static R8Command.Builder allowPartiallyImplementedProguardOptions(
+ R8Command.Builder builder) {
+ builder.allowPartiallyImplementedProguardOptions();
+ return builder;
+ }
+
public static AndroidApp getApp(BaseCommand command) {
return command.getInputApp();
}
@@ -1354,7 +1358,7 @@
}
public static void writeApplication(DexApplication application, InternalOptions options)
- throws ExecutionException, DexOverflowException {
+ throws ExecutionException {
R8.writeApplication(
Executors.newSingleThreadExecutor(),
application,
diff --git a/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java b/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java
index d6e0542..ad6a72b 100644
--- a/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java
+++ b/src/test/java/com/android/tools/r8/cf/DebugInfoTestRunner.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.cf;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.CompilationMode;
@@ -13,6 +14,8 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.InvalidDebugInfoException;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.ThrowingConsumer;
import java.nio.file.Path;
@@ -33,9 +36,18 @@
ProcessResult run1 = ToolHelper.runJava(out1, CLASS.getCanonicalName());
assertEquals(runInput.toString(), run1.toString());
Path out2 = temp.getRoot().toPath().resolve("out2.zip");
- build(builder -> builder.addProgramFiles(out1), new ClassFileConsumer.ArchiveConsumer(out2));
- ProcessResult run2 = ToolHelper.runJava(out2, CLASS.getCanonicalName());
- assertEquals(runInput.toString(), run2.toString());
+ boolean invalidDebugInfo = false;
+ try {
+ build(builder -> builder.addProgramFiles(out1), new ClassFileConsumer.ArchiveConsumer(out2));
+ } catch (CompilationError e) {
+ invalidDebugInfo = e.getCause() instanceof InvalidDebugInfoException;
+ }
+ // TODO(b/77522100): Change to assertFalse when fixed.
+ assertTrue(invalidDebugInfo);
+ if (!invalidDebugInfo) {
+ ProcessResult run2 = ToolHelper.runJava(out2, CLASS.getCanonicalName());
+ assertEquals(runInput.toString(), run2.toString());
+ }
}
private void build(ThrowingConsumer<Builder, Exception> input, ProgramConsumer consumer)
diff --git a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
index c6a2bd3..d5d2c39 100644
--- a/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/ClassMergingTest.java
@@ -6,7 +6,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
@@ -43,7 +42,7 @@
}
private void runR8(Path proguardConfig, Consumer<InternalOptions> optionsConsumer)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
ToolHelper.runR8(
R8Command.builder()
diff --git a/src/test/java/com/android/tools/r8/debuginfo/DebugInfoTestBase.java b/src/test/java/com/android/tools/r8/debuginfo/DebugInfoTestBase.java
index 479a558..d0ad1df 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/DebugInfoTestBase.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/DebugInfoTestBase.java
@@ -5,7 +5,6 @@
import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -32,8 +31,7 @@
@Rule
public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
- static AndroidApp compileWithD8(Class... classes) throws CompilationException, IOException,
- CompilationFailedException {
+ static AndroidApp compileWithD8(Class... classes) throws IOException, CompilationFailedException {
D8Command.Builder builder = D8Command.builder();
for (Class clazz : classes) {
builder.addProgramFiles(ToolHelper.getClassFileForTestClass(clazz));
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index 89935a7..ead9175 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.ReturnVoid;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexApplication;
@@ -108,8 +107,7 @@
}
@Test
- public void manyFilesWithSharedSynthesizedClass()
- throws ExecutionException, IOException, DexOverflowException {
+ public void manyFilesWithSharedSynthesizedClass() throws ExecutionException, IOException {
// Create classes that all reference enough strings to overflow the index, but are all
// at different offsets in the strings array. This ensures we trigger multiple rounds of
diff --git a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java b/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
index 2b2a40b..4b3f4fe 100644
--- a/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
+++ b/src/test/java/com/android/tools/r8/dexfilemerger/DexFileMergerTests.java
@@ -6,7 +6,6 @@
import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.DexFileMergerHelper;
@@ -39,7 +38,7 @@
@Rule public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
private Path createMergerInputWithTwoClasses(OutputMode outputMode, boolean addMarker)
- throws CompilationFailedException, CompilationException, IOException {
+ throws CompilationFailedException, IOException {
// Compile Class1 and Class2
Path mergerInputZip = temp.newFolder().toPath().resolve("merger-input.zip");
D8Command command =
@@ -55,8 +54,7 @@
}
private void testMarker(boolean addMarkerToInput)
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexIndexed, addMarkerToInput);
Marker inputMarker = ExtractMarker.extractMarkerFromDexFile(mergerInputZip);
@@ -74,20 +72,18 @@
@Test
public void testMarkerPreserved()
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
testMarker(true);
}
@Test
public void testMarkerNotAdded()
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
testMarker(false);
}
@Test
- public void mergeTwoFiles() throws CompilationFailedException, CompilationException, IOException {
+ public void mergeTwoFiles() throws CompilationFailedException, IOException {
Path mergerInputZip = createMergerInputWithTwoClasses(OutputMode.DexFilePerClassFile, false);
Path mergerOutputZip = temp.getRoot().toPath().resolve("merger-out.zip");
@@ -107,7 +103,7 @@
}
private void generateClassesAndTest(int extraMethodCount, int programResourcesSize)
- throws IOException, ExecutionException, CompilationException, CompilationFailedException {
+ throws IOException, ExecutionException, CompilationFailedException {
AndroidApp generatedApp =
MainDexListTests.generateApplication(
ImmutableList.of("A", "B"),
@@ -125,8 +121,7 @@
}
@Test(expected = CompilationFailedException.class)
- public void failIfTooBig()
- throws IOException, ExecutionException, CompilationException, CompilationFailedException {
+ public void failIfTooBig() throws IOException, ExecutionException, CompilationFailedException {
// Generates an application with two classes, each with the number of methods just enough not to
// fit into a single dex file.
generateClassesAndTest(1, 2);
@@ -134,7 +129,7 @@
@Test
public void failIfTooBigControl()
- throws IOException, ExecutionException, CompilationException, CompilationFailedException {
+ throws IOException, ExecutionException, CompilationFailedException {
// Control test for failIfTooBig to make sure we don't fail with less methods.
generateClassesAndTest(0, 1);
}
diff --git a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
index 5bbb9d5..a0b2515 100644
--- a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
+++ b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
@@ -8,7 +8,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.DexSplitterHelper;
@@ -56,7 +55,7 @@
@Rule public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
private Path createInput(boolean dontCreateMarkerInD8)
- throws IOException, CompilationFailedException, CompilationException {
+ throws IOException, CompilationFailedException {
// Initial normal compile to create dex files.
Path inputZip = temp.newFolder().toPath().resolve("input.zip");
D8Command command =
@@ -76,8 +75,7 @@
}
private void testMarker(boolean addMarkerToInput)
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
Path inputZip = createInput(!addMarkerToInput);
Path output = temp.newFolder().toPath().resolve("output");
@@ -102,15 +100,13 @@
@Test
public void testMarkerPreserved()
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
testMarker(true);
}
@Test
public void testMarkerNotAdded()
- throws CompilationFailedException, CompilationException, IOException, ResourceException,
- ExecutionException {
+ throws CompilationFailedException, IOException, ResourceException, ExecutionException {
testMarker(false);
}
@@ -124,14 +120,13 @@
@Test
public void splitFilesNoObfuscation()
throws CompilationFailedException, IOException, FeatureMappingException, ResourceException,
- CompilationException, ExecutionException {
+ ExecutionException {
noObfuscation(false);
noObfuscation(true);
}
private void noObfuscation(boolean useOptions)
- throws IOException, CompilationFailedException, FeatureMappingException,
- ResourceException, ExecutionException, CompilationException {
+ throws IOException, CompilationFailedException, FeatureMappingException {
Path inputZip = createInput(false);
Path output = temp.newFolder().toPath().resolve("output");
Files.createDirectory(output);
@@ -228,7 +223,7 @@
@Test
public void splitFilesFromJar()
throws IOException, CompilationFailedException, FeatureMappingException, ResourceException,
- CompilationException, ExecutionException {
+ ExecutionException {
splitFromJars(true, true);
splitFromJars(false, true);
splitFromJars(true, false);
@@ -236,8 +231,7 @@
}
private void splitFromJars(boolean useOptions, boolean explicitBase)
- throws IOException, CompilationFailedException, FeatureMappingException, ResourceException,
- ExecutionException, CompilationException {
+ throws IOException, CompilationFailedException, FeatureMappingException {
Path inputZip = createInput(false);
Path output = temp.newFolder().toPath().resolve("output");
Files.createDirectory(output);
diff --git a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
index 3cab10a..bda9ac5 100644
--- a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
@@ -165,7 +164,7 @@
}
@Test
- public void lookupFieldWithDefaultInInterface() throws DexOverflowException {
+ public void lookupFieldWithDefaultInInterface() {
SmaliBuilder builder = new SmaliBuilder();
builder.addInterface("Interface");
diff --git a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
index a542b70..39c8d28 100644
--- a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
@@ -8,7 +8,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -64,14 +63,14 @@
String referenceApk,
String pgConf,
String input)
- throws ExecutionException, IOException, ProguardRuleParserException, CompilationException,
+ throws ExecutionException, IOException, ProguardRuleParserException,
CompilationFailedException {
return runAndCheckVerification(
compiler, mode, referenceApk, pgConf, null, Collections.singletonList(input));
}
public AndroidApp runAndCheckVerification(D8Command.Builder builder, String referenceApk)
- throws IOException, ExecutionException, CompilationException, CompilationFailedException {
+ throws IOException, ExecutionException, CompilationFailedException {
AndroidAppConsumers appSink = new AndroidAppConsumers(builder);
D8.run(builder.build());
AndroidApp result = appSink.build();
@@ -86,7 +85,7 @@
String pgConf,
Consumer<InternalOptions> optionsConsumer,
List<String> inputs)
- throws ExecutionException, IOException, ProguardRuleParserException, CompilationException,
+ throws ExecutionException, IOException, ProguardRuleParserException,
CompilationFailedException {
assertTrue(referenceApk == null || new File(referenceApk).exists());
AndroidAppConsumers outputApp;
@@ -99,6 +98,7 @@
builder.setMode(mode);
builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
builder.setMinApiLevel(AndroidApiLevel.L.getLevel());
+ ToolHelper.allowPartiallyImplementedProguardOptions(builder);
ToolHelper.addProguardConfigurationConsumer(
builder,
pgConfig -> {
diff --git a/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
index e546607..ab430d5 100644
--- a/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/D8FrameworkDeterministicTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.internal;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -19,7 +18,7 @@
private static final String JAR = "third_party/framework/framework_160115954.jar";
private AndroidApp doRun(D8Command.Builder builder)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
builder.setProgramConsumer(null);
AndroidAppConsumers appSink = new AndroidAppConsumers(builder);
D8.run(builder.build());
diff --git a/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java b/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java
index 0946ded..390105e 100644
--- a/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/D8PhotosVerificationTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.internal;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
@@ -17,7 +16,7 @@
"third_party/photos/2017-06-06/PhotosEnglishOnlyLegacy_proguard.jar";
public void runD8AndCheckVerification(CompilationMode mode, String version)
- throws ProguardRuleParserException, ExecutionException, IOException, CompilationException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
runAndCheckVerification(CompilerUnderTest.D8, mode, version, null, version);
}
diff --git a/src/test/java/com/android/tools/r8/internal/GMSCoreCompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/GMSCoreCompilationTestBase.java
index df4bbfe..f0b1ece 100644
--- a/src/test/java/com/android/tools/r8/internal/GMSCoreCompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/GMSCoreCompilationTestBase.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.internal;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
@@ -33,14 +32,14 @@
static final String REFERENCE_APK = "noshrink_x86_GmsCore_prod_alldpi_release_unsigned.apk";
public void runR8AndCheckVerification(CompilationMode mode, String version)
- throws ProguardRuleParserException, ExecutionException, IOException, CompilationException,
+ throws ProguardRuleParserException, ExecutionException, IOException,
CompilationFailedException {
runAndCheckVerification(CompilerUnderTest.R8, mode, version);
}
public void runAndCheckVerification(
CompilerUnderTest compiler, CompilationMode mode, String version)
- throws ExecutionException, IOException, ProguardRuleParserException, CompilationException,
+ throws ExecutionException, IOException, ProguardRuleParserException,
CompilationFailedException {
runAndCheckVerification(
compiler, mode, version + GMSCORE_APK, null, Paths.get(version, GMSCORE_APK).toString());
diff --git a/src/test/java/com/android/tools/r8/internal/GMSCoreDeployJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/GMSCoreDeployJarVerificationTest.java
index 5f635ff..09ce657 100644
--- a/src/test/java/com/android/tools/r8/internal/GMSCoreDeployJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/GMSCoreDeployJarVerificationTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.internal;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
@@ -19,7 +18,7 @@
public AndroidApp buildFromDeployJar(
CompilerUnderTest compiler, CompilationMode mode, String base, boolean hasReference)
- throws ExecutionException, IOException, ProguardRuleParserException, CompilationException,
+ throws ExecutionException, IOException, ProguardRuleParserException,
CompilationFailedException {
return runAndCheckVerification(
compiler, mode, hasReference ? base + REFERENCE_APK : null, null, base + DEPLOY_JAR);
@@ -29,7 +28,7 @@
public AndroidApp buildFromDeployJar(
CompilerUnderTest compiler, CompilationMode mode, String base, boolean hasReference,
Consumer<InternalOptions> optionsConsumer)
- throws ExecutionException, IOException, ProguardRuleParserException, CompilationException,
+ throws ExecutionException, IOException, ProguardRuleParserException,
CompilationFailedException {
return runAndCheckVerification(
compiler,
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
index 5e1c61f..abc7a73 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.internal;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.OutputMode;
@@ -33,7 +32,7 @@
}
private AndroidApp doRun()
- throws IOException, ProguardRuleParserException, CompilationException, ExecutionException,
+ throws IOException, ProguardRuleParserException, ExecutionException,
CompilationFailedException {
R8Command command =
R8Command.builder()
diff --git a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
index 5afb068..d4ab6c6 100644
--- a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
@@ -5,7 +5,6 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -37,7 +36,7 @@
return buildApplication(
AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build(),
options);
- } catch (IOException | RecognitionException | ExecutionException | DexOverflowException e) {
+ } catch (IOException | RecognitionException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@@ -118,8 +117,7 @@
return iterator;
}
- private AndroidApp writeDex(DexApplication application, InternalOptions options)
- throws DexOverflowException {
+ private AndroidApp writeDex(DexApplication application, InternalOptions options) {
try {
ToolHelper.writeApplication(application, options);
options.signalFinishedToConsumers();
@@ -129,7 +127,7 @@
}
}
- public String run() throws DexOverflowException, IOException {
+ public String run() throws IOException {
AppInfo appInfo = new AppInfo(application);
IRConverter converter = new IRConverter(appInfo, options);
converter.replaceCodeForTesting(method, code);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/MemberValuePropagationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/MemberValuePropagationTest.java
index 47f0db3..a5c7093 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/MemberValuePropagationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/MemberValuePropagationTest.java
@@ -6,7 +6,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
@@ -99,8 +98,7 @@
});
}
- private Path runR8(Path proguardConfig)
- throws IOException, CompilationException, CompilationFailedException {
+ private Path runR8(Path proguardConfig) throws IOException, CompilationFailedException {
Path dexOutputDir = temp.newFolder().toPath();
ToolHelper.runR8(
R8Command.builder()
diff --git a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
index 990fe6e..7b74453 100644
--- a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
+++ b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.jsr45;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
@@ -50,7 +49,7 @@
public TemporaryFolder tmpOutputDir = ToolHelper.getTemporaryFolderForTest();
private AndroidApp compileWithD8(Path intputPath, Path outputPath)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
D8Command.Builder builder =
D8Command.builder()
.setMinApiLevel(AndroidApiLevel.O.getLevel())
@@ -62,7 +61,7 @@
}
private AndroidApp compileWithR8(Path inputPath, Path outputPath, Path keepRulesPath)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
return ToolHelper.runR8(
R8Command.builder()
.addProgramFiles(inputPath)
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 590baa6..4214a67 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -10,11 +10,12 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.StringResource;
@@ -23,9 +24,7 @@
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
@@ -54,9 +53,11 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AbortException;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
+import com.android.tools.r8.utils.DefaultDiagnosticsHandler;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.DexInspector;
import com.android.tools.r8.utils.DexInspector.FoundClassSubject;
@@ -64,6 +65,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.MainDexList;
+import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
@@ -102,6 +104,8 @@
public static TemporaryFolder generatedApplicationsFolder =
ToolHelper.getTemporaryFolderForTest();
+ private List<Diagnostic> errors = new ArrayList<>();
+
// Generate the test applications in a @BeforeClass method, as they are used by several tests.
@BeforeClass
public static void generateTestApplications() throws Throwable {
@@ -179,12 +183,15 @@
try {
verifyMainDexContains(TWO_LARGE_CLASSES, getTwoLargeClassesAppPath(), false);
fail("Expect to fail, for there are too many classes for the main-dex list.");
- } catch (DexOverflowException e) {
+ } catch (AbortException e) {
+ assertEquals(1, errors.size());
+ String message = errors.get(0).getDiagnosticMessage();
// Make sure {@link MonoDexDistributor} was _not_ used.
- assertFalse(e.getMessage().contains("single dex file"));
+ assertFalse(message.contains("single dex file"));
// Make sure what exceeds the limit is the number of methods.
- assertTrue(e.getMessage().contains("# methods: "
- + String.valueOf(TWO_LARGE_CLASSES.size() * MAX_METHOD_COUNT)));
+ assertTrue(
+ message.contains(
+ "# methods: " + String.valueOf(TWO_LARGE_CLASSES.size() * MAX_METHOD_COUNT)));
}
}
@@ -220,12 +227,16 @@
try {
verifyMainDexContains(MANY_CLASSES, getManyClassesMultiDexAppPath(), false);
fail("Expect to fail, for there are too many classes for the main-dex list.");
- } catch (DexOverflowException e) {
+ } catch (AbortException e) {
+ assertEquals(1, errors.size());
+ String message = errors.get(0).getDiagnosticMessage();
// Make sure {@link MonoDexDistributor} was _not_ used.
- assertFalse(e.getMessage().contains("single dex file"));
+ assertFalse(message.contains("single dex file"));
// Make sure what exceeds the limit is the number of methods.
- assertTrue(e.getMessage().contains("# methods: "
- + String.valueOf(MANY_CLASSES_COUNT * MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS)));
+ assertTrue(
+ message.contains(
+ "# methods: "
+ + String.valueOf(MANY_CLASSES_COUNT * MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS)));
}
}
@@ -444,15 +455,22 @@
// Notice that this one fails due to the min API.
try {
generateApplication(
- MANY_CLASSES, AndroidApiLevel.K.getLevel(), false,
- MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
+ MANY_CLASSES,
+ AndroidApiLevel.K.getLevel(),
+ false,
+ MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS,
+ new TestDiagnosticsHandler());
fail("Expect to fail, for there are many classes while multidex is not enabled.");
- } catch (DexOverflowException e) {
+ } catch (AbortException e) {
+ assertEquals(1, errors.size());
+ String message = errors.get(0).getDiagnosticMessage();
// Make sure {@link MonoDexDistributor} was used.
- assertTrue(e.getMessage().contains("single dex file"));
+ assertTrue(message.contains("single dex file"));
// Make sure what exceeds the limit is the number of methods.
- assertTrue(e.getMessage().contains("# methods: "
- + String.valueOf(MANY_CLASSES_COUNT * MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS)));
+ assertTrue(
+ message.contains(
+ "# methods: "
+ + String.valueOf(MANY_CLASSES_COUNT * MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS)));
}
}
@@ -498,7 +516,7 @@
private void doVerifyMainDexContains(
List<String> mainDex, Path app, boolean singleDexApp, boolean minimalMainDex,
MultiDexTestMode testMode)
- throws IOException, CompilationException, ExecutionException, ProguardRuleParserException,
+ throws IOException, ExecutionException, ProguardRuleParserException,
CompilationFailedException {
AndroidApp originalApp = AndroidApp.builder().addProgramFiles(app).build();
DexInspector originalInspector = new DexInspector(originalApp);
@@ -508,7 +526,7 @@
}
Path outDir = temp.newFolder().toPath();
R8Command.Builder builder =
- R8Command.builder()
+ R8Command.builder(new TestDiagnosticsHandler())
.addProgramFiles(app)
.setMode(
minimalMainDex && mainDex.size() > 0
@@ -587,15 +605,27 @@
}
public static AndroidApp generateApplication(List<String> classes, int minApi, int methodCount)
- throws IOException, ExecutionException, CompilationException {
+ throws IOException, ExecutionException {
return generateApplication(classes, minApi, false, methodCount);
}
private static AndroidApp generateApplication(
List<String> classes, int minApi, boolean intermediate, int methodCount)
- throws IOException, ExecutionException, CompilationException {
+ throws IOException, ExecutionException {
+ return generateApplication(
+ classes, minApi, intermediate, methodCount, new DefaultDiagnosticsHandler());
+ }
+
+ private static AndroidApp generateApplication(
+ List<String> classes,
+ int minApi,
+ boolean intermediate,
+ int methodCount,
+ DiagnosticsHandler diagnosticsHandler)
+ throws IOException, ExecutionException {
Timing timing = new Timing("MainDexListTests");
- InternalOptions options = new InternalOptions();
+ InternalOptions options =
+ new InternalOptions(new DexItemFactory(), new Reporter(diagnosticsHandler));
options.minApiLevel = minApi;
options.intermediate = intermediate;
DexItemFactory factory = options.itemFactory;
@@ -765,4 +795,12 @@
throw new Unreachable();
}
}
+
+ private class TestDiagnosticsHandler implements DiagnosticsHandler {
+
+ @Override
+ public void error(Diagnostic error) {
+ errors.add(error);
+ }
+ }
}
diff --git a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
index deb90e4..38af4de 100644
--- a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
@@ -9,7 +9,6 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.R8Command;
@@ -270,8 +269,7 @@
}
private R8Command.Builder getCommandForInstrumentation(
- Path out, Path flag, Path mainApp, Path instrApp)
- throws CompilationException, IOException {
+ Path out, Path flag, Path mainApp, Path instrApp) throws IOException {
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar(), mainApp)
.addProgramFiles(instrApp)
@@ -279,9 +277,8 @@
.addProguardConfigurationFiles(flag);
}
- private R8Command.Builder getCommandForApps(
- Path out, Path flag, Path... jars)
- throws CompilationException, IOException {
+ private R8Command.Builder getCommandForApps(Path out, Path flag, Path... jars)
+ throws IOException {
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.addProgramFiles(jars)
@@ -290,7 +287,7 @@
}
private static AndroidApp runR8(R8Command command)
- throws ProguardRuleParserException, ExecutionException, CompilationException, IOException {
+ throws ProguardRuleParserException, ExecutionException, IOException {
return ToolHelper.runR8(command, options -> {
// Disable inlining to make this test not depend on inlining decisions.
options.enableInlining = false;
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index b60ede7..d9808c0 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.ClassAndMemberPublicizer;
@@ -65,7 +64,7 @@
}
NamingLens runMinifier(List<Path> configPaths)
- throws IOException, ProguardRuleParserException, ExecutionException, CompilationException {
+ throws IOException, ProguardRuleParserException, ExecutionException {
ProguardConfiguration configuration =
ToolHelper.loadProguardConfiguration(dexItemFactory, configPaths);
InternalOptions options = new InternalOptions(configuration,
diff --git a/src/test/java/com/android/tools/r8/resource/DataResourceTest.java b/src/test/java/com/android/tools/r8/resource/DataResourceTest.java
index dbd4e23..2df0612 100644
--- a/src/test/java/com/android/tools/r8/resource/DataResourceTest.java
+++ b/src/test/java/com/android/tools/r8/resource/DataResourceTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.resource;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
@@ -25,8 +24,7 @@
public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest();
@Test
- public void dataResourceTest()
- throws IOException, CompilationFailedException, CompilationException {
+ public void dataResourceTest() throws IOException, CompilationFailedException {
String packageName = "dataresource";
String mainClassName = packageName + ".ResourceTest";
Path inputJar = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR,
diff --git a/src/test/java/com/android/tools/r8/rewrite/longcompare/LongCompare.java b/src/test/java/com/android/tools/r8/rewrite/longcompare/LongCompare.java
index e6c9ada..e0d9ecf 100644
--- a/src/test/java/com/android/tools/r8/rewrite/longcompare/LongCompare.java
+++ b/src/test/java/com/android/tools/r8/rewrite/longcompare/LongCompare.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.rewrite.longcompare;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
@@ -35,7 +34,7 @@
public TemporaryFolder tmpOutputDir = ToolHelper.getTemporaryFolderForTest();
void compileWithD8(Path intputPath, Path outputPath)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
D8.run(
D8Command.builder()
.addProgramFiles(intputPath)
diff --git a/src/test/java/com/android/tools/r8/rewrite/longcompare/RequireNonNullRewriteTest.java b/src/test/java/com/android/tools/r8/rewrite/longcompare/RequireNonNullRewriteTest.java
index fe74da9..a50a667 100644
--- a/src/test/java/com/android/tools/r8/rewrite/longcompare/RequireNonNullRewriteTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/longcompare/RequireNonNullRewriteTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.rewrite.longcompare;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
@@ -34,7 +33,7 @@
public TemporaryFolder tmpOutputDir = ToolHelper.getTemporaryFolderForTest();
void compileWithD8(Path intputPath, Path outputPath, CompilationMode mode)
- throws IOException, CompilationException, CompilationFailedException {
+ throws IOException, CompilationFailedException {
D8.run(
D8Command.builder()
.setMode(mode)
@@ -68,7 +67,7 @@
}
private void runTest(CompilationMode mode)
- throws IOException, CompilationException, ExecutionException, CompilationFailedException {
+ throws IOException, ExecutionException, CompilationFailedException {
final Path inputPath = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR + "/rewrite.jar");
Path outputPath = tmpOutputDir.newFolder().toPath();
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index f558ee7..c176ff3 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -149,6 +149,13 @@
parser = new ProguardConfigurationParser(new DexItemFactory(), reporter);
}
+ @Before
+ public void resetAllowPartiallyImplementedOptions() {
+ handler = new KeepingDiagnosticHandler();
+ reporter = new Reporter(handler);
+ parser = new ProguardConfigurationParser(new DexItemFactory(), reporter, false);
+ }
+
@Test
public void parse() throws Exception {
ProguardConfigurationParser parser;
@@ -859,7 +866,7 @@
@Test
public void parseKeepdirectories() throws Exception {
ProguardConfigurationParser parser =
- new ProguardConfigurationParser(new DexItemFactory(), reporter);
+ new ProguardConfigurationParser(new DexItemFactory(), reporter, false);
parser.parse(Paths.get(KEEPDIRECTORIES));
verifyParserEndsCleanly();
}
@@ -1216,6 +1223,7 @@
@Test
public void parse_adaptresourcexxx_keepdirectories_noArguments1() {
+ resetAllowPartiallyImplementedOptions();
ProguardConfiguration config = parseAndVerifyParserEndsCleanly(ImmutableList.of(
"-adaptresourcefilenames",
"-adaptresourcefilecontents",
@@ -1228,6 +1236,7 @@
@Test
public void parse_adaptresourcexxx_keepdirectories_noArguments2() {
+ resetAllowPartiallyImplementedOptions();
ProguardConfiguration config = parseAndVerifyParserEndsCleanly(ImmutableList.of(
"-keepdirectories",
"-adaptresourcefilenames",
@@ -1240,6 +1249,7 @@
@Test
public void parse_adaptresourcexxx_keepdirectories_noArguments3() {
+ resetAllowPartiallyImplementedOptions();
ProguardConfiguration config = parseAndVerifyParserEndsCleanly(ImmutableList.of(
"-adaptresourcefilecontents",
"-keepdirectories",
@@ -1261,6 +1271,7 @@
@Test
public void parse_adaptresourcexxx_keepdirectories_singleArgument() {
+ resetAllowPartiallyImplementedOptions();
ProguardConfiguration config = parseAndVerifyParserEndsCleanly(ImmutableList.of(
"-adaptresourcefilenames " + FILE_FILTER_SINGLE,
"-adaptresourcefilecontents " + FILE_FILTER_SINGLE,
@@ -1293,6 +1304,7 @@
@Test
public void parse_adaptresourcexxx_keepdirectories_multipleArgument() {
+ resetAllowPartiallyImplementedOptions();
ProguardConfiguration config = parseAndVerifyParserEndsCleanly(ImmutableList.of(
"-adaptresourcefilenames " + FILE_FILTER_MULTIPLE,
"-adaptresourcefilecontents " + FILE_FILTER_MULTIPLE,
@@ -1309,7 +1321,7 @@
"-adaptresourcefilenames", "-adaptresourcefilecontents", "-keepdirectories");
for (String option : options) {
try {
- reset();
+ resetAllowPartiallyImplementedOptions();
parser.parse(createConfigurationForTesting(ImmutableList.of(option + " ,")));
fail("Expect to fail due to the lack of path filter.");
} catch (AbortException e) {
@@ -1324,7 +1336,7 @@
"-adaptresourcefilenames", "-adaptresourcefilecontents", "-keepdirectories");
for (String option : options) {
try {
- reset();
+ resetAllowPartiallyImplementedOptions();
parser.parse(createConfigurationForTesting(ImmutableList.of(option + " xxx,,yyy")));
fail("Expect to fail due to the lack of path filter.");
} catch (AbortException e) {
@@ -1339,7 +1351,7 @@
"-adaptresourcefilenames", "-adaptresourcefilecontents", "-keepdirectories");
for (String option : options) {
try {
- reset();
+ resetAllowPartiallyImplementedOptions();
parser.parse(createConfigurationForTesting(ImmutableList.of(option + " xxx,")));
fail("Expect to fail due to the lack of path filter.");
} catch (AbortException e) {
@@ -1745,6 +1757,24 @@
verifyWithProguard(proguardConfig);
}
+ public void testNotSupported(String option) {
+ try {
+ reset();
+ parser.parse(createConfigurationForTesting(ImmutableList.of(option)));
+ fail("Expect to fail due to unsupported option.");
+ } catch (AbortException e) {
+ checkDiagnostic(handler.errors, null, 1, 1, "Option " + option + " currently not supported");
+ }
+ }
+
+ @Test
+ public void parse_pariallyImplemented_notSupported() {
+ testNotSupported("-keepdirectories");
+ testNotSupported("-adaptresourcefilenames");
+ testNotSupported("-adaptresourcefilecontents");
+ }
+
+
private ProguardConfiguration parseAndVerifyParserEndsCleanly(List<String> config) {
parser.parse(createConfigurationForTesting(config));
verifyParserEndsCleanly();
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/InliningClassVersionTest.java b/src/test/java/com/android/tools/r8/shaking/examples/InliningClassVersionTest.java
new file mode 100644
index 0000000..7fcb318
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/examples/InliningClassVersionTest.java
@@ -0,0 +1,156 @@
+// 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.shaking.examples;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import com.android.tools.r8.ArchiveClassFileProvider;
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.google.common.io.ByteStreams;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+
+public class InliningClassVersionTest extends TestBase {
+
+ private final int OLD_VERSION = Opcodes.V1_6;
+ private final String BASE_DESCRIPTOR = DescriptorUtils.javaTypeToDescriptor(Base.class.getName());
+
+ private static class Base {
+
+ public static void main(String[] args) {
+ System.out.println(Inlinee.foo());
+ }
+ }
+
+ private static class Inlinee {
+ public static String foo() {
+ return "Hello from Inlinee!";
+ }
+ }
+
+ private static class DowngradeVisitor extends ClassVisitor {
+
+ private final int version;
+
+ DowngradeVisitor(ClassVisitor cv, int version) {
+ super(Opcodes.ASM6, cv);
+ this.version = version;
+ }
+
+ @Override
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces) {
+ assert version > this.version
+ : "Going from " + version + " to " + this.version + " is not a downgrade";
+ super.visit(this.version, access, name, signature, superName, interfaces);
+ }
+ }
+
+ private static byte[] downgradeClass(byte[] classBytes, int version) {
+ ClassWriter writer = new ClassWriter(0);
+ new ClassReader(classBytes).accept(new DowngradeVisitor(writer, version), 0);
+ return writer.toByteArray();
+ }
+
+ @Test
+ public void test() throws Exception {
+ Path inputJar = writeInput();
+ assertEquals(OLD_VERSION, getBaseClassVersion(inputJar));
+ ProcessResult runInput = run(inputJar);
+ assertEquals(0, runInput.exitCode);
+ Path outputJar = runR8(inputJar);
+ ProcessResult runOutput = run(outputJar);
+ assertEquals(runInput.toString(), runOutput.toString());
+ assertNotEquals(
+ "Inliner did not upgrade classfile version", OLD_VERSION, getBaseClassVersion(outputJar));
+ }
+
+ private int getBaseClassVersion(Path jar) throws Exception {
+ return getClassVersion(jar, BASE_DESCRIPTOR);
+ }
+
+ private int getClassVersion(Path jar, String descriptor) throws Exception {
+
+ class ClassVersionReader extends ClassVisitor {
+ private int version = -1;
+
+ private ClassVersionReader() {
+ super(Opcodes.ASM6);
+ }
+
+ @Override
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces) {
+ super.visit(version, access, name, signature, superName, interfaces);
+ assert version != -1;
+ this.version = version;
+ }
+ }
+
+ byte[] bytes =
+ ByteStreams.toByteArray(
+ new ArchiveClassFileProvider(jar).getProgramResource(descriptor).getByteStream());
+ ClassVersionReader reader = new ClassVersionReader();
+ new ClassReader(bytes).accept(reader, 0);
+ assert reader.version != -1;
+ return reader.version;
+ }
+
+ private Path writeInput() throws Exception {
+ Path inputJar = temp.getRoot().toPath().resolve("input.jar");
+ ClassFileConsumer consumer = new ClassFileConsumer.ArchiveConsumer(inputJar);
+ consumer.accept(
+ downgradeClass(ToolHelper.getClassAsBytes(Base.class), OLD_VERSION), BASE_DESCRIPTOR, null);
+ consumer.accept(
+ ToolHelper.getClassAsBytes(Inlinee.class),
+ DescriptorUtils.javaTypeToDescriptor(Inlinee.class.getName()),
+ null);
+ consumer.finished(null);
+ return inputJar;
+ }
+
+ private ProcessResult run(Path jar) throws Exception {
+ return ToolHelper.runJava(jar, Base.class.getName());
+ }
+
+ private Path runR8(Path inputJar) throws Exception {
+ List<String> keepRule =
+ Collections.singletonList(
+ "-keep class " + Base.class.getName() + " { public static void main(...); }");
+ Path outputJar = temp.getRoot().toPath().resolve("output.jar");
+ ToolHelper.runR8(
+ R8Command.builder()
+ .addProgramFiles(inputJar)
+ .addLibraryFiles(Paths.get(ToolHelper.JAVA_8_RUNTIME))
+ .addProguardConfiguration(keepRule, Origin.unknown())
+ .setOutput(outputJar, OutputMode.ClassFile)
+ .build());
+ return outputJar;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java
index 91fc9d4..642045c 100644
--- a/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/forceproguardcompatibility/ForceProguardCompatibilityTest.java
@@ -110,7 +110,7 @@
// The test contains only a member class so the enclosing-method attribute will be null.
assertEquals(
- !keepAnnotations && forceProguardCompatibility,
+ forceProguardCompatibility,
!clazz.getDexClass().getInnerClasses().isEmpty());
assertEquals(forceProguardCompatibility || keepAnnotations,
clazz.annotation(annotationClass.getCanonicalName()).isPresent());
diff --git a/src/test/java/com/android/tools/r8/smali/ConstantFoldingTest.java b/src/test/java/com/android/tools/r8/smali/ConstantFoldingTest.java
index 1fd6afd..3381473 100644
--- a/src/test/java/com/android/tools/r8/smali/ConstantFoldingTest.java
+++ b/src/test/java/com/android/tools/r8/smali/ConstantFoldingTest.java
@@ -585,7 +585,7 @@
private void notIntMethodBuilder(SmaliBuilder builder, String name, Object parameters) {
Integer value = (Integer) parameters;
- builder.addStaticMethod("long", name, Collections.emptyList(),
+ builder.addStaticMethod("int", name, Collections.emptyList(),
1,
" const v0, " + value,
" not-int v0, v0",
@@ -950,6 +950,7 @@
addCmpFloatFoldTests(testBuilder);
addCmpDoubleFoldTests(testBuilder);
addCmpLongFold(testBuilder);
+ runDex2Oat(testBuilder.builder.build());
testBuilder.run();
}
diff --git a/src/test/java/com/android/tools/r8/smali/OutlineTest.java b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
index eb66c51..371c4d1 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -94,7 +94,7 @@
DEFAULT_METHOD_NAME,
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -158,7 +158,7 @@
DEFAULT_METHOD_NAME,
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test1\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -231,7 +231,7 @@
DEFAULT_METHOD_NAME,
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -354,7 +354,7 @@
DEFAULT_METHOD_NAME,
parameters,
3,
- " move v0, p0",
+ " move-object v0, p0",
" const-wide v1, 0x7fffffff00000000L",
" invoke-virtual { v0, v1, v2 }, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -430,7 +430,7 @@
DEFAULT_METHOD_NAME,
parameters,
3,
- " move v0, p0",
+ " move-object v0, p0",
" const-wide v1, 0x3ff0000000000000L",
" invoke-virtual { v0, v1, v2 }, Ljava/lang/StringBuilder;->append(D)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -793,7 +793,7 @@
"method1",
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -809,7 +809,7 @@
"method2",
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
@@ -878,7 +878,7 @@
DEFAULT_METHOD_NAME,
parameters,
2,
- " move v0, p0",
+ " move-object v0, p0",
" const-string v1, \"Test\"",
" invoke-virtual { v0, v1 }, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;",
" move-result-object v0",
diff --git a/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
index dae717e..5270cd4 100644
--- a/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
+++ b/src/test/java/com/android/tools/r8/smali/RemoveWriteOfUnusedFieldsTest.java
@@ -6,12 +6,16 @@
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DexInspector;
import com.android.tools.r8.utils.DexInspector.MethodSubject;
import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
import org.junit.Test;
public class RemoveWriteOfUnusedFieldsTest extends SmaliTestBase {
@@ -33,20 +37,28 @@
builder.addStaticField("stringField", "Ljava/lang/String;");
builder.addStaticField("testField", "LTest;");
+ boolean isDalvik = ToolHelper.getDexVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST);
+ String additionalConstZero = isDalvik ? "const v0, 0" : "";
+ String additionalConstZeroWide = isDalvik ? "const-wide v0, 0" : "";
+
builder.addStaticMethod("void", "test", ImmutableList.of(),
2,
"const v0, 0",
- "sput-byte v0, LTest;->booleanField:Z",
+ "sput-boolean v0, LTest;->booleanField:Z",
"sput-byte v0, LTest;->byteField:B",
"sput-short v0, LTest;->shortField:S",
"sput v0, LTest;->intField:I",
+ // Dalvik 4.x. does not require a new const 0 here.
"sput v0, LTest;->floatField:F",
+ additionalConstZero, // Required for Dalvik 4.x.
"sput-char v0, LTest;->charField:C",
+ "const v0, 0",
"sput-object v0, LTest;->objectField:Ljava/lang/Object;",
"sput-object v0, LTest;->stringField:Ljava/lang/String;",
"sput-object v0, LTest;->testField:LTest;",
"const-wide v0, 0",
"sput-wide v0, LTest;->longField:J",
+ additionalConstZeroWide, // Required for Dalvik 4.x.
"sput-wide v0, LTest;->doubleField:D",
"return-void");
@@ -55,9 +67,16 @@
" invoke-static { }, LTest;->test()V",
" return-void ");
+ AndroidApp input =
+ AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+ Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+ input.writeToZip(inputPath, OutputMode.DexIndexed);
+ ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
AndroidApp app =
compileWithR8(
- AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build(),
+ input,
keepMainProguardConfiguration("Test"),
options -> options.enableInlining = false);
@@ -84,32 +103,53 @@
builder.addInstanceField("stringField", "Ljava/lang/String;");
builder.addInstanceField("testField", "LTest;");
+ boolean isDalvik = ToolHelper.getDexVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST);
+ String additionalConstZero = isDalvik ? "const v0, 0" : "";
+ String additionalConstZeroWide = isDalvik ? "const-wide v0, 0" : "";
+
builder.addInstanceMethod("void", "test", ImmutableList.of(),
2,
"const v0, 0",
- "iput-byte v0, p0, LTest;->booleanField:Z",
+ "iput-boolean v0, p0, LTest;->booleanField:Z",
"iput-byte v0, p0, LTest;->byteField:B",
"iput-short v0, p0, LTest;->shortField:S",
"iput v0, p0, LTest;->intField:I",
+ // Dalvik 4.x. does not require a new const 0 here.
"iput v0, p0, LTest;->floatField:F",
+ additionalConstZero, // Required for Dalvik 4.x.
"iput-char v0, p0, LTest;->charField:C",
+ "const v0, 0",
"iput-object v0, p0, LTest;->objectField:Ljava/lang/Object;",
"iput-object v0, p0, LTest;->stringField:Ljava/lang/String;",
"iput-object v0, p0, LTest;->testField:LTest;",
"const-wide v0, 0",
"iput-wide v0, p0, LTest;->longField:J",
+ additionalConstZeroWide, // Required for Dalvik 4.x.
"iput-wide v0, p0, LTest;->doubleField:D",
"return-void");
+ builder.addInitializer(ImmutableList.of(), 0,
+ "invoke-direct {p0}, Ljava/lang/Object;-><init>()V",
+ "return-void"
+ );
+
builder.addMainMethod(
1,
" new-instance v0, LTest;",
+ " invoke-direct { v0 }, LTest;-><init>()V",
" invoke-virtual { v0 }, LTest;->test()V",
" return-void ");
+ AndroidApp input =
+ AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
+
+ Path inputPath = temp.getRoot().toPath().resolve("input.zip");
+ input.writeToZip(inputPath, OutputMode.DexIndexed);
+ ToolHelper.runArtNoVerificationErrors(inputPath.toString(), DEFAULT_CLASS_NAME);
+
AndroidApp app =
compileWithR8(
- AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build(),
+ input,
keepMainProguardConfiguration("Test"),
options -> options.enableInlining = false);
diff --git a/src/test/java/com/android/tools/r8/smali/SmaliBuilder.java b/src/test/java/com/android/tools/r8/smali/SmaliBuilder.java
index 2f6eb51..9a6e778 100644
--- a/src/test/java/com/android/tools/r8/smali/SmaliBuilder.java
+++ b/src/test/java/com/android/tools/r8/smali/SmaliBuilder.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.smali;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
@@ -334,13 +333,11 @@
return result;
}
- public byte[] compile()
- throws IOException, RecognitionException, DexOverflowException, ExecutionException {
+ public byte[] compile() throws IOException, RecognitionException, ExecutionException {
return Smali.compile(buildSource());
}
- public AndroidApp build()
- throws IOException, RecognitionException, DexOverflowException, ExecutionException {
+ public AndroidApp build() throws IOException, RecognitionException, ExecutionException {
return AndroidApp.builder().addDexProgramData(compile(), Origin.unknown()).build();
}
diff --git a/src/test/java/com/android/tools/r8/smali/SmaliDisassembleTest.java b/src/test/java/com/android/tools/r8/smali/SmaliDisassembleTest.java
index a380834..2297ebd 100644
--- a/src/test/java/com/android/tools/r8/smali/SmaliDisassembleTest.java
+++ b/src/test/java/com/android/tools/r8/smali/SmaliDisassembleTest.java
@@ -6,7 +6,6 @@
import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.SmaliWriter;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
@@ -27,7 +26,7 @@
AndroidApp application =
AndroidApp.builder().addDexProgramData(Smali.compile(smali), Origin.unknown()).build();
assertEquals(smali, SmaliWriter.smali(application, new InternalOptions()));
- } catch (IOException | RecognitionException | ExecutionException | DexOverflowException e) {
+ } catch (IOException | RecognitionException | ExecutionException e) {
throw new RuntimeException(e);
}
}
diff --git a/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java b/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
index 3c101ad..6c4b884 100644
--- a/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
+++ b/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
@@ -6,7 +6,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.OutputMode;
@@ -15,7 +14,6 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
@@ -46,7 +44,7 @@
protected AndroidApp buildApplication(SmaliBuilder builder) {
try {
return AndroidApp.builder().addDexProgramData(builder.compile(), Origin.unknown()).build();
- } catch (IOException | RecognitionException | DexOverflowException | ExecutionException e) {
+ } catch (IOException | RecognitionException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@@ -57,7 +55,7 @@
.addDexProgramData(builder.compile(), EmbeddedOrigin.INSTANCE)
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.build();
- } catch (IOException | RecognitionException | ExecutionException | DexOverflowException e) {
+ } catch (IOException | RecognitionException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@@ -79,7 +77,7 @@
Consumer<InternalOptions> optionsConsumer) {
try {
return ToolHelper.runR8(application, optionsConsumer);
- } catch (IOException | CompilationException e) {
+ } catch (IOException e) {
throw new RuntimeException(e);
}
}
@@ -105,7 +103,9 @@
.addDexProgramData(builder.compile(), EmbeddedOrigin.INSTANCE);
ToolHelper.runR8WithFullResult(command.build(), optionsConsumer);
return dexOutputDir.resolve("classes.dex");
- } catch (CompilationException | IOException | RecognitionException | ExecutionException
+ } catch (IOException
+ | RecognitionException
+ | ExecutionException
| CompilationFailedException e) {
throw new RuntimeException(e);
}
@@ -232,13 +232,11 @@
processdApplication, DEFAULT_CLASS_NAME, returnType, DEFAULT_METHOD_NAME, parameters);
}
- public String runArt(AndroidApp application) throws DexOverflowException {
+ public String runArt(AndroidApp application) {
return runArt(application, DEFAULT_MAIN_CLASS_NAME);
}
-
- public String runArt(AndroidApp application, String mainClass)
- throws DexOverflowException {
+ public String runArt(AndroidApp application, String mainClass) {
try {
Path out = temp.getRoot().toPath().resolve("run-art-input.zip");
// TODO(sgjesse): Pass in a unique temp directory for each run.
@@ -257,8 +255,7 @@
}
}
- public void runDex2Oat(AndroidApp application)
- throws DexOverflowException {
+ public void runDex2Oat(AndroidApp application) {
try {
Path dexOut = temp.getRoot().toPath().resolve("run-dex2oat-input.zip");
Path oatFile = temp.getRoot().toPath().resolve("oat-file");
diff --git a/src/test/java/com/android/tools/r8/utils/Smali.java b/src/test/java/com/android/tools/r8/utils/Smali.java
index 30aa7ef..68de752 100644
--- a/src/test/java/com/android/tools/r8/utils/Smali.java
+++ b/src/test/java/com/android/tools/r8/utils/Smali.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
-import com.android.tools.r8.errors.DexOverflowException;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.origin.Origin;
@@ -37,27 +36,27 @@
public class Smali {
public static byte[] compile(String smaliText)
- throws RecognitionException, IOException, DexOverflowException, ExecutionException {
+ throws RecognitionException, IOException, ExecutionException {
return compile(smaliText, 15);
}
public static byte[] compile(String... smaliText)
- throws RecognitionException, IOException, DexOverflowException, ExecutionException {
+ throws RecognitionException, IOException, ExecutionException {
return compile(Arrays.asList(smaliText), 15);
}
public static byte[] compile(String smaliText, int apiLevel)
- throws IOException, RecognitionException, DexOverflowException, ExecutionException {
+ throws IOException, RecognitionException, ExecutionException {
return compile(ImmutableList.of(smaliText), apiLevel);
}
public static byte[] compile(List<String> smaliTexts)
- throws RecognitionException, IOException, DexOverflowException, ExecutionException {
+ throws RecognitionException, IOException, ExecutionException {
return compile(smaliTexts, 15);
}
public static byte[] compile(List<String> smaliTexts, int apiLevel)
- throws RecognitionException, IOException, ExecutionException, DexOverflowException {
+ throws RecognitionException, IOException, ExecutionException {
DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(apiLevel));
for (String smaliText : smaliTexts) {