Re-roll r9549 with a fix that ensures that sub-editors of a LeafValueEditor will be ignored. Patch by: t.broyer, bobv Review by: bobv, rjrjr Review at http://gwt-code-reviews.appspot.com/1295801 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9555 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 e11df64..0ae18b1 100644 --- a/user/src/com/google/gwt/editor/rebind/model/EditorModel.java +++ b/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
@@ -28,6 +28,7 @@ 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 java.util.ArrayList; import java.util.Arrays; @@ -60,7 +61,7 @@ if (compositeEditorIntf.equals(parameterized.getBaseType())) { JClassType[] typeArgs = parameterized.getTypeArgs(); assert typeArgs.length == 3; - return new JClassType[]{typeArgs[1], typeArgs[2]}; + return new JClassType[] {typeArgs[1], typeArgs[2]}; } } } @@ -175,6 +176,8 @@ */ private final JGenericType isEditorIntf; + private final JGenericType leafValueEditorIntf; + private final TreeLogger logger; private final EditorModel parentModel; @@ -216,6 +219,8 @@ assert isEditorIntf != null : "No IsEditor type"; compositeEditorIntf = oracle.findType(CompositeEditor.class.getName()).isGenericType(); assert compositeEditorIntf != null : "No CompositeEditor type"; + leafValueEditorIntf = oracle.findType(LeafValueEditor.class.getName()).isGenericType(); + assert leafValueEditorIntf != null; JClassType[] interfaces = intf.getImplementedInterfaces(); if (interfaces.length != 1) { @@ -244,6 +249,7 @@ this.editorType = editorType; this.editorSoFar = subEditor; this.isEditorIntf = parent.isEditorIntf; + this.leafValueEditorIntf = parent.leafValueEditorIntf; this.parentModel = parent; this.proxyType = proxyType; this.typeData = parent.typeData; @@ -301,41 +307,44 @@ List<EditorData> flatData = new ArrayList<EditorData>(); List<EditorData> toReturn = new ArrayList<EditorData>(); - for (JClassType type : editorType.getFlattenedSupertypeHierarchy()) { - for (JField field : type.getFields()) { - if (field.isPrivate() || field.isStatic() - || field.getAnnotation(Editor.Ignore.class) != null) { - continue; - } - JType fieldClassType = field.getType(); - if (shouldExamine(fieldClassType)) { - List<EditorData> data = createEditorData(EditorAccess.via(field)); - accumulateEditorData(data, flatData, toReturn); - } - } - for (JMethod method : type.getMethods()) { - if (method.isPrivate() || method.isStatic() - || method.getAnnotation(Editor.Ignore.class) != null) { - continue; - } - JType methodReturnType = method.getReturnType(); - if (shouldExamine(methodReturnType) - && method.getParameters().length == 0) { - EditorAccess access = EditorAccess.via(method); - if (access.getPath().equals("as") - && isEditorIntf.isAssignableFrom(editorType)) { - // Ignore IsEditor.asEditor() - continue; - } else if (access.getPath().equals("createEditorForTraversal") - && compositeEditorIntf.isAssignableFrom(editorType)) { - // Ignore CompositeEditor.createEditorForTraversal(); + // Only look for sub-editor accessors if the editor isn't a leaf + if (!leafValueEditorIntf.isAssignableFrom(editorType)) { + for (JClassType type : editorType.getFlattenedSupertypeHierarchy()) { + for (JField field : type.getFields()) { + if (field.isPrivate() || field.isStatic() + || field.getAnnotation(Editor.Ignore.class) != null) { continue; } - List<EditorData> data = createEditorData(access); - accumulateEditorData(data, flatData, toReturn); + JType fieldClassType = field.getType(); + if (shouldExamine(fieldClassType)) { + List<EditorData> data = createEditorData(EditorAccess.via(field)); + accumulateEditorData(data, flatData, toReturn); + } } + for (JMethod method : type.getMethods()) { + if (method.isPrivate() || method.isStatic() + || method.getAnnotation(Editor.Ignore.class) != null) { + continue; + } + JType methodReturnType = method.getReturnType(); + if (shouldExamine(methodReturnType) + && method.getParameters().length == 0) { + EditorAccess access = EditorAccess.via(method); + if (access.getPath().equals("as") + && isEditorIntf.isAssignableFrom(editorType)) { + // Ignore IsEditor.asEditor() + continue; + } else if (access.getPath().equals("createEditorForTraversal") + && compositeEditorIntf.isAssignableFrom(editorType)) { + // Ignore CompositeEditor.createEditorForTraversal(); + continue; + } + List<EditorData> data = createEditorData(access); + accumulateEditorData(data, flatData, toReturn); + } + } + type = type.getSuperclass(); } - type = type.getSuperclass(); } if (compositeEditorIntf.isAssignableFrom(editorType)) { @@ -423,7 +432,7 @@ superModel = superModel.parentModel; } - if (!data.isLeafValueEditor()) { + if (data.isDelegateRequired()) { EditorModel subModel = new EditorModel(this, data.getEditorType(), data, calculateEditedType(logger, data.getEditorType())); accumulator.addAll(accumulator.indexOf(data) + 1,
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 564b02f..25e82f3 100644 --- a/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java +++ b/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java
@@ -144,6 +144,40 @@ assertEquals(types.findType("t.PersonProxy"), m.getProxyType()); } + /** + * Verify that we correctly descend into a subeditor of a CompositeEditor that + * also is a LeafValueEditor (as is the case of OptionalFieldEditor). + */ + public void testCompositeAndLeafValueEditor() + throws UnableToCompleteException { + EditorModel m = new EditorModel(logger, + types.findType("t.CompositeAndLeafEditorDriver"), rfedType); + + assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AProxy"), + m.getProxyType()); + assertEquals(types.findType("t.CompositeAndLeafEditorDriver.AEditor"), + m.getEditorType()); + + EditorData[] data = m.getEditorData(); + assertEquals(1, data.length); + + assertTrue(data[0].isCompositeEditor()); + + EditorData composed = data[0].getComposedData(); + assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BProxy"), + composed.getEditedType()); + assertEquals(types.findType("t.CompositeAndLeafEditorDriver.BEditor"), + composed.getEditorType()); + + // Nonsensical for the optional editor to have any data + EditorData[] optionalEditorData = m.getEditorData(data[0].getEditorType()); + assertEquals(0, optionalEditorData.length); + + // Make sure we have EditorData for the sub-editor + EditorData[] subEditorData = m.getEditorData(composed.getEditorType()); + assertEquals(1, subEditorData.length); + } + public void testCompositeDriver() throws UnableToCompleteException { EditorModel m = new EditorModel(logger, types.findType("t.CompositeEditorDriver"), rfedType); @@ -796,6 +830,42 @@ code.append("}"); return code; } + }, new MockJavaResource("t.CompositeAndLeafEditorDriver") { + /* + * Tests that we descend into sub-editor of a CompositeEditor that also is + * a LeafValueEditor (this is the case for the + * c.g.g.editor.client.adapters.OptionalFieldEditor). Also test that any + * editor-like fields within the LeafValueEditor are ignored. + */ + @Override + protected CharSequence getContent() { + StringBuilder code = new StringBuilder(); + code.append("package t;\n"); + code.append("import " + Editor.class.getName() + ";\n"); + code.append("import " + IsEditor.class.getName() + ";\n"); + code.append("import " + EntityProxy.class.getName() + ";\n"); + code.append("import " + RequestFactoryEditorDriver.class.getName() + + ";\n"); + code.append("import " + SimpleEditor.class.getName() + ";\n"); + code.append("import " + CompositeEditor.class.getName() + ";\n"); + code.append("import " + LeafValueEditor.class.getName() + ";\n"); + code.append("interface CompositeAndLeafEditorDriver extends" + + " RequestFactoryEditorDriver<CompositeAndLeafEditorDriver.AProxy," + + " CompositeAndLeafEditorDriver.AEditor> {\n"); + code.append(" interface AProxy extends EntityProxy { BProxy getB();}"); + code.append(" interface BProxy extends EntityProxy { String getString();}"); + code.append(" interface AEditor extends Editor<AProxy> {"); + code.append(" OptionalBEditor bEditor();"); + code.append(" }"); + code.append(" interface OptionalBEditor extends CompositeEditor<BProxy, BProxy, BEditor>, LeafValueEditor<BProxy> {"); + code.append(" LeafValueEditor<String> ignored();"); + code.append(" }"); + code.append(" interface BEditor extends Editor<BProxy> {"); + code.append(" @Editor.Path(\"string\") SimpleEditor<String> coEditor();"); + code.append(" }"); + code.append("}"); + return code; + } }, new MockJavaResource("java.util.List") { // Tests a Driver interface that extends more than RFED @Override @@ -809,7 +879,7 @@ }}; Set<Resource> toReturn = new HashSet<Resource>(Arrays.asList(javaFiles)); - toReturn.addAll(Arrays.asList(new Resource[]{ + toReturn.addAll(Arrays.asList(new Resource[] { new RealJavaResource(CompositeEditor.class), new RealJavaResource(Editor.class), new RealJavaResource(EditorError.class),