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) {
|
if (opCode == Opcodes.INVOKESTATIC || opCode == Opcodes.INVOKESPECIAL) {
|
||||||
// target is static, no fancy search needed
|
// target is static, no fancy search needed
|
||||||
callSite.addPossibleTargetClass(clazz); // Cave Johnson, we're done here
|
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<>();
|
final Deque<ClassType> subClasses = new ArrayDeque<>();
|
||||||
subClasses.add(clazz);
|
subClasses.add(clazz);
|
||||||
|
|
||||||
// BFS over class and subclasses and add them all as possible targets
|
// BFS over class and subclasses and add them all as possible targets
|
||||||
while (!subClasses.isEmpty()) {
|
while (!subClasses.isEmpty()) {
|
||||||
final ClassType subClazz = subClasses.pop();
|
final ClassType subClazz = subClasses.pop();
|
||||||
callSite.addPossibleTargetClass(subClazz);
|
if (!subClazz.isAbstract()) {
|
||||||
|
callSite.addPossibleTargetClass(subClazz);
|
||||||
|
}
|
||||||
subClasses.addAll(subClazz.getSubTypes());
|
subClasses.addAll(subClazz.getSubTypes());
|
||||||
}
|
}
|
||||||
} else { // opCode == Opcodes.INVOKEINTERFACE
|
} else { // opCode == Opcodes.INVOKEINTERFACE
|
||||||
|
|
|
@ -48,31 +48,25 @@ public class DotGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scanMethods() {
|
private void scanMethods() {
|
||||||
final Deque<DotMethodNode> methodQueue = new ArrayDeque<>(methodNodes.getAll());
|
|
||||||
|
|
||||||
while (!methodQueue.isEmpty()) {
|
for (final DotMethodNode fromMethodNode : methodNodes.getAll()) {
|
||||||
final DotMethodNode methodNode = methodQueue.pop();
|
final Method m = fromMethodNode.getMethodLike().getMethod();
|
||||||
final Method m = methodNode.getMethodLike().getMethod();
|
|
||||||
if (m == null) continue; // we care about actual methods only, not callsites
|
if (m == null) continue; // we care about actual methods only, not callsites
|
||||||
|
|
||||||
for (final CallSite c : m.getCallSites()) {
|
for (final CallSite c : m.getCallSites()) {
|
||||||
final DotMethodNode toMethodNode = methodNodes.addIfNew(new DotMethodNode(new CallSiteAdapter(c)));
|
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()) {
|
for (final ClassType p : c.getPossibleTargetClasses()) {
|
||||||
if (p.getInternalName().endsWith("Math")) {
|
final DotMethodNode toPossibleMethodNode = methodNodes.addIfNew(new DotMethodNode(new PossibleTargetAdapter(c, p)));
|
||||||
System.out.println("aaa");
|
otherEdges.add(new InvokeEdge(fromMethodNode, toPossibleMethodNode, c.getOpcode(), false));
|
||||||
}
|
|
||||||
|
|
||||||
final DotMethodNode pm = methodNodes.addIfNew(new DotMethodNode(new PossibleTargetAdapter(c, p)));
|
|
||||||
final DotClassNode pc = classNodes.addIfNew(new DotClassNode(p));
|
|
||||||
|
|
||||||
// if the target is a new node, the class of that node might not have been analyzed,
|
// 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
|
// thus class to method edges might not have been added. We re-add the class to method edge, and
|
||||||
classToMethodEdges.add(new ClassToMethodEdge(pc, pm));
|
// 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() {
|
public DotMethodNode getTo() {
|
||||||
return to;
|
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