001: /* TestTryStacks.java */
002: package org.quilt.cl;
003:
004: import java.util.Comparator;
005: import junit.framework.*;
006: import org.apache.bcel.generic.*;
007: import org.quilt.graph.*;
008:
009: /**
010: * Exercise quilt.cl.TryStacks.
011: *
012: * @author < a href="jddixon@users.sourceforge.net">Jim Dixon</a>
013: */
014: public class TestTryStacks extends TestCase {
015:
016: private CodeExceptionGen[] handlers = null;
017: private ControlFlowGraph graph = null;
018: private InstructionList ilist = null;
019: private SortedBlocks blox = null;
020: private TryStacks ts = null;
021:
022: private InstructionHandle startMain, midMain, endMain, tryStart2,
023: tryEnd2, catch2A, catch2B, tryMid1, tryEnd1, catch1A,
024: catch1B, catch1C;
025: private CodeExceptionGen handler1A, handler1B, handler1C,
026: handler2A, handler2B;
027:
028: public TestTryStacks(String name) {
029: super (name);
030: }
031:
032: public void setUp() {
033: blox = new SortedBlocks();
034: graph = new ControlFlowGraph();
035: ilist = new InstructionList();
036:
037: // a method with two try blocks starting at the same position
038: // A
039: // try {
040: // try {
041: // B
042: // } catch (...) {
043: // catch2A
044: // } catch (...) {
045: // catch2B
046: // }
047: // tryMid1
048: // } catch ( ...) {
049: // catch 1A
050: // } catch ( ...) {
051: // catch 1B
052: // } catch ( ...) {
053: // catch 1C
054: // }
055: // midMain
056: // endMain
057: startMain = ilist.append(new NOP()); // 0
058: ilist.append(new NOP());
059: tryStart2 = ilist.append(new NOP()); // 2
060: ilist.append(new NOP());
061: tryEnd2 = ilist.append(new NOP()); // 4
062: ilist.append(new NOP());
063: catch2A = ilist.append(new NOP()); // 6
064: ilist.append(new NOP());
065: catch2B = ilist.append(new NOP()); // 8
066: ilist.append(new NOP());
067: tryMid1 = ilist.append(new NOP()); // 10
068: ilist.append(new NOP());
069: tryEnd1 = ilist.append(new NOP()); // 12
070: ilist.append(new NOP());
071: catch1A = ilist.append(new NOP()); // 14
072: ilist.append(new NOP());
073: catch1B = ilist.append(new NOP()); // 16
074: ilist.append(new NOP());
075: catch1C = ilist.append(new NOP()); // 18
076: ilist.append(new NOP());
077: midMain = ilist.append(new NOP()); // 20
078: ilist.append(new NOP());
079: endMain = ilist.append(new NOP()); // 22
080:
081: ilist.setPositions();
082: handler1A = new CodeExceptionGen(tryStart2, tryEnd1, catch1A,
083: new ObjectType("Exception"));
084: handler1B = new CodeExceptionGen(tryStart2, tryEnd1, catch1B,
085: new ObjectType("Exception"));
086: handler1C = new CodeExceptionGen(tryStart2, tryEnd1, catch1C,
087: new ObjectType("Exception"));
088:
089: handler2A = new CodeExceptionGen(tryStart2, tryEnd2, catch2A,
090: new ObjectType("Exception"));
091: handler2B = new CodeExceptionGen(tryStart2, tryEnd2, catch2B,
092: new ObjectType("Exception"));
093: }
094:
095: public void testPositions() {
096: assertEquals("startMain offset wrong", 0, startMain
097: .getPosition());
098: assertEquals("tryStart2 offset wrong", 2, tryStart2
099: .getPosition());
100: assertEquals("tryEnd1 offset wrong", 12, tryEnd1.getPosition());
101: assertEquals("midMain offset wrong", 20, midMain.getPosition());
102: assertEquals("endMain offset wrong", 22, endMain.getPosition());
103: }
104:
105: public void testNewEmpty() {
106: assertEquals("new graph has wrong number of vertices", 2, graph
107: .size());
108: handlers = new CodeExceptionGen[0];
109: ts = new TryStacks(handlers, blox, graph);
110: assertEquals(
111: "no handlers, but TryStacks constructor changed graph",
112: 2, graph.size());
113: }
114:
115: public void testComparator() {
116: CodeExceptionGen[] handlers = { handler1A, handler1B,
117: handler1C, handler2A, handler2B };
118: ts = new TryStacks(handlers, blox, graph);
119: Comparator cmp = ts.getComparator();
120: assertEquals("handler1A doesn't equal itself ;-)", 0, cmp
121: .compare(handler1A, handler1A));
122: assertEquals("handler1A doesn't sort before 1B", -1, cmp
123: .compare(handler1A, handler1B));
124: assertEquals("handler1C doesn't sort after 1B", 1, cmp.compare(
125: handler1C, handler1B));
126: assertEquals("shorter try block doesn't sort after longer", 1,
127: cmp.compare(handler2A, handler1B));
128: assertEquals("longer try block doesn't sort before shorter",
129: -1, cmp.compare(handler1C, handler2B));
130: }
131:
132: /**
133: * Graph should look like so (E = Entry, X = Exit, Tk = try block
134: * e0, nA/B/C = catch block, Vn = code vertex)
135: * E
136: * T1 T2 V2
137: * 2A 2B
138: * X
139: * 1A 1B 1C
140: * X
141: * X
142: */
143: private void checkScrambledHandlers(int n) {
144: Entry e0, e1, e2; // (sub)graph entry vertices
145: Connector connE0, connE1, connE2;//their connectors
146: Edge e0out, e1out, e2out; // their preferred edges
147: // connector multi-edges
148: Edge connE1out0, connE1out1, connE1out2;
149: Edge connE2out0, connE2out1;
150:
151: Exit x0, x1, x2; // (sub)graph exit vertices
152: Connector connX0, connX1, connX2;
153: Edge x0out, x1out, x2out;
154:
155: CodeVertex v1A, v1B, v1C, v2A, v2B; // catch vertices
156: Edge v1Aout, v1Bout, v1Cout, v2Aout, v2Bout;
157:
158: CodeVertex v2; // code vertex
159: Connector connV2;
160: Edge v2out;
161:
162: GraphTalker talker = new GraphTalker();
163: talker.xform(null, null, graph);
164: System.out.print(ts);
165:
166: e0 = graph.getEntry(); // 1
167: connE0 = e0.getConnector();
168: e0out = e0.getEdge();
169: assertEquals("graph Entry should have 1 edge out", 1, connE0
170: .size());
171:
172: e1 = (Entry) e0out.getTarget(); // 2
173: connE1 = e1.getConnector();
174: e1out = e1.getEdge();
175: assertEquals("first try block should have 3 edges out", 3,
176: connE1.size());
177:
178: e2 = (Entry) e1out.getTarget(); // 3
179: connE2 = e2.getConnector();
180: e2out = e2.getEdge();
181: assertEquals("second try block should have 2 edges out", 2,
182: connE2.size());
183:
184: v2 = (CodeVertex) e2out.getTarget(); // 4
185: connV2 = v2.getConnector();
186: e2out = v2.getEdge();
187: assertEquals("code vertex should have 1 edge out", 1, connV2
188: .size());
189: assertEquals("catch block has wrong offset", tryStart2
190: .getPosition(), v2.getPosition());
191:
192: assertEquals("graph Entry has wrong index", 0, e0.getIndex());
193: assertEquals("graph Entry has wrong index", 0, e1.getIndex());
194: assertEquals("graph Entry has wrong index", 0, e2.getIndex());
195:
196: assertEquals("e0's target should be e1", e1, e0.getTarget());
197: assertEquals("e1's target should be e2", e2, e1.getTarget());
198: assertEquals("e2's target should be v2", v2, e2.getTarget());
199:
200: assertEquals("v2 should be in graph 2", 2, v2.getGraph()
201: .getIndex());
202: // handlers are 2.2 and 2.3
203: assertEquals("v2 has wrong index", 4, v2.getIndex());
204:
205: x2 = (Exit) e2out.getTarget(); // 5
206: connX2 = x2.getConnector();
207: x2out = x2.getEdge();
208: assertEquals("second subgraph exit should have 1 edge out", 1,
209: connX2.size());
210:
211: x1 = (Exit) x2out.getTarget(); // 6
212: connX1 = x1.getConnector();
213: x1out = x1.getEdge();
214: assertEquals("first subgraph exit should have 1 edge out", 1,
215: connX1.size());
216:
217: x0 = (Exit) x1out.getTarget(); // 7
218: connX0 = x0.getConnector();
219: x0out = x0.getEdge();
220: assertEquals("main graph exit should have 1 edge out", 1,
221: connX0.size());
222: assertEquals("graph exit doesn't loop back to graph e0", e0,
223: x0out.getTarget());
224:
225: assertEquals("v2's target should be x2", x2, v2.getTarget());
226: assertEquals("x2's target should be x1", x1, x2.getTarget());
227: assertEquals("x2's target should be x0", x0, x1.getTarget());
228:
229: assertEquals("graph exit has wrong index", 1, x2.getIndex());
230: assertEquals("graph exit has wrong index", 1, x1.getIndex());
231: assertEquals("graph exit has wrong index", 1, x0.getIndex());
232:
233: // CATCH BLOCKS (1)
234: ComplexConnector cc = (ComplexConnector) connE1;
235: connE1out0 = cc.getEdge(0);
236: v1A = (CodeVertex) connE1out0.getTarget(); // 8
237: v1Aout = v1A.getEdge();
238: assertEquals("catch block edge doesn't go to exit", v1Aout
239: .getTarget(), x1);
240: assertEquals("catch block has wrong offset", catch1A
241: .getPosition(), v1A.getPosition());
242: assertEquals("catch block has wrong index", 2, v1A.getIndex());
243:
244: connE1out1 = cc.getEdge(1);
245: v1B = (CodeVertex) connE1out1.getTarget(); // 9
246: v1Bout = v1B.getEdge();
247: assertEquals("catch block edge doesn't go to exit", v1Bout
248: .getTarget(), x1);
249: assertEquals("catch block has wrong offset", catch1B
250: .getPosition(), v1B.getPosition());
251: assertEquals("catch block has wrong index", 3, v1B.getIndex());
252:
253: connE1out2 = cc.getEdge(2);
254: v1C = (CodeVertex) connE1out2.getTarget(); // 10
255: v1Cout = v1C.getEdge();
256: assertEquals("catch block edge doesn't go to exit", v1Cout
257: .getTarget(), x1);
258: assertEquals("catch block has wrong offset", catch1C
259: .getPosition(), v1C.getPosition());
260: assertEquals("catch block has wrong index", 4, v1C.getIndex());
261:
262: // CATCH BLOCKS (2)
263: cc = (ComplexConnector) e2.getConnector();
264: connE2out0 = cc.getEdge(0);
265: v2A = (CodeVertex) connE2out0.getTarget(); // 11
266: v2Aout = v2A.getEdge();
267: assertEquals("catch block edge doesn't go to exit", v2Aout
268: .getTarget(), x2);
269: assertEquals("catch block has wrong offset", catch2A
270: .getPosition(), v2A.getPosition());
271: assertEquals("catch block has wrong index", 2, v2A.getIndex());
272:
273: connE2out1 = cc.getEdge(1);
274: v2B = (CodeVertex) connE2out1.getTarget(); // 12
275: v2Bout = v2B.getEdge();
276: assertEquals("catch block edge doesn't go to exit", v2Bout
277: .getTarget(), x2);
278: assertEquals("catch block has wrong offset", catch2B
279: .getPosition(), v2B.getPosition());
280: assertEquals("catch block has wrong index", 3, v2B.getIndex());
281:
282: }
283:
284: public void testGraphSize() {
285: CodeExceptionGen[] handlers = { handler1B, handler2B,
286: handler1C, handler2A, handler1A };
287: ts = new TryStacks(handlers, blox, graph);
288: // // DEBUG
289: // System.out.print(ts);
290: // GraphTalker talker = new GraphTalker();
291: // talker.xform (null, null, graph);
292: // // END
293: assertEquals("wrong number of vertices in complex graph ", 12,
294: graph.size());
295: }
296:
297: public void testScrambledHandlers1() {
298: CodeExceptionGen[] handlers = { handler1B, handler2B,
299: handler1C, handler2A, handler1A };
300: ts = new TryStacks(handlers, blox, graph);
301: checkScrambledHandlers(1);
302: }
303:
304: public void testScrambledHandlers2() {
305: CodeExceptionGen[] handlers = { handler2B, handler1C,
306: handler2A, handler1A, handler1B };
307: ts = new TryStacks(handlers, blox, graph);
308: checkScrambledHandlers(2);
309: }
310:
311: public void testScrambledHandlers3() {
312: CodeExceptionGen[] handlers = { handler2B, handler2A,
313: handler1C, handler1B, handler1A };
314: ts = new TryStacks(handlers, blox, graph);
315: checkScrambledHandlers(3);
316: }
317: }
|