1 package polyglot.visit; 2 3 import polyglot.ast.*; 4 import polyglot.types.*; 5 import polyglot.util.*; 6 import java.util.*; 7 8 public class FlowGraph { 9 29 protected Map peerMap; 30 31 34 protected Term root; 35 36 39 protected boolean forward; 40 41 FlowGraph(Term root, boolean forward) { 42 this.root = root; 43 this.forward = forward; 44 this.peerMap = new HashMap(); 45 } 46 47 public Term startNode() { return forward ? root.entry() : root; } 48 public Term finishNode() { return forward ? root : root.entry(); } 49 public Term entryNode() { return root.entry(); } 50 public Term exitNode() { return root; } 51 public Term root() { return root; } 52 public boolean forward() { return forward; } 53 54 public Collection pathMaps() { 55 return peerMap.values(); 56 } 57 58 public Map pathMap(Node n) { 59 return (Map) peerMap.get(new IdentityKey(n)); 60 } 61 62 65 public Collection peers() { 66 Collection c = new ArrayList(); 67 for (Iterator i = peerMap.values().iterator(); i.hasNext(); ) { 68 Map m = (Map) i.next(); 69 for (Iterator j = m.values().iterator(); j.hasNext(); ) { 70 c.add(j.next()); 71 } 72 } 73 return c; 74 } 75 76 83 public Peer peer(Term n, DataFlow df) { 84 return peer(n, Collections.EMPTY_LIST, df); 85 } 86 87 91 public Collection peers(Term n) { 92 IdentityKey k = new IdentityKey(n); 93 Map pathMap = (Map) peerMap.get(k); 94 if (pathMap == null) { 95 return Collections.EMPTY_LIST; 96 } 97 return pathMap.values(); 98 } 99 100 108 public Peer peer(Term n, List path_to_finally, DataFlow df) { 109 IdentityKey k = new IdentityKey(n); 110 Map pathMap = (Map) peerMap.get(k); 111 if (pathMap == null) { 112 pathMap = new HashMap(); 113 peerMap.put(k, pathMap); 114 } 115 116 ListKey lk = new ListKey(path_to_finally); 117 Peer p = (Peer) pathMap.get(lk); 118 if (p == null) { 119 p = new Peer(n, path_to_finally); 120 pathMap.put(lk, p); 121 } 122 return p; 123 } 124 125 137 public static class EdgeKey { 138 protected Object o; 139 protected EdgeKey(Object o) { 140 this.o = o; 141 } 142 public int hashCode() { 143 return o.hashCode(); 144 } 145 public boolean equals(Object other) { 146 return (other instanceof EdgeKey) && 147 (((EdgeKey)other).o.equals(this.o)); 148 } 149 public String toString() { 150 return o.toString(); 151 } 152 } 153 154 172 public static class ExceptionEdgeKey extends EdgeKey { 173 public ExceptionEdgeKey(Type t) { 174 super(t); 175 } 176 177 public Type type() { 178 return (Type) o; 179 } 180 181 public String toString() { 182 return (type().isClass() ? type().toClass().name() : type().toString() ); 183 } 184 } 185 186 190 public static final EdgeKey EDGE_KEY_TRUE = new EdgeKey("true"); 191 192 196 public static final EdgeKey EDGE_KEY_FALSE = new EdgeKey("false"); 197 198 205 public static final EdgeKey EDGE_KEY_OTHER = new EdgeKey(""); 206 207 217 public static class Edge { 218 protected Edge(EdgeKey key, Peer target) { 219 this.key = key; 220 this.target = target; 221 } 222 public EdgeKey getKey() { 223 return key; 224 } 225 public Peer getTarget() { 226 return target; 227 } 228 protected EdgeKey key; 229 protected Peer target; 230 public String toString() { 231 return "(" + key + ")" + target; 232 } 233 234 } 235 236 244 public static class Peer { 245 protected DataFlow.Item inItem; protected Map outItems; protected Term node; protected List succs; protected List preds; protected List path_to_finally; 254 259 private Set succEdgeKeys; 260 261 public Peer(Term node, List path_to_finally) { 262 this.node = node; 263 this.path_to_finally = path_to_finally; 264 this.inItem = null; 265 this.outItems = null; 266 this.succs = new ArrayList(); 267 this.preds = new ArrayList(); 268 this.succEdgeKeys = null; 269 } 270 271 272 public List succs() { return succs; } 273 274 275 public List preds() { return preds; } 276 277 278 public Term node() { return node; } 279 280 284 public DataFlow.Item inItem() { return inItem; } 285 286 290 public DataFlow.Item outItem(EdgeKey key) { 291 return (DataFlow.Item) outItems.get(key); 292 } 293 294 public String toString() { 295 return node + "[" + hashCode() + ": " + path_to_finally + "]"; 296 } 297 298 public Set succEdgeKeys() { 299 if (this.succEdgeKeys == null) { 300 this.succEdgeKeys = new HashSet(); 303 for (Iterator iter = this.succs.iterator(); iter.hasNext(); ) { 304 Edge e = (Edge)iter.next(); 305 this.succEdgeKeys.add(e.getKey()); 306 } 307 if (this.succEdgeKeys.isEmpty()) { 308 this.succEdgeKeys.add(FlowGraph.EDGE_KEY_OTHER); 312 } 313 } 314 return this.succEdgeKeys; 315 } 316 } 317 318 322 protected static class ListKey { 323 protected List list; 324 325 ListKey(List list) { 326 this.list = list; 327 } 328 329 public int hashCode() { 330 return list.hashCode(); 331 } 332 333 public boolean equals(Object other) { 334 if (other instanceof ListKey) { 335 ListKey k = (ListKey) other; 336 return CollectionUtil.equals(list, k.list); 337 } 338 339 return false; 340 } 341 } 342 343 public String toString() { 344 345 StringBuffer sb = new StringBuffer (); 346 Set todo = new HashSet(this.peers()); 347 LinkedList queue = new LinkedList(this.peers(this.startNode())); 348 349 while (!queue.isEmpty()) { 350 Peer p = (Peer)queue.removeFirst(); 351 todo.remove(p); 352 sb.append(p.node+" (" + p.node.position()+ ")\n"); 354 for (Iterator i = p.succs.iterator(); i.hasNext(); ) { 355 Edge e = (Edge)i.next(); 356 Peer q = e.getTarget(); 357 sb.append(" -> " + q.node+" (" + q.node.position()+ ")\n"); 358 if (todo.contains(q) && !queue.contains(q)) { 360 queue.addLast(q); 361 } 362 } 363 364 if (queue.isEmpty() && !todo.isEmpty()) { 365 sb.append("\n\n***UNREACHABLE***\n"); 366 queue.addAll(todo); 367 todo = Collections.EMPTY_SET; 368 } 369 } 370 371 return sb.toString(); 372 } 373 } 374 | Popular Tags |