Fixes issue where UiRenderer breaks when a field is referenced more than once Review at http://gwt-code-reviews.appspot.com/1525805 Review by: rjrjr@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10541 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java index f858731..7464999 100644 --- a/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java +++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderParser.java
@@ -374,7 +374,7 @@ fieldWriter = fieldManager.registerField( FieldWriterType.IMPORTED, matchingResourceType.getErasedType(), resourceName); - fieldWriter.setInitializer("this." + resourceName); + fieldWriter.setInitializer(UiBinderWriter.RENDER_PARAM_HOLDER_PREFIX + 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 6b3232e..92adea4 100644 --- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java +++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -66,6 +66,9 @@ * Writer for UiBinder generated classes. */ public class UiBinderWriter implements Statements { + + static final String RENDER_PARAM_HOLDER_PREFIX = "_renderer_param_holder_"; + private static final String PACKAGE_URI_SCHEME = "urn:import:"; // TODO(rjrjr) Another place that we need a general anonymous field @@ -1749,7 +1752,8 @@ private void writeRenderParameterDefinitions(IndentedWriter w, JParameter[] renderParameters) { for (int i = 0; i < renderParameters.length; i++) { JParameter parameter = renderParameters[i]; - w.write("private %s %s;", parameter.getType().getQualifiedSourceName(), parameter.getName()); + w.write("private %s %s%s;", parameter.getType().getQualifiedSourceName(), + RENDER_PARAM_HOLDER_PREFIX, parameter.getName()); w.newline(); } } @@ -1757,7 +1761,7 @@ private void writeRenderParameterInitializers(IndentedWriter w, JParameter[] renderParameters) { for (int i = 0; i < renderParameters.length; i++) { JParameter parameter = renderParameters[i]; - w.write("this.%s = %s;", parameter.getName(), parameter.getName()); + w.write("%s%s = %s;", RENDER_PARAM_HOLDER_PREFIX, 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 8e4e6b0..33d7a81 100644 --- a/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java +++ b/user/test/com/google/gwt/uibinder/test/client/UiRendererTest.java
@@ -30,6 +30,7 @@ public class UiRendererTest extends GWTTestCase { private static final String RENDERED_VALUE = "bar"; + private static final String RENDERED_VALUE_TWICE = "quux"; private DivElement docDiv; private SafeHtml renderedHtml; @@ -46,7 +47,7 @@ super.gwtSetUp(); UiRendererTestApp app = UiRendererTestApp.getInstance(); safeHtmlUi = app.getSafeHtmlUi(); - renderedHtml = safeHtmlUi.render(RENDERED_VALUE); + renderedHtml = safeHtmlUi.render(RENDERED_VALUE, RENDERED_VALUE_TWICE); renderer = safeHtmlUi.getRenderer(); docDiv = Document.get().createDivElement(); @@ -66,7 +67,7 @@ // Get nameSpan SpanElement nameSpan = renderer.getNameSpan(docDiv); - assertSpanContainsRenderedValueText(nameSpan.getFirstChild()); + assertSpanContainsRenderedValueText(RENDERED_VALUE, nameSpan.getFirstChild()); // Getters also work from the root element DivElement root2 = renderer.getRoot(root); @@ -74,7 +75,7 @@ assertNotNull(root2); assertSpanContainsRenderedValue(root2); nameSpan = renderer.getNameSpan(root); - assertSpanContainsRenderedValueText(nameSpan.getFirstChild()); + assertSpanContainsRenderedValueText(RENDERED_VALUE, nameSpan.getFirstChild()); } public void testFieldGettersDetachedRoot() { @@ -197,7 +198,7 @@ // In prod mode we avoid checking for being the only child assertTrue(renderer.isParentOrRenderer(docDiv)); SpanElement nameSpan = renderer.getNameSpan(docDiv); - assertSpanContainsRenderedValueText(nameSpan.getFirstChild()); + assertSpanContainsRenderedValueText(RENDERED_VALUE, nameSpan.getFirstChild()); } else { // in dev mode an explicit check is made assertFalse(renderer.isParentOrRenderer(docDiv)); @@ -237,6 +238,14 @@ assertEquals(Node.ELEMENT_NODE, spanNode.getNodeType()); assertEquals("span", spanNode.getNodeName().toLowerCase()); assertFalse(spanNode.hasChildNodes()); + + // Field passed to render() and used twice was rendered correctly too + Node spanNode2 = innerDiv.getChild(5); + assertEquals(Node.ELEMENT_NODE, spanNode2.getNodeType()); + assertEquals("span", spanNode2.getNodeName().toLowerCase()); + assertTrue(spanNode2.hasChildNodes()); + assertSpanContainsRenderedValueText(RENDERED_VALUE_TWICE + RENDERED_VALUE_TWICE, + spanNode2.getFirstChild()); } @Override @@ -251,11 +260,11 @@ assertEquals("span", firstFieldNode.getNodeName().toLowerCase()); assertTrue(firstFieldNode.hasChildNodes()); Node renderedValue = firstFieldNode.getFirstChild(); - assertSpanContainsRenderedValueText(renderedValue); + assertSpanContainsRenderedValueText(RENDERED_VALUE, renderedValue); } - private void assertSpanContainsRenderedValueText(Node renderedValue) { + private void assertSpanContainsRenderedValueText(String expectedValue, Node renderedValue) { assertEquals(Node.TEXT_NODE, renderedValue.getNodeType()); - assertEquals(RENDERED_VALUE, renderedValue.getNodeValue()); + assertEquals(expectedValue, renderedValue.getNodeValue()); } }
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 5127079..902724a 100644 --- a/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java +++ b/user/test/com/google/gwt/uibinder/test/client/UiRendererUi.java
@@ -72,7 +72,7 @@ Element getTmElement(Element owner); TableRowElement getTr(Element owner); - void render(SafeHtmlBuilder sb, Foo aValue); + void render(SafeHtmlBuilder sb, Foo aValue, Foo aValueTwice); } private static final HtmlRenderer renderer = GWT.create(HtmlRenderer.class); @@ -84,9 +84,9 @@ public UiRendererUi() { } - public SafeHtml render(String value) { + public SafeHtml render(String value, String valueTwice) { SafeHtmlBuilder sb = new SafeHtmlBuilder(); - getRenderer().render(sb, new Foo(value)); + getRenderer().render(sb, new Foo(value), new Foo(valueTwice)); return sb.toSafeHtml(); } }
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 e5e228c..2634254 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
@@ -17,13 +17,14 @@ > <ui:with field="constants" type="com.google.gwt.uibinder.test.client.Constants"/> <ui:with field="aValue"/> + <ui:with field="aValueTwice"/> <div ui:field='root' res:class="style.bodyColor style.bodyFont" title="The title of this div is localizable"> <ui:attribute name='title'/> <span><ui:text from="{constants.getText}" /></span> Hello, <span ui:field="nameSpan"><ui:text from="{aValue.getBar}"/></span>. <ui:msg>How goes it?</ui:msg> - <span/> + <span/><span><ui:text from="{aValueTwice.getBar}{aValueTwice.getBar}"/></span> <h2 res:class="style.bodyColor style.bodyFont">Placeholders in localizables</h2> <p><ui:msg>When you mark up your text for translation, there will be bits that you don't want the translators to mess with. You can protect