Reland "Reintroduce assertion in enum unboxing"

This reverts commit a1db81c6c480b6ab9e40bf35d7e4e3254ad2e226.

Change-Id: I3790b0e7c25b3b690badfe1266fd96affe61e1df
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 d775aa1..8f9af7a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -256,6 +256,10 @@
     assert parameterAnnotationsList != null;
   }
 
+  public DexTypeList parameters() {
+    return method.proto.parameters;
+  }
+
   public DexType returnType() {
     return method.proto.returnType;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeList.java b/src/main/java/com/android/tools/r8/graph/DexTypeList.java
index 58b6afd..2272c98 100644
--- a/src/main/java/com/android/tools/r8/graph/DexTypeList.java
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeList.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.dex.MixedSectionCollection;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.utils.ArrayUtils;
 import java.util.Arrays;
 
 public class DexTypeList extends DexItem {
@@ -28,6 +29,10 @@
     this.values = values;
   }
 
+  public boolean contains(DexType type) {
+    return ArrayUtils.contains(values, type);
+  }
+
   @Override
   public int hashCode() {
     return Arrays.hashCode(values);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingCandidateAnalysis.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingCandidateAnalysis.java
index 5e4eaed..692b2ee 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingCandidateAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingCandidateAnalysis.java
@@ -132,6 +132,7 @@
   private void removeEnumsInAnnotations() {
     for (DexProgramClass clazz : appView.appInfo().classes()) {
       if (clazz.isAnnotation()) {
+        assert clazz.interfaces.contains(appView.dexItemFactory().annotationType);
         removeEnumsInAnnotation(clazz);
       }
     }
@@ -141,16 +142,11 @@
     // Browse annotation values types in search for enum.
     // Each annotation value is represented by a virtual method.
     for (DexEncodedMethod method : clazz.virtualMethods()) {
-      DexProto proto = method.method.proto;
-      // There can be references to  enum unboxing candidates even if the parameter list is non
-      // empty. That is possible by injecting methods in the bytecode, but such methods are no
-      // different from other methods in the program, and can be rewritten by enum unboxing.
-      if (proto.parameters.isEmpty()) {
-        DexType valueType = proto.returnType.toBaseType(appView.appInfo().dexItemFactory());
-        if (enumToUnboxCandidates.containsKey(valueType)) {
-          enumUnboxer.reportFailure(valueType, Reason.ANNOTATION);
-          enumToUnboxCandidates.remove(valueType);
-        }
+      assert method.parameters().isEmpty();
+      DexType valueType = method.returnType().toBaseType(appView.dexItemFactory());
+      if (enumToUnboxCandidates.containsKey(valueType)) {
+        enumUnboxer.reportFailure(valueType, Reason.ANNOTATION);
+        enumToUnboxCandidates.remove(valueType);
       }
     }
   }
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/AnnotationEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/AnnotationEnumUnboxingTest.java
index f9a5d80..1cf4e93 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/AnnotationEnumUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/AnnotationEnumUnboxingTest.java
@@ -8,14 +8,9 @@
 import com.android.tools.r8.NeverMerge;
 import com.android.tools.r8.NeverPropagateValue;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.graph.ClassAccessFlags;
-import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import org.junit.Assume;
 import org.junit.Test;
@@ -48,8 +43,7 @@
         "The methods values and valueOf are required for reflection.",
         enumKeepRules.toString().equals("none"));
     testForR8(parameters.getBackend())
-        .addProgramFiles(getProgramClasses())
-        .addProgramClassFileData(getProgramClassesData())
+        .addInnerClasses(AnnotationEnumUnboxingTest.class)
         .noMinification()
         .addKeepMainRule(Main.class)
         .addKeepRules(enumKeepRules.getKeepRule())
@@ -78,24 +72,6 @@
         .assertSuccessWithOutputLines("print", "1", "1", "1", "1", "1", "0", "0", "0", "0");
   }
 
-  private Collection<byte[]> getProgramClassesData() throws IOException {
-    return Collections.singletonList(transformAnnotationToBe());
-  }
-
-  private Collection<Path> getProgramClasses() throws IOException {
-    Collection<Path> inputs =
-        ToolHelper.getClassFilesForInnerClasses(
-            Collections.singletonList(AnnotationEnumUnboxingTest.class));
-    inputs.removeIf(p -> p.toString().contains("ClassAnnotationToBe.class"));
-    return inputs;
-  }
-
-  private byte[] transformAnnotationToBe() throws IOException {
-    return transformer(ClassAnnotationToBe.class)
-        .setAccessFlags(ClassAccessFlags::setAnnotation)
-        .transform();
-  }
-
   @Retention(RetentionPolicy.RUNTIME)
   @interface ClassAnnotationDefault {
     MyEnumDefault myEnumDefault() default MyEnumDefault.A;
@@ -107,16 +83,9 @@
     MyEnumArray[] myEnumArray();
   }
 
-  // This will be transformed into an annotation.
   @NeverMerge
-  @NeverClassInline
-  interface ClassAnnotationToBe {
-    @NeverInline
-    @NeverPropagateValue
-    default MyEnumRetMethod2 enumMethod(MyEnumParamMethod2 param) {
-      return param == MyEnumParamMethod2.A ? MyEnumRetMethod2.A : MyEnumRetMethod2.B;
-    }
-  }
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface ClassAnnotation {}
 
   enum MyEnumParamMethod2 {
     A,
@@ -161,7 +130,19 @@
     }
   }
 
-  static class ClassAnnotationToBeSub implements ClassAnnotationToBe {}
+  static class ClassAnnotationSub implements ClassAnnotation {
+
+    @NeverInline
+    @NeverPropagateValue
+    MyEnumRetMethod2 enumMethod(MyEnumParamMethod2 param) {
+      return param == MyEnumParamMethod2.A ? MyEnumRetMethod2.A : MyEnumRetMethod2.B;
+    }
+
+    @Override
+    public Class<? extends Annotation> annotationType() {
+      return null;
+    }
+  }
 
   static class Main {
     public static void main(String[] args) {
@@ -176,8 +157,7 @@
       System.out.println(annotation.myEnumArray()[0].ordinal());
       System.out.println(annotation.myEnumArrayDefault()[0].ordinal());
       System.out.println(annotation.myEnumDefault().ordinal());
-      // We need two classes toa void merging.
-      System.out.println(new ClassAnnotationToBeSub().enumMethod(MyEnumParamMethod2.A).ordinal());
+      System.out.println(new ClassAnnotationSub().enumMethod(MyEnumParamMethod2.A).ordinal());
     }
   }
 }