1
2
3
4 package joeq.Compiler.Quad;
5
6 import java.util.Collection;
7 import java.util.Iterator;
8 import joeq.Class.jq_Class;
9 import joeq.Util.Templates.List;
10 import joeq.Util.Templates.ListIterator;
11 import joeq.Util.Templates.ListWrapper;
12
13 /***
14 * Holds a list of exception handlers that protect a basic block.
15 * It includes a reference to a parent exception handler list, to handle nesting
16 * of exception handlers.
17 * These form a tree structure where each node has a pointer to its parent.
18 *
19 * @author John Whaley <jwhaley@alum.mit.edu>
20 * @see ExceptionHandler
21 * @see ExceptionHandlerIterator
22 * @version $Id: ExceptionHandlerList.java 1931 2004-09-22 22:17:47Z joewhaley $
23 */
24
25 public class ExceptionHandlerList extends java.util.AbstractList implements List.ExceptionHandler {
26
27 /*** The exception handler. */
28 private ExceptionHandler exception_handler;
29 /*** The parent exception handler set. */
30 ExceptionHandlerList parent;
31
32 ExceptionHandlerList() {}
33
34 /*** Creates new ExceptionHandlerList containing the given exception handler and no parent set.
35 * @param exception_handler exception handler to include in the set. */
36 public ExceptionHandlerList(ExceptionHandler exception_handler) {
37 this.exception_handler = exception_handler;
38 this.parent = null;
39 }
40 /*** Creates new ExceptionHandlerList containing the given exception handler and parent set.
41 * @param exception_handler exception handler to include in the set.
42 * @param parent the parent set of exception handlers. */
43 public ExceptionHandlerList(ExceptionHandler exception_handler, ExceptionHandlerList parent) {
44 this.exception_handler = exception_handler;
45 this.parent = parent;
46 }
47
48 /*** Return the handler in this set. Doesn't include parent handlers.
49 * @return the handler in this set, without parent handlers. */
50 public ExceptionHandler getHandler() { return exception_handler; }
51 public void setHandler(ExceptionHandler eh) { exception_handler = eh; }
52 /*** Return the parent set of exception handlers, or null if this set doesn't have a parent.
53 * @return the parent set of exception handlers, or null if this set doesn't have a parent. */
54 public ExceptionHandlerList getParent() { return parent; }
55 public void setParent(ExceptionHandlerList p) { parent = p; }
56
57 /*** Returns the first exception handler in the list that MUST catch an
58 * exception of the given type, or null if there is no handler that must catch it.
59 * @return the handler that must catch the exception type, or null if there is no such handler
60 */
61 public ExceptionHandler mustCatch(jq_Class exType) {
62 ExceptionHandlerList p = this;
63 while (p != null) {
64 if (p.getHandler().mustCatch(exType)) return p.getHandler();
65 p = p.getParent();
66 }
67 return null;
68 }
69
70 /*** Returns the list of exception handlers in this list that MAY catch the given exception type.
71 * @return the list of handlers that may catch the exception type
72 */
73 public List.ExceptionHandler mayCatch(jq_Class exType) {
74 java.util.List list = new java.util.LinkedList();
75 ExceptionHandlerList p = this;
76 while (p != null) {
77 if (p.getHandler().mustCatch(exType)) {
78 list.add(p.getHandler()); break;
79 }
80 if (p.getHandler().mayCatch(exType)) list.add(p.getHandler());
81 p = p.getParent();
82 }
83 return new ListWrapper.ExceptionHandler(list);
84 }
85
86 /*** Returns the list of exception handlers in this list that MAY catch the given exception type.
87 * @return the list of handlers that may catch the exception type
88 */
89 public List.ExceptionHandler mayCatch(Collection exTypes) {
90 java.util.List list = new java.util.LinkedList();
91 java.util.List eTypes = new java.util.LinkedList(exTypes);
92 ExceptionHandlerList p = this;
93 outer:
94 while (p != null) {
95 for (Iterator i = eTypes.iterator(); i.hasNext(); ) {
96 jq_Class exType = (jq_Class) i.next();
97 if (p.getHandler().mustCatch(exType)) {
98 list.add(p.getHandler());
99 i.remove();
100 if (eTypes.isEmpty()) break outer;
101 else continue;
102 }
103 if (p.getHandler().mayCatch(exType)) {
104 list.add(p.getHandler());
105 }
106 }
107 p = p.getParent();
108 }
109 return new ListWrapper.ExceptionHandler(list);
110 }
111
112 /*** Return an iteration over the handlers in this set (and the handlers in parent sets).
113 * Handlers are returned in the correct order (this set, followed by parent sets.)
114 * @return an iteration over the handlers in this set (and the handlers in parent sets) in correct order. */
115 public ListIterator.ExceptionHandler exceptionHandlerIterator() {
116 return new ExceptionHandlerIterator(this);
117 }
118 public java.util.Iterator iterator() { return exceptionHandlerIterator(); }
119 public java.util.ListIterator listIterator() { return exceptionHandlerIterator(); }
120
121 public joeq.Compiler.Quad.ExceptionHandler getExceptionHandler(int index) {
122 if (index < 0) throw new IndexOutOfBoundsException();
123 ExceptionHandlerList p = this;
124 while (--index >= 0) {
125 if (p == null) throw new IndexOutOfBoundsException();
126 p = p.parent;
127 }
128 return p.exception_handler;
129 }
130
131 public Object get(int index) { return getExceptionHandler(index); }
132
133 public int size() {
134 int size = 0;
135 ExceptionHandlerList p = this;
136 while (p != null) {
137 ++size;
138 p = p.parent;
139 }
140 return size;
141 }
142
143 public static ExceptionHandlerList getEmptyList() { return EMPTY; }
144 public static final ExceptionHandlerList EMPTY = new ExceptionHandlerList(null) {
145 public int size() { return 0; }
146 public ListIterator.ExceptionHandler exceptionHandlerIterator() { return ExceptionHandlerIterator.getEmptyIterator(); }
147 public ExceptionHandler mustCatch(jq_Class exType) { return null; }
148 public List.ExceptionHandler mayCatch(jq_Class exType) { return getEmptyList(); }
149 };
150
151 }