When analyzing method signatures to look up a JSNI
reference, consistently ignore the method return type.

Review at http://gwt-code-reviews.appspot.com/312801

Review by: scottb@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7881 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
index 7225e63..527c37d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
@@ -156,22 +156,22 @@
     }
   }
 
+  /**
+   * Add a member to the table of most derived members.
+   * 
+   * @param matchesBySig The table so far of most derived members
+   * @param member The member to add to it
+   * @param refSig The string used to refer to that member, possibly shortened
+   * @param fullSig The fully qualified signature for that member
+   */
   private static void addMember(
       LinkedHashMap<String, LinkedHashMap<String, HasEnclosingType>> matchesBySig,
-      HasEnclosingType member, String refSig) {
+      HasEnclosingType member, String refSig, String fullSig) {
     LinkedHashMap<String, HasEnclosingType> matchesByFullSig = matchesBySig.get(refSig);
     if (matchesByFullSig == null) {
       matchesByFullSig = new LinkedHashMap<String, HasEnclosingType>();
       matchesBySig.put(refSig, matchesByFullSig);
     }
-
-    String fullSig;
-    if (member instanceof JField) {
-      fullSig = ((JField) member).getName();
-    } else {
-      fullSig = JProgram.getJsniSig((JMethod) member);
-    }
-
     matchesByFullSig.put(fullSig, member);
   }
 
@@ -211,15 +211,17 @@
             continue;
           }
         }
-        addMember(matchesBySig, method, getJsniSignature(method, false));
-        addMember(matchesBySig, method, getJsniSignature(method, true));
+        String fullSig = getJsniSignature(method, false);
+        String wildcardSig = getJsniSignature(method, true);
+        addMember(matchesBySig, method, fullSig, fullSig);
+        addMember(matchesBySig, method, wildcardSig, fullSig);
       }
     }
 
     // Get the fields on this class/interface.
     for (JField field : targetType.getFields()) {
       if (field.getName().equals(memberName)) {
-        addMember(matchesBySig, field, field.getName());
+        addMember(matchesBySig, field, field.getName(), field.getName());
       }
     }
   }
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java
index e394d54..5c0f479 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java
@@ -153,6 +153,32 @@
       }
     });
 
+    sourceOracle.addOrReplace(new MockJavaResource("test.DiffRetSuper") {
+      @Override
+      protected CharSequence getContent() {
+        StringBuffer code = new StringBuffer();
+        code.append("package test;\n");
+        code.append("public interface DiffRetSuper {\n");
+        code.append("  Object foo();\n");
+        code.append("}\n");
+        return code;
+      }
+    });
+
+    sourceOracle.addOrReplace(new MockJavaResource("test.DiffRetSub") {
+      @Override
+      protected CharSequence getContent() {
+        StringBuffer code = new StringBuffer();
+        code.append("package test;\n");
+        code.append("public interface DiffRetSub extends DiffRetSuper {\n");
+        code.append("  String foo();\n");
+        code.append("}\n");
+        return code;
+      }
+    });
+
+    addSnippetImport("test.DiffRetSub");
+
     try {
       // The snippet must reference the classes so they will be compiled in
       program = compileSnippet("void",
@@ -375,6 +401,18 @@
       HasEnclosingType res = lookup("test.Bar::foo(*)", errors);
       errors.assertHasError();
     }
+
+    /*
+     * Test a lookup where the subtype has a narrower return type than the
+     * supertype.
+     */
+    {
+      MockErrorReporter errors = new MockErrorReporter();
+      JMethod res = (JMethod) lookup("test.DiffRetSub::foo()", errors);
+      errors.assertNoError();
+      assertEquals("test.DiffRetSub", res.getEnclosingType().getName());
+      assertEquals("foo", res.getName());
+    }
   }
 
   public void testInterfaces() {
@@ -446,7 +484,7 @@
       assertEquals("test.PrivateSub", res.getEnclosingType().getName());
       assertEquals("field", res.getName());
     }
-    
+
     // test private entries in the superclass
     {
       MockErrorReporter errors = new MockErrorReporter();