In UiBinder, when referring to a component that extends a base UI object, the
base type is used for the generated Java declaration, resulting in a type
mismatch when the field is initialized with the more specific type.

This problem occurs because the custom UiBinder element parsers pass the type of
the associated base class into the UiBinderWriter.

The attached patch changes the implementation of
UiBinderWriter#setFieldInitializerAsConstructor() to look up the more specific
class name for the field as it was declared in the UiBinder markup, instead of
taking the one passed to it by the base class parser.  Since this change renders
the type parameter unused, the patch also removes the parameter from the
function declaration and all of its invocations.

GWT issue #4342
Review by rjrjr at http://gwt-code-reviews.appspot.com/1556806/

Review by: rchandia@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10697 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java b/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
index e2ba793..5e1e6a0 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/BeanParser.java
@@ -192,7 +192,7 @@
         }
         writer.setFieldInitializer(fieldName, initializer);
       } else { // Annotated Constructor
-        writer.setFieldInitializerAsConstructor(fieldName, type, args);
+        writer.setFieldInitializerAsConstructor(fieldName, args);
       }
     }
 
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java
index cb0b04a..9959d78 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/DateLabelParser.java
@@ -48,7 +48,7 @@
         String timeZone = (supportsTimeZone ? consumeTimeZone(elem, writer)
             : null);
 
-        writer.setFieldInitializerAsConstructor(fieldName, type, makeArgs(
+        writer.setFieldInitializerAsConstructor(fieldName, makeArgs(
             format, timeZone));
       } else if (supportsTimeZone && hasTimeZone(elem)) {
         writer.die(elem, NO_TIMEZONE_WITHOUT_SPECIFIED_FORMAT);
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java b/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
index 211aa80..e4367d4 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/DialogBoxParser.java
@@ -133,12 +133,9 @@
         String fieldElement = writer.parseElementToField(customCaption);
 
         writer.setFieldInitializerAsConstructor(fieldName,
-            writer.getOracle().findType(DialogBox.class.getCanonicalName()),
             autoHide, modal, fieldElement);
       } else {
-        writer.setFieldInitializerAsConstructor(fieldName,
-          writer.getOracle().findType(DialogBox.class.getCanonicalName()),
-          autoHide, modal);
+        writer.setFieldInitializerAsConstructor(fieldName, autoHide, modal);
       }
     }
   }
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
index 156828a..7b98f84 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/DockLayoutPanelParser.java
@@ -22,14 +22,13 @@
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLElement;
-import com.google.gwt.user.client.ui.DockLayoutPanel;
 import com.google.gwt.user.client.ui.SplitLayoutPanel;
 
 import java.util.HashMap;
 import java.util.Map;
 
 /**
- * Parses {@link DockLayoutPanel} widgets.
+ * Parses {@link com.google.gwt.user.client.ui.DockLayoutPanel} widgets.
  * 
  * TODO(jgw): The code that explicitly excludes SplitLayoutPanel in a fairly
  * awkward way could be greatly simplified if we hoisted the "dock-ness" into an
@@ -71,8 +70,7 @@
       String unit = elem.consumeAttributeWithDefault("unit",
           String.format("%s.%s", unitEnumType.getQualifiedSourceName(), "PX"),
           unitEnumType);
-      writer.setFieldInitializerAsConstructor(fieldName,
-          writer.getOracle().findType(DockLayoutPanel.class.getName()), unit);
+      writer.setFieldInitializerAsConstructor(fieldName, unit);
     }
 
     CenterChild center = null;
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/HTMLPanelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/HTMLPanelParser.java
index 7ab49b0..f5e8754 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/HTMLPanelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/HTMLPanelParser.java
@@ -67,10 +67,10 @@
     String customTag = elem.consumeStringAttribute("tag", null);
 
     if (null == customTag) {
-      writer.setFieldInitializerAsConstructor(fieldName, type,
+      writer.setFieldInitializerAsConstructor(fieldName,
           writer.declareTemplateCall(html, fieldName));
     } else {
-      writer.setFieldInitializerAsConstructor(fieldName, type, customTag,
+      writer.setFieldInitializerAsConstructor(fieldName, customTag,
           writer.declareTemplateCall(html, fieldName));
     }
   }
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java b/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java
index 55d27fc..9698da9 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/ImageParser.java
@@ -35,7 +35,7 @@
     if (hasImageResourceConstructor(writer.getOracle(), type)) {
       String resource = elem.consumeImageResourceAttribute("resource");
       if (null != resource) {
-        writer.setFieldInitializerAsConstructor(fieldName, type, resource);
+        writer.setFieldInitializerAsConstructor(fieldName, resource);
       }
     }
   }
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/MenuBarParser.java b/user/src/com/google/gwt/uibinder/elementparsers/MenuBarParser.java
index d4c3167..b63c9f7 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/MenuBarParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/MenuBarParser.java
@@ -36,8 +36,7 @@
     if (MenuBar.class.getName().equals(type.getQualifiedSourceName())) {
       if (elem.hasAttribute("vertical")) {
         String vertical = elem.consumeBooleanAttribute("vertical");
-        writer.setFieldInitializerAsConstructor(fieldName,
-            writer.getOracle().findType(MenuBar.class.getName()), vertical);
+        writer.setFieldInitializerAsConstructor(fieldName, vertical);
       }
     }
 
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/MenuItemParser.java b/user/src/com/google/gwt/uibinder/elementparsers/MenuItemParser.java
index 82385ca..71bb725 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/MenuItemParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/MenuItemParser.java
@@ -34,8 +34,7 @@
     // Use special initializer for standard MenuItem,
     // custom subclass should have default constructor.
     if (MenuItem.class.getName().equals(type.getQualifiedSourceName())) {
-      writer.setFieldInitializerAsConstructor(fieldName,
-          writer.getOracle().findType(MenuItem.class.getName()), "\"\"",
+      writer.setFieldInitializerAsConstructor(fieldName, "\"\"",
           "(com.google.gwt.user.client.Command) null");
     }
 
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java
index 01b4002..6b02d86 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/NumberLabelParser.java
@@ -58,7 +58,7 @@
       String format = consumeFormat(elem, writer);
 
       if (format != null) {
-        writer.setFieldInitializerAsConstructor(fieldName, type, format);
+        writer.setFieldInitializerAsConstructor(fieldName, format);
       }
     }
   }
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/RenderablePanelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/RenderablePanelParser.java
index 7292162..47c8bfc 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/RenderablePanelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/RenderablePanelParser.java
@@ -85,7 +85,7 @@
           "RenderablePanel does not support custom root elements yet.");
     }
 
-    writer.setFieldInitializerAsConstructor(fieldName, type, writer.declareTemplateCall(html,
+    writer.setFieldInitializerAsConstructor(fieldName, writer.declareTemplateCall(html,
         fieldName));
   }
 
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
index 00f3ffb..0726b4f 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
@@ -21,10 +21,9 @@
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLElement;
-import com.google.gwt.user.client.ui.StackLayoutPanel;
 
 /**
- * Parses {@link StackLayoutPanel} widgets.
+ * Parses {@link com.google.gwt.user.client.ui.StackLayoutPanel} widgets.
  */
 public class StackLayoutPanelParser implements ElementParser {
   private static class Children {
@@ -46,8 +45,7 @@
         String.format("%s.%s", unitEnumType.getQualifiedSourceName(), "PX"),
         unitEnumType);
 
-    writer.setFieldInitializerAsConstructor(fieldName,
-        writer.getOracle().findType(StackLayoutPanel.class.getName()), unit);
+    writer.setFieldInitializerAsConstructor(fieldName, unit);
 
     // Parse children.
     for (XMLElement stackElem : panelElem.consumeChildElements()) {
diff --git a/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java b/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
index 0eceec0..b77534f 100644
--- a/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
+++ b/user/src/com/google/gwt/uibinder/elementparsers/TabLayoutPanelParser.java
@@ -21,10 +21,9 @@
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
 import com.google.gwt.uibinder.rebind.XMLElement;
-import com.google.gwt.user.client.ui.TabLayoutPanel;
 
 /**
- * Parses {@link TabLayoutPanel} widgets.
+ * Parses {@link com.google.gwt.user.client.ui.TabLayoutPanel} widgets.
  */
 public class TabLayoutPanelParser implements ElementParser {
 
@@ -50,8 +49,7 @@
         String.format("%s.%s", unitEnumType.getQualifiedSourceName(), "PX"),
         unitEnumType);
 
-    writer.setFieldInitializerAsConstructor(fieldName,
-        writer.getOracle().findType(TabLayoutPanel.class.getName()), size, unit);
+    writer.setFieldInitializerAsConstructor(fieldName, size, unit);
 
     // Parse children.
     for (XMLElement tabElem : panelElem.consumeChildElements()) {
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
index c9e873c..0a9e0dc 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java
@@ -982,8 +982,9 @@
    * @param type the type of the field
    * @param args arguments to the constructor call
    */
-  public void setFieldInitializerAsConstructor(String fieldName, JClassType type, String... args) {
-    setFieldInitializer(fieldName, formatCode("new %s(%s)", type.getQualifiedSourceName(),
+  public void setFieldInitializerAsConstructor(String fieldName, String... args) {
+    JClassType assignableType = fieldManager.lookup(fieldName).getAssignableType();
+    setFieldInitializer(fieldName, formatCode("new %s(%s)", assignableType.getQualifiedSourceName(),
         asCommaSeparatedList(args)));
   }