diff options
author | Paul Duffin <paulduffin@google.com> | 2016-08-05 13:24:03 +0100 |
---|---|---|
committer | Paul Duffin <paulduffin@google.com> | 2017-03-21 15:28:38 +0000 |
commit | 309cc66e50aaac713a5c2c72e3ea6b236716b036 (patch) | |
tree | 57350c8dc8be15096525e676b6e69563f1a8ecbb /dexmaker | |
parent | 7c8fd7bceb7ca05e236386167614ce359e6633b9 (diff) | |
download | dexmaker-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.java | 12 |
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) { |