Support is/has methods in Editor framework. Issue 6040. Patch by: bobv Review by: rjrjr Review at http://gwt-code-reviews.appspot.com/1443812 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10288 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/editor/rebind/model/EditorModel.java b/user/src/com/google/gwt/editor/rebind/model/EditorModel.java index 378cb4f..c17a709 100644 --- a/user/src/com/google/gwt/editor/rebind/model/EditorModel.java +++ b/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
@@ -22,13 +22,13 @@ import com.google.gwt.core.ext.typeinfo.JGenericType; import com.google.gwt.core.ext.typeinfo.JMethod; import com.google.gwt.core.ext.typeinfo.JParameterizedType; -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.client.CompositeEditor; import com.google.gwt.editor.client.Editor; import com.google.gwt.editor.client.IsEditor; import com.google.gwt.editor.client.LeafValueEditor; +import com.google.web.bindery.autobean.gwt.rebind.model.JBeanMethod; import java.util.ArrayList; import java.util.Arrays; @@ -376,13 +376,6 @@ return toReturn.toArray(new EditorData[toReturn.size()]); } - private String camelCase(String prefix, String name) { - StringBuilder sb = new StringBuilder(); - sb.append(prefix).append(Character.toUpperCase(name.charAt(0))).append( - name, 1, name.length()); - return sb.toString(); - } - private List<EditorData> createEditorData(EditorAccess access) throws UnableToCompleteException { TreeLogger subLogger = logger.branch(TreeLogger.DEBUG, "Examining " @@ -471,64 +464,73 @@ continue; } boolean lastPart = i == j - 1; - String getterName = camelCase("get", parts[i]); + boolean foundGetterForPart = false; - for (JClassType search : lookingAt.getFlattenedSupertypeHierarchy()) { - // If looking at the last element of the path, also look for a setter - if (i == j - 1 && setterName == null) { - for (JMethod maybeSetter : search.getOverloads(camelCase("set", - parts[i]))) { - if (maybeSetter.getReturnType().equals(JPrimitiveType.VOID) - && maybeSetter.getParameters().length == 1) { + for (JMethod maybeSetter : lookingAt.getInheritableMethods()) { + JBeanMethod which = JBeanMethod.which(maybeSetter); + if (JBeanMethod.CALL.equals(which)) { + continue; + } + if (!which.inferName(maybeSetter).equals(parts[i])) { + continue; + } + switch (which) { + case GET: { + JType returnType = maybeSetter.getReturnType(); + lookingAt = returnType.isClassOrInterface(); + if (!lastPart && lookingAt == null) { + poison(foundPrimitiveMessage(returnType, interstitialGetters.toString(), path)); + return; + } + interstitialGetters.append(".").append(maybeSetter.getName()).append("()"); + interstitialGuard.append(" && %1$s").append(interstitialGetters).append(" != null"); + builder.propertyOwnerType(maybeSetter.getEnclosingType()); + foundGetterForPart = true; + if (!lastPart) { + continue part; + } + break; + } + case SET: + case SET_BUILDER: { + if (lastPart && setterName == null) { + /* + * If looking at the last element of the path, also look for a + * setter. + */ + JType setterParamType = maybeSetter.getParameters()[0].getType(); // Handle the case of setFoo(int) vs. Editor<Integer> if (setterParamType.isPrimitive() != null) { // Replace the int with Integer - setterParamType = oracle.findType(setterParamType.isPrimitive().getQualifiedBoxedSourceName()); + setterParamType = + oracle.findType(setterParamType.isPrimitive().getQualifiedBoxedSourceName()); } - boolean matches = setterParamType.isClassOrInterface().isAssignableFrom( - propertyType); + boolean matches = setterParamType.isClassOrInterface().isAssignableFrom(propertyType); if (matches) { setterName = maybeSetter.getName(); - break; } } + break; } } - - JMethod getter = search.findMethod(getterName, new JType[0]); - if (getter != null) { - JType returnType = getter.getReturnType(); - lookingAt = returnType.isClassOrInterface(); - if (!lastPart && lookingAt == null) { - poison(foundPrimitiveMessage(returnType, - interstitialGetters.toString(), path)); - return; - } - interstitialGetters.append(".").append(getterName).append("()"); - interstitialGuard.append(" && %1$s").append(interstitialGetters).append( - " != null"); - builder.propertyOwnerType(search); - continue part; - } } - poison(noGetterMessage(path, proxyType)); - return; + if (!foundGetterForPart) { + poison(noGetterMessage(path, proxyType)); + return; + } } int idx = interstitialGetters.lastIndexOf("."); - builder.beanOwnerExpression(idx <= 0 ? "" : interstitialGetters.substring( - 0, idx)); + builder.beanOwnerExpression(idx <= 0 ? "" : interstitialGetters.substring(0, idx)); if (parts.length > 1) { // Strip after last && since null is a valid value - interstitialGuard.delete(interstitialGuard.lastIndexOf(" &&"), - interstitialGuard.length()); + interstitialGuard.delete(interstitialGuard.lastIndexOf(" &&"), interstitialGuard.length()); builder.beanOwnerGuard(interstitialGuard.substring(8)); } if (interstitialGetters.length() > 0) { builder.getterExpression("." - + interstitialGetters.substring(idx + 1, - interstitialGetters.length() - 2) + "()"); + + interstitialGetters.substring(idx + 1, interstitialGetters.length() - 2) + "()"); } else { builder.getterExpression(""); }
diff --git a/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java b/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java index ba3ae78..bb270d7 100644 --- a/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java +++ b/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java
@@ -188,7 +188,7 @@ types.findType("t.CompositeEditorDriver"), rfedType); EditorData[] data = m.getEditorData(); - assertEquals(7, data.length); + assertEquals(9, data.length); String[] paths = new String[data.length]; String[] expressions = new String[data.length]; @@ -196,20 +196,22 @@ paths[i] = data[i].getPath(); expressions[i] = data[i].getExpression(); } - assertEquals(Arrays.asList("address", "address.city", "address.street", - "person", "person.lastModified", "person.name", "person.readonly"), - Arrays.asList(paths)); + assertEquals(Arrays.asList("address", "address.city", "address.street", "person", "person.has", + "person.is", "person.lastModified", "person.name", "person.readonly"), Arrays.asList(paths)); // address is a property, person is a method in CompositeEditor - assertEquals(Arrays.asList("address", "address.city", "address.street", - "person()", "person().lastModified", "person().name", + assertEquals(Arrays.asList("address", "address.city", "address.street", "person()", + "person().has", "person().is", "person().lastModified", "person().name", "person().readonly"), Arrays.asList(expressions)); assertTrue(data[0].isDelegateRequired()); assertFalse(data[0].isLeafValueEditor() || data[0].isValueAwareEditor()); assertTrue(data[3].isDelegateRequired()); assertFalse(data[3].isLeafValueEditor() || data[3].isValueAwareEditor()); - checkPersonLastModified(data[4]); - checkPersonName(data[5]); - checkPersonReadonly(data[6]); + int fieldNum = 4; + checkPersonHasHas(data[fieldNum++]); + checkPersonIsIs(data[fieldNum++]); + checkPersonLastModified(data[fieldNum++]); + checkPersonName(data[fieldNum++]); + checkPersonReadonly(data[fieldNum++]); } public void testCyclicDriver() { @@ -259,14 +261,19 @@ EditorModel m = new EditorModel(logger, types.findType("t.PersonEditorDriver"), rfedType); EditorData[] fields = m.getEditorData(); - assertEquals(3, fields.length); + assertEquals(5, fields.length); + int fieldNum = 0; + // hasHas + checkPersonHasHas(fields[fieldNum++]); + // isIs + checkPersonIsIs(fields[fieldNum++]); // lastModified - checkPersonLastModified(fields[0]); + checkPersonLastModified(fields[fieldNum++]); // name - checkPersonName(fields[1]); + checkPersonName(fields[fieldNum++]); // readonly - checkPersonReadonly(fields[2]); + checkPersonReadonly(fields[fieldNum++]); } public void testFlatData() throws UnableToCompleteException { @@ -282,10 +289,13 @@ assertEquals("person", composite[1].getPropertyName()); EditorData[] person = m.getEditorData(types.findType("t.PersonEditor")); - assertEquals(3, person.length); - assertEquals("lastModified", person[0].getPropertyName()); - assertEquals("name", person[1].getPropertyName()); - assertEquals("readonly", person[2].getPropertyName()); + assertEquals(5, person.length); + int fieldNum = 0; + assertEquals("has", person[fieldNum++].getPropertyName()); + assertEquals("is", person[fieldNum++].getPropertyName()); + assertEquals("lastModified", person[fieldNum++].getPropertyName()); + assertEquals("name", person[fieldNum++].getPropertyName()); + assertEquals("readonly", person[fieldNum++].getPropertyName()); EditorData[] address = m.getEditorData(types.findType("t.AddressEditor")); assertEquals("city", address[0].getPropertyName()); @@ -465,7 +475,29 @@ EditorModel m = new EditorModel(logger, types.findType("t.PersonEditorWithAliasedSubEditorsDriver"), rfedType); EditorData[] fields = m.getEditorData(); - assertEquals(8, fields.length); + assertEquals(12, fields.length); + } + + private void checkPersonHasHas(EditorData editorField) { + assertNotNull(editorField); + assertEquals(types.findType(SimpleEditor.class.getName()), + editorField.getEditorType().isParameterized().getBaseType()); + assertTrue(editorField.isLeafValueEditor()); + assertFalse(editorField.isDelegateRequired()); + assertFalse(editorField.isValueAwareEditor()); + assertEquals(".hasHas()", editorField.getGetterExpression()); + assertEquals("setHas", editorField.getSetterName()); + } + + private void checkPersonIsIs(EditorData editorField) { + assertNotNull(editorField); + assertEquals(types.findType(SimpleEditor.class.getName()), + editorField.getEditorType().isParameterized().getBaseType()); + assertTrue(editorField.isLeafValueEditor()); + assertFalse(editorField.isDelegateRequired()); + assertFalse(editorField.isValueAwareEditor()); + assertEquals(".isIs()", editorField.getGetterExpression()); + assertEquals("setIs", editorField.getSetterName()); } private void checkPersonLastModified(EditorData editorField) { @@ -676,6 +708,10 @@ code.append("String getName();\n"); code.append("long getLastModified();\n"); code.append("String getReadonly();\n"); + code.append("boolean hasHas();\n"); + code.append("boolean isIs();\n"); + code.append("void setHas(boolean has);\n"); + code.append("void setIs(boolean is);\n"); code.append("void setName(String name);\n"); code.append("void setLastModified(long value);\n"); code.append("}"); @@ -689,6 +725,8 @@ code.append("import " + Editor.class.getName() + ";\n"); code.append("import " + SimpleEditor.class.getName() + ";\n"); code.append("class PersonEditor implements Editor<PersonProxy> {\n"); + code.append("SimpleEditor<Boolean> has;\n"); + code.append("SimpleEditor<Boolean> is;\n"); code.append("SimpleEditor<Long> lastModified;\n"); code.append("public SimpleEditor<String> name;\n"); code.append("SimpleEditor<String> readonly;\n");