Skip to content
This repository was archived by the owner on Sep 26, 2020. It is now read-only.

Commit 4f47fa6

Browse files
author
rluble@google.com
committed
Avoid creating anonymous inner classes with wildcard type parameters.
Under Java 7 wildcards can not be type parameters of superclasses in the extends clause nor superinterfaces in the implementing clause. Anonymous inner classes can not have wildcards in their type parameters. Change-Id: Ifbcd6ecec455512a7da5eb473c6bf2e9f402f0ea Review-Link: https://gwt-review.googlesource.com/#/c/2470/ Review by: goktug@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11596 8db76d5a-ed1c-0410-87a9-c151d255dfc7
1 parent cac9e64 commit 4f47fa6

File tree

6 files changed

+184
-8
lines changed

6 files changed

+184
-8
lines changed

user/src/com/google/gwt/uibinder/rebind/HandlerEvaluator.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,20 @@ protected void writeHandler(IndentedWriter writer, String uiOwner,
200200
}
201201

202202
writer.newline();
203-
writer.write("final %1$s %2$s = new %1$s() {",
204-
handlerType.getParameterizedQualifiedSourceName(), handlerVarName);
203+
// Create the anonymous class extending the raw type to avoid errors under the new JDT
204+
// if the type has a wildcard.
205+
writer.write("final %1$s %2$s = (%1$s) new %3$s() {",
206+
handlerType.getParameterizedQualifiedSourceName(), handlerVarName,
207+
handlerType.getQualifiedSourceName());
205208
writer.indent();
206209
writer.write("public void %1$s(%2$s event) {", methods[0].getName(),
207-
eventType.getParameterizedQualifiedSourceName());
210+
// Use the event raw type to match the signature as we are using implementing the raw type
211+
// interface.
212+
eventType.getQualifiedSourceName());
208213
writer.indent();
209-
writer.write("%1$s.%2$s(event);", uiOwner, boundMethod);
214+
// Cast the event to the parameterized type to avoid warnings..
215+
writer.write("%1$s.%2$s((%3$s) event);", uiOwner, boundMethod,
216+
eventType.getParameterizedQualifiedSourceName());
210217
writer.outdent();
211218
writer.write("}");
212219
writer.outdent();

user/test/com/google/gwt/uibinder/UiBinderSuite.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.gwt.uibinder.test.client.SafeUriIntegrationTest;
2323
import com.google.gwt.uibinder.test.client.UiBinderTest;
2424
import com.google.gwt.uibinder.test.client.UiChildTest;
25+
import com.google.gwt.uibinder.test.client.UiHandlerTest;
2526

2627
import junit.framework.Test;
2728

@@ -39,7 +40,8 @@ public static Test suite() {
3940
suite.addTestSuite(UiBinderTest.class);
4041
suite.addTestSuite(UiBinderUtilTest.class);
4142
suite.addTestSuite(UiChildTest.class);
42-
43+
suite.addTestSuite(UiHandlerTest.class);
44+
4345
return suite;
4446
}
4547

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2013 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.google.gwt.uibinder.test.client;
17+
18+
import com.google.gwt.junit.client.GWTTestCase;
19+
import com.google.gwt.user.client.ui.DockPanel;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
/**
25+
* Functional test for UiHandler
26+
*
27+
* TODO(rluble): add more relevant tests.
28+
*/
29+
public class UiHandlerTest extends GWTTestCase {
30+
private WidgetBasedUi widgetUi;
31+
private DomBasedUi domUi;
32+
private DockPanel root;
33+
34+
@Override
35+
public String getModuleName() {
36+
return "com.google.gwt.uibinder.test.UiBinderSuite";
37+
}
38+
39+
@Override
40+
public void gwtSetUp() throws Exception {
41+
super.gwtSetUp();
42+
UiBinderTestApp app = UiBinderTestApp.getInstance();
43+
widgetUi = app.getWidgetUi();
44+
domUi = app.getDomUi();
45+
root = widgetUi.root;
46+
}
47+
48+
public void testValueChangeEvent() {
49+
widgetUi.valueChangeEvent = null;
50+
widgetUi.myDoubleBox.setValue(0.0);
51+
widgetUi.myDoubleBox.setValue(10.0, true);
52+
assertNotNull(widgetUi.valueChangeEvent);
53+
assertEquals(10.0, widgetUi.valueChangeEvent.getValue());
54+
}
55+
56+
/**
57+
* Tests that the code generated for handling events parametrized by wildcards work.
58+
*/
59+
public void testValueChangeEventWildcardString() {
60+
widgetUi.wildcardValueChangeEventString = null;
61+
widgetUi.myWildcardValueChangeWidgetString.setValue(null);
62+
widgetUi.myWildcardValueChangeWidgetString.setValue("Changed");
63+
assertNotNull(widgetUi.wildcardValueChangeEventString);
64+
assertEquals("Changed", (String) widgetUi.wildcardValueChangeEventString.getValue());
65+
}
66+
67+
/**
68+
* Tests that the code generated for handling events parametrized by wildcards work.
69+
*/
70+
public void testValueChangeEventWildcardList() {
71+
widgetUi.wildcardValueChangeEventList = null;
72+
List<String> newValue = new ArrayList<String>();
73+
newValue.add("Changed");
74+
widgetUi.myWildcardValueChangeWidgetList.setValue(null);
75+
widgetUi.myWildcardValueChangeWidgetList.setValue(newValue);
76+
assertNotNull(widgetUi.wildcardValueChangeEventList);
77+
assertEquals(newValue, widgetUi.wildcardValueChangeEventList.getValue());
78+
}
79+
}

user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.gwt.dom.client.ParagraphElement;
2525
import com.google.gwt.dom.client.SpanElement;
2626
import com.google.gwt.dom.client.TableElement;
27+
import com.google.gwt.event.logical.shared.ValueChangeEvent;
2728
import com.google.gwt.i18n.client.DateTimeFormat;
2829
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
2930
import com.google.gwt.i18n.client.NumberFormat;
@@ -36,12 +37,14 @@
3637
import com.google.gwt.uibinder.client.UiBinder;
3738
import com.google.gwt.uibinder.client.UiFactory;
3839
import com.google.gwt.uibinder.client.UiField;
40+
import com.google.gwt.uibinder.client.UiHandler;
3941
import com.google.gwt.user.client.ui.AbsolutePanel;
4042
import com.google.gwt.user.client.ui.Button;
4143
import com.google.gwt.user.client.ui.Composite;
4244
import com.google.gwt.user.client.ui.DateLabel;
4345
import com.google.gwt.user.client.ui.DisclosurePanel;
4446
import com.google.gwt.user.client.ui.DockPanel;
47+
import com.google.gwt.user.client.ui.DoubleBox;
4548
import com.google.gwt.user.client.ui.Grid;
4649
import com.google.gwt.user.client.ui.HTML;
4750
import com.google.gwt.user.client.ui.HTMLPanel;
@@ -63,6 +66,8 @@
6366
import com.google.gwt.user.client.ui.ValueLabel;
6467
import com.google.gwt.user.client.ui.Widget;
6568

69+
import java.util.List;
70+
6671
/**
6772
* Sample use of a {@code UiBinder} with the com.google.gwt.user Widget set, and
6873
* custom widgets.
@@ -76,7 +81,7 @@ public class WidgetBasedUi extends Composite {
7681
public interface Style extends CssResource {
7782
String menuBar();
7883
}
79-
84+
8085
interface Binder extends UiBinder<Widget, WidgetBasedUi> {
8186
}
8287
static class FakeBundle2 extends FakeBundle {
@@ -85,10 +90,10 @@ static class FakeBundle2 extends FakeBundle {
8590
static class FakeBundle3 extends FakeBundle {
8691
}
8792
private static final Binder binder = GWT.create(Binder.class);
88-
93+
8994
@UiField(provided = true)
9095
final WidgetBasedUiExternalResources external = GWT.create(WidgetBasedUiExternalResources.class);
91-
96+
9297
public static final DateTimeFormat MY_DATE_FORMAT = DateTimeFormat.getFormat(PredefinedFormat.DATE_FULL);
9398
public static final NumberFormat MY_NUMBER_FORMAT = NumberFormat.getDecimalFormat();
9499

@@ -195,11 +200,36 @@ static class FakeBundle3 extends FakeBundle {
195200
@UiField(provided = true) @SuppressWarnings("rawtypes")
196201
Renderer doubleRenderer = DoubleRenderer.instance();
197202
@UiField ValueLabel<Double> myValueLabel;
203+
@UiField DoubleBox myDoubleBox;
204+
@UiField(provided = true)
205+
WildcardValueChangeWidget myWildcardValueChangeWidgetString =
206+
new WildcardValueChangeWidget<String>();
207+
@UiField(provided = true)
208+
WildcardValueChangeWidget myWildcardValueChangeWidgetList =
209+
new WildcardValueChangeWidget<List<?>>();
198210
@UiField ImageElement myImage;
199211
@UiField HTML htmlWithComputedSafeHtml;
200212
@UiField HTML htmlWithComputedText;
201213
@UiField Label labelWithComputedText;
202214

215+
public ValueChangeEvent<Double> valueChangeEvent;
216+
@UiHandler("myDoubleBox")
217+
void onValueChange(ValueChangeEvent<Double> event) {
218+
this.valueChangeEvent = event;
219+
}
220+
221+
public ValueChangeEvent<?> wildcardValueChangeEventString;
222+
@UiHandler("myWildcardValueChangeWidgetString")
223+
void onWildcaredValueChangeString(ValueChangeEvent<?> event) {
224+
this.wildcardValueChangeEventString = event;
225+
}
226+
227+
public ValueChangeEvent<List<?>> wildcardValueChangeEventList;
228+
@UiHandler("myWildcardValueChangeWidgetList")
229+
void onWildcaredValueChangeList(ValueChangeEvent<List<?>> event) {
230+
this.wildcardValueChangeEventList = event;
231+
}
232+
203233
public WidgetBasedUi() {
204234
external.style().ensureInjected();
205235
initWidget(binder.createAndBindUi(this));

user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,10 @@
691691

692692
<gwt3:google.gwt.user.client.ui.ValueLabel ui:field='myValueLabel' renderer='{doubleRenderer}' />
693693

694+
<gwt:DoubleBox ui:field='myDoubleBox' />
695+
<demo:WildcardValueChangeWidget ui:field='myWildcardValueChangeWidgetString' />
696+
<demo:WildcardValueChangeWidget ui:field='myWildcardValueChangeWidgetList' />
697+
694698
<img src="{values.aUrl}" ui:field='myImage'/>
695699

696700
<gwt:HTML ui:field='htmlWithComputedSafeHtml'><ui:safehtml from="{constants.getSafeHtml}" /></gwt:HTML>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2013 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
package com.google.gwt.uibinder.test.client;
17+
18+
import com.google.gwt.dom.client.Document;
19+
import com.google.gwt.event.logical.shared.ValueChangeEvent;
20+
import com.google.gwt.event.logical.shared.ValueChangeHandler;
21+
import com.google.gwt.event.shared.HandlerRegistration;
22+
import com.google.gwt.user.client.ui.FocusWidget;
23+
24+
/**
25+
* A Widget that has an event parametrized by a wildcard.
26+
* Note that parameterizing events by wildcards is not good practice.
27+
*
28+
* @param <T> Type for the value. Note that the addValueChangeHandler does not use <T>, but ?
29+
* instead. (That is exactly what the test is testing).
30+
*/
31+
public class WildcardValueChangeWidget<T> extends FocusWidget {
32+
33+
T myValue;
34+
35+
protected WildcardValueChangeWidget() {
36+
super(Document.get().createDivElement());
37+
}
38+
39+
/**
40+
* Here is the key for the test. ValueChangeHandler is parameterized by ? and not <T>
41+
*/
42+
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<?> handler) {
43+
return addHandler(handler, ValueChangeEvent.getType());
44+
}
45+
46+
public T getValue() {
47+
return myValue;
48+
}
49+
50+
public void setValue(T value) {
51+
myValue = value;
52+
fireEvent(new ValueChangeEvent<T>(value) { });
53+
}
54+
}

0 commit comments

Comments
 (0)