Revision: 5756
Author: [email protected]
Date: Mon Jul 20 14:25:19 2009
Log: Fix incorrect computation in JTypeOracle.computeSingleJsoImplData()  
which to include super-interfaces when determining if an interface is a tag  
interface.

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

Modified:
  /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.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     Sun May 
 
24 16:56:31 2009
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java     Mon Jul 
 
20 14:25:19 2009
@@ -486,6 +486,36 @@
    public boolean isSuperClass(JClassType type, JClassType qType) {
      return get(superClassMap, type).contains(qType);
    }
+
+  /**
+   * Returns true if the given type and it's super-interfaces define no  
methods.
+   */
+  public boolean isTagInterface(JInterfaceType type) {
+    Set<JInterfaceType> seen = new IdentityHashSet<JInterfaceType>();
+    List<JInterfaceType> q = new LinkedList<JInterfaceType>();
+    seen.add(type);
+    q.add(type);
+
+    while (!q.isEmpty()) {
+      JInterfaceType intf = q.remove(0);
+
+      List<JMethod> methods = intf.getMethods();
+      int size = methods.size();
+      if (size == 0
+          || (size == 1 && methods.get(0).getName().equals("$clinit"))) {
+        // OK, add any super-interfaces;
+        for (JInterfaceType superIntf : intf.getImplements()) {
+          if (seen.add(superIntf)) {
+            q.add(superIntf);
+          }
+        }
+      } else {
+        return false;
+      }
+    }
+
+    return true;
+  }

    /**
     * This method should be called after altering the types that are live  
in the
@@ -683,14 +713,12 @@
          }
          JInterfaceType intr = (JInterfaceType) refType;

-        if (intr.getMethods().size() <= 1) {
+        if (isTagInterface(intr)) {
            /*
             * Record a tag interface as being implemented by JSO, since they
             * don't actually have any methods and we want to avoid spurious
             * messages about multiple JSO types implementing a common  
interface.
             */
-          assert intr.getMethods().size() == 0
-              || intr.getMethods().get(0).getName().equals("$clinit");
            jsoSingleImpls.put(intr, program.getJavaScriptObject());

            /*
=======================================
---  
/trunk/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java   
 
Sun May 24 10:37:46 2009
+++  
/trunk/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java   
 
Mon Jul 20 14:25:19 2009
@@ -15,12 +15,49 @@
   */
  package com.google.gwt.dev.jjs.test.singlejso;

+import com.google.gwt.core.client.JavaScriptObject;
  import com.google.gwt.junit.client.GWTTestCase;

  /**
   * Tests SingleJso semantics in non-trivial type hierarchies.
   */
  public class TypeHierarchyTest extends GWTTestCase {
+
+  /**
+   * The bottom type for a non-trivial diamond-shaped inheritance pattern.
+   */
+  static class DiamondImpl extends JavaScriptObject implements IDiamond2A,
+      IDiamond2B {
+    public static native DiamondImpl create() /*-{
+      return {size : 42};
+    }-*/;
+
+    protected DiamondImpl() {
+    }
+
+    public final native int size() /*-{
+      return this.size;
+    }-*/;
+  }
+
+  /**
+   * The root type for a non-trivial diamond-shaped inheritance pattern.
+   */
+  interface IDiamond1 {
+    int size();
+  }
+
+  /**
+   * The left type for a non-trivial diamond-shaped inheritance pattern.
+   */
+  interface IDiamond2A extends IDiamond1 {
+  }
+
+  /**
+   * The right type for a non-trivial diamond-shaped inheritance pattern.
+   */
+  interface IDiamond2B extends IDiamond1 {
+  }

    @Override
    public String getModuleName() {
@@ -60,4 +97,14 @@
      assertEquals("B2", b2.whoAmI());
    }

-}
+  public void testDiamond() {
+    IDiamond1 d1 = DiamondImpl.create();
+    assertEquals(42, d1.size());
+
+    IDiamond2A d2a = DiamondImpl.create();
+    assertEquals(42, d2a.size());
+
+    IDiamond2B d2b = DiamondImpl.create();
+    assertEquals(42, d2b.size());
+  }
+}


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

Reply via email to