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();
+    }
+  }
+}