| // 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.Diagnostic; |
| import com.android.tools.r8.Keep; |
| import com.android.tools.r8.dex.VirtualFile; |
| import com.android.tools.r8.origin.Origin; |
| import com.android.tools.r8.position.Position; |
| |
| /** |
| * Diagnostic information about errors when classes cannot fit in a DEX file. |
| * |
| * <p>This can happen when compiling to a single DEX file but not all classes can fit in it; or when |
| * compiling for legacy multidex but there are too many classes that need to fit in the main DEX |
| * file, e.g., classes.dex. |
| */ |
| @Keep |
| public class DexFileOverflowDiagnostic implements Diagnostic { |
| private final boolean hasMainDexSpecification; |
| private final long numOfMethods; |
| private final long numOfFields; |
| |
| public DexFileOverflowDiagnostic( |
| boolean hasMainDexSpecification, long numOfMethods, long numOfFields) { |
| this.hasMainDexSpecification = hasMainDexSpecification; |
| this.numOfMethods = numOfMethods; |
| this.numOfFields = numOfFields; |
| } |
| |
| /** The number of fields that the application needs to include in the main DEX file. */ |
| public long getNumberOfFields() { |
| return numOfFields; |
| } |
| |
| /** The number of methods that the application needs to include in the main DEX file. */ |
| public long getNumberOfMethods() { |
| return numOfMethods; |
| } |
| |
| /** The maximum number of fields that can be included in a DEX file. */ |
| public long getMaximumNumberOfFields() { |
| return VirtualFile.MAX_ENTRIES; |
| } |
| |
| /** The maximum number of methods that can be included in a DEX file. */ |
| public long getMaximumNumberOfMethods() { |
| return VirtualFile.MAX_ENTRIES; |
| } |
| |
| /** True if the application has specified lists and/or rules for computing the main DEX file. */ |
| public boolean hasMainDexSpecification() { |
| return hasMainDexSpecification; |
| } |
| |
| /** The origin of a main DEX file overflow is not unique. (The whole app is to blame.) */ |
| @Override |
| public Origin getOrigin() { |
| return Origin.unknown(); |
| } |
| |
| /** The position of the main DEX error is not specified. */ |
| @Override |
| public Position getPosition() { |
| return null; |
| } |
| |
| @Override |
| public String getDiagnosticMessage() { |
| StringBuilder builder = new StringBuilder(); |
| // General message: Cannot fit. |
| builder |
| .append("Cannot fit requested classes in ") |
| .append(hasMainDexSpecification() ? "the main-" : "a single ") |
| .append("dex file") |
| .append(" ("); |
| // Show the numbers of methods and/or fields that exceed the limit. |
| if (getNumberOfMethods() > getMaximumNumberOfMethods()) { |
| builder |
| .append("# methods: ") |
| .append(getNumberOfMethods()) |
| .append(" > ") |
| .append(getMaximumNumberOfMethods()); |
| if (getNumberOfFields() > getMaximumNumberOfFields()) { |
| builder.append(" ; "); |
| } |
| } |
| if (getNumberOfFields() > getMaximumNumberOfFields()) { |
| builder |
| .append("# fields: ") |
| .append(getNumberOfFields()) |
| .append(" > ") |
| .append(getMaximumNumberOfFields()); |
| } |
| return builder.append(")").toString(); |
| } |
| } |