Author: [email protected]
Date: Wed Apr  8 10:47:16 2009
New Revision: 5197

Modified:
    trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
    trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java

Log:
Fixes a bug with calling private instance methods in web mode from
native methods; private methods could effectively override each
other.  This patch adjusts the mangled name of private instance
methods by adding the class name at the beginning.

Review by: bobv



Modified:  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
==============================================================================
---  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java       
 
(original)
+++  
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java       
 
Wed Apr  8 10:47:16 2009
@@ -1978,13 +1978,25 @@
    }

    String mangleNameForPolyImpl(JMethod x) {
-    String s = getNameString(x) + "__";
+    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("$");
+    }
+    sb.append(getNameString(x));
+    sb.append("__");
      for (int i = 0; i < x.getOriginalParamTypes().size(); ++i) {
        JType type = x.getOriginalParamTypes().get(i);
-      s += type.getJavahSignatureName();
+      sb.append(type.getJavahSignatureName());
      }
-    s += x.getOriginalReturnType().getJavahSignatureName();
-    return s;
+    sb.append(x.getOriginalReturnType().getJavahSignatureName());
+    return sb.toString();
    }

    String mangleNameSpecialObfuscate(JField x) {

Modified: trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
==============================================================================
--- trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java       
(original)
+++ trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java       Wed Apr 
  
8 10:47:16 2009
@@ -27,7 +27,6 @@
   */
  @SuppressWarnings("unused")
  public class CompilerTest extends GWTTestCase {
-
    interface MyMap {
      Object get(String key);
    }
@@ -172,6 +171,84 @@
      }
    }

+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoChild extends TpoParent {
+    @Override
+    public int foo() {
+      return callSuper();
+    }
+
+    private int callSuper() {
+      return super.foo();
+    }
+  }
+
+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoGrandparent {
+    public int foo() {
+      return 0;
+    }
+  }
+
+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoJsniChild extends TpoJsniParent {
+    @Override
+    public native int foo() /*-{
+      return  
[email protected]$tpojsnichild::callSuper()();
+    }-*/;
+
+    private int callSuper() {
+      return super.foo();
+    }
+  }
+
+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoJsniGrandparent {
+    public int foo() {
+      return 0;
+    }
+  }
+
+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoJsniParent extends TpoJsniGrandparent {
+    @Override
+    public native int foo() /*-{
+      // This should call callSuper in TpoJsniParent, not the one
+      // in TpoJsniChild
+      return  
[email protected]$tpojsniparent::callSuper()();
+    }-*/;
+
+    private int callSuper() {
+      return super.foo();
+    }
+  }
+
+  /**
+   * Used in test {...@link #testPrivateOverride()}.
+   */
+  private static class TpoParent extends TpoGrandparent {
+    @Override
+    public int foo() {
+      // This should call the callSuper in TpoJsniParent, not the one
+      // in TpoJsniChild
+      return callSuper();
+    }
+
+    private int callSuper() {
+      return super.foo();
+    }
+  }
+
    private static final class UninstantiableType {
      public Object field;
      public int intField;
@@ -903,6 +980,16 @@

    public void testOuterSuperThisRefs() {
      new B();
+  }
+
+  /**
+   * Test that calling a private instance method does not accidentally call
+   * another private method that appears to override it. Private methods  
don't
+   * truly override each other.
+   */
+  public void testPrivateOverride() {
+    assertEquals(0, new TpoChild().foo());
+    assertEquals(0, new TpoJsniChild().foo());
    }

    public void testReturnStatementInCtor() {

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

Reply via email to