import java.io.*;
public class CallGraph {
- private State state;
+ protected State state;
// MethodDescriptor maps to HashSet<MethodDescriptor>
- private Hashtable mapVirtual2ImplementationSet;
+ protected Hashtable mapVirtual2ImplementationSet;
// MethodDescriptor or TaskDescriptor maps to HashSet<MethodDescriptor>
- private Hashtable mapCaller2CalleeSet;
+ protected Hashtable mapCaller2CalleeSet;
// MethodDescriptor maps to HashSet<MethodDescriptor or TaskDescriptor>
- private Hashtable mapCallee2CallerSet;
+ protected Hashtable mapCallee2CallerSet;
+
+ protected CallGraph() {}
public CallGraph(State state) {
this.state=state;
// build a mapping of virtual methods to all
// possible implementations of that method
- private void buildVirtualMap() {
+ protected void buildVirtualMap() {
//Iterator through classes
Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
while(it.hasNext()) {
}
}
- private void analyzeMethod(Object caller, FlatMethod fm) {
+ protected void analyzeMethod(Object caller, FlatMethod fm) {
HashSet toexplore=new HashSet();
toexplore.add(fm);
HashSet explored=new HashSet();
--- /dev/null
+package Analysis.CallGraph;
+import IR.State;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatCall;
+import IR.Flat.FKind;
+import IR.Descriptor;
+import IR.ClassDescriptor;
+import IR.MethodDescriptor;
+import IR.TaskDescriptor;
+import IR.TypeDescriptor;
+import IR.TypeUtil;
+import java.util.*;
+import java.io.*;
+
+public class JavaCallGraph extends CallGraph {
+ TypeUtil tu;
+ public JavaCallGraph(State state, TypeUtil tu) {
+ this.state=state;
+ mapVirtual2ImplementationSet = new Hashtable();
+ mapCaller2CalleeSet = new Hashtable();
+ mapCallee2CallerSet = new Hashtable();
+ this.tu=tu;
+ buildVirtualMap();
+ buildGraph();
+ }
+
+ //Work our way down from main
+ private void buildGraph() {
+ MethodDescriptor main=tu.getMain();
+ HashSet tovisit=new HashSet();
+ HashSet discovered=new HashSet();
+ tovisit.add(main);
+ discovered.add(main);
+ while(!tovisit.isEmpty()) {
+ MethodDescriptor md=(MethodDescriptor)tovisit.iterator().next();
+ tovisit.remove(md);
+ FlatMethod fm=state.getMethodFlat(main);
+ analyzeMethod(md, fm);
+ for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
+ FlatNode fn=fnit.next();
+ if (fn.kind()==FKind.FlatCall) {
+ FlatCall fcall=(FlatCall)fn;
+ Set callees=getMethods(fcall.getMethod(),fcall.getThis().getType());
+ for(Iterator mdit=callees.iterator();mdit.hasNext();) {
+ MethodDescriptor callee=(MethodDescriptor)mdit.next();
+ if (!discovered.contains(callee)) {
+ discovered.add(callee);
+ tovisit.add(callee);
+ }
+ }
+ }
+ }
+ }
+ }
+}