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