aspect CallGraph { // Total Call Graph syn Set MethodDecl.calls() { HashSet s = new HashSet(); this.collectCalls(s); return s; } syn Set MethodAccess.potentialTargetMethods() { return new HashSet(); } eq StaticMethodAccess.potentialTargetMethods() { HashSet s = new HashSet(); s.add(decl()); return s; } eq VirtualMethodAccess.potentialTargetMethods() { TypeDecl f = isQualified() ? qualifier().type() : hostType(); HashSet s = new HashSet(); s.add(decl()); for(Iterator iter=decl().overriders().iterator(); iter.hasNext();) { MethodDecl mo = (MethodDecl) iter.next(); if (mo.hostType().instanceOf(f)) { s.add(mo); } } return s; } // Traverse a method to collect references to all called methods void ASTNode.collectCalls(Set s) { for (int i = 0; i < getNumChild(); i++) { getChild(i).collectCalls(s); } } void TypeDecl.collectCalls(Set s) { // Do nothing, since inner types should not be traversed when collecting calls within a method.. } void MethodAccess.collectCalls(Set s) { s.addAll(potentialTargetMethods()); } }