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