blob: cc2aa0c9557531a0e6afe2b20fe73a7c6eb4d93e [file] [log] [blame]
// 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;
// This class implements support methods for enum unboxing. The enum unboxing optimization may
// rewrite any call to an enum method into one of the following methods.
// The methods Enum#name, Enum#toString and MyEnum#valueOf cannot be implemented here since they
// are different on each Enum implementation.
public class EnumUnboxingMethods {
// An enum is unboxed to ordinal + 1.
// For example, enum E {A,B}, is unboxed to null -> 0, A -> 1, B-> 2.
// Computing the ordinal of an unboxed enum throws a null pointer exception on 0,
// else answers the value - 1.
public static int ordinal(int unboxedEnum) {
if (unboxedEnum == 0) {
throw new NullPointerException();
}
return unboxedEnum - 1;
}
// The values methods normally reads the $VALUES field, then clones and returns it.
// In our case we just create a new instance each time.
// Note: This can replace a MyEnum#values() call, but not a MyEnum#$VALUES static get.
// numEnums is the number of elements in the enum.
public static int[] values(int numEnums) {
int[] ints = new int[numEnums];
for (int i = 0; i < ints.length; i++) {
ints[i] = i + 1;
}
return ints;
}
// We assume the enum could be unboxed only if both parameters were proven to be of the same
// enum types, so we do not check they belong to the same Enum type.
// We need the 0 checks for null pointer exception.
public static int compareTo(int unboxedEnum1, int unboxedEnum2) {
if (unboxedEnum1 == 0 || unboxedEnum2 == 0) {
throw new NullPointerException();
}
// Formula: unboxedEnum1 - 1 - (unboxedEnum2 - 1), simplified as follow:
return unboxedEnum1 - unboxedEnum2;
}
// Equals on Enum is implemented using directly ==. The invoke raises a NPE if the
// receiver is null, but returns false if the parameter is null.
public static boolean equals(int unboxedEnum1, int unboxedEnum2) {
if (unboxedEnum1 == 0) {
throw new NullPointerException();
}
return unboxedEnum1 == unboxedEnum2;
}
// Methods zeroCheck and zeroCheckMessage are used to replace null checks on unboxed enums.
public static void zeroCheck(int unboxedEnum) {
if (unboxedEnum == 0) {
throw new NullPointerException();
}
}
public static void zeroCheckMessage(int unboxedEnum, String message) {
if (unboxedEnum == 0) {
throw new NullPointerException(message);
}
}
}