Revert "Reland "Enum unboxing: Enums with static methods""
This reverts commit ff5713001835765cdb6ea8aaf799b9bc665c52bf.
Reason for revert: Bot failures
Change-Id: I24327f95ec1789ae1debb9cf6de8e5282e684d41
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 ee33b11..9822c48 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
@@ -480,7 +480,7 @@
private void synthesizeEnumUnboxingUtilityClass(
Builder<?> builder, ExecutorService executorService) throws ExecutionException {
if (enumUnboxer != null) {
- enumUnboxer.synthesizeUtilityMethods(builder, this, executorService);
+ enumUnboxer.synthesizeUtilityClass(builder, this, executorService);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index b71b10c..b601000 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -7,7 +7,7 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication.Builder;
+import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClass.FieldSetter;
import com.android.tools.r8.graph.DexEncodedField;
@@ -17,7 +17,6 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.DexValue.DexValueNull;
@@ -59,7 +58,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.IdentityHashMap;
@@ -155,10 +153,20 @@
} else if (instruction.isCheckCast()) {
analyzeCheckCast(instruction.asCheckCast(), eligibleEnums);
} else if (instruction.isInvokeStatic()) {
+ // TODO(b/150370354): Since we temporary allow enum unboxing on enums with values and
+ // valueOf static methods only if such methods are unused, such methods cannot be
+ // called. the long term solution is to simply move called methods to a companion class,
+ // as any static helper method, and remove these checks.
DexMethod invokedMethod = instruction.asInvokeStatic().getInvokedMethod();
DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(invokedMethod.holder);
if (enumClass != null) {
- eligibleEnums.add(enumClass.type);
+ if (factory.enumMethods.isValueOfMethod(invokedMethod, enumClass)) {
+ markEnumAsUnboxable(Reason.VALUE_OF_INVOKE, enumClass);
+ } else if (factory.enumMethods.isValuesMethod(invokedMethod, enumClass)) {
+ markEnumAsUnboxable(Reason.VALUES_INVOKE, enumClass);
+ } else {
+ assert false; // We do not allow any other static call in unboxing candidates.
+ }
}
}
}
@@ -297,8 +305,8 @@
return;
}
ImmutableSet<DexType> enumsToUnbox = ImmutableSet.copyOf(this.enumsUnboxingCandidates.keySet());
- enumUnboxerRewriter = new EnumUnboxingRewriter(appView, enumsToUnbox);
NestedGraphLense enumUnboxingLens = new TreeFixer(enumsToUnbox).fixupTypeReferences();
+ enumUnboxerRewriter = new EnumUnboxingRewriter(appView, enumsToUnbox);
appView.setUnboxedEnums(enumUnboxerRewriter.getEnumsToUnbox());
if (enumUnboxingLens != null) {
appView.setGraphLense(enumUnboxingLens);
@@ -592,11 +600,12 @@
return Sets.newIdentityHashSet();
}
- public void synthesizeUtilityMethods(
- Builder<?> builder, IRConverter converter, ExecutorService executorService)
+ public void synthesizeUtilityClass(
+ DexApplication.Builder<?> appBuilder, IRConverter converter, ExecutorService executorService)
throws ExecutionException {
if (enumUnboxerRewriter != null) {
- enumUnboxerRewriter.synthesizeEnumUnboxingUtilityMethods(builder, converter, executorService);
+ enumUnboxerRewriter.synthesizeEnumUnboxingUtilityClass(
+ appBuilder, converter, executorService);
}
}
@@ -654,7 +663,6 @@
private class TreeFixer {
- private final List<DexEncodedMethod> unboxedEnumsMethods = new ArrayList<>();
private final EnumUnboxingLens.Builder lensBuilder = EnumUnboxingLens.builder();
private final Set<DexType> enumsToUnbox;
@@ -663,26 +671,27 @@
}
private NestedGraphLense fixupTypeReferences() {
- assert enumUnboxerRewriter != null;
// Fix all methods and fields using enums to unbox.
for (DexProgramClass clazz : appView.appInfo().classes()) {
if (enumsToUnbox.contains(clazz.type)) {
assert clazz.instanceFields().size() == 0;
- // Clear the initializers and move the static methods to the utility class.
- clazz
- .methods()
- .forEach(
- m -> {
- if (m.isInitializer()) {
- clearEnumToUnboxMethod(m);
- } else {
- assert m.isStatic();
- unboxedEnumsMethods.add(
- fixupEncodedMethodToUtility(m, factory.enumUnboxingUtilityType));
- }
- });
+ // TODO(b/150370354): Remove when static methods are supported.
+ if (appView.options().testing.enumUnboxingRewriteJavaCGeneratedMethod) {
+ // Clear only the initializers.
+ clazz
+ .methods()
+ .forEach(
+ m -> {
+ if (m.isInitializer()) {
+ clearEnumToUnboxMethod(m);
+ }
+ });
+ clazz.getMethodCollection().replaceMethods(this::fixupMethod);
+ } else {
+ clazz.methods().forEach(this::clearEnumToUnboxMethod);
+ }
} else {
- clazz.getMethodCollection().replaceMethods(this::fixupEncodedMethod);
+ clazz.getMethodCollection().replaceMethods(this::fixupMethod);
fixupFields(clazz.staticFields(), clazz::setStaticField);
fixupFields(clazz.instanceFields(), clazz::setInstanceField);
}
@@ -690,10 +699,6 @@
for (DexType toUnbox : enumsToUnbox) {
lensBuilder.map(toUnbox, factory.intType);
}
- DexProgramClass utilityClass =
- appView.definitionForProgramType(factory.enumUnboxingUtilityType);
- assert utilityClass != null : "Should have been synthesized in the enqueuer";
- utilityClass.addDirectMethods(unboxedEnumsMethods);
return lensBuilder.build(factory, appView.graphLense());
}
@@ -710,19 +715,7 @@
appView);
}
- private DexEncodedMethod fixupEncodedMethodToUtility(
- DexEncodedMethod encodedMethod, DexType newHolder) {
- DexMethod method = encodedMethod.method;
- DexString newMethodName =
- factory.createString(
- enumUnboxerRewriter.compatibleName(method.holder) + "$$" + method.name.toString());
- DexMethod newMethod = fixupMethod(method, newHolder, newMethodName);
- lensBuilder.move(method, newMethod, encodedMethod.isStatic());
- encodedMethod.accessFlags.promoteToPublic();
- return encodedMethod.toTypeSubstitutedMethod(newMethod);
- }
-
- private DexEncodedMethod fixupEncodedMethod(DexEncodedMethod encodedMethod) {
+ private DexEncodedMethod fixupMethod(DexEncodedMethod encodedMethod) {
DexMethod newMethod = fixupMethod(encodedMethod.method);
if (newMethod != encodedMethod.method) {
lensBuilder.move(encodedMethod.method, newMethod, encodedMethod.isStatic());
@@ -754,11 +747,7 @@
}
private DexMethod fixupMethod(DexMethod method) {
- return fixupMethod(method, method.holder, method.name);
- }
-
- private DexMethod fixupMethod(DexMethod method, DexType newHolder, DexString newMethodName) {
- return factory.createMethod(newHolder, fixupProto(method.proto), newMethodName);
+ return factory.createMethod(method.holder, fixupProto(method.proto), method.name);
}
private DexProto fixupProto(DexProto proto) {
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 b5530c2..7ae1ffa 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
@@ -81,11 +81,23 @@
enumUnboxer.reportFailure(clazz.type, Reason.MISSING_INFO_MAP);
return false;
}
-
- // TODO(b/155036467): Fail lazily when an unsupported method is not only present but also used.
- // Only Enums with default initializers and static methods can be unboxed at the moment.
+ // Methods values, valueOf, init, clinit are present on each enum.
+ // Methods init and clinit are required if the enum is used.
+ // Methods valueOf and values are normally kept by the commonly used/recommended enum keep rule
+ // -keepclassmembers,allowoptimization enum * {
+ // public static **[] values();
+ // public static ** valueOf(java.lang.String);
+ // }
+ // In general there will be 4 methods, unless the enum keep rule is not present.
+ if (clazz.getMethodCollection().numberOfDirectMethods() > 4) {
+ enumUnboxer.reportFailure(clazz.type, Reason.UNEXPECTED_DIRECT_METHOD);
+ return false;
+ }
for (DexEncodedMethod directMethod : clazz.directMethods()) {
- if (!(directMethod.isStatic() || isStandardEnumInitializer(directMethod))) {
+ if (!(factory.enumMethods.isValuesMethod(directMethod.method, clazz)
+ || factory.enumMethods.isValueOfMethod(directMethod.method, clazz)
+ || isStandardEnumInitializer(directMethod)
+ || directMethod.isClassInitializer())) {
enumUnboxer.reportFailure(clazz.type, Reason.UNEXPECTED_DIRECT_METHOD);
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
index 0db5e28..383b03b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexApplication.Builder;
+import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -45,6 +45,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -66,6 +67,7 @@
private final Map<DexMethod, DexEncodedMethod> extraUtilityMethods = new ConcurrentHashMap<>();
private final Map<DexField, DexEncodedField> extraUtilityFields = new ConcurrentHashMap<>();
+ private final DexType utilityClassType;
private final DexMethod ordinalUtilityMethod;
private final DexMethod valuesUtilityMethod;
@@ -81,14 +83,15 @@
}
this.enumsToUnbox = builder.build();
+ this.utilityClassType = factory.enumUnboxingUtilityType;
this.ordinalUtilityMethod =
factory.createMethod(
- factory.enumUnboxingUtilityType,
+ utilityClassType,
factory.createProto(factory.intType, factory.intType),
ENUM_UNBOXING_UTILITY_ORDINAL);
this.valuesUtilityMethod =
factory.createMethod(
- factory.enumUnboxingUtilityType,
+ utilityClassType,
factory.createProto(factory.intArrayType, factory.intType),
ENUM_UNBOXING_UTILITY_VALUES);
}
@@ -219,13 +222,13 @@
return enumsToUnbox.containsEnum(type.asClassType().getClassType());
}
- public String compatibleName(DexType type) {
+ private String compatibleName(DexType type) {
return type.toSourceString().replace('.', '$');
}
private DexField createValuesField(DexType type) {
return factory.createField(
- factory.enumUnboxingUtilityType,
+ utilityClassType,
factory.intArrayType,
factory.enumValuesFieldName + "$field$" + compatibleName(type));
}
@@ -241,7 +244,7 @@
private DexMethod createValuesMethod(DexType type) {
return factory.createMethod(
- factory.enumUnboxingUtilityType,
+ utilityClassType,
factory.createProto(factory.intArrayType),
factory.enumValuesFieldName + "$method$" + compatibleName(type));
}
@@ -250,11 +253,7 @@
DexMethod method, DexField fieldValues, int numEnumInstances) {
CfCode cfCode =
new EnumUnboxingCfCodeProvider.EnumUnboxingValuesCfCodeProvider(
- appView,
- factory.enumUnboxingUtilityType,
- fieldValues,
- numEnumInstances,
- valuesUtilityMethod)
+ appView, utilityClassType, fieldValues, numEnumInstances, valuesUtilityMethod)
.generateCfCode();
return synthesizeUtilityMethod(cfCode, method, true);
}
@@ -263,7 +262,7 @@
assert enumsToUnbox.containsEnum(type);
DexMethod valueOf =
factory.createMethod(
- factory.enumUnboxingUtilityType,
+ utilityClassType,
factory.createProto(factory.intType, factory.stringType),
"valueOf" + compatibleName(type));
extraUtilityMethods.computeIfAbsent(valueOf, m -> synthesizeValueOfUtilityMethod(m, type));
@@ -284,8 +283,9 @@
&& enumsToUnbox.containsEnum(baseType.asClassType().getClassType());
}
- void synthesizeEnumUnboxingUtilityMethods(
- Builder<?> builder, IRConverter converter, ExecutorService executorService)
+ // TODO(b/150172351): Synthesize the utility class upfront in the enqueuer.
+ void synthesizeEnumUnboxingUtilityClass(
+ DexApplication.Builder<?> appBuilder, IRConverter converter, ExecutorService executorService)
throws ExecutionException {
// Synthesize a class which holds various utility methods that may be called from the IR
// rewriting. If any of these methods are not used, they will be removed by the Enqueuer.
@@ -302,50 +302,38 @@
if (requiredMethods.isEmpty()) {
return;
}
- List<DexEncodedField> fields = new ArrayList<>(extraUtilityFields.values());
- fields.sort((f1, f2) -> f1.field.name.slowCompareTo(f2.field.name));
+ DexEncodedField[] fields = extraUtilityFields.values().toArray(DexEncodedField.EMPTY_ARRAY);
+ Arrays.sort(fields, (f1, f2) -> f1.field.name.slowCompareTo(f2.field.name));
DexProgramClass utilityClass =
- appView.definitionForProgramType(factory.enumUnboxingUtilityType);
- assert utilityClass != null : "Should have been synthesized in the enqueuer.";
- utilityClass.appendStaticFields(fields);
- utilityClass.addDirectMethods(requiredMethods);
- assert requiredMethods.stream().allMatch(DexEncodedMethod::isPublic);
- if (utilityClassInMainDexList()) {
- builder.addToMainDexList(Collections.singletonList(utilityClass.type));
- }
+ new DexProgramClass(
+ utilityClassType,
+ null,
+ new SynthesizedOrigin("EnumUnboxing ", getClass()),
+ ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC),
+ factory.objectType,
+ DexTypeList.empty(),
+ factory.createString("enumunboxing"),
+ null,
+ Collections.emptyList(),
+ null,
+ Collections.emptyList(),
+ DexAnnotationSet.empty(),
+ fields,
+ DexEncodedField.EMPTY_ARRAY,
+ // All synthesized methods are static in this case.
+ requiredMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
+ DexEncodedMethod.EMPTY_ARRAY,
+ factory.getSkipNameValidationForTesting(),
+ DexProgramClass::checksumFromType);
+ appBuilder.addSynthesizedClass(utilityClass, utilityClassInMainDexList());
+ appView.appInfo().addSynthesizedClass(utilityClass);
converter.optimizeSynthesizedClass(utilityClass, executorService);
}
- public static DexProgramClass synthesizeEmptyEnumUnboxingUtilityClass(AppView<?> appView) {
- DexItemFactory factory = appView.dexItemFactory();
- return new DexProgramClass(
- factory.enumUnboxingUtilityType,
- null,
- new SynthesizedOrigin("EnumUnboxing ", EnumUnboxingRewriter.class),
- ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC),
- factory.objectType,
- DexTypeList.empty(),
- factory.createString("enumunboxing"),
- null,
- Collections.emptyList(),
- null,
- Collections.emptyList(),
- DexAnnotationSet.empty(),
- DexEncodedField.EMPTY_ARRAY,
- DexEncodedField.EMPTY_ARRAY,
- DexEncodedMethod.EMPTY_ARRAY,
- DexEncodedMethod.EMPTY_ARRAY,
- factory.getSkipNameValidationForTesting(),
- DexProgramClass::checksumFromType);
- }
-
private DexEncodedMethod synthesizeValueOfUtilityMethod(DexMethod method, DexType enumType) {
CfCode cfCode =
new EnumUnboxingCfCodeProvider.EnumUnboxingValueOfCfCodeProvider(
- appView,
- factory.enumUnboxingUtilityType,
- enumType,
- enumsToUnbox.getEnumValueInfoMap(enumType))
+ appView, utilityClassType, enumType, enumsToUnbox.getEnumValueInfoMap(enumType))
.generateCfCode();
return new DexEncodedMethod(
method,
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 278945e..f2dddae 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -87,7 +87,6 @@
import com.android.tools.r8.ir.desugar.LambdaClass;
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
-import com.android.tools.r8.ir.optimize.enums.EnumUnboxingRewriter;
import com.android.tools.r8.kotlin.KotlinMetadataEnqueuerExtension;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.shaking.DelayedRootSetActionItem.InterfaceMethodSyntheticBridgeAction;
@@ -2619,7 +2618,6 @@
new IdentityHashMap<>();
Map<DexMethod, ProgramMethod> liveMethods = new IdentityHashMap<>();
- Set<DexProgramClass> liveTypes = Sets.newIdentityHashSet();
Map<DexType, DexClasspathClass> syntheticClasspathClasses = new IdentityHashMap<>();
@@ -2630,8 +2628,7 @@
Set<DexType> mainDexTypes = Sets.newIdentityHashSet();
boolean isEmpty() {
- boolean empty =
- syntheticInstantiations.isEmpty() && liveMethods.isEmpty() && liveTypes.isEmpty();
+ boolean empty = syntheticInstantiations.isEmpty() && liveMethods.isEmpty();
assert !empty || (pinnedMethods.isEmpty() && mainDexTypes.isEmpty());
return empty;
}
@@ -2645,14 +2642,6 @@
}
}
- void addLiveType(DexProgramClass clazz, boolean isMainDexClass) {
- assert !liveTypes.contains(clazz);
- liveTypes.add(clazz);
- if (isMainDexClass) {
- mainDexTypes.add(clazz.type);
- }
- }
-
void addClasspathClass(DexClasspathClass clazz) {
DexClasspathClass old = syntheticClasspathClasses.put(clazz.type, clazz);
assert old == null;
@@ -2675,9 +2664,6 @@
syntheticInstantiations.values()) {
appBuilder.addProgramClass(clazzAndContext.getFirst());
}
- for (DexProgramClass liveClass : liveTypes) {
- appBuilder.addProgramClass(liveClass);
- }
appBuilder.addClasspathClasses(syntheticClasspathClasses.values());
appBuilder.addToMainDexList(mainDexTypes);
}
@@ -2697,9 +2683,6 @@
InstantiationReason.SYNTHESIZED_CLASS,
fakeReason);
}
- for (DexProgramClass liveType : liveTypes) {
- enqueuer.workList.enqueueMarkTypeLiveAction(liveType, fakeReason);
- }
for (ProgramMethod liveMethod : liveMethods.values()) {
assert !enqueuer.targetedMethods.contains(liveMethod.getDefinition());
enqueuer.markMethodAsTargeted(liveMethod, fakeReason);
@@ -2719,7 +2702,6 @@
synthesizeInterfaceMethodBridges(additions);
synthesizeLambdas(additions);
synthesizeLibraryConversionWrappers(additions);
- synthesizeEnumUnboxingUtilityClass(additions);
if (additions.isEmpty()) {
return;
}
@@ -2737,17 +2719,6 @@
additions.enqueueWorkItems(this);
}
- private void synthesizeEnumUnboxingUtilityClass(SyntheticAdditions additions) {
- // This class can be synthesized only when compiling cf to dex.
- if (appView.options().enableEnumUnboxing
- && appView.definitionFor(appView.dexItemFactory().enumUnboxingUtilityType) == null) {
- DexProgramClass utilityClass =
- EnumUnboxingRewriter.synthesizeEmptyEnumUnboxingUtilityClass(appView);
- // The flag isMainDexClass may be set later, the compiler does not know at this point.
- additions.addLiveType(utilityClass, false);
- }
- }
-
private void synthesizeInterfaceMethodBridges(SyntheticAdditions additions) {
for (ProgramMethod bridge : syntheticInterfaceMethodBridges.values()) {
DexProgramClass holder = bridge.getHolder();
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index b51c442..3c9649d 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -51,22 +51,6 @@
}
}
- static class MarkTypeLiveAction extends EnqueuerAction {
-
- final DexProgramClass target;
- final KeepReasonWitness keepReason;
-
- public MarkTypeLiveAction(DexProgramClass target, KeepReasonWitness keepReason) {
- this.target = target;
- this.keepReason = keepReason;
- }
-
- @Override
- public void run(Enqueuer enqueuer) {
- enqueuer.markTypeAsLive(target, keepReason);
- }
- }
-
static class MarkReachableFieldAction extends EnqueuerAction {
final ProgramField field;
final KeepReason reason;
@@ -260,10 +244,6 @@
return queue.poll();
}
- void enqueueMarkTypeLiveAction(DexProgramClass clazz, KeepReasonWitness keepReason) {
- queue.add(new MarkTypeLiveAction(clazz, keepReason));
- }
-
void enqueueMarkReachableDirectAction(DexMethod method, KeepReason reason) {
queue.add(new MarkReachableDirectAction(method, reason));
}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/StaticMethodsEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/StaticMethodsEnumUnboxingTest.java
deleted file mode 100644
index 0d01ffe..0000000
--- a/src/test/java/com/android/tools/r8/enumunboxing/StaticMethodsEnumUnboxingTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-// 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.enumunboxing;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.R8TestRunResult;
-import com.android.tools.r8.TestParameters;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class StaticMethodsEnumUnboxingTest extends EnumUnboxingTestBase {
-
- private final TestParameters parameters;
- private final boolean enumValueOptimization;
- private final KeepRule enumKeepRules;
-
- @Parameters(name = "{0} valueOpt: {1} keep: {2}")
- public static List<Object[]> data() {
- return enumUnboxingTestParameters();
- }
-
- public StaticMethodsEnumUnboxingTest(
- TestParameters parameters, boolean enumValueOptimization, KeepRule enumKeepRules) {
- this.parameters = parameters;
- this.enumValueOptimization = enumValueOptimization;
- this.enumKeepRules = enumKeepRules;
- }
-
- @Test
- public void testEnumUnboxing() throws Exception {
- Class<?> classToTest = StaticMethods.class;
- R8TestRunResult run =
- testForR8(parameters.getBackend())
- .addInnerClasses(StaticMethodsEnumUnboxingTest.class)
- .addKeepMainRule(classToTest)
- .addKeepRules(enumKeepRules.getKeepRule())
- .enableNeverClassInliningAnnotations()
- .enableInliningAnnotations()
- .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
- .allowDiagnosticInfoMessages()
- .setMinApi(parameters.getApiLevel())
- .compile()
- .inspectDiagnosticMessages(
- m -> {
- assertEnumIsUnboxed(MyEnum.class, classToTest.getSimpleName(), m);
- assertEnumIsUnboxed(MyEnum2.class, classToTest.getSimpleName(), m);
- })
- .run(parameters.getRuntime(), classToTest)
- .assertSuccess();
- assertLines2By2Correct(run.getStdOut());
- }
-
- @SuppressWarnings("SameParameterValue")
- @NeverClassInline
- enum MyEnum {
- A,
- B,
- C;
-
- @NeverInline
- public static void print(Object o) {
- System.out.println(o);
- }
-
- @NeverInline
- public static void printEnum(MyEnum e) {
- System.out.println(e.ordinal());
- }
-
- @NeverInline
- public static MyEnum returnEnum(boolean bool) {
- return bool ? MyEnum.A : MyEnum.B;
- }
-
- @NeverInline
- protected static void printProtected() {
- System.out.println("protected");
- }
-
- @NeverInline
- static void printPackagePrivate() {
- System.out.println("package-private");
- }
-
- @NeverInline
- private static void printPrivate() {
- System.out.println("private");
- }
-
- @NeverInline
- public static void callPrivate() {
- System.out.print("call: ");
- printPrivate();
- }
- }
-
- // Use two enums to test collision between values and valueOf.
- enum MyEnum2 {
- A,
- B,
- C;
- }
-
- static class StaticMethods {
-
- public static void main(String[] args) {
- testCustomMethods();
- testNonPublicMethods();
- testGeneratedMethods();
- testGeneratedMethods2();
- }
-
- @NeverInline
- private static void testNonPublicMethods() {
- MyEnum.printPrivate();
- System.out.println("private");
- MyEnum.printPackagePrivate();
- System.out.println("package-private");
- MyEnum.printProtected();
- System.out.println("protected");
- MyEnum.callPrivate();
- System.out.println("call: private");
- }
-
- @NeverInline
- private static void testCustomMethods() {
- MyEnum.print("print");
- System.out.println("print");
- MyEnum.printEnum(MyEnum.A);
- System.out.println(0);
- System.out.println((MyEnum.returnEnum(true).ordinal()));
- System.out.println(0);
- }
-
- @NeverInline
- private static void testGeneratedMethods() {
- System.out.println(MyEnum.valueOf("C").ordinal());
- System.out.println(2);
- System.out.println(MyEnum.values()[0].ordinal());
- System.out.println(0);
- }
-
- @NeverInline
- private static void testGeneratedMethods2() {
- System.out.println(MyEnum2.valueOf("C").ordinal());
- System.out.println(2);
- System.out.println(MyEnum2.values()[0].ordinal());
- System.out.println(0);
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingTest.java
index dc2e217..3ccdd37 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingTest.java
@@ -50,7 +50,15 @@
.setMinApi(parameters.getApiLevel())
.compile()
.inspectDiagnosticMessages(
- m -> assertEnumIsUnboxed(ENUM_CLASS, classToTest.getSimpleName(), m))
+ m -> {
+ // TODO(b/150370354): We need to allow static helper method to re-enable unboxing
+ // with switches.
+ if (enumValueOptimization && enumKeepRules.getKeepRule().equals("")) {
+ assertEnumIsUnboxed(ENUM_CLASS, classToTest.getSimpleName(), m);
+ } else {
+ assertEnumIsBoxed(ENUM_CLASS, classToTest.getSimpleName(), m);
+ }
+ })
.run(parameters.getRuntime(), classToTest)
.assertSuccess();
assertLines2By2Correct(run.getStdOut());