aboutsummaryrefslogtreecommitdiff
path: root/dexmaker
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2016-08-05 13:24:03 +0100
committerPaul Duffin <paulduffin@google.com>2017-03-21 15:28:38 +0000
commit309cc66e50aaac713a5c2c72e3ea6b236716b036 (patch)
tree57350c8dc8be15096525e676b6e69563f1a8ecbb /dexmaker
parent7c8fd7bceb7ca05e236386167614ce359e6633b9 (diff)
downloaddexmaker-309cc66e50aaac713a5c2c72e3ea6b236716b036.tar.gz
Scan for methods in extra interface hierarchy
The ProxyBuilder was not traversing the interface hierarchy of the extra interfaces provided by the caller to find methods to proxy. That resulted in an AbstractMethodError when those methods were called. (cherry picked from d6b8d02d4fc7d57f0b72dba598b6320ef02a8213) Bug: 36407367 Bug: 32912773 Test: Added a failing test then fixed it, reran tests Change-Id: If68105da3b7e62383c8fa8ececc21383b299d854
Diffstat (limited to 'dexmaker')
-rw-r--r--dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java12
1 files changed, 12 insertions, 0 deletions
diff --git a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
index 1daf8e3..b618c84 100644
--- a/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
+++ b/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java
@@ -632,9 +632,13 @@ public final class ProxyBuilder<T> {
private Method[] getMethodsToProxyRecursive() {
Set<MethodSetEntry> methodsToProxy = new HashSet<>();
Set<MethodSetEntry> seenFinalMethods = new HashSet<>();
+ // Traverse the class hierarchy to ensure that all concrete methods (which could be marked
+ // as final) are visited before any abstract methods from interfaces.
for (Class<?> c = baseClass; c != null; c = c.getSuperclass()) {
getMethodsToProxy(methodsToProxy, seenFinalMethods, c);
}
+ // Now traverse the interface hierarchy, starting with the ones implemented by the class,
+ // followed by any extra interfaces.
for (Class<?> c = baseClass; c != null; c = c.getSuperclass()) {
for (Class<?> i : c.getInterfaces()) {
getMethodsToProxy(methodsToProxy, seenFinalMethods, i);
@@ -710,6 +714,14 @@ public final class ProxyBuilder<T> {
}
sink.add(entry);
}
+
+ // Only visit the interfaces of this class if it is itself an interface. That prevents
+ // visiting interfaces of a class before its super classes.
+ if (c.isInterface()) {
+ for (Class<?> i : c.getInterfaces()) {
+ getMethodsToProxy(sink, seenFinalMethods, i);
+ }
+ }
}
private static <T> String getMethodNameForProxyOf(Class<T> clazz) {