changes.
[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 BaseCallGraph {
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 isCalled(MethodDescriptor md) {
32     return false;
33   }
34
35   public boolean isCallable(MethodDescriptor md) {
36     return discovered.contains(md);
37   }
38
39   //Work our way down from main
40   private void buildGraph() {
41     MethodDescriptor main=tu.getMain();
42     HashSet tovisit=new HashSet();
43     tovisit.add(main);
44     discovered.add(main);
45     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
46
47     while(it.hasNext()) {
48       ClassDescriptor cn=(ClassDescriptor)it.next();
49       Iterator methodit=cn.getMethods();
50       //Iterator through methods
51       while(methodit.hasNext()) {
52         MethodDescriptor md=(MethodDescriptor)methodit.next();
53         if (md.isStaticBlock()) {
54           tovisit.add(md);
55           discovered.add(md);
56         }
57       }
58     }
59
60
61     while(!tovisit.isEmpty()) {
62       MethodDescriptor md=(MethodDescriptor)tovisit.iterator().next();
63       tovisit.remove(md);
64       FlatMethod fm=state.getMethodFlat(md);
65       if (fm==null)
66         continue;
67       analyzeMethod(md, fm);
68       for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator(); fnit.hasNext(); ) {
69         FlatNode fn=fnit.next();
70         if (fn.kind()==FKind.FlatCall) {
71           FlatCall fcall=(FlatCall)fn;
72           Set callees=fcall.getThis()==null?getMethods(fcall.getMethod()):getMethods(fcall.getMethod(),fcall.getThis().getType());
73
74           if (fcall.getThis()!=null) {
75             MethodDescriptor methodd=fcall.getMethod();
76
77             if (methodd.getClassDesc()==tu.getClass(TypeUtil.ThreadClass)&&
78                 methodd.getSymbol().equals("start")&&methodd.numParameters()==0&&!methodd.getModifiers().isStatic()) {
79               //Have call to start
80               HashSet ns=new HashSet();
81               ns.addAll(callees);
82               ns.addAll(getMethods(tu.getRun(), fcall.getThis().getType()));
83               ns.addAll(getMethods(tu.getStaticStart(), fcall.getThis().getType()));
84               callees=ns;
85             }
86           }
87
88           for(Iterator mdit=callees.iterator(); mdit.hasNext(); ) {
89             MethodDescriptor callee=(MethodDescriptor)mdit.next();
90             if (!discovered.contains(callee)) {
91               discovered.add(callee);
92               tovisit.add(callee);
93             }
94           }
95         }
96       }
97     }
98   }
99 }