Revision: 10190
Author:   sco...@google.com
Date:     Tue May 17 05:22:26 2011
Log:      Salvage useful bits from overrides work.

http://gwt-code-reviews.appspot.com/1436801/

Review by: jbrosenb...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=10190

Deleted:
 /trunk/dev/core/src/com/google/gwt/core/ext/soyc/HasOverrides.java
Modified:
 /trunk/dev/core/src/com/google/gwt/core/ext/soyc/ClassMember.java
 /trunk/dev/core/src/com/google/gwt/core/ext/soyc/MethodMember.java
/trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StandardMethodMember.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java
 /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/HasOverrides.java Thu May 5 06:03:58 2011
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-/**
- *
- */
-package com.google.gwt.core.ext.soyc;
-
-import java.util.SortedSet;
-
-/**
- * A tag interface for Members to indicate that they override or extend another
- * Member.
- *
- * @param <T> the type of Member that is overridden or extended
- */
-public interface HasOverrides<T extends Member> {
-  /**
-   * Returns the complete set of overridden members. For example, if
-   * <code>C</code> extends <code>B</code> extends <code>A</code>, then
-   * <code>C</code> would return the set <code>[A, B]</code>.
-   */
-  SortedSet<T> getOverrides();
-}
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/ClassMember.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/src/com/google/gwt/core/ext/soyc/ClassMember.java Tue May 17 05:22:26 2011
@@ -24,8 +24,8 @@
* {@link #getMethods()} may be incomplete when compared to the original Java
  * type.
  */
-public interface ClassMember extends HasDependencies,
-    HasOverrides<ClassMember>, Member {
+public interface ClassMember extends HasDependencies, Member {
+
   /**
    * Returns the fields of the ClassMember that have been retained in the
    * compiled output.
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/MethodMember.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/src/com/google/gwt/core/ext/soyc/MethodMember.java Tue May 17 05:22:26 2011
@@ -12,15 +12,11 @@
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
  * the License.
- */
-/**
- *
  */
 package com.google.gwt.core.ext.soyc;

 /**
  * Represents compiled JS code derived from a Java method.
  */
-public interface MethodMember extends HasDependencies, HasEnclosing,
-    HasOverrides<MethodMember>, Member {
-}
+public interface MethodMember extends HasDependencies, HasEnclosing, Member {
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StandardMethodMember.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StandardMethodMember.java Tue May 17 05:22:26 2011
@@ -16,15 +16,10 @@
 package com.google.gwt.core.ext.soyc.impl;

 import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.Member;
 import com.google.gwt.core.ext.soyc.MethodMember;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JType;

-import java.util.Collections;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
 /**
  * An implementation of MethodMember.
  */
@@ -32,7 +27,6 @@
     implements MethodMember {
   private final ClassMember enclosing;
   private final String sourceName;
-  private final SortedSet<MethodMember> overridesView;

   /**
    * Constructed by {@link MemberFactory#get(JMethod)}.
@@ -49,22 +43,11 @@
     sb.append(")");
     sb.append(method.getOriginalReturnType().getJsniSignatureName());
     this.sourceName = sb.toString();
-
-    SortedSet<MethodMember> overrides = new TreeSet<MethodMember>(
-        Member.SOURCE_NAME_COMPARATOR);
-    for (JMethod override : method.getOverrides()) {
-      overrides.add(factory.get(override));
-    }
-    overridesView = Collections.unmodifiableSortedSet(overrides);
   }

   public ClassMember getEnclosing() {
     return enclosing;
   }
-
-  public SortedSet<MethodMember> getOverrides() {
-    return overridesView;
-  }

   @Override
   public String getSourceName() {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java Tue May 17 05:22:26 2011
@@ -17,10 +17,12 @@

 import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
 import com.google.gwt.dev.jjs.impl.HasNameSort;
+import com.google.gwt.dev.util.collect.HashMap;
 import com.google.gwt.dev.util.collect.IdentityHashMap;
 import com.google.gwt.dev.util.collect.IdentityHashSet;
 import com.google.gwt.dev.util.collect.IdentitySets;
 import com.google.gwt.dev.util.collect.Lists;
+import com.google.gwt.dev.util.collect.Maps;

 import java.io.Serializable;
 import java.util.ArrayList;
@@ -187,6 +189,8 @@
     }
     return true;
   }
+
+  private JDeclaredType baseArrayType;

   /**
    * A map of all interfaces to the set of classes that could theoretically
@@ -287,6 +291,12 @@
private final Map<JMethod, Map<JClassType, Set<JMethod>>> virtualUpRefMap =
       new IdentityHashMap<JMethod, Map<JClassType, Set<JMethod>>>();

+  /**
+   * An index of all polymorphic methods for each class.
+   */
+  private final Map<JClassType, Map<String, JMethod>> polyClassMethodMap =
+      new IdentityHashMap<JClassType, Map<String, JMethod>>();
+
   public JTypeOracle(JProgram program) {
     this.program = program;
   }
@@ -417,7 +427,7 @@
         }
       }

-      if (qType == javaIoSerializable || qType == javaLangCloneable) {
+ if (qType == javaIoSerializable || qType == javaLangCloneable || qType == baseArrayType) {
         return true;
       }
     } else if (type instanceof JClassType) {
@@ -455,6 +465,7 @@
   }

   public void computeBeforeAST() {
+    baseArrayType = program.getIndexedType("Array");
     javaLangObject = program.getTypeJavaLangObject();
javaIoSerializable = program.getFromTypeMap(Serializable.class.getName());
     javaLangCloneable = program.getFromTypeMap(Cloneable.class.getName());
@@ -526,44 +537,12 @@
       }
     }
   }
-
-  public Set<JMethod> getAllOverrides(JMethod method) {
-    return getAllOverrides(method, instantiatedTypes);
-  }

   /**
* References to any methods which this method implementation might override
-   * or implement in any instantiable class.
-   */
- public Set<JMethod> getAllOverrides(JMethod method, Set<JReferenceType> instantiatedTypes) {
-    Set<JMethod> results = new IdentityHashSet<JMethod>();
-    getAllRealOverrides(method, results);
-    getAllVirtualOverrides(method, instantiatedTypes, results);
-    return results;
-  }
-
-  /**
- * References to any methods which this method directly overrides. This should
-   * be an EXHAUSTIVE list, that is, if C overrides B overrides A, then C's
-   * overrides list will contain both A and B.
-   */
-  public Set<JMethod> getAllRealOverrides(JMethod method) {
-    Set<JMethod> results = new IdentityHashSet<JMethod>();
-    getAllRealOverrides(method, results);
-    return results;
-  }
-
-  public Set<JClassType> getAllSubClasses(JReferenceType type) {
-    return subClassMap.get(type);
-  }
-
-  /**
- * Returns the set of methods the given method virtually overrides. A virtual
-   * override is an association between a concrete method and an unrelated
- * interface method with the exact same name and signature. The association
-   * occurs if and only if some subclass extends the concrete method's
-   * containing class and implements the interface method's containing
-   * interface. Example:
+ * or implement in any instantiable class, including strange cases where there + * is no direct relationship between the methods except in a subclass that
+   * inherits one and implements the other. Example:
    *
    * <pre>
    * interface IFoo {
@@ -579,11 +558,16 @@
    * In this case, <code>Unrelated.foo()</code> virtually implements
    * <code>IFoo.foo()</code> in subclass <code>Foo</code>.
    */
-  public Set<JMethod> getAllVirtualOverrides(JMethod method) {
+  public Set<JMethod> getAllOverrides(JMethod method) {
     Set<JMethod> results = new IdentityHashSet<JMethod>();
-    getAllVirtualOverrides(method, instantiatedTypes, results);
+    getAllRealOverrides(method, results);
+    getAllVirtualOverrides(method, results);
     return results;
   }
+
+  public JMethod getPolyMethod(JClassType type, String signature) {
+    return getOrCreatePolyMap(type).get(signature);
+  }

   public JClassType getSingleJsoImpl(JReferenceType maybeSingleJsoIntf) {
     return jsoSingleImpls.get(maybeSingleJsoIntf.getUnderlyingType());
@@ -606,8 +590,43 @@
     }
   }

+  /**
+   * Determine whether a type is instantiated.
+   */
+  public boolean isInstantiatedType(JDeclaredType type) {
+    return instantiatedTypes == null || instantiatedTypes.contains(type);
+  }
+
+  /**
+   * Determine whether a type is instantiated.
+   */
   public boolean isInstantiatedType(JReferenceType type) {
-    return isInstantiatedType(type, instantiatedTypes);
+    type = type.getUnderlyingType();
+    if (instantiatedTypes == null || instantiatedTypes.contains(type)) {
+      return true;
+    }
+
+    if (type.isExternal()) {
+ // TODO(tobyr) I don't know under what situations it is safe to assume
+      // that an external type won't be instantiated. For example, if we
+ // assumed that an external exception weren't instantiated, because we
+      // didn't see it constructed in our code, dead code elimination would
+      // incorrectly elide any catch blocks for that exception.
+      //
+ // We should see how this effects optimization and if we can limit its
+      // impact if necessary.
+      return true;
+    }
+
+    if (type instanceof JNullType) {
+      return true;
+    } else if (type instanceof JArrayType) {
+      JArrayType arrayType = (JArrayType) type;
+      if (arrayType.getLeafType() instanceof JNullType) {
+        return true;
+      }
+    }
+    return false;
   }

   public boolean isSameOrSuper(JClassType type, JClassType qType) {
@@ -665,8 +684,8 @@
   }

   public void setInstantiatedTypes(Set<JReferenceType> instantiatedTypes) {
-    this.instantiatedTypes = new IdentityHashSet<JReferenceType>();
-    this.instantiatedTypes.addAll(instantiatedTypes);
+    this.instantiatedTypes = instantiatedTypes;
+    polyClassMethodMap.keySet().retainAll(instantiatedTypes);
   }

   private <K, V> void add(Map<K, Set<V>> map, K key, V value) {
@@ -891,13 +910,12 @@
     }
   }

- private void getAllVirtualOverrides(JMethod method, Set<JReferenceType> instantiatedTypes,
-      Set<JMethod> results) {
+ private void getAllVirtualOverrides(JMethod method, Set<JMethod> results) { Map<JClassType, Set<JMethod>> overrideMap = virtualUpRefMap.get(method);
     if (overrideMap != null) {
for (Map.Entry<JClassType, Set<JMethod>> entry : overrideMap.entrySet()) {
         JClassType classType = entry.getKey();
-        if (isInstantiatedType(classType, instantiatedTypes)) {
+        if (isInstantiatedType(classType)) {
           results.addAll(entry.getValue());
         }
       }
@@ -921,6 +939,27 @@
     }
     return map2;
   }
+
+  private Map<String, JMethod> getOrCreatePolyMap(JClassType type) {
+    Map<String, JMethod> polyMap = polyClassMethodMap.get(type);
+    if (polyMap == null) {
+      JClassType superClass = type.getSuperClass();
+      if (superClass == null) {
+        polyMap = new HashMap<String, JMethod>();
+      } else {
+ Map<String, JMethod> superPolyMap = getOrCreatePolyMap(type.getSuperClass());
+        polyMap = new HashMap<String, JMethod>(superPolyMap);
+      }
+      for (JMethod method : type.getMethods()) {
+        if (method.canBePolymorphic()) {
+          polyMap.put(method.getSignature(), method);
+        }
+      }
+      polyMap = Maps.normalize(polyMap);
+      polyClassMethodMap.put(type, polyMap);
+    }
+    return polyMap;
+  }

   /**
* Returns true if type implements the interface represented by qType, either
@@ -929,48 +968,6 @@
private boolean implementsInterface(JClassType type, JInterfaceType qType) {
     return get(implementsMap, type).contains(qType);
   }
-
-  /**
-   * Determine whether a type is instantiated, given an assumed list of
-   * instantiated types.
-   *
-   * @param type any type
-   * @param instantiatedTypes a set of types assumed to be instantiated. If
- * <code>null</code>, then there are no assumptions about which types
-   *          are instantiated.
-   * @return whether the type is instantiated
-   */
- private boolean isInstantiatedType(JReferenceType type, Set<JReferenceType> instantiatedTypes) {
-    type = type.getUnderlyingType();
-
-    if (type.isExternal()) {
- // TODO(tobyr) I don't know under what situations it is safe to assume
-      // that an external type won't be instantiated. For example, if we
- // assumed that an external exception weren't instantiated, because we
-      // didn't see it constructed in our code, dead code elimination would
-      // incorrectly elide any catch blocks for that exception.
-      //
- // We should see how this effects optimization and if we can limit its
-      // impact if necessary.
-      return true;
-    }
-
-    if (instantiatedTypes == null) {
-      return true;
-    }
-
-    if (type instanceof JNullType) {
-      return true;
-    }
-
-    if (type instanceof JArrayType) {
-      JArrayType arrayType = (JArrayType) type;
-      if (arrayType.getLeafType() instanceof JNullType) {
-        return true;
-      }
-    }
-    return instantiatedTypes.contains(type);
-  }

   /**
    * Record the all of my super classes (and myself as a subclass of them).
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Tue May 10 05:59:20 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Tue May 17 05:22:26 2011
@@ -146,6 +146,7 @@
 import com.google.gwt.dev.util.collect.IdentityHashSet;
 import com.google.gwt.dev.util.collect.Maps;

+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumMap;
@@ -198,7 +199,7 @@
         recordSymbol(x, jsName);
       } else {
         JsName jsName;
-        if (belongsToSpecialObfuscatedType(x)) {
+        if (specialObfuscatedFields.containsKey(x)) {
           jsName = peek().declareName(mangleNameSpecialObfuscate(x));
           jsName.setObfuscatable(false);
         } else {
@@ -319,13 +320,14 @@
       String name = x.getName();
       if (x.needsVtable()) {
         if (polymorphicNames.get(x) == null) {
-          String mangleName = mangleNameForPoly(x);
           JsName polyName;
-          if (belongsToSpecialObfuscatedType(x)) {
+          if (x.isPrivate()) {
+ polyName = interfaceScope.declareName(mangleNameForPrivatePoly(x), name); + } else if (specialObfuscatedMethodSigs.containsKey(x.getSignature())) { polyName = interfaceScope.declareName(mangleNameSpecialObfuscate(x));
             polyName.setObfuscatable(false);
           } else {
-            polyName = interfaceScope.declareName(mangleName, name);
+ polyName = interfaceScope.declareName(mangleNameForPoly(x), name);
           }
           polymorphicNames.put(x, polyName);
         }
@@ -2032,20 +2034,14 @@
   private final JProgram program;

   /**
-   * All of the fields and polymorphic methods in String.
-   *
- * Because we modify String's prototype, all fields and polymorphic methods on
-   * String's super types need special handling.
+ * All of the fields in String and Array need special handling for interop.
    */
- private final Map<String, String> specialObfuscatedIdents = new HashMap<String, String>(); + private final Map<JField, String> specialObfuscatedFields = new HashMap<JField, String>();

   /**
-   * All of the super types of String.
-   *
- * Because we modify String's prototype, all fields and polymorphic methods on
-   * String's super types need special handling.
+ * All of the methods in String and Array need special handling for interop.
    */
- private final Set<JDeclaredType> specialObfuscatedTypes = new HashSet<JDeclaredType>(); + private final Map<String, String> specialObfuscatedMethodSigs = new HashMap<String, String>();

   /**
* If true, polymorphic functions are made anonymous vtable declarations and
@@ -2084,54 +2080,54 @@

     this.stripStack =
JsStackEmulator.getStackMode(propertyOracles) == JsStackEmulator.StackMode.STRIP;
+
     /*
- * Because we modify String's prototype, all fields and polymorphic methods
-     * on String's super types need special handling.
+     * Because we modify the JavaScript String prototype, all fields and
+     * polymorphic methods on String and super types need special handling.
      */
-    specialObfuscatedTypes.add(program.getIndexedType("Comparable"));
-    specialObfuscatedTypes.add(program.getIndexedType("CharSequence"));
-    specialObfuscatedTypes.add(program.getTypeJavaLangObject());
-    specialObfuscatedTypes.add(program.getTypeJavaLangString());
-    specialObfuscatedTypes.add(program.getIndexedType("Array"));

     // Object polymorphic
-    specialObfuscatedIdents.put("getClass", "gC");
-    specialObfuscatedIdents.put("hashCode", "hC");
-    specialObfuscatedIdents.put("equals", "eQ");
-    specialObfuscatedIdents.put("toString", "tS");
-    specialObfuscatedIdents.put("finalize", "fZ");
-
-    // Object fields
-    specialObfuscatedIdents.put("expando", "eX");
-    specialObfuscatedIdents.put("typeMarker", "tM");
-    specialObfuscatedIdents.put("castableTypeMap", "cM");
-
+    Map<String, String> namesToIdents = new HashMap<String, String>();
+    namesToIdents.put("getClass", "gC");
+    namesToIdents.put("hashCode", "hC");
+    namesToIdents.put("equals", "eQ");
+    namesToIdents.put("toString", "tS");
+    namesToIdents.put("finalize", "fZ");
     // String polymorphic
-    specialObfuscatedIdents.put("charAt", "cA");
-    specialObfuscatedIdents.put("compareTo", "cT");
-    specialObfuscatedIdents.put("length", "lN");
-    specialObfuscatedIdents.put("subSequence", "sS");
-
+    namesToIdents.put("charAt", "cA");
+    namesToIdents.put("compareTo", "cT");
+    namesToIdents.put("length", "lN");
+    namesToIdents.put("subSequence", "sS");
+
+ List<JMethod> methods = new ArrayList<JMethod>(program.getTypeJavaLangObject().getMethods());
+    methods.addAll(program.getIndexedType("Comparable").getMethods());
+    methods.addAll(program.getIndexedType("CharSequence").getMethods());
+    for (JMethod method : methods) {
+      if (method.canBePolymorphic()) {
+        String ident = namesToIdents.get(method.getName());
+        assert ident != null;
+        specialObfuscatedMethodSigs.put(method.getSignature(), ident);
+      }
+    }
+
+    namesToIdents.clear();
+    // Object fields
+    namesToIdents.put("expando", "eX");
+    namesToIdents.put("typeMarker", "tM");
+    namesToIdents.put("castableTypeMap", "cM");
     // Array magic field
-    specialObfuscatedIdents.put("arrayClass", "aC");
-    specialObfuscatedIdents.put("queryId", "qI");
-  }
-
-  boolean belongsToSpecialObfuscatedType(JField x) {
-    return specialObfuscatedTypes.contains(x.getEnclosingType());
-  }
-
-  boolean belongsToSpecialObfuscatedType(JMethod x) {
-    if (specialObfuscatedTypes.contains(x.getEnclosingType())) {
-      return true;
-    }
-    for (Object element : x.getOverrides()) {
-      JMethod override = (JMethod) element;
-      if (specialObfuscatedTypes.contains(override.getEnclosingType())) {
-        return true;
+    namesToIdents.put("arrayClass", "aC");
+    namesToIdents.put("queryId", "qI");
+
+ List<JField> fields = new ArrayList<JField>(program.getTypeJavaLangObject().getFields());
+    fields.addAll(program.getIndexedType("Array").getFields());
+    for (JField field : fields) {
+      if (!field.isStatic()) {
+        String ident = namesToIdents.get(field.getName());
+        assert ident != null;
+        specialObfuscatedFields.put(field, ident);
       }
     }
-    return false;
   }

   String getNameString(HasName hasName) {
@@ -2155,30 +2151,29 @@
   }

   String mangleNameForPoly(JMethod x) {
-    if (x.getOverrides().isEmpty()) {
-      return mangleNameForPolyImpl(x);
-    } else {
-      for (JMethod override : x.getOverrides()) {
-        if (override.getOverrides().isEmpty()) {
-          return mangleNameForPolyImpl(override);
-        }
-      }
-    }
-    throw new InternalCompilerException("Cycle in overrides???");
+    assert !x.isPrivate() && !x.isStatic();
+    StringBuffer sb = new StringBuffer();
+    sb.append(getNameString(x));
+    sb.append("__");
+    for (int i = 0; i < x.getOriginalParamTypes().size(); ++i) {
+      JType type = x.getOriginalParamTypes().get(i);
+      sb.append(type.getJavahSignatureName());
+    }
+    sb.append(x.getOriginalReturnType().getJavahSignatureName());
+    return sb.toString();
   }

-  String mangleNameForPolyImpl(JMethod x) {
+  String mangleNameForPrivatePoly(JMethod x) {
+    assert x.isPrivate() && !x.isStatic();
     StringBuffer sb = new StringBuffer();
-    if (x.isPrivate() && !x.isStatic()) {
-      /*
- * Private instance methods in different classes should not override each - * other, so they must have distinct polymorphic names. Therefore, add the
-       * class name to the mangled name.
-       */
-      sb.append("private$");
-      sb.append(getNameString(x.getEnclosingType()));
-      sb.append("$");
-    }
+    /*
+ * Private instance methods in different classes should not override each + * other, so they must have distinct polymorphic names. Therefore, add the
+     * class name to the mangled name.
+     */
+    sb.append("private$");
+    sb.append(getNameString(x.getEnclosingType()));
+    sb.append("$");
     sb.append(getNameString(x));
     sb.append("__");
     for (int i = 0; i < x.getOriginalParamTypes().size(); ++i) {
@@ -2190,10 +2185,10 @@
   }

   String mangleNameSpecialObfuscate(JField x) {
-    assert (specialObfuscatedIdents.containsKey(x.getName()));
+    assert (specialObfuscatedFields.containsKey(x));
     switch (output) {
       case OBFUSCATED:
-        return specialObfuscatedIdents.get(x.getName());
+        return specialObfuscatedFields.get(x);
       case PRETTY:
         return x.getName() + "$";
       case DETAILED:
@@ -2203,10 +2198,10 @@
   }

   String mangleNameSpecialObfuscate(JMethod x) {
-    assert (specialObfuscatedIdents.containsKey(x.getName()));
+    assert (specialObfuscatedMethodSigs.containsKey(x.getSignature()));
     switch (output) {
       case OBFUSCATED:
-        return specialObfuscatedIdents.get(x.getName());
+        return specialObfuscatedMethodSigs.get(x.getSignature());
       case PRETTY:
         return x.getName() + "$";
       case DETAILED:
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/MethodCallTightener.java Tue May 17 05:22:26 2011
@@ -16,16 +16,12 @@
 package com.google.gwt.dev.jjs.impl;

 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JArrayType;
 import com.google.gwt.dev.jjs.ast.JClassType;
-import com.google.gwt.dev.jjs.ast.JExpression;
-import com.google.gwt.dev.jjs.ast.JInterfaceType;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodCall;
 import com.google.gwt.dev.jjs.ast.JModVisitor;
 import com.google.gwt.dev.jjs.ast.JNewInstance;
 import com.google.gwt.dev.jjs.ast.JNode;
-import com.google.gwt.dev.jjs.ast.JNullType;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.ast.JReferenceType;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
@@ -49,54 +45,35 @@

     @Override
     public void endVisit(JMethodCall x, Context ctx) {
-      JMethod method = x.getTarget();
-      JExpression instance = x.getInstance();
-
       // The method call is already known statically
       if (!x.canBePolymorphic()) {
         return;
       }

- JReferenceType instanceType = ((JReferenceType) instance.getType()).getUnderlyingType();
-      JReferenceType enclosingType = method.getEnclosingType();
-
- if (instanceType == enclosingType || instanceType instanceof JInterfaceType) {
-        // This method call is as tight as it can be for the type of the
-        // qualifier
+      JReferenceType instanceType =
+          ((JReferenceType) x.getInstance().getType()).getUnderlyingType();
+      if (!(instanceType instanceof JClassType)) {
+        // Cannot tighten.
         return;
       }

-      if (instanceType instanceof JArrayType) {
-        // shouldn't get here; arrays don't have extra methods
+      JMethod method = x.getTarget();
+      if (instanceType == method.getEnclosingType()) {
+        // Cannot tighten.
         return;
       }

-      if (instanceType instanceof JNullType) {
-        // TypeTightener will handle this case
+      JMethod foundMethod =
+ program.typeOracle.getPolyMethod((JClassType) instanceType, method.getSignature());
+      if (foundMethod == null) {
+ // The declared instance type is abstract and doesn't have the method.
         return;
       }
-
-      assert (instanceType instanceof JClassType);
-
-      /*
- * Search myself and all my super types to find a tighter implementation
-       * of the called method, if possible.
-       */
-      JMethod foundMethod = null;
-      JClassType type;
- outer : for (type = (JClassType) instanceType; type != null && type != enclosingType; type =
-          type.getSuperClass()) {
-        for (JMethod methodIt : type.getMethods()) {
-          if (methodOverrides(methodIt, method)) {
-            foundMethod = methodIt;
-            break outer;
-          }
-        }
-      }
-
-      if (foundMethod == null) {
+      if (foundMethod == method) {
+        // The instance type doesn't override the method.
         return;
       }
+      assert foundMethod.canBePolymorphic();

       /*
* Replace the call to the original method with a call to the same method
@@ -111,30 +88,6 @@
     public void endVisit(JNewInstance x, Context ctx) {
       // Do not tighten new operations.
     }
-
-    /**
- * Check whether <code>subMethod</code> overrides <code>supMethod</code>.
-     * For the purposes of this method, indirect overrides are considered
- * overrides. For example, if method A.m overrides B.m, and B.m overrides - * C.m, then A.m is considered to override C.m. Additionally, implementing - * an interface is considered <q>overriding</q> for the purposes of this
-     * method.
-     *
-     */
-    private boolean methodOverrides(JMethod subMethod, JMethod supMethod) {
-      if (subMethod.getParams().size() != supMethod.getParams().size()) {
-        // short cut: check the number of parameters
-        return false;
-      }
-
-      if (!subMethod.getName().equals(supMethod.getName())) {
-        // short cut: check the method names
-        return false;
-      }
-
-      // long way: get all overrides and see if supMethod is included
- return program.typeOracle.getAllOverrides(subMethod).contains(supMethod);
-    }
   }

public static final String NAME = MethodCallTightener.class.getSimpleName();
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java Thu May 5 06:03:58 2011 +++ /trunk/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java Tue May 17 05:22:26 2011
@@ -26,8 +26,6 @@

 import junit.framework.TestCase;

-import org.eclipse.jdt.core.compiler.CharOperation;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -238,6 +236,7 @@

     classObject = createClass("java.lang.Object", null, false, false);
classString = createClass("java.lang.String", classObject, false, true);
+    createClass("com.google.gwt.lang.Array", classObject, false, true);
     classJso = createClass("com.google.gwt.core.client.JavaScriptObject",
         classObject, false, false);

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

Reply via email to