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();
-
+
}