Revision: 10129
Author: her...@google.com
Date: Tue May 3 08:15:07 2011
Log: Promoting LazyDomElement to be used externally. LazyDomElement
can be
used to boost rendering time. Today, html elements marked with
"ui:field" need to call getElementById() by the time the template is
created even if is not used. LazyDomElement delays this.
Review at http://gwt-code-reviews.appspot.com/1427809
http://code.google.com/p/google-web-toolkit/source/detail?r=10129
Added:
/trunk/user/src/com/google/gwt/uibinder/client/LazyDomElement.java
/trunk/user/src/com/google/gwt/uibinder/rebind/FieldWriterOfLazyDomElement.java
/trunk/user/test/com/google/gwt/uibinder/rebind/FieldWriterOfExistingTypeTest.java
/trunk/user/test/com/google/gwt/uibinder/rebind/FieldWriterOfLazyDomElementTest.java
Modified:
/trunk/user/src/com/google/gwt/uibinder/client/UiBinderUtil.java
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetInterpreter.java
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetPlaceholderInterpreter.java
/trunk/user/src/com/google/gwt/uibinder/rebind/FieldManager.java
/trunk/user/src/com/google/gwt/uibinder/rebind/FieldWriterType.java
/trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
/trunk/user/src/com/google/gwt/uibinder/rebind/model/OwnerField.java
/trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/uibinder/client/LazyDomElement.java Tue
May 3 08:15:07 2011
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+
+package com.google.gwt.uibinder.client;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+
+/**
+ * Wraps a call to a DOM element. LazyDomElement can boost performance of
html
+ * elements and delay calls to getElementById() to when the element is
actually
+ * used. But note that it will throw a RuntimeException in case the
element is
+ * accessed but not yet attached in the DOM tree.
+ *
+ * Usage example:
+ *
+ * <b>Template:</b>
+ * <pre>
+ * <gwt:HTMLPanel>
+ * <div ui:field="myDiv" />
+ * </gwt:HTMLPanel>
+ * </pre>
+ *
+ * <b>Class:</b>
+ * <pre>
+ * @UiField LazyDomElement<DivElement> myDiv;
+ *
+ * public setText(String text) {
+ * myDiv.get().setInnerHtml(text);
+ * }
+ * </pre>
+ *
+ * @param <T> the Element type associated
+ */
+public class LazyDomElement<T extends Element> {
+
+ private T element;
+ private final String domId;
+
+ /**
+ * Creates an instance to fetch the element with the given id.
+ */
+ public LazyDomElement(String domId) {
+ this.domId = domId;
+ }
+
+ /**
+ * Returns the dom element.
+ *
+ * @return the dom element
+ * @throws RuntimeException if the element cannot be found
+ */
+ public T get() {
+ if (element == null) {
+ element = Document.get().getElementById(domId).cast();
+ if (element == null) {
+ throw new RuntimeException("Cannot find element with id \"" + domId
+ + "\". Perhaps it is not attached to the document body.");
+ }
+ element.removeAttribute("id");
+ }
+ return element;
+ }
+}
=======================================
--- /dev/null
+++
/trunk/user/src/com/google/gwt/uibinder/rebind/FieldWriterOfLazyDomElement.java
Tue May 3 08:15:07 2011
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package com.google.gwt.uibinder.rebind;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JParameterizedType;
+import com.google.gwt.uibinder.rebind.model.OwnerField;
+
+/**
+ * Implementation of FieldWriter for a {@link
com.google.gwt.uibinder.client.LazyDomElement}.
+ */
+public class FieldWriterOfLazyDomElement extends AbstractFieldWriter {
+
+ /**
+ * The field type for @UiField LazyDomElement<T>.
+ */
+ private final JParameterizedType ownerFieldType;
+
+ /**
+ * The T parameter in LazyDomElement<T>.
+ */
+ private final JClassType parameterType;
+
+ public FieldWriterOfLazyDomElement(JClassType templateFieldType,
+ OwnerField ownerField, MortalLogger logger) throws
UnableToCompleteException {
+ super(ownerField.getName(), FieldWriterType.DEFAULT, logger);
+
+ // ownerFieldType null means LazyDomElement is not parameterized.
+ this.ownerFieldType = ownerField.getRawType().isParameterized();
+ if (ownerFieldType == null) {
+ logger.die("LazyDomElement must be of type LazyDomElement<? extends
Element>.");
+ }
+
+ // Parameterized LazyDomElement<T> must match its respective html
element.
+ // Example:
+ // DivElement -> div
+ // SpanElement -> span
+ parameterType = ownerFieldType.getTypeArgs()[0];
+ if (!templateFieldType.isAssignableTo(parameterType)) {
+ logger.die("Field %s is %s<%s>, must be %s<%s>.",
ownerField.getName(),
+ ownerFieldType.getQualifiedSourceName(), parameterType,
+ ownerFieldType.getQualifiedSourceName(), templateFieldType);
+ }
+ }
+
+ public JClassType getAssignableType() {
+ return ownerFieldType;
+ }
+
+ public JClassType getInstantiableType() {
+ return ownerFieldType;
+ }
+
+ public String getQualifiedSourceName() {
+ return ownerFieldType.getQualifiedSourceName()
+ + "<" + parameterType.getQualifiedSourceName() + ">";
+ }
+}
=======================================
--- /dev/null
+++
/trunk/user/test/com/google/gwt/uibinder/rebind/FieldWriterOfExistingTypeTest.java
Tue May 3 08:15:07 2011
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package com.google.gwt.uibinder.rebind;
+
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JGenericType;
+import com.google.gwt.core.ext.typeinfo.JRawType;
+
+import junit.framework.TestCase;
+
+import static org.easymock.EasyMock.expect;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+/**
+ * Tests for FieldWriterOfExistingType.
+ */
+public class FieldWriterOfExistingTypeTest extends TestCase {
+
+ private static final String FIELD_NAME = "field_name";
+ private static final String QUALIFIED_SOURCE_NAME
= "qualified_source_name";
+ private static final String ARG_QUALIFIED_SOURCE_NAME
= "arg_qualified_source_name";
+
+ private IMocksControl control;
+
+ private JClassType type;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ control = EasyMock.createControl();
+
+ type = control.createMock(JClassType.class);
+ }
+
+ /**
+ * Null type not allowed, must fail.
+ */
+ public void testNullType() throws Exception {
+ control.replay();
+ try {
+ FieldWriter field = new FieldWriterOfExistingType(
+ FieldWriterType.DEFAULT, null, FIELD_NAME, MortalLogger.NULL);
+ fail("Expected exception not thrown.");
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ control.verify();
+ }
+
+ /**
+ * Generic type.
+ */
+ public void testGenericType() throws Exception {
+ JGenericType genericType = control.createMock(JGenericType.class);
+ expect(type.isGenericType()).andReturn(genericType);
+
+ JRawType rawType = control.createMock(JRawType.class);
+ expect(genericType.getRawType()).andReturn(rawType);
+
+
expect(rawType.getQualifiedSourceName()).andReturn(QUALIFIED_SOURCE_NAME);
+
+ control.replay();
+ FieldWriter field = new FieldWriterOfExistingType(
+ FieldWriterType.DEFAULT, type, FIELD_NAME, MortalLogger.NULL);
+
+ assertSame(rawType, field.getAssignableType());
+ assertSame(rawType, field.getInstantiableType());
+ assertEquals(QUALIFIED_SOURCE_NAME, field.getQualifiedSourceName());
+ control.verify();
+ }
+
+ /**
+ * Non generic type.
+ */
+ public void testNonGenericType() throws Exception {
+ expect(type.isGenericType()).andReturn(null);
+
+ expect(type.getQualifiedSourceName()).andReturn(QUALIFIED_SOURCE_NAME);
+
+ control.replay();
+ FieldWriter field = new FieldWriterOfExistingType(
+ FieldWriterType.DEFAULT, type, FIELD_NAME, MortalLogger.NULL);
+
+ assertSame(type, field.getAssignableType());
+ assertSame(type, field.getInstantiableType());
+ assertEquals(QUALIFIED_SOURCE_NAME, field.getQualifiedSourceName());
+ control.verify();
+ }
+}
=======================================
--- /dev/null
+++
/trunk/user/test/com/google/gwt/uibinder/rebind/FieldWriterOfLazyDomElementTest.java
Tue May 3 08:15:07 2011
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package com.google.gwt.uibinder.rebind;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JParameterizedType;
+import com.google.gwt.uibinder.rebind.model.OwnerField;
+
+import junit.framework.TestCase;
+
+import static org.easymock.EasyMock.expect;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+/**
+ * Tests for FieldWriterOfLazyDomElement.
+ */
+public class FieldWriterOfLazyDomElementTest extends TestCase {
+
+ private static final String FIELD_NAME = "field_name";
+ private static final String QUALIFIED_SOURCE_NAME
= "qualified_source_name";
+ private static final String ARG_QUALIFIED_SOURCE_NAME
= "arg_qualified_source_name";
+
+ private IMocksControl control;
+
+ private JClassType templateFieldType;
+ private OwnerField ownerField;
+ private JClassType ownerFieldType;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ control = EasyMock.createControl();
+
+ templateFieldType = control.createMock(JClassType.class);
+ ownerField = control.createMock(OwnerField.class);
+ ownerFieldType = control.createMock(JClassType.class);
+
+ expect(ownerField.getName()).andStubReturn(FIELD_NAME);
+ expect(ownerField.getRawType()).andStubReturn(ownerFieldType);
+ }
+
+ /**
+ * Not parameterized LazyDomElement must fail. Example:
+ * <pre>
+ * @UiField LazyDomElement el;
+ * </pre>
+ */
+ public void testLazyDomElementNotParameterized() throws Exception {
+ expect(ownerFieldType.isParameterized()).andReturn(null);
+
+ control.replay();
+ try {
+ FieldWriter field = new FieldWriterOfLazyDomElement(
+ templateFieldType, ownerField, MortalLogger.NULL);
+ fail("Expected exception not thrown.");
+ } catch (UnableToCompleteException utce) {
+ // Expected
+ }
+ control.verify();
+ }
+
+ /**
+ * LazyDomElement has parameter but it's not assignable to the template
field
+ * type. Example:
+ * <pre>
+ * @UiField LazyDomElement<DivElement> el;
+ * </pre>
+ *
+ * but in the template 'el' is defined as:
+ * <pre>
+ * <span ui:field='el' />
+ * </pre>
+ */
+ public void testLazyDomElementIncompatibleParameter() throws Exception {
+ JParameterizedType parameterClass =
control.createMock(JParameterizedType.class);
+ expect(ownerFieldType.isParameterized()).andReturn(parameterClass);
+
+ JClassType arg = control.createMock(JClassType.class);
+ expect(parameterClass.getTypeArgs()).andReturn(new JClassType[] { arg
});
+
+ expect(templateFieldType.isAssignableTo(arg)).andReturn(false);
+
expect(parameterClass.getQualifiedSourceName()).andStubReturn(QUALIFIED_SOURCE_NAME);
+
+ control.replay();
+ try {
+ FieldWriter field = new FieldWriterOfLazyDomElement(
+ templateFieldType, ownerField, MortalLogger.NULL);
+ fail("Expected exception not thrown.");
+ } catch (UnableToCompleteException utce) {
+ // Expected
+ }
+ control.verify();
+ }
+
+ /**
+ * The success test, everything works fine.
+ */
+ public void testLazyDomElementCompatibleType() throws Exception {
+ JParameterizedType parameterClass =
control.createMock(JParameterizedType.class);
+ expect(ownerFieldType.isParameterized()).andReturn(parameterClass);
+
+ JClassType arg = control.createMock(JClassType.class);
+ expect(parameterClass.getTypeArgs()).andReturn(new JClassType[] { arg
});
+
+ expect(templateFieldType.isAssignableTo(arg)).andReturn(true);
+
+
expect(parameterClass.getQualifiedSourceName()).andStubReturn(QUALIFIED_SOURCE_NAME);
+
expect(arg.getQualifiedSourceName()).andReturn(ARG_QUALIFIED_SOURCE_NAME);
+
+ control.replay();
+ FieldWriter field = new FieldWriterOfLazyDomElement(templateFieldType,
ownerField, MortalLogger.NULL);
+ assertSame(parameterClass, field.getAssignableType());
+ assertSame(parameterClass, field.getInstantiableType());
+ assertEquals(QUALIFIED_SOURCE_NAME + "<" + ARG_QUALIFIED_SOURCE_NAME
+ ">",
+ field.getQualifiedSourceName());
+ control.verify();
+ }
+}
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/client/UiBinderUtil.java Fri
Apr 22 11:18:50 2011
+++ /trunk/user/src/com/google/gwt/uibinder/client/UiBinderUtil.java Tue
May 3 08:15:07 2011
@@ -26,27 +26,6 @@
* so please don't use them for non-UiBinder code.
*/
public class UiBinderUtil {
-
- /**
- * A helper class to enable lazy creation of DOM elements.
- */
- public static class LazyDomElement {
-
- private Element element;
- private final String domId;
-
- public LazyDomElement(String domId) {
- this.domId = domId;
- }
-
- public Element get() {
- if (element == null) {
- element = Document.get().getElementById(domId).cast();
- element.removeAttribute("id");
- }
- return element;
- }
- }
/**
* Temporary attachment record that keeps track of where an element was
=======================================
---
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetInterpreter.java
Wed Apr 27 13:54:04 2011
+++
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetInterpreter.java
Tue May 3 08:15:07 2011
@@ -16,9 +16,9 @@
package com.google.gwt.uibinder.elementparsers;
import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.uibinder.client.UiBinderUtil.LazyDomElement;
import com.google.gwt.uibinder.rebind.FieldManager;
import com.google.gwt.uibinder.rebind.FieldWriter;
+import com.google.gwt.uibinder.client.LazyDomElement;
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;
@@ -97,8 +97,8 @@
// Register a DOM id field.
String lazyDomElementPath = LazyDomElement.class.getCanonicalName();
FieldWriter elementWriter =
fieldManager.registerField(lazyDomElementPath, elementPointer);
- elementWriter.setInitializer(String.format("new %s(%s)",
- lazyDomElementPath,
fieldManager.convertFieldToGetter(idHolder)));
+ elementWriter.setInitializer(String.format("new %s<Element>(%s)",
+ lazyDomElementPath,
fieldManager.convertFieldToGetter(idHolder)));
// Add attach/detach sections for this element.
fieldWriter.addAttachStatement("%s.get();",
=======================================
---
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetPlaceholderInterpreter.java
Wed Apr 27 13:54:04 2011
+++
/trunk/user/src/com/google/gwt/uibinder/elementparsers/WidgetPlaceholderInterpreter.java
Tue May 3 08:15:07 2011
@@ -18,9 +18,9 @@
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.uibinder.client.UiBinderUtil.LazyDomElement;
import com.google.gwt.uibinder.rebind.FieldManager;
import com.google.gwt.uibinder.rebind.FieldWriter;
+import com.google.gwt.uibinder.client.LazyDomElement;
import com.google.gwt.uibinder.rebind.UiBinderWriter;
import com.google.gwt.uibinder.rebind.XMLElement;
import com.google.gwt.uibinder.rebind.messages.MessageWriter;
@@ -131,7 +131,7 @@
String elementPointer = idHolder + "Element";
FieldWriter elementWriter = fieldManager.registerField(
lazyDomElementPath, elementPointer);
- elementWriter.setInitializer(String.format("new %s(%s)",
+ elementWriter.setInitializer(String.format("new %s<Element>(%s)",
lazyDomElementPath,
fieldManager.convertFieldToGetter(idHolder)));
// Add attach/detach sections for this element.
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/FieldManager.java Mon
May 2 12:52:38 2011
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/FieldManager.java Tue
May 3 08:15:07 2011
@@ -21,6 +21,7 @@
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.uibinder.rebind.model.ImplicitCssResource;
+import com.google.gwt.uibinder.rebind.model.OwnerField;
import com.google.gwt.uibinder.rebind.model.OwnerClass;
import java.util.Arrays;
@@ -209,6 +210,27 @@
types.findType(String.class.getCanonicalName()), cssResource,
logger);
return registerField(cssResource.getName(), field);
}
+
+ /**
+ * Register a new field for {@link
com.google.gwt.uibinder.client.LazyDomElement}
+ * types. LazyDomElement fields can only be associated with html
elements. Example:
+ *
+ * <li>LazyDomElement<DivElement> -> <div></li>
+ * <li>LazyDomElement<Element> -> <div></li>
+ * <li>LazyDomElement<SpanElement> -> <span></li>
+ *
+ * @param templateFieldType the html type to bind, eg, SpanElement,
DivElement, etc
+ * @param ownerField the field instance
+ */
+ public FieldWriter registerFieldForLazyDomElement(JClassType
templateFieldType,
+ OwnerField ownerField) throws UnableToCompleteException {
+ if (ownerField == null) {
+ throw new RuntimeException("Cannot register a null owner field for
LazyDomElement.");
+ }
+ FieldWriter field = new FieldWriterOfLazyDomElement(
+ templateFieldType, ownerField, logger);
+ return registerField(ownerField.getName(), field);
+ }
/**
* Used to declare fields of a type (other than CssResource) that is to
be
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/FieldWriterType.java Mon
May 2 12:52:38 2011
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/FieldWriterType.java Tue
May 3 08:15:07 2011
@@ -21,9 +21,10 @@
*/
enum FieldWriterType {
- GENERATED_BUNDLE(4),
- GENERATED_CSS(3),
- IMPORTED(2), // ui:with clauses.
+ GENERATED_BUNDLE(5),
+ GENERATED_CSS(4),
+ IMPORTED(3), // ui:with clauses.
+ DOM_ID_HOLDER(2),
DEFAULT(1);
/**
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Mon
May 2 12:52:38 2011
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Tue
May 3 08:15:07 2011
@@ -25,8 +25,8 @@
import com.google.gwt.uibinder.attributeparsers.AttributeParsers;
import com.google.gwt.uibinder.attributeparsers.BundleAttributeParser;
import com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers;
+import com.google.gwt.uibinder.client.LazyDomElement;
import com.google.gwt.uibinder.client.UiBinder;
-import com.google.gwt.uibinder.client.UiBinderUtil.LazyDomElement;
import com.google.gwt.uibinder.elementparsers.AttributeMessageParser;
import com.google.gwt.uibinder.elementparsers.BeanParser;
import com.google.gwt.uibinder.elementparsers.ElementParser;
@@ -198,6 +198,8 @@
private final JClassType attachableClassType;
+ private final JClassType lazyDomElementClass;
+
private final OwnerClass ownerClass;
private final FieldManager fieldManager;
@@ -279,6 +281,7 @@
uiOwnerType = typeArgs[1];
attachableClassType =
oracle.findType(Attachable.class.getCanonicalName());
+ lazyDomElementClass =
oracle.findType(LazyDomElement.class.getCanonicalName());
ownerClass = new OwnerClass(uiOwnerType, logger, uiBinderCtx);
bundleClass = new
ImplicitClientBundle(baseClass.getPackage().getName(),
@@ -373,13 +376,26 @@
if (useLazyWidgetBuilders) {
// Create and initialize the dom field with LazyDomElement.
FieldWriter field = fieldManager.require(fieldName);
- field.setInitializer(formatCode("new %s(%s).get().cast()",
- LazyDomElement.class.getCanonicalName(),
- fieldManager.convertFieldToGetter(name)));
-
- // The dom must be created by its ancestor.
- fieldManager.require(ancestorField).addAttachStatement(
- fieldManager.convertFieldToGetter(fieldName) + ";");
+
+ /**
+ * But if the owner field is an instance of LazyDomElement then the
code
+ * can be optimized, no cast is needed and the getter doesn't need
to be
+ * called in its ancestral.
+ */
+ if (isOwnerFieldLazyDomElement(fieldName)) {
+ field.setInitializer(formatCode("new %s(%s)",
+ field.getQualifiedSourceName(),
+ fieldManager.convertFieldToGetter(name)));
+ } else {
+
+ field.setInitializer(formatCode("new %s(%s).get().cast()",
+ LazyDomElement.class.getCanonicalName(),
+ fieldManager.convertFieldToGetter(name)));
+
+ // The dom must be created by its ancestor.
+ fieldManager.require(ancestorField).addAttachStatement(
+ fieldManager.convertFieldToGetter(fieldName) + ";");
+ }
} else {
setFieldInitializer(fieldName, "null");
addInitStatement(
@@ -399,7 +415,7 @@
*/
public String declareDomIdHolder() throws UnableToCompleteException {
String domHolderName = "domId" + domId++;
- FieldWriter domField = fieldManager.registerField(
+ FieldWriter domField =
fieldManager.registerField(FieldWriterType.DOM_ID_HOLDER,
oracle.findType(String.class.getName()), domHolderName);
domField.setInitializer("com.google.gwt.dom.client.Document.get().createUniqueId()");
@@ -442,7 +458,16 @@
throws UnableToCompleteException {
String fieldName = getFieldName(elem);
if (fieldName != null) {
- fieldManager.registerField(findFieldType(elem), fieldName);
+
+ /**
+ * We can switch types if useLazyWidgetBuilders is enabled and the
+ * respective owner field is a LazyDomElement.
+ */
+ if (useLazyWidgetBuilders && isOwnerFieldLazyDomElement(fieldName)) {
+ fieldManager.registerFieldForLazyDomElement(findFieldType(elem),
ownerClass.getUiField(fieldName));
+ } else {
+ fieldManager.registerField(findFieldType(elem), fieldName);
+ }
}
return fieldName;
}
@@ -672,6 +697,18 @@
String uri = elem.getNamespaceUri();
return uri != null && UiBinderGenerator.BINDER_URI.equals(uri);
}
+
+ /**
+ * Checks whether the given owner field name is a LazyDomElement or not.
+ */
+ public boolean isOwnerFieldLazyDomElement(String fieldName) {
+ OwnerField ownerField = ownerClass.getUiField(fieldName);
+ if (ownerField == null) {
+ return false;
+ }
+
+ return
lazyDomElementClass.isAssignableFrom(ownerField.getType().getRawType());
+ }
public boolean isWidgetElement(XMLElement elem) {
String uri = elem.getNamespaceUri();
=======================================
--- /trunk/user/src/com/google/gwt/uibinder/rebind/model/OwnerField.java
Thu Sep 9 08:24:17 2010
+++ /trunk/user/src/com/google/gwt/uibinder/rebind/model/OwnerField.java
Tue May 3 08:15:07 2011
@@ -74,6 +74,14 @@
public String getName() {
return name;
}
+
+ /**
+ * Gets the type associated with this field.
+ */
+ public JClassType getRawType() {
+ // This shorten getType().getRawType() and make tests easier.
+ return getType().getRawType();
+ }
/**
* Returns a descriptor for the type of the field.
=======================================
--- /trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java Fri Apr
22 09:21:14 2011
+++ /trunk/user/test/com/google/gwt/uibinder/UiBinderJreSuite.java Tue May
3 08:15:07 2011
@@ -45,7 +45,9 @@
import com.google.gwt.uibinder.elementparsers.HasTreeItemsParserTest;
import com.google.gwt.uibinder.elementparsers.UIObjectParserTest;
import com.google.gwt.uibinder.rebind.DesignTimeUtilsTest;
+import com.google.gwt.uibinder.rebind.FieldWriterOfExistingTypeTest;
import
com.google.gwt.uibinder.rebind.FieldWriterOfGeneratedCssResourceTest;
+import com.google.gwt.uibinder.rebind.FieldWriterOfLazyDomElementTest;
import com.google.gwt.uibinder.rebind.GwtResourceEntityResolverTest;
import com.google.gwt.uibinder.rebind.HandlerEvaluatorTest;
import com.google.gwt.uibinder.rebind.TokenatorTest;
@@ -66,7 +68,9 @@
TestSuite suite = new TestSuite("UiBinder tests that require the JRE");
// rebind
+ suite.addTestSuite(FieldWriterOfExistingTypeTest.class);
suite.addTestSuite(FieldWriterOfGeneratedCssResourceTest.class);
+ suite.addTestSuite(FieldWriterOfLazyDomElementTest.class);
suite.addTestSuite(GwtResourceEntityResolverTest.class);
suite.addTestSuite(HandlerEvaluatorTest.class);
suite.addTestSuite(TokenatorTest.class);
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors