Fix inheritance provider chaining

Previously, each provider would be consulted until a matching parent is
found. This is incorrect and caused spurious warnings with --live
(jar + runtime inheritance), as unmatched classes in the jar would fall
through to the runtime inheritance provider.

Now once a provider returns non-null, no other providers are checked.
null indicates the provider knows nothing about the class and should
ask elsewhere, non-null indicates a definitive list of inheritance
(extends/implements list) classes. Should be slightly faster, too.
This commit is contained in:
Agaricus 2013-01-23 19:55:44 -08:00
parent b69a11cf5b
commit 7ed216d944
4 changed files with 23 additions and 12 deletions

View File

@ -36,7 +36,7 @@ public interface IInheritanceProvider {
* Get the superclass and implemented interfaces of a class
*
* @param className
* @return
* @return List of interfaces, or null if no information is available and other providers should be checked
*/
List<String> getParents(String className);
}

View File

@ -49,14 +49,18 @@ public class JarInheritanceProvider implements IInheritanceProvider {
@Override
@SuppressWarnings("unchecked") // Saddens me to see ASM strip vital info like that
public List<String> getParents(String owner) {
List<String> parents = new ArrayList<String>();
ClassNode node = self.getNode(owner);
if (node != null) {
for (String iface : (List<String>) node.interfaces) {
parents.add(iface);
}
parents.add(node.superName);
if (node == null) {
return null;
}
List<String> parents = new ArrayList<String>();
for (String iface : (List<String>) node.interfaces) {
parents.add(iface);
}
parents.add(node.superName);
return parents;
}
}

View File

@ -97,12 +97,19 @@ public class JarRemapper extends Remapper {
String mapped = map.get(key);
if (mapped == null) {
// ask each provider for inheritance information on the class, until one responds
for (IInheritanceProvider inheritanceProvider : inheritanceProviders) {
for (String parent : inheritanceProvider.getParents(owner)) {
mapped = tryClimb(map, type, parent, name);
if (mapped != null) {
return mapped;
List<String> parents = inheritanceProvider.getParents(owner);
if (parents != null) {
// climb the inheritance tree
for (String parent : parents) {
mapped = tryClimb(map, type, parent, name);
if (mapped != null) {
return mapped;
}
}
break;
}
}
}

View File

@ -47,7 +47,7 @@ public class RuntimeInheritanceProvider implements IInheritanceProvider {
//clazz = Class.forName(toSourceName(sourceClassName)); // runs static initializers - avoid!
} catch (Throwable t) {
SpecialSource.log("RuntimeInheritanceProvider failed: " + t);
return parents;
return null;
}
for (Class iface : clazz.getInterfaces()) {