Revision: 6216
Author: b...@google.com
Date: Fri Sep 25 11:27:03 2009
Log: Fix compiler and hosted-mode crash caused by virtual overrides in  
SingleJsoImpl types.

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

Modified:
  /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
   
/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
  /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
   
/trunk/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java     Tue Jul 
 
21 18:31:48 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java     Fri Sep 
 
25 11:27:03 2009
@@ -448,7 +448,6 @@
              }
            }
          }
-        jsoSubType.clearImplements();
        }
      }

=======================================
---  
/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java 
 
Tue Jul 21 18:30:12 2009
+++  
/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java 
 
Fri Sep 25 11:27:03 2009
@@ -177,13 +177,21 @@

      private JMethod findConcreteImplementation(JMethod method,
          JClassType concreteType) {
-      for (JMethod m : concreteType.getMethods()) {
-        if (program.typeOracle.getAllOverrides(m).contains(method)) {
-          if (!m.isAbstract()) {
-            return m;
+      /*
+       * Search supertypes for virtual overrides via subclass. See the  
javadoc
+       * on JTypeOracle.getAllVirtualOverrides for an example.
+       */
+      while (concreteType != null) {
+        for (JMethod m : concreteType.getMethods()) {
+          if (program.typeOracle.getAllOverrides(m).contains(method)) {
+            if (!m.isAbstract()) {
+              return m;
+            }
            }
          }
-      }
+        concreteType = concreteType.getSuperClass();
+      }
+
        return null;
      }

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java      
 
Fri Jul 31 13:43:46 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java      
 
Fri Sep 25 11:27:03 2009
@@ -36,9 +36,9 @@
  import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter;
  import  
com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;
  import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.Name.SourceOrBinaryName;
-import com.google.gwt.dev.util.Name.InternalName;
  import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.Name.InternalName;
+import com.google.gwt.dev.util.Name.SourceOrBinaryName;
  import com.google.gwt.util.tools.Utility;

  import org.apache.commons.collections.map.AbstractReferenceMap;
@@ -910,6 +910,21 @@
           */
          String mangledName = getBinaryName(type).replace('.', '_') + "_"
              + m.getName();
+
+        JType[] parameterTypes = new JType[m.getParameters().length];
+        for (int i = 0; i < parameterTypes.length; i++) {
+          parameterTypes[i] = m.getParameters()[i].getType();
+        }
+
+        /*
+         * Handle virtual overrides by finding the method that we would  
normally
+         * invoke and using its declaring class as the dispatch target.
+         */
+        while (implementingType.findMethod(m.getName(), parameterTypes) ==  
null) {
+          implementingType = implementingType.getSuperclass();
+        }
+        assert implementingType != null : "Unable to find virtual override  
for "
+            + m.toString();

          /*
           * Cook up the a pseudo-method declaration for the concrete type.  
This
@@ -921,9 +936,9 @@
           */
          String decl = getBinaryOrPrimitiveName(m.getReturnType()) + " "
              + m.getName() + "$ (" +  
getBinaryOrPrimitiveName(implementingType);
-        for (JParameter p : m.getParameters()) {
+        for (JType paramType : parameterTypes) {
            decl += ",";
-          decl += getBinaryOrPrimitiveName(p.getType());
+          decl += getBinaryOrPrimitiveName(paramType);
          }
          decl += ")";

=======================================
---  
/trunk/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java   
 
Mon Jul 20 14:25:19 2009
+++  
/trunk/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java   
 
Fri Sep 25 11:27:03 2009
@@ -22,6 +22,16 @@
   * Tests SingleJso semantics in non-trivial type hierarchies.
   */
  public class TypeHierarchyTest extends GWTTestCase {
+
+  /**
+   * Used with PlainJso and PlainJsoWithInterface to mix interfaces into
+   * existing base classes.
+   */
+  interface Arrayish {
+    int getLength();
+
+    JavaScriptObject getObject(int i);
+  }

    /**
     * The bottom type for a non-trivial diamond-shaped inheritance pattern.
@@ -58,6 +68,35 @@
     */
    interface IDiamond2B extends IDiamond1 {
    }
+
+  /**
+   * This is a base class that is used to test adding interfaces to a JSO  
via a
+   * subclass.
+   */
+  static class PlainJso extends JavaScriptObject {
+    protected PlainJso() {
+    }
+
+    public final native int getLength()/*-{
+      return this.length;
+    }-*/;
+
+    public final native JavaScriptObject getObject(int i) /*-{
+      return this[i];
+    }-*/;
+  }
+
+  /**
+   * We'll mix in an interface into PlainJso.
+   */
+  static class PlainJsoWithInterface extends PlainJso implements Arrayish {
+    public static PlainJsoWithInterface create() {
+      return JavaScriptObject.createArray().cast();
+    }
+
+    protected PlainJsoWithInterface() {
+    }
+  }

    @Override
    public String getModuleName() {
@@ -107,4 +146,10 @@
      IDiamond2B d2b = DiamondImpl.create();
      assertEquals(42, d2b.size());
    }
-}
+
+  public void testVirtualOverrides() {
+    Arrayish array = PlainJsoWithInterface.create();
+    assertEquals(0, array.getLength());
+    assertNull(array.getObject(0));
+  }
+}

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

Reply via email to