Revision: 7343
Author: [email protected]
Date: Mon Dec 21 10:20:58 2009
Log: Fixes issue 1822.  Arrays now implement Serializable and Cloneable.

Review by: scottb

http://code.google.com/p/google-web-toolkit/source/detail?r=7343

Modified:
  /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
  /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
  /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
  /trunk/user/test/com/google/gwt/dev/jjs/test/ClassCastTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java        Wed Dec 
 9  
09:10:40 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java        Mon Dec 
21  
10:20:58 2009
@@ -71,10 +71,10 @@

    public static final Set<String> INDEX_TYPES_SET = new  
LinkedHashSet<String>(
        Arrays.asList(new String[] {
-          "java.lang.Object", "java.lang.String", "java.lang.Class",
-          "java.lang.CharSequence", "java.lang.Comparable", "java.lang.Enum",
-          "java.lang.Iterable", "java.util.Iterator",
-          "com.google.gwt.core.client.GWT",
+          "java.io.Serializable", "java.lang.Object", "java.lang.String",
+          "java.lang.Class", "java.lang.CharSequence", "java.lang.Cloneable",
+          "java.lang.Comparable", "java.lang.Enum", "java.lang.Iterable",
+          "java.util.Iterator", "com.google.gwt.core.client.GWT",
            "com.google.gwt.core.client.JavaScriptObject",
            "com.google.gwt.lang.ClassLiteralHolder",
            "com.google.gwt.core.client.RunAsyncCallback",
@@ -313,6 +313,10 @@

    private Map<JReferenceType, Integer> typeIdMap = new  
HashMap<JReferenceType, Integer>();

+  private JInterfaceType typeJavaIoSerializable;
+
+  private JInterfaceType typeJavaLangCloneable;
+
    private JClassType typeJavaLangEnum;

    private JClassType typeJavaLangObject;
@@ -334,10 +338,10 @@
    /**
     * Constructor.
     *
-   * @param enableSourceInfoDescendants Controls whether or not SourceInfo  
nodes
-   *          created via the JProgram will record descendant information.
-   *          Enabling this feature will collect extra data during the
-   *          compilation cycle, but at a cost of memory and object  
allocations.
+   * @param correlator Controls whether or not SourceInfo nodes created  
via the
+   *          JProgram will record descendant information. Enabling this  
feature
+   *          will collect extra data during the compilation cycle, but at  
a
+   *          cost of memory and object allocations.
     */
    public JProgram(CorrelationFactory correlator) {
      super(correlator.makeSourceInfo(SourceOrigin.create(0,
@@ -467,6 +471,11 @@

      if (INDEX_TYPES_SET.contains(sname)) {
        indexedTypes.put(x.getShortName(), x);
+      if (sname.equals("java.lang.Cloneable")) {
+        typeJavaLangCloneable = x;
+      } else if (sname.equals("java.io.Serializable")) {
+        typeJavaIoSerializable = x;
+      }
      }

      return x;
@@ -720,6 +729,9 @@
          // unrelated
          return typeJavaLangObject;

+      } else if (greater == IS_ARRAY
+          && ((tLesser == typeJavaLangCloneable) || (tLesser ==  
typeJavaIoSerializable))) {
+        return tLesser;
        } else {

          // unrelated: the best commonality between an interface and array,  
or
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java     Wed  
Dec  9 09:10:40 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java     Mon Dec 
 
21 10:20:58 2009
@@ -262,6 +262,9 @@
     */
    private final Map<JMethod, Map<JClassType, Set<JMethod>>>  
virtualUpRefMap = new IdentityHashMap<JMethod, Map<JClassType,  
Set<JMethod>>>();

+  private JDeclaredType javaIoSerializable;
+  private JDeclaredType javaLangCloneable;
+
    public JTypeOracle(JProgram program) {
      this.program = program;
    }
@@ -310,6 +313,12 @@
          }
        }

+      /*
+       * Warning: If this code is ever updated to consider casts of array  
types
+       * to interface types, then be sure to consider that casting an  
array to
+       * Serializable and Cloneable succeeds. Currently all casts of an  
array to
+       * an interface return true, which is overly conservative but is  
safe.
+       */
      } else if (type instanceof JClassType) {

        JClassType cType = (JClassType) type;
@@ -369,6 +378,10 @@
            }
          }
        }
+
+      if (qType == javaIoSerializable || qType == javaLangCloneable) {
+        return true;
+      }
      } else if (type instanceof JClassType) {

        JClassType cType = (JClassType) type;
@@ -402,6 +415,9 @@

    public void computeBeforeAST() {
      javaLangObject = program.getTypeJavaLangObject();
+    javaIoSerializable =  
program.getFromTypeMap(Serializable.class.getName());
+    javaLangCloneable = program.getFromTypeMap(Cloneable.class.getName());
+
      superClassMap.clear();
      subClassMap.clear();
      superInterfaceMap.clear();
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java        Wed Dec 
 9  
09:10:40 2009
+++ /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java        Mon Dec 
21  
10:20:58 2009
@@ -64,6 +64,8 @@
    private SourceInfo synthSource;
    private JReferenceType typeNull;
    private JTypeOracle typeOracle;
+  private JReferenceType intfSerializable;
+  private JReferenceType intfCloneable;

    public void testCanTheoreticallyCast() {
      assertFalse(typeOracle.canTheoreticallyCast(classBnn, typeNull));
@@ -90,6 +92,12 @@

      assertTrue(typeOracle.canTheoreticallyCast(intfIBase, classBase));
      assertFalse(typeOracle.canTheoreticallyCast(intfJ, classA));
+
+    assertTrue(typeOracle.canTheoreticallyCast(arrayOfA,  
intfSerializable));
+    assertTrue(typeOracle.canTheoreticallyCast(intfSerializable,  
arrayOfA));
+
+    assertTrue(typeOracle.canTheoreticallyCast(arrayOfA, intfCloneable));
+    assertTrue(typeOracle.canTheoreticallyCast(intfCloneable, arrayOfA));
    }

    public void testCanTriviallyCast() {
@@ -133,6 +141,12 @@

      assertTrue(typeOracle.canTriviallyCast(classJso, classJso1));
      assertTrue(typeOracle.canTriviallyCast(classJso, classJso1));
+
+    assertTrue(typeOracle.canTriviallyCast(arrayOfA, intfSerializable));
+    assertFalse(typeOracle.canTriviallyCast(intfSerializable, arrayOfA));
+
+    assertTrue(typeOracle.canTriviallyCast(arrayOfA, intfCloneable));
+    assertFalse(typeOracle.canTriviallyCast(intfCloneable, arrayOfA));

      /*
       * Test that two types cannot both be trivially castable to each other,
@@ -172,6 +186,9 @@

      assertSame(classObject, generalizeTypes(intfI, arrayOfInt));

+    assertSame(intfSerializable, generalizeTypes(intfSerializable,  
arrayOfA));
+    assertSame(intfCloneable, generalizeTypes(intfCloneable, arrayOfA));
+
      for (JReferenceType type1 : severalTypes()) {
        for (JReferenceType type2 : severalTypes()) {
          JReferenceType generalized = generalizeTypes(type1, type2);
@@ -187,6 +204,8 @@
      assertSame(classB, program.strongerType(classB, classBase));
      assertSame(classB, program.strongerType(classBase, classB));
      assertSame(intfI, program.strongerType(intfI, intfJ));
+    assertSame(arrayOfA, program.strongerType(intfSerializable, arrayOfA));
+    assertSame(arrayOfA, program.strongerType(intfCloneable, arrayOfA));
    }

    @Override
@@ -220,6 +239,9 @@
      classJso = createClass("com.google.gwt.core.client.JavaScriptObject",
          classObject, false, false);

+    intfSerializable = createInterface("java.io.Serializable");
+    intfCloneable = createInterface("java.lang.Cloneable");
+
      intfIBase = createInterface("IBase");

      intfI = createInterface("I");
=======================================
--- /trunk/user/test/com/google/gwt/dev/jjs/test/ClassCastTest.java     Wed  
Sep  3 13:46:24 2008
+++ /trunk/user/test/com/google/gwt/dev/jjs/test/ClassCastTest.java     Mon Dec 
 
21 10:20:58 2009
@@ -16,9 +16,12 @@
  package com.google.gwt.dev.jjs.test;

  import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.ui.Widget;
+
+import java.io.Serializable;

  /**
- * TODO: document me.
+ * Test type casts and <code>instanceof</code>.
   */
  @SuppressWarnings("unused")
  public class ClassCastTest extends GWTTestCase {
@@ -32,13 +35,26 @@
    static abstract class Food {
    }

-  private final Food foodItem = new Apple();
-
-  private final CanEatRaw rawFoodItem = new Apple();
-
+  private volatile Object arrayOfInt = new int[3];
+  private volatile Object arrayOfWidget = new Widget[4];
+  private volatile Food foodItem = new Apple();
+  private volatile CanEatRaw rawFoodItem = new Apple();
+
+  @Override
    public String getModuleName() {
      return "com.google.gwt.dev.jjs.CompilerSuite";
    }
+
+  public void testArrayInterfaces() {
+    assertTrue(arrayOfInt instanceof Serializable);
+    assertTrue(arrayOfWidget instanceof Serializable);
+
+    assertTrue(arrayOfInt instanceof Cloneable);
+    assertTrue(arrayOfWidget instanceof Cloneable);
+
+    assertFalse(arrayOfInt instanceof Food);
+    assertFalse(arrayOfWidget instanceof Food);
+  }

    public void testBaseToInterface() {
      Apple apple = (Apple) foodItem;

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

Reply via email to