Revision: 9482
Author: b...@google.com
Date: Thu Dec 23 07:05:27 2010
Log: Ensure that enum types reachable through AutoBean method
parameterizations are included in the EnumMap.
Patch by: bobv
Review by: jbrosenberg
Review at http://gwt-code-reviews.appspot.com/1240801
http://code.google.com/p/google-web-toolkit/source/detail?r=9482
Modified:
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
/trunk/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java
=======================================
---
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
Wed Nov 10 11:04:47 2010
+++
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanFactoryModel.java
Thu Dec 23 07:05:27 2010
@@ -249,7 +249,7 @@
AutoBeanMethod toAdd = builder.build();
// Collect referenced enums
- if (toAdd.isEnum()) {
+ if (toAdd.hasEnumMap()) {
allEnumConstants.putAll(toAdd.getEnumMap());
}
=======================================
---
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
Wed Nov 10 11:04:47 2010
+++
/trunk/user/src/com/google/gwt/autobean/rebind/model/AutoBeanMethod.java
Thu Dec 23 07:05:27 2010
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.typeinfo.JEnumType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.editor.rebind.model.ModelUtils;
@@ -158,40 +159,29 @@
toReturn.method = method;
TypeOracle oracle = method.getEnclosingType().getOracle();
- toReturn.isValueType = ModelUtils.isValueType(oracle,
- method.getReturnType());
+ JType returnType = method.getReturnType();
+ toReturn.isValueType = ModelUtils.isValueType(oracle, returnType);
if (!toReturn.isValueType) {
// See if it's a collection or a map
- JClassType returnClass =
method.getReturnType().isClassOrInterface();
+ JClassType returnClass = returnType.isClassOrInterface();
JClassType collectionInterface =
oracle.findType(Collection.class.getCanonicalName());
JClassType mapInterface =
oracle.findType(Map.class.getCanonicalName());
if (collectionInterface.isAssignableFrom(returnClass)) {
JClassType[] parameterizations =
ModelUtils.findParameterizationOf(
collectionInterface, returnClass);
toReturn.elementType = parameterizations[0];
+ maybeProcessEnumType(toReturn.elementType);
} else if (mapInterface.isAssignableFrom(returnClass)) {
JClassType[] parameterizations =
ModelUtils.findParameterizationOf(
mapInterface, returnClass);
toReturn.keyType = parameterizations[0];
toReturn.valueType = parameterizations[1];
- }
- }
-
- JEnumType enumType = method.getReturnType().isEnum();
- if (enumType != null) {
- Map<JEnumConstant, String> map = new LinkedHashMap<JEnumConstant,
String>();
- for (JEnumConstant e : enumType.getEnumConstants()) {
- String name;
- PropertyName annotation = e.getAnnotation(PropertyName.class);
- if (annotation == null) {
- name = e.getName();
- } else {
- name = annotation.value();
- }
- map.put(e, name);
- }
- toReturn.enumMap = map;
+ maybeProcessEnumType(toReturn.keyType);
+ maybeProcessEnumType(toReturn.valueType);
+ }
+ } else {
+ maybeProcessEnumType(returnType);
}
}
@@ -202,6 +192,39 @@
public void setStaticImp(JMethod staticImpl) {
toReturn.staticImpl = staticImpl;
}
+
+ /**
+ * Call {...@link #processEnumType(JEnumType)} if {...@code type} is a
+ * {...@link JEnumType}.
+ */
+ private void maybeProcessEnumType(JType type) {
+ assert type != null : "type == null";
+ JEnumType enumType = type.isEnum();
+ if (enumType != null) {
+ processEnumType(enumType);
+ }
+ }
+
+ /**
+ * Adds a JEnumType to the AutoBeanMethod's enumMap so that the
+ * AutoBeanFactoryGenerator can embed extra metadata about the enum
values.
+ */
+ private void processEnumType(JEnumType enumType) {
+ Map<JEnumConstant, String> map = toReturn.enumMap;
+ if (map == null) {
+ map = toReturn.enumMap = new LinkedHashMap<JEnumConstant,
String>();
+ }
+ for (JEnumConstant e : enumType.getEnumConstants()) {
+ String name;
+ PropertyName annotation = e.getAnnotation(PropertyName.class);
+ if (annotation == null) {
+ name = e.getName();
+ } else {
+ name = annotation.value();
+ }
+ map.put(e, name);
+ }
+ }
}
private Action action;
@@ -255,12 +278,12 @@
return valueType;
}
- public boolean isCollection() {
- return elementType != null;
+ public boolean hasEnumMap() {
+ return enumMap != null;
}
- public boolean isEnum() {
- return enumMap != null;
+ public boolean isCollection() {
+ return elementType != null;
}
public boolean isMap() {
=======================================
--- /trunk/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java
Wed Nov 24 12:33:58 2010
+++ /trunk/user/test/com/google/gwt/autobean/shared/AutoBeanCodexTest.java
Thu Dec 23 07:05:27 2010
@@ -48,6 +48,22 @@
AutoBean<Simple> simple();
}
+
+ /*
+ * These enums are used to verify that a List<Enum> or Map<Enum, Enum>
pulls
+ * in the necessary metadata.
+ */
+ enum EnumReachableThroughList {
+ FOO_LIST
+ }
+
+ enum EnumReachableThroughMapKey {
+ FOO_KEY
+ }
+
+ enum EnumReachableThroughMapValue {
+ FOO_VALUE
+ }
interface HasAutoBean {
Splittable getSimple();
@@ -79,6 +95,10 @@
Map<MyEnum, Integer> getMap();
+ List<EnumReachableThroughList> getParameterizedList();
+
+ Map<EnumReachableThroughMapKey, EnumReachableThroughMapValue>
getParameterizedMap();
+
void setEnum(MyEnum value);
void setEnums(List<MyEnum> value);
@@ -156,13 +176,6 @@
assertNotNull(decodedBean.as().getList());
assertTrue(decodedBean.as().getList().isEmpty());
}
-
- private <T> AutoBean<T> checkEncode(AutoBean<T> bean) {
- Splittable split = AutoBeanCodex.encode(bean);
- AutoBean<T> decoded = AutoBeanCodex.decode(f, bean.getType(), split);
- assertTrue(AutoBeanUtils.deepEquals(bean, decoded));
- return decoded;
- }
public void testEnum() {
EnumMap map = (EnumMap) f;
@@ -191,6 +204,24 @@
assertEquals(arrayValue, decoded.as().getEnums());
assertEquals(mapValue, decoded.as().getMap());
}
+
+ /**
+ * Ensures that enum types that are reachable only through a method
+ * parameterization are included in the enum map.
+ */
+ public void testEnumReachableOnlyThroughParameterization() {
+ EnumMap map = (EnumMap) f;
+ assertEquals("FOO_LIST",
map.getToken(EnumReachableThroughList.FOO_LIST));
+ assertEquals("FOO_KEY",
map.getToken(EnumReachableThroughMapKey.FOO_KEY));
+ assertEquals("FOO_VALUE",
+ map.getToken(EnumReachableThroughMapValue.FOO_VALUE));
+ assertEquals(EnumReachableThroughList.FOO_LIST,
+ map.getEnum(EnumReachableThroughList.class, "FOO_LIST"));
+ assertEquals(EnumReachableThroughMapKey.FOO_KEY,
+ map.getEnum(EnumReachableThroughMapKey.class, "FOO_KEY"));
+ assertEquals(EnumReachableThroughMapValue.FOO_VALUE,
+ map.getEnum(EnumReachableThroughMapValue.class, "FOO_VALUE"));
+ }
public void testMap() {
AutoBean<HasMap> bean = f.hasMap();
@@ -291,4 +322,11 @@
protected void gwtSetUp() throws Exception {
f = GWT.create(Factory.class);
}
-}
+
+ private <T> AutoBean<T> checkEncode(AutoBean<T> bean) {
+ Splittable split = AutoBeanCodex.encode(bean);
+ AutoBean<T> decoded = AutoBeanCodex.decode(f, bean.getType(), split);
+ assertTrue(AutoBeanUtils.deepEquals(bean, decoded));
+ return decoded;
+ }
+}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors