Revision: 6670
Author: b...@google.com
Date: Wed Nov  4 13:19:43 2009
Log: Fix generic parameters for SingleJsoImpl types.

Patch by: bobv
Review by: spoon
http://code.google.com/p/google-web-toolkit/source/detail?r=6670

Modified:
  /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
  /trunk/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java      
 
Wed Nov  4 13:19:11 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java      
 
Wed Nov  4 13:19:43 2009
@@ -539,11 +539,6 @@
            String mangledName = getBinaryName(type).replace('.', '_') + "_"
                + intfMethod.getName();
            mangledNames.add(mangledName);
-
-          JType[] parameterTypes = new  
JType[intfMethod.getParameters().length];
-          for (int i = 0; i < parameterTypes.length; i++) {
-            parameterTypes[i] = intfMethod.getParameters()[i].getType();
-          }

            /*
             * Handle virtual overrides by finding the method that we would
@@ -551,8 +546,8 @@
             * target.
             */
            JMethod implementingMethod;
-          while ((implementingMethod = implementingType.findMethod(
-              intfMethod.getName(), parameterTypes)) == null) {
+          while ((implementingMethod = findOverloadUsingErasure(
+              implementingType, intfMethod)) == null) {
              implementingType = implementingType.getSuperclass();
            }
            // implementingmethod and implementingType cannot be null here
@@ -566,11 +561,11 @@
             * This must be kept in sync with the WriteJsoImpl class.
             */
            {
-            String decl =  
getBinaryOrPrimitiveName(intfMethod.getReturnType())
+            String decl =  
getBinaryOrPrimitiveName(intfMethod.getReturnType().getErasedType())
                  + " " + intfMethod.getName() + "(";
-            for (JType paramType : parameterTypes) {
+            for (JParameter param : intfMethod.getParameters()) {
                decl += ",";
-              decl += getBinaryOrPrimitiveName(paramType);
+              decl +=  
getBinaryOrPrimitiveName(param.getType().getErasedType());
              }
              decl += ")";

@@ -587,14 +582,14 @@
             * This must be kept in sync with the WriteJsoImpl class.
             */
            {
-            String returnName =  
getBinaryOrPrimitiveName(implementingMethod.getReturnType());
+            String returnName =  
getBinaryOrPrimitiveName(implementingMethod.getReturnType().getErasedType());
              String jsoName = getBinaryOrPrimitiveName(implementingType);

              String decl = returnName + " " + intfMethod.getName() + "$ ("
                  + jsoName;
-            for (JType paramType : parameterTypes) {
+            for (JParameter param : implementingMethod.getParameters()) {
                decl += ",";
-              decl += getBinaryOrPrimitiveName(paramType);
+              decl +=  
getBinaryOrPrimitiveName(param.getType().getErasedType());
              }
              decl += ")";

@@ -648,6 +643,34 @@
          }
        }
      }
+
+    /**
+     * Looks for a concrete implementation of <code>intfMethod</code> in
+     * <code>implementingType</code>.
+     */
+    private JMethod findOverloadUsingErasure(JClassType implementingType,
+        JMethod intfMethod) {
+
+      int numParams = intfMethod.getParameters().length;
+      JType[] erasedTypes = new JType[numParams];
+      for (int i = 0; i < numParams; i++) {
+        erasedTypes[i] =  
intfMethod.getParameters()[i].getType().getErasedType();
+      }
+
+      outer : for (JMethod method :  
implementingType.getOverloads(intfMethod.getName())) {
+        JParameter[] params = method.getParameters();
+        if (params.length != numParams) {
+          continue;
+        }
+        for (int i = 0; i < numParams; i++) {
+          if (params[i].getType().getErasedType() != erasedTypes[i]) {
+            continue outer;
+          }
+        }
+        return method;
+      }
+      return null;
+    }
    }

    /**
=======================================
--- /trunk/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java Wed  
Nov  4 13:19:11 2009
+++ /trunk/user/test/com/google/gwt/dev/jjs/test/SingleJsoImplTest.java Wed  
Nov  4 13:19:43 2009
@@ -19,6 +19,7 @@
  import  
com.google.gwt.dev.jjs.test.SingleJsoImplTest.JsoHasInnerJsoType.InnerType;
  import  
com.google.gwt.dev.jjs.test.jsointfs.JsoInterfaceWithUnreferencedImpl;
  import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.rpc.AsyncCallback;

  import java.io.IOException;

@@ -377,6 +378,32 @@
        return new String[1];
      }
    }
+
+  static class JsoUsesGeneric extends JavaScriptObject implements  
UsesGenerics {
+    public static native <T extends CharSequence> JsoUsesGeneric create()  
/*-{
+      return {suffix : "42"};
+    }-*/;
+
+    protected JsoUsesGeneric() {
+    }
+
+    public final native <T> String acceptsGeneric(T chars) /*-{
+      return chars + this.suffix;
+    }-*/;
+
+    public final native <T> void callback(AsyncCallback<T> callback, T  
chars) /*-{
+       
callba...@com.google.gwt.user.client.rpc.asynccallback::onSuccess(Ljava/lang/Object;)(chars
  
+ this.suffix);
+    }-*/;
+
+    /**
+     * What you're seeing here is would be achieved by an unsafe (T) cast  
and
+     * would break with a ClassCastException if accessed via  
JsoIsGenericFinal
+     * in normal Java.
+     */
+    public final native <T> T returnsGeneric(String chars) /*-{
+      return chars + this.suffix;
+    }-*/;
+  }

    /**
     * Ensure that SingleJsoImpl interfaces can be extended and implemented  
by
@@ -426,7 +453,6 @@
    interface SimpleOnlyJavaInterface {
      String simpleOnlyJava();
    }
-
    interface Tag {
    }

@@ -458,6 +484,14 @@

      String[] returnStringArray();
    }
+
+  interface UsesGenerics {
+    <T extends Object> String acceptsGeneric(T chars);
+
+    <T> void callback(AsyncCallback<T> callback, T chars);
+
+    <T> T returnsGeneric(String chars);
+  }

    private static native JsoAdder makeAdder(int offset) /*-{
      return {offset:offset};
@@ -587,6 +621,20 @@
      assertSame(Adder.SAME_OBJECT, Adder.SAME_OBJECT2);
      assertNotSame(Adder.DIFFERENT_OBJECT, Adder.SAME_OBJECT);
    }
+
+  public void testGenerics() {
+    UsesGenerics j = JsoUsesGeneric.create();
+    assertEquals("Hello42", j.acceptsGeneric("Hello"));
+    assertEquals("Hello42", j.returnsGeneric("Hello"));
+    j.callback(new AsyncCallback<CharSequence>() {
+      public void onFailure(Throwable caught) {
+      }
+
+      public void onSuccess(CharSequence result) {
+        assertEquals("Hello42", result);
+      }
+    }, "Hello");
+  }

    @SuppressWarnings("cast")
    public void testSimpleCase() {

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to