Fixes an unreleased bug where RPC could generate a proxy that contained duplicate create* methods; one for a generic type and a separate one for its corresponding raw type.

STOB no longer special cases generic types in the closure computation.  It simply converts any generic type into its corresponding raw type after the closure is computed.

Patch by: mmendez
Review by: scottb (TBR)

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1676 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
index 6d05759..9fcb128 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleBuilder.java
@@ -330,6 +330,16 @@
   }
 
   /**
+   * Compares {@link JClassType}s according to their qualified source names.
+   */
+  private static final Comparator<JClassType> JCLASS_TYPE_COMPARATOR = new Comparator<JClassType>() {
+    public int compare(JClassType t1, JClassType t2) {
+      return t1.getQualifiedSourceName().compareTo(
+          t2.getQualifiedSourceName());
+    }
+  };
+
+  /**
    * Finds the custom field serializer for a given type.
    * 
    * @param typeOracle
@@ -496,14 +506,15 @@
     return isSpeculative ? TreeLogger.WARN : TreeLogger.ERROR;
   }
 
-  private static void logSerializableTypes(TreeLogger logger, JType[] types) {
+  private static void logSerializableTypes(TreeLogger logger,
+      Set<JClassType> fieldSerializableTypes) {
     TreeLogger localLogger = logger.branch(TreeLogger.DEBUG, "Identified "
-        + types.length + " serializable type"
-        + ((types.length == 1) ? "" : "s"), null);
+        + fieldSerializableTypes.size() + " serializable type"
+        + ((fieldSerializableTypes.size() == 1) ? "" : "s"), null);
 
-    for (int i = 0; i < types.length; ++i) {
+    for (JClassType fieldSerializableType : fieldSerializableTypes) {
       localLogger.branch(TreeLogger.DEBUG,
-          types[i].getParameterizedQualifiedSourceName(), null);
+          fieldSerializableType.getParameterizedQualifiedSourceName(), null);
     }
   }
 
@@ -660,8 +671,12 @@
       }
     }
 
-    Set<JClassType> possiblyInstantiatedTypes = new HashSet<JClassType>();
-    List<JClassType> serializableTypesList = new ArrayList<JClassType>();
+    Set<JClassType> possiblyInstantiatedTypes = new TreeSet<JClassType>(
+        JCLASS_TYPE_COMPARATOR);
+
+    Set<JClassType> fieldSerializableTypes = new TreeSet<JClassType>(
+        JCLASS_TYPE_COMPARATOR);
+
     for (TypeInfoComputed tic : typeToTypeInfoComputed.values()) {
       JClassType type = tic.getType();
 
@@ -678,6 +693,8 @@
       // Only record real types
       if (type.isParameterized() != null) {
         type = type.isParameterized().getRawType();
+      } else if (type.isGenericType() != null) {
+        type = type.isGenericType().getRawType();
       }
 
       if (tic.isInstantiable()) {
@@ -685,24 +702,13 @@
       }
 
       if (tic.isFieldSerializable()) {
-        serializableTypesList.add(type);
+        fieldSerializableTypes.add(type);
       }
     }
 
-    JClassType[] serializableTypes = new JClassType[serializableTypesList.size()];
-    serializableTypesList.toArray(serializableTypes);
+    logSerializableTypes(logger, fieldSerializableTypes);
 
-    Arrays.sort(serializableTypes, new Comparator<JType>() {
-      public int compare(JType o1, JType o2) {
-        String n1 = o1.getQualifiedSourceName();
-        String n2 = o2.getQualifiedSourceName();
-        return n1.compareTo(n2);
-      }
-    });
-
-    logSerializableTypes(logger, serializableTypes);
-
-    return new SerializableTypeOracleImpl(typeOracle, serializableTypes,
+    return new SerializableTypeOracleImpl(typeOracle, fieldSerializableTypes,
         possiblyInstantiatedTypes);
   }
 
@@ -947,10 +953,6 @@
     assert (type instanceof JClassType);
 
     JClassType classType = (JClassType) type;
-    if (classType.isGenericType() != null) {
-      // Treat generic types as raw types.
-      classType = classType.isGenericType().getRawType();
-    }
 
     TreeLogger localLogger = logger.branch(TreeLogger.DEBUG,
         classType.getParameterizedQualifiedSourceName(), null);
diff --git a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleImpl.java b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleImpl.java
index efe05a9..faf66dc 100644
--- a/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleImpl.java
+++ b/user/src/com/google/gwt/user/rebind/rpc/SerializableTypeOracleImpl.java
@@ -26,13 +26,11 @@
 
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.TreeSet;
 import java.util.zip.CRC32;
 
 final class SerializableTypeOracleImpl implements SerializableTypeOracle {
@@ -43,12 +41,6 @@
     }
   };
 
-  private static final Comparator<JType> TYPE_COMPARATOR = new Comparator<JType>() {
-    public int compare(JType t1, JType t2) {
-      return t1.getParameterizedQualifiedSourceName().compareTo(
-          t2.getParameterizedQualifiedSourceName());
-    }
-  };
   private static final String GENERATED_FIELD_SERIALIZER_SUFFIX = "_FieldSerializer";
   private static final String TYPE_SERIALIZER_SUFFIX = "_TypeSerializer";
   private static final Set<String> TYPES_WHOSE_IMPLEMENTATION_IS_EXCLUDED_FROM_SIGNATURES = new HashSet<String>();
@@ -73,10 +65,9 @@
   private final Set<JClassType> possiblyInstantiatedTypes;
 
   public SerializableTypeOracleImpl(TypeOracle typeOracle,
-      JClassType[] serializableTypes, Set<JClassType> possiblyInstantiatedTypes) {
+      Set<JClassType> serializableTypes, Set<JClassType> possiblyInstantiatedTypes) {
 
-    serializableTypesSet = new TreeSet<JClassType>(TYPE_COMPARATOR);
-    serializableTypesSet.addAll(Arrays.asList(serializableTypes));
+    serializableTypesSet = serializableTypes;
     this.typeOracle = typeOracle;
 
     this.possiblyInstantiatedTypes = possiblyInstantiatedTypes;