Merge commit '2b04eb482f57225284ee93ea2fe9400031514c20' into dev-release
diff --git a/foo.txt b/foo.txt
deleted file mode 100644
index d896812..0000000
--- a/foo.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Caused by: java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.AssertionError
- at com.android.tools.r8.dex.a.a(SourceFile:298)
- at com.android.tools.r8.dex.a.a(SourceFile:227)
- at com.android.tools.r8.dex.a.a(SourceFile:217)
- at com.android.tools.r8.dex.a.a(SourceFile:214)
- at com.android.tools.r8.ResourceShrinker.run(ResourceShrinker.java:5)
- at com.android.builder.dexing.R8ResourceShrinker.runResourceShrinkerAnalysis(r8ResourceShrinker.kt:33)
- at com.android.build.gradle.tasks.ResourceUsageAnalyzer.recordClassUsages(ResourceUsageAnalyzer.java:1493)
- at com.android.build.gradle.tasks.ResourceUsageAnalyzer.recordClassUsages(ResourceUsageAnalyzer.java:1412)
- at com.android.build.gradle.tasks.ResourceUsageAnalyzer.recordClassUsages(ResourceUsageAnalyzer.java:1406)
- at com.android.build.gradle.tasks.ResourceUsageAnalyzer.analyze(ResourceUsageAnalyzer.java:288)
- at com.android.build.gradle.internal.transforms.ShrinkResourcesTransform.splitAction(ShrinkResourcesTransform.java:317)
- at com.android.build.gradle.internal.transforms.ShrinkResourcesTransform.lambda$transform$0(ShrinkResourcesTransform.java:248)
- at com.android.build.gradle.internal.scope.BuildElements$ExecutorBasedScheduler$transform$$inlined$forEach$lambda$1.call(BuildElements.kt:121)
- at com.android.build.gradle.internal.scope.BuildElements$ExecutorBasedScheduler$transform$$inlined$forEach$lambda$1.call(BuildElements.kt:110)
-Caused by: java.util.concurrent.ExecutionException: java.lang.AssertionError
- at com.android.tools.r8.utils.Y0.a(SourceFile:50)
- at com.android.tools.r8.dex.a.a(SourceFile:278)
- ... 13 more
-Caused by: java.lang.AssertionError
- at com.android.tools.r8.graph.W$b.a(SourceFile:3)
- at com.android.tools.r8.graph.W.o0(SourceFile:6)
- at com.android.tools.r8.dex.n.a(SourceFile:707)
- at com.android.tools.r8.dex.n.a(SourceFile:989)
- at com.android.tools.r8.dex.a$a.a(SourceFile:90)
diff --git a/src/main/java/com/android/tools/r8/ApiLevelException.java b/src/main/java/com/android/tools/r8/ApiLevelException.java
index 0ad75c7..d58f0ec 100644
--- a/src/main/java/com/android/tools/r8/ApiLevelException.java
+++ b/src/main/java/com/android/tools/r8/ApiLevelException.java
@@ -16,7 +16,7 @@
assert unsupportedFeatures != null;
}
- private static String makeMessage(
+ public static String makeMessage(
AndroidApiLevel minApiLevel, String unsupportedFeatures, String sourceString) {
String message =
unsupportedFeatures
diff --git a/src/main/java/com/android/tools/r8/ResourceShrinker.java b/src/main/java/com/android/tools/r8/ResourceShrinker.java
index 86859f7..0affffd 100644
--- a/src/main/java/com/android/tools/r8/ResourceShrinker.java
+++ b/src/main/java/com/android/tools/r8/ResourceShrinker.java
@@ -102,9 +102,7 @@
@Override
InternalOptions getInternalOptions() {
- InternalOptions internalOptions = new InternalOptions();
- internalOptions.isRunningDeprecatedResourceShrinker = true;
- return internalOptions;
+ return new InternalOptions();
}
}
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 4dba5c6..26dca03 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -668,14 +668,10 @@
annotationIterator.getNextFor(method),
parameterAnnotationsIterator.getNextFor(method),
code);
- if (accessFlags.isAbstract()
- && ensureNonAbstract
- && !options.isRunningDeprecatedResourceShrinker) {
+ if (accessFlags.isAbstract() && ensureNonAbstract) {
accessFlags.unsetAbstract();
- encodedMethod =
- options.isGeneratingClassFiles()
- ? encodedMethod.toEmptyThrowingMethodCf()
- : encodedMethod.toEmptyThrowingMethodDex();
+ assert !options.isGeneratingClassFiles();
+ encodedMethod = encodedMethod.toEmptyThrowingMethodDex(false);
}
methods[i] = encodedMethod;
}
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index c4040a2..867f32d 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -5,10 +5,13 @@
import static com.android.tools.r8.utils.LebUtils.sizeAsUleb128;
-import com.android.tools.r8.ApiLevelException;
import com.android.tools.r8.ByteBufferProvider;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.errors.DefaultInterfaceMethodDiagnostic;
+import com.android.tools.r8.errors.InvokeCustomDiagnostic;
+import com.android.tools.r8.errors.PrivateInterfaceMethodDiagnostic;
+import com.android.tools.r8.errors.StaticInterfaceMethodDiagnostic;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationDirectory;
import com.android.tools.r8.graph.DexAnnotationElement;
@@ -48,6 +51,7 @@
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.position.MethodPosition;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.DexVersion;
import com.android.tools.r8.utils.InternalOptions;
@@ -267,10 +271,8 @@
}
if (method.accessFlags.isStatic()) {
if (!options.canUseDefaultAndStaticInterfaceMethods()) {
- throw new ApiLevelException(
- AndroidApiLevel.N,
- "Static interface methods",
- method.method.toSourceString());
+ throw options.reporter.fatalError(
+ new StaticInterfaceMethodDiagnostic(new MethodPosition(method.method)));
}
} else {
@@ -280,10 +282,8 @@
}
if (!method.accessFlags.isAbstract() && !method.accessFlags.isPrivate() &&
!options.canUseDefaultAndStaticInterfaceMethods()) {
- throw new ApiLevelException(
- AndroidApiLevel.N,
- "Default interface methods",
- method.method.toSourceString());
+ throw options.reporter.fatalError(
+ new DefaultInterfaceMethodDiagnostic(new MethodPosition(method.method)));
}
}
@@ -291,10 +291,8 @@
if (options.canUsePrivateInterfaceMethods()) {
return;
}
- throw new ApiLevelException(
- AndroidApiLevel.N,
- "Private interface methods",
- method.method.toSourceString());
+ throw options.reporter.fatalError(
+ new PrivateInterfaceMethodDiagnostic(new MethodPosition(method.method)));
}
if (!method.accessFlags.isPublic()) {
@@ -1383,10 +1381,7 @@
private void checkThatInvokeCustomIsAllowed() {
if (!options.canUseInvokeCustom()) {
- throw new ApiLevelException(
- AndroidApiLevel.O,
- "Invoke-customs",
- null /* sourceString */);
+ throw options.reporter.fatalError(new InvokeCustomDiagnostic());
}
}
}
diff --git a/src/main/java/com/android/tools/r8/errors/ApiLevelDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ApiLevelDiagnostic.java
new file mode 100644
index 0000000..fde6860
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/ApiLevelDiagnostic.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+
+// TODO(b/154778581): Flesh out this class/interface and keep it.
+public abstract class ApiLevelDiagnostic implements Diagnostic {
+
+ @Override
+ public Origin getOrigin() {
+ return Origin.unknown();
+ }
+
+ @Override
+ public Position getPosition() {
+ return Position.UNKNOWN;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java
new file mode 100644
index 0000000..f9d49f0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/ClassFileOverflowDiagnostic.java
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
+
+@Keep
+public abstract class ClassFileOverflowDiagnostic implements Diagnostic {
+
+ private final Origin origin;
+
+ public ClassFileOverflowDiagnostic(Origin origin) {
+ this.origin = origin;
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return origin;
+ }
+
+ @Override
+ public Position getPosition() {
+ return Position.UNKNOWN;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java
new file mode 100644
index 0000000..5359ee0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/CodeSizeOverflowDiagnostic.java
@@ -0,0 +1,49 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.MethodPosition;
+import com.android.tools.r8.position.Position;
+import com.android.tools.r8.references.MethodReference;
+
+/**
+ * Diagnostic information about a class file which could not be generated as the code size of a
+ * method overflowed the limit.
+ */
+@Keep
+public class CodeSizeOverflowDiagnostic extends ClassFileOverflowDiagnostic {
+
+ private final MethodReference method;
+ private final int codeSize;
+ private final MethodPosition position;
+
+ public CodeSizeOverflowDiagnostic(Origin origin, MethodReference method, int codeSize) {
+ super(origin);
+ this.method = method;
+ this.codeSize = codeSize;
+ this.position = new MethodPosition(method);
+ }
+
+ /** Code size of the method. */
+ public int getCodeSize() {
+ return codeSize;
+ }
+
+ @Override
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return "Method "
+ + method
+ + " too large for class file."
+ + " Code size was "
+ + getCodeSize()
+ + ".";
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java b/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java
new file mode 100644
index 0000000..3c39f22
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/ConstantPoolOverflowDiagnostic.java
@@ -0,0 +1,40 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.references.ClassReference;
+
+/**
+ * Diagnostic information about a class file which could not be generated as the size of the
+ * required constant pool overflowed the limit.
+ */
+@Keep
+public class ConstantPoolOverflowDiagnostic extends ClassFileOverflowDiagnostic {
+
+ private final int constantPoolSize;
+ private final ClassReference clazz;
+
+ public ConstantPoolOverflowDiagnostic(Origin origin, ClassReference clazz, int constantPoolSize) {
+ super(origin);
+ this.clazz = clazz;
+ this.constantPoolSize = constantPoolSize;
+ }
+
+ /** Constant pool size of the clazz. */
+ public int getConstantPoolSize() {
+ return constantPoolSize;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return "Class "
+ + clazz
+ + " too large for class file."
+ + " Constant pool size was "
+ + getConstantPoolSize()
+ + ".";
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/DefaultInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/DefaultInterfaceMethodDiagnostic.java
new file mode 100644
index 0000000..b0dfe4e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/DefaultInterfaceMethodDiagnostic.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.position.MethodPosition;
+import com.android.tools.r8.position.Position;
+import com.android.tools.r8.utils.AndroidApiLevel;
+
+public class DefaultInterfaceMethodDiagnostic extends ApiLevelDiagnostic {
+
+ private final MethodPosition position;
+
+ public DefaultInterfaceMethodDiagnostic(MethodPosition position) {
+ assert position != null;
+ this.position = position;
+ }
+
+ @Override
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return ApiLevelException.makeMessage(
+ AndroidApiLevel.N, "Default interface methods", position.toString());
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/InvokeCustomDiagnostic.java b/src/main/java/com/android/tools/r8/errors/InvokeCustomDiagnostic.java
new file mode 100644
index 0000000..ab8ff24
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/InvokeCustomDiagnostic.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.utils.AndroidApiLevel;
+
+public class InvokeCustomDiagnostic extends ApiLevelDiagnostic {
+
+ @Override
+ public String getDiagnosticMessage() {
+ return ApiLevelException.makeMessage(AndroidApiLevel.O, "Invoke-customs", null);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/PrivateInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/PrivateInterfaceMethodDiagnostic.java
new file mode 100644
index 0000000..568a7a0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/PrivateInterfaceMethodDiagnostic.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.position.MethodPosition;
+import com.android.tools.r8.position.Position;
+import com.android.tools.r8.utils.AndroidApiLevel;
+
+public class PrivateInterfaceMethodDiagnostic extends ApiLevelDiagnostic {
+
+ private final MethodPosition position;
+
+ public PrivateInterfaceMethodDiagnostic(MethodPosition position) {
+ assert position != null;
+ this.position = position;
+ }
+
+ @Override
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return ApiLevelException.makeMessage(
+ AndroidApiLevel.N, "Private interface methods", position.toString());
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/errors/StaticInterfaceMethodDiagnostic.java b/src/main/java/com/android/tools/r8/errors/StaticInterfaceMethodDiagnostic.java
new file mode 100644
index 0000000..cb00b94
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/errors/StaticInterfaceMethodDiagnostic.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.errors;
+
+import com.android.tools.r8.ApiLevelException;
+import com.android.tools.r8.position.MethodPosition;
+import com.android.tools.r8.position.Position;
+import com.android.tools.r8.utils.AndroidApiLevel;
+
+public class StaticInterfaceMethodDiagnostic extends ApiLevelDiagnostic {
+
+ private final MethodPosition position;
+
+ public StaticInterfaceMethodDiagnostic(MethodPosition position) {
+ assert position != null;
+ this.position = position;
+ }
+
+ @Override
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public String getDiagnosticMessage() {
+ return ApiLevelException.makeMessage(
+ AndroidApiLevel.N, "Static interface methods", position.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 6e99fbe..7071fda 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -773,24 +773,24 @@
}
public DexEncodedMethod toEmptyThrowingMethod(InternalOptions options) {
- return options.isGeneratingClassFiles()
- ? toEmptyThrowingMethodCf()
- : toEmptyThrowingMethodDex();
- }
-
- public DexEncodedMethod toEmptyThrowingMethodDex() {
- checkIfObsolete();
- assert !shouldNotHaveCode();
- Builder builder = builder(this);
- builder.setCode(buildEmptyThrowingDexCode());
- if (isNonPrivateVirtualMethod()) {
- builder.setIsLibraryMethodOverride(isLibraryMethodOverride());
- }
// Note that we are not marking this instance obsolete, since this util is only used by
// TreePruner while keeping non-live yet targeted, empty method. Such method can be retrieved
// again only during the 2nd round of tree sharking, and seeing an obsolete empty body v.s.
// seeing this empty throwing code do not matter.
// If things are changed, the cure point is obsolete instances inside RootSet.
+ return options.isGeneratingClassFiles()
+ ? toEmptyThrowingMethodCf()
+ : toEmptyThrowingMethodDex(true);
+ }
+
+ public DexEncodedMethod toEmptyThrowingMethodDex(boolean setIsLibraryOverride) {
+ checkIfObsolete();
+ assert !shouldNotHaveCode();
+ Builder builder = builder(this);
+ builder.setCode(buildEmptyThrowingDexCode());
+ if (setIsLibraryOverride && isNonPrivateVirtualMethod()) {
+ builder.setIsLibraryMethodOverride(isLibraryMethodOverride());
+ }
return builder.build();
}
@@ -805,7 +805,7 @@
Collections.emptyList());
}
- public DexEncodedMethod toEmptyThrowingMethodCf() {
+ private DexEncodedMethod toEmptyThrowingMethodCf() {
checkIfObsolete();
assert !shouldNotHaveCode();
Builder builder = builder(this);
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index 5236191..d3dd5fc 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -33,15 +33,16 @@
return "Method " + holder + "." + name + " " + proto.toString();
}
- public MethodReference asMethodReference(AppView<?> appView) {
+ public MethodReference asMethodReference() {
List<TypeReference> parameters = new ArrayList<>();
for (DexType value : proto.parameters.values) {
parameters.add(Reference.typeFromDescriptor(value.toDescriptorString()));
}
+ String returnTypeDescriptor = proto.returnType.toDescriptorString();
TypeReference returnType =
- proto.returnType == appView.dexItemFactory().voidType
+ returnTypeDescriptor.equals("V")
? null
- : Reference.typeFromDescriptor(proto.returnType.toDescriptorString());
+ : Reference.typeFromDescriptor(returnTypeDescriptor);
return Reference.method(
Reference.classFromDescriptor(holder.toDescriptorString()),
name.toString(),
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index e7a799d..06f8c42 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -375,7 +375,7 @@
throw new CompilationError(
"Absent Code attribute in method that is not native or abstract",
origin,
- new MethodPosition(method));
+ new MethodPosition(method.asMethodReference()));
}
code.setCode(
new CfCode(
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index f1a6b89..b79a063 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -64,7 +64,7 @@
+ " by constraint: "
+ constraint,
origin,
- new MethodPosition(method)));
+ new MethodPosition(method.asMethodReference())));
} else if (constrainedType != type) {
setType(constrainedType);
}
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 ecd971f..dba65f7 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
@@ -1099,7 +1099,7 @@
MethodProcessingId methodProcessingId) {
return ExceptionUtils.withOriginAndPositionAttachmentHandler(
method.getOrigin(),
- new MethodPosition(method.getReference()),
+ new MethodPosition(method.getReference().asMethodReference()),
() -> rewriteCodeInternal(method, feedback, methodProcessor, methodProcessingId));
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
index 8279864..4c073e1 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
@@ -152,7 +152,7 @@
+ ", its imprecise type is: "
+ stillImprecise.get(0).getType(),
code.origin,
- new MethodPosition(code.method().method)));
+ new MethodPosition(code.method().method.asMethodReference())));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index b32ab3b..4737d39 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -386,7 +386,7 @@
"Attempt to add forwarding method that conflicts with existing method.",
null,
clazz.getOrigin(),
- new MethodPosition(methodOnSelf.method));
+ new MethodPosition(methodOnSelf.method.asMethodReference()));
}
DexMethod method = target.method;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index 9d14d61..250737f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -453,8 +453,7 @@
libraryClass.type,
libraryClass.superType,
message,
- retarget,
- appView);
+ retarget);
}
private DexType dispatchInterfaceTypeFor(DexMethod method) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 79a8a40..901517a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -1124,7 +1124,7 @@
}
DexMethod method = appView.graphLense().getOriginalMethodSignature(referencedFrom);
Origin origin = getMethodOrigin(method);
- MethodPosition position = new MethodPosition(method);
+ MethodPosition position = new MethodPosition(method.asMethodReference());
options.warningMissingTypeForDesugar(origin, position, missing, method);
}
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 4f1e59a..18de3c5 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -11,6 +11,8 @@
import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.errors.CodeSizeOverflowDiagnostic;
+import com.android.tools.r8.errors.ConstantPoolOverflowDiagnostic;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
@@ -36,6 +38,7 @@
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableMap;
@@ -45,8 +48,10 @@
import java.util.Optional;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassTooLargeException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodTooLargeException;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
@@ -109,7 +114,30 @@
if (clazz.getSynthesizedFrom().isEmpty()
|| options.isDesugaredLibraryCompilation()
|| options.cfToCfDesugar) {
- writeClass(clazz, consumer, markerString);
+ try {
+ writeClass(clazz, consumer, markerString);
+ } catch (ClassTooLargeException e) {
+ throw appView
+ .options()
+ .reporter
+ .fatalError(
+ new ConstantPoolOverflowDiagnostic(
+ clazz.getOrigin(),
+ Reference.classFromBinaryName(e.getClassName()),
+ e.getConstantPoolCount()));
+ } catch (MethodTooLargeException e) {
+ throw appView
+ .options()
+ .reporter
+ .fatalError(
+ new CodeSizeOverflowDiagnostic(
+ clazz.getOrigin(),
+ Reference.methodFromDescriptor(
+ Reference.classFromBinaryName(e.getClassName()).getDescriptor(),
+ e.getMethodName(),
+ e.getDescriptor()),
+ e.getCodeSize()));
+ }
} else {
throw new Unimplemented("No support for synthetics in the Java bytecode backend.");
}
diff --git a/src/main/java/com/android/tools/r8/position/MethodPosition.java b/src/main/java/com/android/tools/r8/position/MethodPosition.java
index 3f22117..fa86ac8 100644
--- a/src/main/java/com/android/tools/r8/position/MethodPosition.java
+++ b/src/main/java/com/android/tools/r8/position/MethodPosition.java
@@ -5,8 +5,8 @@
import com.android.tools.r8.Keep;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
-import java.util.Arrays;
+import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.TypeReference;
import java.util.List;
import java.util.stream.Collectors;
@@ -14,38 +14,46 @@
@Keep
public class MethodPosition implements Position {
- // Do not expose the internal dex method structure.
- private DexMethod method;
+ private final MethodReference method;
+ @Deprecated
public MethodPosition(DexMethod method) {
+ this(method.asMethodReference());
+ }
+
+ public MethodPosition(MethodReference method) {
this.method = method;
}
+ /** The method */
+ public MethodReference getMethod() {
+ return method;
+ }
/** The unqualified name of the method. */
public String getName() {
- return method.name.toString();
+ return method.getMethodName();
}
/** The type descriptor of the method holder. */
public String getHolder() {
- return method.holder.toDescriptorString();
+ return method.getHolderClass().getDescriptor();
}
/** The type descriptor of the methods return type. */
public String getReturnType() {
- return method.proto.returnType.toDescriptorString();
+ return method.getReturnType().getDescriptor();
}
/** The type descriptors for the methods formal parameter types. */
public List<String> getParameterTypes() {
- return Arrays.stream(method.proto.parameters.values)
- .map(DexType::toDescriptorString)
+ return method.getFormalTypes().stream()
+ .map(TypeReference::getDescriptor)
.collect(Collectors.toList());
}
@Override
public String toString() {
- return method.toSourceString();
+ return method.toString();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/references/Reference.java b/src/main/java/com/android/tools/r8/references/Reference.java
index 1071cbd..f2c5442 100644
--- a/src/main/java/com/android/tools/r8/references/Reference.java
+++ b/src/main/java/com/android/tools/r8/references/Reference.java
@@ -181,6 +181,22 @@
return method(classFromClass(holderClass), "<init>", builder.build(), null);
}
+ /** Get a method reference from class name, method name and signature. */
+ public static MethodReference methodFromDescriptor(
+ String classDescriptor, String methodName, String methodDescriptor) {
+ ImmutableList.Builder<TypeReference> builder = ImmutableList.builder();
+ for (String parameterTypeDescriptor :
+ DescriptorUtils.getArgumentTypeDescriptors(methodDescriptor)) {
+ builder.add(typeFromDescriptor(parameterTypeDescriptor));
+ }
+ String returnTypeDescriptor = DescriptorUtils.getReturnTypeDescriptor(methodDescriptor);
+ return method(
+ classFromDescriptor(classDescriptor),
+ methodName,
+ builder.build(),
+ returnTypeDescriptor.equals("V") ? null : typeFromDescriptor(returnTypeDescriptor));
+ }
+
public static MethodReference classConstructor(ClassReference type) {
return method(type, "<clinit>", Collections.emptyList(), null);
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 997d4e9..43a53c7 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -75,7 +75,6 @@
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
import org.objectweb.asm.Opcodes;
public class InternalOptions {
@@ -482,9 +481,6 @@
// to disable the check that the build makes sense for multi-dexing.
public boolean enableMainDexListCheck = true;
- // TODO(b/156934674): Remove when resource shrinker is removed.
- public boolean isRunningDeprecatedResourceShrinker = false;
-
private final boolean enableTreeShaking;
private final boolean enableMinification;
@@ -875,8 +871,7 @@
DexType libraryType,
DexType invalidSuperType,
String message,
- Set<DexMethod> retarget,
- AppView<?> appView) {
+ Set<DexMethod> retarget) {
if (invalidLibraryClasses.add(invalidSuperType)) {
reporter.warning(
new InvalidLibrarySuperclassDiagnostic(
@@ -884,9 +879,7 @@
Reference.classFromDescriptor(libraryType.toDescriptorString()),
Reference.classFromDescriptor(invalidSuperType.toDescriptorString()),
message,
- retarget.stream()
- .map(method -> method.asMethodReference(appView))
- .collect(Collectors.toList())));
+ ListUtils.map(retarget, DexMethod::asMethodReference)));
}
}
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index be6ffbb..8ae9c0f 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -242,8 +242,12 @@
return self();
}
- public T setEnableDesugaring(boolean enableDesugaring) {
- builder.setEnableDesugaring(enableDesugaring);
+ public T disableDesugaring() {
+ return setDisableDesugaring(true);
+ }
+
+ public T setDisableDesugaring(boolean disableDesugaring) {
+ builder.setDisableDesugaring(disableDesugaring);
return self();
}
diff --git a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeStaticInvokeTest.java b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeStaticInvokeTest.java
index 7422eb8..2ee795b 100644
--- a/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeStaticInvokeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/DesugarMissingTypeStaticInvokeTest.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -80,7 +81,9 @@
assertEquals(Reference.classFromClass(TestClass.class), desugarWarning.getContextType());
assertThat(
desugarWarning.getPosition().getDescription(),
- containsString(TestClass.class.getTypeName() + ".main"));
+ containsString(
+ DescriptorUtils.javaTypeToDescriptor(TestClass.class.getTypeName())
+ + "main([Ljava/lang/String;)V"));
}
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/DesugarToClassFile.java b/src/test/java/com/android/tools/r8/desugar/DesugarToClassFile.java
index e8ac332..39f0ef1 100644
--- a/src/test/java/com/android/tools/r8/desugar/DesugarToClassFile.java
+++ b/src/test/java/com/android/tools/r8/desugar/DesugarToClassFile.java
@@ -65,7 +65,7 @@
testForD8()
.addProgramFiles(jar)
.setMinApi(parameters.getApiLevel())
- .setEnableDesugaring(false)
+ .disableDesugaring()
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutputLines("Hello, world!", "I::foo");
}
diff --git a/src/test/java/com/android/tools/r8/desugar/DesugarToClassFileInputCfVersion.java b/src/test/java/com/android/tools/r8/desugar/DesugarToClassFileInputCfVersion.java
index 0fd267d..49437ff 100644
--- a/src/test/java/com/android/tools/r8/desugar/DesugarToClassFileInputCfVersion.java
+++ b/src/test/java/com/android/tools/r8/desugar/DesugarToClassFileInputCfVersion.java
@@ -68,7 +68,7 @@
testForD8()
.addProgramFiles(jar)
.setMinApi(parameters.getApiLevel())
- .setEnableDesugaring(false)
+ .disableDesugaring()
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutputLines("Hello, world!");
}
diff --git a/src/test/java/com/android/tools/r8/diagnostics/ApiLevelDiagnosticTest.java b/src/test/java/com/android/tools/r8/diagnostics/ApiLevelDiagnosticTest.java
new file mode 100644
index 0000000..40fab17
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/diagnostics/ApiLevelDiagnosticTest.java
@@ -0,0 +1,124 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.diagnostics;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.startsWith;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+// TODO(b/154778581): Extend these tests with typed diagnostics and improved information.
+@RunWith(Parameterized.class)
+public class ApiLevelDiagnosticTest extends TestBase {
+
+ // Hard coded messages in AGP. See D8DexArchiveBuilder.
+
+ private static final String AGP_INVOKE_CUSTOM =
+ "Invoke-customs are only supported starting with Android O";
+
+ private static final String AGP_DEFAULT_INTERFACE_METHOD =
+ "Default interface methods are only supported starting with Android N (--min-api 24)";
+
+ private static final String AGP_STATIC_INTERFACE_METHOD =
+ "Static interface methods are only supported starting with Android N (--min-api 24)";
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ public ApiLevelDiagnosticTest(TestParameters parameters) {}
+
+ @Test(expected = CompilationFailedException.class)
+ public void testInvokeLambdaMetafactory() throws Exception {
+ testForD8()
+ .addProgramClassesAndInnerClasses(LambdaMetafactoryTest.class)
+ .setMinApi(AndroidApiLevel.B)
+ .disableDesugaring()
+ .compileWithExpectedDiagnostics(
+ diagnostics -> {
+ diagnostics
+ .assertOnlyErrors()
+ .assertErrorsMatch(diagnosticMessage(startsWith(AGP_INVOKE_CUSTOM)));
+ });
+ }
+
+ @Test(expected = CompilationFailedException.class)
+ public void testDefaultInterfaceMethods() throws Exception {
+ testForD8()
+ .addProgramClassesAndInnerClasses(DefaultInterfaceMethodsTest.class)
+ .setMinApi(AndroidApiLevel.B)
+ .disableDesugaring()
+ .compileWithExpectedDiagnostics(
+ diagnostics -> {
+ diagnostics
+ .assertOnlyErrors()
+ .assertErrorsMatch(diagnosticMessage(startsWith(AGP_DEFAULT_INTERFACE_METHOD)));
+ });
+ }
+
+ @Test(expected = CompilationFailedException.class)
+ public void testStaticInterfaceMethods() throws Exception {
+ testForD8()
+ .addProgramClassesAndInnerClasses(StaticInterfaceMethodsTest.class)
+ .setMinApi(AndroidApiLevel.B)
+ .disableDesugaring()
+ .compileWithExpectedDiagnostics(
+ diagnostics -> {
+ diagnostics
+ .assertOnlyErrors()
+ .assertErrorsMatch(diagnosticMessage(startsWith(AGP_STATIC_INTERFACE_METHOD)));
+ });
+ }
+
+ static class LambdaMetafactoryTest {
+
+ public interface StringSupplier {
+ String get();
+ }
+
+ public static void print(StringSupplier supplier) {
+ System.out.println(supplier.get());
+ }
+
+ public static void main(String[] args) {
+ print(() -> "Hello, world");
+ }
+ }
+
+ static class DefaultInterfaceMethodsTest {
+
+ interface WithDefaults {
+ default void foo() {
+ System.out.println("WithDefaults::foo");
+ }
+ }
+
+ static class MyClass implements WithDefaults {}
+
+ public static void main(String[] args) {
+ new MyClass().foo();
+ }
+ }
+
+ static class StaticInterfaceMethodsTest {
+
+ interface WithStatics {
+ static void foo() {
+ System.out.println("WithStatics::foo");
+ }
+ }
+
+ public static void main(String[] args) {
+ WithStatics.foo();
+ }
+ }
+}