Fix virtual invocation resolution during dependency check

This commit is contained in:
Alexey Andreev 2015-05-10 13:46:54 +03:00
parent 1945e6cb44
commit 578c2ce4b8

View File

@ -177,7 +177,7 @@ class DependencyGraphBuilder {
@Override @Override
public void consume(DependencyType type) { public void consume(DependencyType type) {
for (int i = 0; i < exceptions.length; ++i) { for (int i = 0; i < exceptions.length; ++i) {
if (exceptions[i] == null || isAssignableFrom(checker.getClassSource(), exceptions[i], if (exceptions[i] == null || isAssignableFrom(checker.getClassSource(), exceptions[i].getName(),
type.getName())) { type.getName())) {
if (vars[i] != null) { if (vars[i] != null) {
vars[i].propagate(type); vars[i].propagate(type);
@ -226,15 +226,24 @@ class DependencyGraphBuilder {
if (className.startsWith("[")) { if (className.startsWith("[")) {
className = "java.lang.Object"; className = "java.lang.Object";
} }
if (!isAssignableFrom(checker.getClassSource(), filterClass, className)) { if (!isAssignableFrom(checker.getClassSource(), filterClass.getName(), className)) {
return; return;
} }
MethodReference methodRef = new MethodReference(className, methodDesc); MethodReference methodRef = new MethodReference(className, methodDesc);
MethodDependency methodDep = checker.linkMethod(methodRef, new CallLocation(caller.getMethod(), location)); final MethodDependency methodDep = checker.linkMethod(methodRef,
new CallLocation(caller.getMethod(), location));
if (!methodDep.isMissing() && knownMethods.add(methodRef)) { if (!methodDep.isMissing() && knownMethods.add(methodRef)) {
methodDep.use(); methodDep.use();
DependencyNode[] targetParams = methodDep.getVariables(); DependencyNode[] targetParams = methodDep.getVariables();
for (int i = 0; i < parameters.length; ++i) { if (parameters[0] != null && targetParams[0] != null) {
parameters[0].connect(targetParams[0], new DependencyTypeFilter() {
@Override public boolean match(DependencyType thisType) {
return isAssignableFrom(checker.getClassSource(), methodDep.getMethod().getOwnerName(),
thisType.getName());
}
});
}
for (int i = 1; i < parameters.length; ++i) {
if (parameters[i] != null && targetParams[i] != null) { if (parameters[i] != null && targetParams[i] != null) {
parameters[i].connect(targetParams[i]); parameters[i].connect(targetParams[i]);
} }
@ -247,9 +256,8 @@ class DependencyGraphBuilder {
} }
} }
private static boolean isAssignableFrom(ClassReaderSource classSource, ClassReader supertype, private static boolean isAssignableFrom(ClassReaderSource classSource, String supertype, String subtypeName) {
String subtypeName) { if (supertype.equals(subtypeName)) {
if (supertype.getName().equals(subtypeName)) {
return true; return true;
} }
ClassReader subtype = classSource.get(subtypeName); ClassReader subtype = classSource.get(subtypeName);
@ -355,7 +363,7 @@ class DependencyGraphBuilder {
if (targetClass.getName().equals("java.lang.Object")) { if (targetClass.getName().equals("java.lang.Object")) {
return true; return true;
} }
return isAssignableFrom(dependencyChecker.getClassSource(), targetClass, return isAssignableFrom(dependencyChecker.getClassSource(), targetClass.getName(),
type.getName()); type.getName());
} }
}); });