Fixed
This commit is contained in:
parent
621a95e291
commit
300a6099b7
3 changed files with 23 additions and 17 deletions
|
@ -54,14 +54,16 @@ public final class CallGraphBuilder implements ClassAnalyzer {
|
|||
if (opCode == Opcodes.INVOKESTATIC || opCode == Opcodes.INVOKESPECIAL) {
|
||||
// target is static, no fancy search needed
|
||||
callSite.addPossibleTargetClass(clazz); // Cave Johnson, we're done here
|
||||
} else if (opCode == Opcodes.INVOKEDYNAMIC) {
|
||||
} else if (opCode == Opcodes.INVOKEVIRTUAL) {
|
||||
final Deque<ClassType> subClasses = new ArrayDeque<>();
|
||||
subClasses.add(clazz);
|
||||
|
||||
// BFS over class and subclasses and add them all as possible targets
|
||||
while (!subClasses.isEmpty()) {
|
||||
final ClassType subClazz = subClasses.pop();
|
||||
callSite.addPossibleTargetClass(subClazz);
|
||||
if (!subClazz.isAbstract()) {
|
||||
callSite.addPossibleTargetClass(subClazz);
|
||||
}
|
||||
subClasses.addAll(subClazz.getSubTypes());
|
||||
}
|
||||
} else { // opCode == Opcodes.INVOKEINTERFACE
|
||||
|
|
|
@ -48,31 +48,25 @@ public class DotGraph {
|
|||
}
|
||||
|
||||
private void scanMethods() {
|
||||
final Deque<DotMethodNode> methodQueue = new ArrayDeque<>(methodNodes.getAll());
|
||||
|
||||
while (!methodQueue.isEmpty()) {
|
||||
final DotMethodNode methodNode = methodQueue.pop();
|
||||
final Method m = methodNode.getMethodLike().getMethod();
|
||||
for (final DotMethodNode fromMethodNode : methodNodes.getAll()) {
|
||||
final Method m = fromMethodNode.getMethodLike().getMethod();
|
||||
if (m == null) continue; // we care about actual methods only, not callsites
|
||||
|
||||
for (final CallSite c : m.getCallSites()) {
|
||||
final DotMethodNode toMethodNode = methodNodes.addIfNew(new DotMethodNode(new CallSiteAdapter(c)));
|
||||
otherEdges.add(new InvokeEdge(methodNode, toMethodNode, c.getOpcode(), true));
|
||||
otherEdges.add(new InvokeEdge(fromMethodNode, toMethodNode, c.getOpcode(), true));
|
||||
|
||||
for (final ClassType p : c.getPossibleTargetClasses()) {
|
||||
if (p.getInternalName().endsWith("Math")) {
|
||||
System.out.println("aaa");
|
||||
}
|
||||
|
||||
final DotMethodNode pm = methodNodes.addIfNew(new DotMethodNode(new PossibleTargetAdapter(c, p)));
|
||||
final DotClassNode pc = classNodes.addIfNew(new DotClassNode(p));
|
||||
final DotMethodNode toPossibleMethodNode = methodNodes.addIfNew(new DotMethodNode(new PossibleTargetAdapter(c, p)));
|
||||
otherEdges.add(new InvokeEdge(fromMethodNode, toPossibleMethodNode, c.getOpcode(), false));
|
||||
|
||||
// if the target is a new node, the class of that node might not have been analyzed,
|
||||
// thus class to method edges might not have been added
|
||||
classToMethodEdges.add(new ClassToMethodEdge(pc, pm));
|
||||
// thus class to method edges might not have been added. We re-add the class to method edge, and
|
||||
// duplicates are handled by the Set collection.
|
||||
final DotClassNode toPossibleClassNode = classNodes.addIfNew(new DotClassNode(p));
|
||||
classToMethodEdges.add(new ClassToMethodEdge(toPossibleClassNode, toPossibleMethodNode));
|
||||
}
|
||||
|
||||
otherEdges.add(new InvokeEdge(methodNode, toMethodNode, c.getOpcode(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,4 +57,14 @@ public class InvokeEdge implements DotEdge {
|
|||
public DotMethodNode getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InvokeEdge{" +
|
||||
"from=" + from.getMethodLike().prettyName() +
|
||||
", to=" + to.getMethodLike().prettyName() +
|
||||
", invokeOpCode=" + invokeOpCode +
|
||||
", isDeclared=" + isDeclared +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue