5 import Analysis.CallGraph.*;
7 public class SESETree {
12 Hashtable<MethodDescriptor, Set<SESENode>> toanalyze=new Hashtable<MethodDescriptor,Set<SESENode>>();
13 Hashtable<MethodDescriptor, Set<SESENode>> discovered=new Hashtable<MethodDescriptor,Set<SESENode>>();
14 Hashtable<FlatSESEEnterNode, SESENode> sesemap=new Hashtable<FlatSESEEnterNode, SESENode>();
16 public SESETree(State state, TypeUtil typeutil, CallGraph callgraph) {
18 this.typeutil=typeutil;
19 this.callgraph=callgraph;
20 root=new SESENode(null, true);
24 public SESENode getRoot() {
28 public void doAnalysis() {
29 MethodDescriptor main=typeutil.getMain();
30 add(toanalyze, main, root);
31 add(discovered, main, root);
33 while(!toanalyze.isEmpty()) {
34 MethodDescriptor md=toanalyze.keySet().iterator().next();
35 Set<SESENode> context=toanalyze.get(md);
37 FlatMethod fm=state.getMethodFlat(md);
38 analyzeMethod(fm, context);
42 public SESENode getSESE(FlatSESEEnterNode enter) {
43 if (!sesemap.containsKey(enter)) {
44 sesemap.put(enter, new SESENode(enter, false));
46 return sesemap.get(enter);
49 public Set<SESENode> getSESE(MethodDescriptor md) {
50 return discovered.get(md);
53 public Hashtable<FlatNode, Stack<SESENode>> analyzeMethod(FlatMethod fm) {
54 return analyzeMethod(fm, null);
57 private Hashtable<FlatNode, Stack<SESENode>> analyzeMethod(FlatMethod fm, Set<SESENode> context) {
58 Hashtable<FlatNode, Stack<SESENode>> stacks=new Hashtable<FlatNode, Stack<SESENode>> ();
59 stacks.put(fm, new Stack<SESENode>());
60 HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
61 HashSet<FlatNode> fndiscovered=new HashSet<FlatNode>();
64 while(!tovisit.isEmpty()) {
65 FlatNode fn=tovisit.iterator().next();
67 Stack<SESENode> instack=stacks.get(fm);
69 case FKind.FlatCall: {
72 FlatCall fc=(FlatCall)fn;
74 Set<SESENode> parents;
75 if (instack.isEmpty()) {
78 parents=new HashSet<SESENode>();
79 parents.add(instack.peek());
81 for(Iterator<SESENode> parentit=parents.iterator();parentit.hasNext();) {
82 SESENode parentsese=parentit.next();
83 for(Iterator<MethodDescriptor> calleeit=(fc.getThis()==null?callgraph.getMethods(fc.getMethod()):callgraph.getMethods(fc.getMethod(), fc.getThis().getType())).iterator(); calleeit.hasNext();) {
84 MethodDescriptor md=calleeit.next();
85 if (add(discovered,md, parentsese)) {
86 add(toanalyze, md, parentsese);
92 case FKind.FlatSESEEnterNode: {
93 FlatSESEEnterNode enter=(FlatSESEEnterNode)fn;
96 Set<SESENode> parents;
97 if (instack.isEmpty()) {
100 parents=new HashSet<SESENode>();
101 parents.add(instack.peek());
103 SESENode sese=getSESE(enter);
104 for(Iterator<SESENode> parentit=parents.iterator();parentit.hasNext();) {
105 SESENode parentsese=parentit.next();
106 parentsese.addChild(sese);
109 Stack<SESENode> copy=(Stack<SESENode>)instack.clone();
114 case FKind.FlatSESEExitNode: {
115 FlatSESEExitNode exit=(FlatSESEExitNode)fn;
116 Stack<SESENode> copy=(Stack<SESENode>)instack.clone();
122 for(int i=0;i<fn.numNext();i++) {
123 FlatNode fnext=fn.getNext(i);
124 if (!fndiscovered.contains(fnext)) {
125 fndiscovered.add(fnext);
127 stacks.put(fnext, instack);
134 public static boolean add(Hashtable<MethodDescriptor, Set<SESENode>> discovered, MethodDescriptor md, SESENode sese) {
135 if (!discovered.containsKey(md))
136 discovered.put(md, new HashSet<SESENode>());
137 if (discovered.get(md).contains(sese))
139 discovered.get(md).add(sese);
146 HashSet<SESENode> children;
147 HashSet<SESENode> parents;
149 FlatSESEEnterNode node;
150 SESENode(FlatSESEEnterNode node, boolean isRoot) {
151 children=new HashSet<SESENode>();
156 public boolean isLeaf() {
157 return children.isEmpty();
160 protected void addChild(SESENode child) {
162 child.parents.add(this);
165 public Set<SESENode> getParents() {
169 public Set<SESENode> getChildren() {