JClassType.getOverridableMethods() could return methods overridden as 'final'.

In AbstractMembers, final methods were simply ignored instead of being treated
as possible overrides of already seenm ethods. A final method should trigger the
removal of a method with the same signature from methodsBySignature.

http://gwt-code-reviews.appspot.com/839803/show
Fixes issues: 5270
Review by: scottb, jat


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8765 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
index e23f0a9..0d3336f 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
@@ -158,15 +158,22 @@
     for (int i = 0; i < declaredMethods.length; i++) {
       JMethod method = declaredMethods[i];
 
-      // Ensure that this method is overridable.
-      if (method.isFinal() || method.isPrivate() || method.isStatic()) {
-        // We cannot override this method, so skip it.
+      // Ensure that this method is inherited.
+      if (method.isPrivate() || method.isStatic()) {
+        // We don't inherit this method, so skip it.
         continue;
       }
 
-      // We can override this method, so record it.
       String sig = computeInternalSignature(method);
-      methodsBySignature.put(sig, method);
+
+      // Ensure that this method is overridable.
+      if (method.isFinal()) {
+        // We cannot override this method, but it might override another method, so remove any possibly overridden method.
+        methodsBySignature.remove(sig);
+      } else {
+        // We can override this method, so record it.
+        methodsBySignature.put(sig, method);
+      }
     }
   }
 
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
index 1f23d47..e231289 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
@@ -201,6 +201,21 @@
     // Check that we aren't including methods that aren't actually overridable
     // because they are final and/or private.
     {
+      assertMethodOverridable(typeOracle,
+          "com.google.gwt.core.ext.typeinfo.test.IA",
+          "com.google.gwt.core.ext.typeinfo.test.CA", "foo",
+          noParams);
+
+      assertMethodNotOverridable(typeOracle,
+          "com.google.gwt.core.ext.typeinfo.test.CB",
+          "com.google.gwt.core.ext.typeinfo.test.CB", "foo",
+          noParams);
+
+      assertMethodNotOverridable(typeOracle,
+          "com.google.gwt.core.ext.typeinfo.test.CB",
+          "com.google.gwt.core.ext.typeinfo.test.CC", "foo",
+          noParams);
+
       assertMethodNotOverridable(typeOracle,
           "com.google.gwt.core.ext.typeinfo.test.CA",
           "com.google.gwt.core.ext.typeinfo.test.CA", "caNotOverridableFinal",
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
index 30959ab..aa5f9b8 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
@@ -148,12 +148,12 @@
     assertEquals("A", annotation.value());
     JClassType aClass = constants[0].getType().isClass();
     JMethod[] methods = aClass.getOverridableMethods();
-    assertEquals(7, methods.length);
+    assertEquals(4, methods.length);
     // TODO(jat): verify getExtra is from A's anonymous subclass of
     //     EnumInterface when/if that is implemented.
     boolean found = false;
     for (JMethod method : methods) {
-      if ("name".equals(method.getName())) {
+      if ("getExtra".equals(method.getName())) {
         found = true;
         // TODO(jat); any other verification here?
       }
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java
index c9145c4..3e41990 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/CB.java
@@ -1,7 +1,10 @@
 package com.google.gwt.core.ext.typeinfo.test;
 
 public abstract class CB extends CA implements IB {
-  
+
+  public final void foo() {
+  }
+
   public abstract void ic();
-  
+
 }