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