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