prevent infinite recursion for cycle of callers
[IRC.git] / Robust / src / Analysis / CallGraph / CallGraph.java
index 3042da3ee960b561b8a241f2412861d614019110..6039499347773c36aaa32feca72c5f5ce7823489 100644 (file)
@@ -100,18 +100,40 @@ public class CallGraph {
 
   /** Given a call to MethodDescriptor, lists the methods which
       could actually be call by that method. */
+  public Set getMethodCalls(TaskDescriptor td) {
+    return getMethodCalls( (Descriptor) td);
+  }
+
   public Set getMethodCalls(MethodDescriptor md) {
+    return getMethodCalls( (Descriptor) md);
+  }
+
+  public Set getMethodCalls(Descriptor d) {
+    assert d instanceof MethodDescriptor ||
+    d instanceof TaskDescriptor;
+
     HashSet ns=new HashSet();
-    ns.add(md);
-    Set s=(Set)mapCaller2CalleeSet.get(md);
+    ns.add(d);
+    return getMoreMethodCalls( ns, d );
+  }
+
+  private Set getMoreMethodCalls( HashSet found, Descriptor d ) {
+    HashSet ns=new HashSet();
+    ns.add(d);
+    found.add(d);
+    Set s=(Set)mapCaller2CalleeSet.get(d);
     if (s!=null)
       for(Iterator it=s.iterator(); it.hasNext();) {
-       MethodDescriptor md2=(MethodDescriptor)it.next();
-       ns.addAll(getMethodCalls(md2));
+       MethodDescriptor md=(MethodDescriptor)it.next();
+       if( !found.contains(md) ) {
+         found.contains(md);
+         ns.addAll(getMoreMethodCalls(found, md));
+       }
       }
-    return ns;
+    return ns;    
   }
 
+
   private void buildGraph() {
     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
     while(it.hasNext()) {
@@ -169,54 +191,55 @@ public class CallGraph {
     }
   }
 
-  public void writeToDot(String graphName)  throws java.io.IOException {
-    // each task or method only needs to be labeled once
-    // in a dot file
+
+  public void writeVirtual2ImplemToDot(String graphName)  throws java.io.IOException {
     HashSet labeledInDot = new HashSet();
 
-    // write out the call graph using the callees mapping
-    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallees.dot") );
-    bw.write("digraph "+graphName+"byCallees {\n");
-    Iterator mapItr = mapCallee2CallerSet.entrySet().iterator();
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+".dot") );
+    bw.write("digraph "+graphName+" {\n");
+    Iterator mapItr =  mapVirtual2ImplementationSet.entrySet().iterator();
     while( mapItr.hasNext() ) {
       Map.Entry me        = (Map.Entry)mapItr.next();
-      MethodDescriptor callee    = (MethodDescriptor) me.getKey();
-      HashSet callerSet = (HashSet)          me.getValue();
+      MethodDescriptor virtual   = (MethodDescriptor) me.getKey();
+      HashSet implemSet = (HashSet)          me.getValue();
 
-      if( !labeledInDot.contains(callee) ) {
-       labeledInDot.add(callee);
-       bw.write("  " + callee.getNum() + "[label=\"" + callee + "\"];\n");
+      if( !labeledInDot.contains(virtual) ) {
+       labeledInDot.add(virtual);
+       bw.write("  "+virtual.getNum()+"[label=\""+virtual+"\"];\n");
       }
 
-      Iterator callerItr = callerSet.iterator();
-      while( callerItr.hasNext() ) {
-       Descriptor caller = (Descriptor) callerItr.next();
+      Iterator implemItr = implemSet.iterator();
+      while( implemItr.hasNext() ) {
+       Descriptor implem = (Descriptor) implemItr.next();
 
-       if( !labeledInDot.contains(caller) ) {
-         labeledInDot.add(caller);
-         bw.write("  " + caller.getNum() + "[label=\"" + caller + "\"];\n");
+       if( !labeledInDot.contains(implem) ) {
+         labeledInDot.add(implem);
+         bw.write("  "+implem.getNum()+"[label=\""+implem+"\"];\n");
        }
 
-       bw.write("  " + callee.getNum() + "->" + caller.getNum() + ";\n");
+       bw.write("  "+virtual.getNum()+"->"+implem.getNum()+";\n");
       }
     }
     bw.write("}\n");
     bw.close();
+  }
+
 
+  public void writeCaller2CalleesToDot(String graphName)  throws java.io.IOException {
     // write out the call graph (should be equivalent) by
     // using the callers mapping
-    labeledInDot = new HashSet();
-    bw = new BufferedWriter(new FileWriter(graphName+"byCallers.dot") );
+    HashSet labeledInDot = new HashSet();
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallers.dot") );
     bw.write("digraph "+graphName+"byCallers {\n");
-    mapItr = mapCaller2CalleeSet.entrySet().iterator();
+    Iterator mapItr = mapCaller2CalleeSet.entrySet().iterator();
     while( mapItr.hasNext() ) {
-      Map.Entry me        = (Map.Entry)mapItr.next();
-      Descriptor caller    = (Descriptor) me.getKey();
+      Map.Entry me      = (Map.Entry)mapItr.next();
+      Descriptor caller = (Descriptor) me.getKey();
       HashSet calleeSet = (HashSet)    me.getValue();
 
       if( !labeledInDot.contains(caller) ) {
        labeledInDot.add(caller);
-       bw.write("  " + caller.getNum() + "[label=\"" + caller + "\"];\n");
+       bw.write("  "+caller.getNum()+"[label=\"" +caller+"\"];\n");
       }
 
       Iterator calleeItr = calleeSet.iterator();
@@ -225,10 +248,46 @@ public class CallGraph {
 
        if( !labeledInDot.contains(callee) ) {
          labeledInDot.add(callee);
-         bw.write("  " + callee.getNum() + "[label=\"" + callee + "\"];\n");
+         bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
+       }
+
+       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
+      }
+    }
+    bw.write("}\n");
+    bw.close();
+  }
+
+
+  public void writeCallee2CallersToDot(String graphName)  throws java.io.IOException {
+    // each task or method only needs to be labeled once
+    // in a dot file
+    HashSet labeledInDot = new HashSet();
+
+    // write out the call graph using the callees mapping
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallees.dot") );
+    bw.write("digraph "+graphName+"byCallees {\n");
+    Iterator mapItr = mapCallee2CallerSet.entrySet().iterator();
+    while( mapItr.hasNext() ) {
+      Map.Entry me        = (Map.Entry)mapItr.next();
+      MethodDescriptor callee    = (MethodDescriptor) me.getKey();
+      HashSet callerSet = (HashSet)          me.getValue();
+
+      if( !labeledInDot.contains(callee) ) {
+       labeledInDot.add(callee);
+       bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
+      }
+
+      Iterator callerItr = callerSet.iterator();
+      while( callerItr.hasNext() ) {
+       Descriptor caller = (Descriptor) callerItr.next();
+
+       if( !labeledInDot.contains(caller) ) {
+         labeledInDot.add(caller);
+         bw.write("  "+caller.getNum()+"[label=\""+caller+"\"];\n");
        }
 
-       bw.write("  " + callee.getNum() + "->" + caller.getNum() + ";\n");
+       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
       }
     }
     bw.write("}\n");