Implements Enum.valueOf(Class,String), which is also required for Sun's JDK
to correctly compile code using enums.
Patch by: tobyr
Review by: scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1749 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/lang/Enum.java b/user/super/com/google/gwt/emul/java/lang/Enum.java
index c0efe0b..e632fa5 100644
--- a/user/super/com/google/gwt/emul/java/lang/Enum.java
+++ b/user/super/com/google/gwt/emul/java/lang/Enum.java
@@ -27,6 +27,33 @@
public abstract class Enum<E extends Enum<E>> implements Comparable<E>,
Serializable {
+ public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
+
+ // Have to explicitly test for null, otherwise we won't get
+ // NullPointerExceptions in web mode
+ if (enumType == null || name == null) {
+ throw new NullPointerException("enumType and name must not be null.");
+ }
+
+ // TODO(scottb) Work some compiler magic to improve this from a linear
+ // search to a map lookup.
+ T[] constants = enumType.getEnumConstants();
+
+ if (constants == null) {
+ throw new IllegalArgumentException(
+ enumType.getName() + " is not an enum.");
+ }
+
+ for (T constant : constants) {
+ if (constant.name().equals(name)) {
+ return constant;
+ }
+ }
+
+ throw new IllegalArgumentException(enumType.getName()
+ + " does not have an enum constant named, " + name + ".");
+ }
+
protected static <T extends Enum<T>> T valueOf(JavaScriptObject map,
String name) {
T result = Enum.<T> valueOf0(map, "_" + name);
diff --git a/user/test/com/google/gwt/dev/jjs/test/EnumsTest.java b/user/test/com/google/gwt/dev/jjs/test/EnumsTest.java
index 1a67d32..086f7bc 100644
--- a/user/test/com/google/gwt/dev/jjs/test/EnumsTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/EnumsTest.java
@@ -197,6 +197,40 @@
fail("Subclassing.valueOf(\"D\") -- expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
}
+
+ enumValuesTest(Basic.class);
+ enumValuesTest(Complex.class);
+ enumValuesTest(Subclassing.class);
+
+ try {
+ Enum.valueOf(Basic.class, "foo");
+ fail("Passed an invalid enum constant name to Enum.valueOf; expected "
+ + "IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Class fakeEnumClass = String.class;
+ Enum.valueOf(fakeEnumClass, "foo");
+ fail("Passed a non enum class to Enum.valueOf; expected "
+ + "IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ }
+
+ try {
+ Class<Basic> nullEnumClass = null;
+ Enum.valueOf(nullEnumClass, "foo");
+ fail("Passed a null enum class to Enum.valueOf; expected "
+ + "NullPointerException");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ Enum.valueOf(Basic.class, null);
+ fail("Passed a null enum constant to Enum.valueOf; expected "
+ + "NullPointerException");
+ } catch (NullPointerException e) {
+ }
}
public void testValues() {
@@ -218,4 +252,11 @@
assertEquals(Subclassing.B, subs[1]);
assertEquals(Subclassing.C, subs[2]);
}
+
+ private <T extends Enum<T>> void enumValuesTest(Class<T> enumClass) {
+ T[] constants = enumClass.getEnumConstants();
+ for (T constant : constants) {
+ assertEquals(constant, Enum.valueOf(enumClass, constant.name()));
+ }
+ }
}