Merge "Remove DexOverflowException"
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/R8.java b/src/main/java/com/android/tools/r8/R8.java
index d14f96e..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;
@@ -179,7 +178,7 @@
String proguardSeedsData,
InternalOptions options,
ProguardMapSupplier proguardMapSupplier)
- throws ExecutionException, DexOverflowException {
+ throws ExecutionException {
try {
Marker marker = getMarker(options);
if (options.isGeneratingClassFiles()) {
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/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 818c980..0000000
--- a/src/main/java/com/android/tools/r8/errors/DexOverflowException.java
+++ /dev/null
@@ -1,14 +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;
-
-/**
- * Signals when there were too many items to fit in a given dex file.
- */
-public class DexOverflowException extends CompilationError {
-
- public DexOverflowException(String message) {
- super(message);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/errors/MainDexOverflow.java b/src/main/java/com/android/tools/r8/errors/MainDexOverflow.java
new file mode 100644
index 0000000..e33cf59
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/MainDexOverflow.java
@@ -0,0 +1,85 @@
+// 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;
+
+/**
+ * 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 MainDexOverflow {
+ private final boolean hasMainDexList;
+ private final long numOfMethods;
+ private final long numOfFields;
+ private final long maxNumOfEntries;
+
+ public MainDexOverflow(
+ boolean hasMainDexList, long numOfMethods, long numOfFields, long maxNumOfEntries) {
+ super();
+ this.hasMainDexList = hasMainDexList;
+ this.numOfMethods = numOfMethods;
+ this.numOfFields = numOfFields;
+ this.maxNumOfEntries = maxNumOfEntries;
+ }
+
+ private StringBuilder getGeneralMessage() {
+ StringBuilder messageBuilder = new StringBuilder();
+ // General message: Cannot fit.
+ messageBuilder.append("Cannot fit requested classes in ");
+ messageBuilder.append(hasMainDexList ? "the main-" : "a single ");
+ messageBuilder.append("dex file");
+
+ return messageBuilder;
+ }
+
+ private String getNumberRelatedMessage() {
+ StringBuilder messageBuilder = new StringBuilder();
+ // Show the numbers of methods and/or fields that exceed the limit.
+ if (numOfMethods > maxNumOfEntries) {
+ messageBuilder.append("# methods: ");
+ messageBuilder.append(numOfMethods);
+ messageBuilder.append(" > ").append(maxNumOfEntries);
+ if (numOfFields > maxNumOfEntries) {
+ messageBuilder.append(" ; ");
+ }
+ }
+ if (numOfFields > maxNumOfEntries) {
+ messageBuilder.append("# fields: ");
+ messageBuilder.append(numOfFields);
+ messageBuilder.append(" > ").append(maxNumOfEntries);
+ }
+
+ return messageBuilder.toString();
+ }
+
+ public String getMessage() {
+ // Default message
+ return getGeneralMessage()
+ .append(" (")
+ .append(getNumberRelatedMessage())
+ .append(")")
+ .toString();
+ }
+
+ public String getMessageForD8() {
+ StringBuilder messageBuilder = getGeneralMessage();
+ if (!hasMainDexList) {
+ messageBuilder.append(". ");
+ messageBuilder.append("Try supplying a main-dex list");
+ }
+ messageBuilder.append(".").append(System.getProperty("line.separator"));
+ messageBuilder.append(getNumberRelatedMessage());
+ return messageBuilder.toString();
+ }
+
+ public String getMessageForR8() {
+ StringBuilder messageBuilder = getGeneralMessage();
+ if (!hasMainDexList) {
+ messageBuilder.append(". ");
+ messageBuilder.append("Try supplying a main-dex list or main dex rules");
+ }
+ messageBuilder.append(".").append(System.getProperty("line.separator"));
+ messageBuilder.append(getNumberRelatedMessage());
+ return messageBuilder.toString();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java b/src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java
deleted file mode 100644
index 7c3d87d..0000000
--- a/src/main/java/com/android/tools/r8/errors/MainDexOverflowException.java
+++ /dev/null
@@ -1,43 +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;
-
-/**
- * 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.
- */
-public class MainDexOverflowException extends DexOverflowException {
-
- public MainDexOverflowException(
- boolean hasMainDexList, long numOfMethods, long numOfFields, long maxNumOfEntries) {
- super(getMessage(hasMainDexList, numOfMethods, numOfFields, maxNumOfEntries));
- }
-
- private static String getMessage(
- boolean hasMainDexList, long numOfMethods, long maxNumOfEntries, long numOfFields) {
- StringBuilder messageBuilder = new StringBuilder();
- // General message: Cannot fit.
- messageBuilder.append("Cannot fit requested classes in ");
- messageBuilder.append(hasMainDexList ? "the main-" : "a single ");
- messageBuilder.append("dex file");
- messageBuilder.append(" (");
- // Show the numbers of methods and/or fields that exceed the limit.
- if (numOfMethods > maxNumOfEntries) {
- messageBuilder.append("# methods: ");
- messageBuilder.append(numOfMethods);
- messageBuilder.append(" > ").append(maxNumOfEntries);
- if (numOfFields > maxNumOfEntries) {
- messageBuilder.append(" ; ");
- }
- }
- if (numOfFields > maxNumOfEntries) {
- messageBuilder.append("# fields: ");
- messageBuilder.append(numOfFields);
- messageBuilder.append(" > ").append(maxNumOfEntries);
- }
- messageBuilder.append(")");
- return messageBuilder.toString();
- }
-
-}
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/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 6e8ea93..0e99a7c 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;
@@ -1353,7 +1352,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/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/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/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/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 99ffc11..4214a67 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -14,6 +14,8 @@
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;
@@ -22,7 +24,6 @@
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.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
@@ -52,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;
@@ -62,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;
@@ -100,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 {
@@ -177,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)));
}
}
@@ -218,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)));
}
}
@@ -442,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)));
}
}
@@ -506,7 +526,7 @@
}
Path outDir = temp.newFolder().toPath();
R8Command.Builder builder =
- R8Command.builder()
+ R8Command.builder(new TestDiagnosticsHandler())
.addProgramFiles(app)
.setMode(
minimalMainDex && mainDex.size() > 0
@@ -592,8 +612,20 @@
private static AndroidApp generateApplication(
List<String> classes, int minApi, boolean intermediate, int methodCount)
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;
@@ -763,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/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 1d3fd93..6c4b884 100644
--- a/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
+++ b/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
@@ -14,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;
@@ -45,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);
}
}
@@ -56,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);
}
}
@@ -233,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.
@@ -258,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) {