checkin to only generate C for callable methods...
[IRC.git] / Robust / src / Analysis / CallGraph / JavaCallGraph.java
1 package Analysis.CallGraph;
2 import IR.State;
3 import IR.Flat.FlatMethod;
4 import IR.Flat.FlatNode;
5 import IR.Flat.FlatCall;
6 import IR.Flat.FKind;
7 import IR.Descriptor;
8 import IR.ClassDescriptor;
9 import IR.MethodDescriptor;
10 import IR.TaskDescriptor;
11 import IR.TypeDescriptor;
12 import IR.TypeUtil;
13 import java.util.*;
14 import java.io.*;
15
16 public class JavaCallGraph extends CallGraph {
17   TypeUtil tu;
18   HashSet discovered;
19
20   public JavaCallGraph(State state, TypeUtil tu) {
21     this.state=state;
22     mapVirtual2ImplementationSet = new Hashtable();
23     mapCaller2CalleeSet          = new Hashtable();
24     mapCallee2CallerSet          = new Hashtable();
25     discovered=new HashSet();
26     this.tu=tu;
27     buildVirtualMap();
28     buildGraph();
29   }
30
31   public boolean isCallable(MethodDescriptor md) {
32     return discovered.contains(md);
33   }
34
35   //Work our way down from main
36   private void buildGraph() {
37     MethodDescriptor main=tu.getMain();
38     HashSet tovisit=new HashSet();
39     tovisit.add(main);
40     discovered.add(main);
41     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
42
43     while(it.hasNext()) {
44       ClassDescriptor cn=(ClassDescriptor)it.next();
45       Iterator methodit=cn.getMethods();
46       //Iterator through methods
47       while(methodit.hasNext()) {
48         MethodDescriptor md=(MethodDescriptor)methodit.next();
49         if (md.isStaticBlock()) {
50           tovisit.add(md);
51           discovered.add(md);
52         }
53       }
54     }
55
56
57     while(!tovisit.isEmpty()) {
58       MethodDescriptor md=(MethodDescriptor)tovisit.iterator().next();
59       tovisit.remove(md);
60       FlatMethod fm=state.getMethodFlat(md);
61       if (fm==null)
62         continue;
63       analyzeMethod(md, fm);
64       for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
65         FlatNode fn=fnit.next();
66         if (fn.kind()==FKind.FlatCall) {
67           FlatCall fcall=(FlatCall)fn;
68           Set callees=fcall.getThis()==null?getMethods(fcall.getMethod()):getMethods(fcall.getMethod(),fcall.getThis().getType());
69
70           if (fcall.getThis()!=null) {
71             MethodDescriptor methodd=fcall.getMethod();
72
73             if (methodd.getClassDesc()==tu.getClass(TypeUtil.ThreadClass)&&
74                 methodd.getSymbol().equals("start")&&methodd.numParameters()==0&&!methodd.getModifiers().isStatic()) {
75               //Have call to start
76               HashSet ns=new HashSet();
77               ns.addAll(callees);
78               ns.addAll(getMethods(tu.getRun(), fcall.getThis().getType()));
79               callees=ns;
80             }
81           }
82
83           for(Iterator mdit=callees.iterator();mdit.hasNext();) {
84             MethodDescriptor callee=(MethodDescriptor)mdit.next();
85             if (!discovered.contains(callee)) {
86               discovered.add(callee);
87               tovisit.add(callee);
88             }
89           }
90         }
91       }
92     }
93   }
94 }