Allows UiRenderer styles before the first call to render()
Fields are initialized both upon construction and on a call to render()
Also ensured that ui:with fields never get optimized as final.
Review at http://gwt-code-reviews.appspot.com/1794803
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11231 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/FieldManager.java b/user/src/com/google/gwt/uibinder/rebind/FieldManager.java
index 6cbc633..706c6ec 100644
--- a/user/src/com/google/gwt/uibinder/rebind/FieldManager.java
+++ b/user/src/com/google/gwt/uibinder/rebind/FieldManager.java
@@ -134,11 +134,27 @@
return fieldName;
}
- int count = getGetterCounter(fieldName) + 1;
- gettersCounter.put(fieldName, count);
+ incrementFieldCounter(fieldName);
return getFieldGetter(fieldName);
}
+ /**
+ * Prevent a field from being optimized as only being referenced once (and therefore constant for
+ * all intents). This is necessary for UiRenderer fields passed as parameters to render() calls.
+ * Those fields are modified every time a template is rendered with the parameter values.
+ */
+ public void disableOptimization(String fieldName) {
+ // TODO(rchandia): This hackish method should go away when the
+ // UiRenderer generator gets separated from the one used for
+ // UiBinder. Fields corresponding to parameters of render() will
+ // not use the initialization generated by the FieldWriter.
+
+ // Incrementing the counter twice ensures no optimization happens.
+ // See AbstractFieldWriter#writeFieldDefinition()
+ incrementFieldCounter(fieldName);
+ incrementFieldCounter(fieldName);
+ }
+
public FieldReference findFieldReference(String expressionIn) {
String expression = expressionIn;
if (useLazyWidgetBuilders) {
@@ -392,6 +408,14 @@
return (count == null) ? 0 : count;
}
+ /**
+ * Increments the number of times a getter for the given field is called.
+ */
+ private void incrementFieldCounter(String fieldName) {
+ int count = getGetterCounter(fieldName) + 1;
+ gettersCounter.put(fieldName, count);
+ }
+
private FieldWriter registerField(String fieldName, FieldWriter field)
throws UnableToCompleteException {
ensureValidity(fieldName);
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
index 9cd10d3..76feb3e 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
@@ -394,7 +394,9 @@
fieldWriter = fieldManager.registerField(
FieldWriterType.IMPORTED, matchingResourceType.getErasedType(), resourceName);
- fieldWriter.setInitializer(UiBinderWriter.RENDER_PARAM_HOLDER_PREFIX + resourceName);
+ // Sets initialization as a NOOP. These fields are set from
+ // parameters passed to UiRenderer#render(), instead.
+ fieldWriter.setInitializer(resourceName);
}
private void createSingleImport(XMLElement elem, JClassType enclosingType,
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index fd6347c..9935863 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -76,8 +76,6 @@
*/
public class UiBinderWriter implements Statements {
- static final String RENDER_PARAM_HOLDER_PREFIX = "_renderer_param_holder_";
-
private static final String SAFE_VAR_PREFIX =
"somethingUnlikelyToCollideWithParamNamesWefio";
@@ -1935,8 +1933,28 @@
w.newline();
JParameter[] renderParameters = findRenderParameters(baseClass);
+ for (JParameter param : renderParameters) {
+ // Prevent fields from render() parameters from being optimized.
+ fieldManager.disableOptimization(param.getName());
+ }
- writeRenderParameterDefinitions(w, renderParameters);
+ // public UiRendererImplClass() {
+ w.write("public %s() {", implClassName);
+ w.indent();
+ w.write("build_fields();");
+ w.outdent();
+ // }
+ w.write("}");
+ w.newline();
+
+ // private build_fields() {
+ w.write("private void build_fields() {");
+ w.indent();
+ fieldManager.initializeWidgetsInnerClass(w, getOwnerClass());
+ w.outdent();
+ // }
+ w.write("}");
+ w.newline();
String renderParameterDeclarations = renderMethodParameters(renderParameters);
w.write("public void render(final %s sb%s%s) {", SafeHtmlBuilder.class.getName(),
@@ -1949,7 +1967,7 @@
w.write("uiId = com.google.gwt.dom.client.Document.get().createUniqueId();");
w.newline();
- fieldManager.initializeWidgetsInnerClass(w, getOwnerClass());
+ w.write("build_fields();");
w.newline();
String safeHtml = rootField.getSafeHtml();
@@ -2245,20 +2263,13 @@
}
}
- private void writeRenderParameterDefinitions(IndentedWriter w, JParameter[] renderParameters) {
- for (int i = 0; i < renderParameters.length; i++) {
- JParameter parameter = renderParameters[i];
- w.write("private %s %s%s;", parameter.getType().getQualifiedSourceName(),
- RENDER_PARAM_HOLDER_PREFIX, parameter.getName());
- w.newline();
- }
- }
-
private void writeRenderParameterInitializers(IndentedWriter w, JParameter[] renderParameters) {
for (int i = 0; i < renderParameters.length; i++) {
JParameter parameter = renderParameters[i];
- w.write("%s%s = %s;", RENDER_PARAM_HOLDER_PREFIX, parameter.getName(), parameter.getName());
- w.newline();
+ if (fieldManager.lookup(parameter.getName()) != null) {
+ w.write("this.%s = %s;", parameter.getName(), parameter.getName());
+ w.newline();
+ }
}
}
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java b/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java
index 0474a0e..b5a5ef5 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java
@@ -256,6 +256,12 @@
assertEquals(renderer.getUiStyle().disabled(), nameSpan.getClassName());
}
+ public void testGetStyleBeforeRender() {
+ HtmlRenderer renderer = GWT.create(HtmlRenderer.class);
+ assertNotNull(renderer.getUiStyle().enabled());
+ assertNotNull(renderer.getUiStyle2().ok());
+ }
+
@Override
protected void gwtTearDown() {
docDiv.removeFromParent();
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java b/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java
index 12a6ebd..c745519 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java
+++ b/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java
@@ -86,10 +86,19 @@
}
/**
+ * Another style defined within the UiBinder file.
+ */
+ public interface UiStyle2 extends CssResource {
+ String ok();
+ String bad();
+ }
+
+ /**
* A UiRinder Cell renderer.
*/
public interface HtmlRenderer extends UiRenderer {
UiStyle getUiStyle();
+ UiStyle2 getUiStyle2();
SpanElement getNameSpan(Element owner);
TableColElement getNarrowColumn(Element owner);
DivElement getRoot(Element owner);
diff --git a/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.ui.xml
index e0eb3ba..8c1ca5c 100644
--- a/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.ui.xml
@@ -21,6 +21,10 @@
.enabled { color:black; }
.disabled { color:gray; }
</ui:style>
+ <ui:style field="uiStyle2" type="com.google.gwt.uibinder.test.client.UiRendererUi.UiStyle2">
+ .ok { color:blue; }
+ .bad { color:red; }
+ </ui:style>
<div ui:field='root' class="{res.style.bodyColor} {res.style.bodyFont}"
title="The title of this div is localizable">