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">