KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > ast > TryCatchStmt


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.ast;
26
27 import org.aspectj.compiler.base.*;
28 import java.util.*;
29
30 import org.aspectj.compiler.base.JavaCompiler;
31 import org.aspectj.compiler.base.CodeWriter;
32
33 import org.aspectj.compiler.base.bcg.CodeBuilder;
34 import org.aspectj.compiler.base.bcg.Label;
35
36 import java.util.Iterator JavaDoc;
37
38 /**
39  * @grammar try {body} (catches)*;
40  * @child Stmt body
41  * @child CatchClauses catches
42  */

43 public class TryCatchStmt extends TryStmt {
44
45     public void checkSpec() {
46         super.checkSpec();
47         if (catches.size() == 0) {
48             showError("'try' without 'catch' or 'finally'");
49         }
50         
51         body.requireBlockStmt();
52     }
53     
54     public void unparse(CodeWriter writer) {
55         if (catches.size() == 0) {
56             writer.write(body);
57             return;
58         }
59
60         writer.writeKeyword("try");
61         writer.optionalSpace();
62         writer.write(body);
63
64         writer.writeChildren(catches);
65     }
66
67     // ------------------------------
68
// INTRO from ASTFixerPass
69
public ASTObject postFixAST(final ASTFixerPass fixer) {
70         if (! isOptional()) return super.postFixAST(fixer);
71
72         // remove any catch clauses that are impossible
73
Set exceptions = ExceptionFinder.getPossibleExceptions(getBody(), true);
74         
75         //System.err.println("TCS: exceptions: " + exceptions);
76
//this.display(0);
77

78         exceptions.add(getTypeManager().getRuntimeExceptionType());
79         exceptions.add(getTypeManager().getErrorType());
80         //showError("body might throw: "+exceptions);
81

82         filterCatchClauses(catches, exceptions);
83         setIsOptional(false);
84         return super.postFixAST(fixer);
85     }
86     private void filterCatchClauses(CatchClauses ccs, Set exceptions) {
87         //System.out.println("***********************" + exceptions);
88
for (int i = 0; i < ccs.size(); i++) {
89             CatchClause cc = ccs.get(i);
90             //System.out.println(cc.getFormal().getType());
91
if (!possibleCatchClause(cc, exceptions)) {
92                 //System.out.println(" can't throw");
93
ccs.remove(i);
94                 i--;
95             }
96         }
97     }
98     private boolean possibleCatchClause(CatchClause cc, Set exceptions) {
99         return canThrow(exceptions, cc.getFormal().getType());
100     }
101     //XXX cut-and-paste from JoinPoint
102
private boolean canThrow(Set types, Type baseType) {
103         //if (isUncheckedException(baseType)) {
104
// return true;
105
//}
106

107         for(Iterator JavaDoc iter = types.iterator(); iter.hasNext(); ) {
108             Type checkType = (Type)iter.next();
109             if (checkType != null && (checkType.isSubtypeOf(baseType) ||
110                 baseType.isSubtypeOf(checkType))) {
111                 return true;
112             }
113         }
114         return false;
115     }
116
117     // ------------------------------
118
// INTRO from FlowCheckerPass
119

120     public void walkFlow(FlowCheckerPass w) {
121         FlowCheckerPass.Vars beforeV = w.getVars();
122         FlowCheckerPass.ESet beforeExns = w.popExns();
123         w.enterContext(this);
124         w.process(getBody());
125         w.leaveContext();
126         boolean bodyLive = w.isLive();
127         FlowCheckerPass.ESet bodyExns = w.popExns();
128
129         FlowCheckerPass.Vars v = w.getVars(); // da
130
FlowCheckerPass.Vars tv = w.getTryVars(this); //dua
131

132         FlowCheckerPass.Vars cv =
133             FlowCheckerPass.Vars.makeSets(beforeV.getDa(),
134                                           v.getDua().inter(tv.getDua()));
135
136         FlowCheckerPass.ESet caughtExns = FlowCheckerPass.ESet.getEmpty();
137         FlowCheckerPass.ESet thrownExns = beforeExns;
138         FlowCheckerPass.Vars cvExit = v;
139         boolean liveSoFar = bodyLive;
140         CatchClauses c = getCatches();
141         if (c != null) {
142             for (int i = 0, len = c.size(); i < len; i++) {
143                 CatchClause cl = c.get(i);
144                 NameType exnType = (NameType) cl.getFormal().getType();
145                 if (! bodyExns.containsSuperOrSub(exnType) &&
146                     ! exnType.isUncheckedThrowable() &&
147                     exnType != getTypeManager().getExceptionType() &&
148                     exnType != getTypeManager().getThrowableType()) {
149                     cl.showError("exception " + exnType.getId() +
150                                  " is never thrown in body of corresponding try statement");
151                     continue;
152                 }
153                 if (caughtExns.containsSuper(exnType)) {
154                     cl.showError("exception " + exnType.getId() + " has already been caught");
155                     continue;
156                 }
157                 w.setLive(true);
158                 w.setVars(cv);
159                 // here we're just entering and leaving the context to
160
// prevent breaks and continues to escape without
161
// figuring out whether our (possible) finally
162
// terminates normally. We won't use any of the vars
163
// associated with this stmt anymore, they were taken
164
// out earlier.
165
w.enterContext(this);
166                 w.process(cl);
167                 w.leaveContext();
168                 liveSoFar = liveSoFar | w.isLive();
169                 cvExit = cvExit.join(w.getVars());
170                 thrownExns = thrownExns.union(w.popExns());
171                 caughtExns = caughtExns.add(exnType);
172             }
173         }
174         w.setExns(bodyExns.diff(caughtExns).union(thrownExns).union(beforeExns));
175         w.setVars(cvExit);
176         w.releasePendingTransfers(this);
177         w.setLive(liveSoFar);
178     }
179
180     // ------------------------------
181
// Intro: ByteCodeCleanupPass
182

183     public void walkCleanup(ByteCodeCleanupPass w) {
184         w.enterContext(this);
185         setBody((Stmt) w.process(getBody()));
186         w.leaveContext();
187         boolean bodyLive = w.isLive();
188
189         boolean liveSoFar = bodyLive;
190         CatchClauses c = getCatches();
191         for (int i = 0, len = c.size(); i < len; i++) {
192             CatchClause cl = c.get(i);
193             w.setLive(true);
194             w.process(cl);
195             liveSoFar = liveSoFar || w.isLive();
196         }
197         w.setLive(liveSoFar);
198     }
199
200     public ASTObject postCleanup(ByteCodeCleanupPass walker) {
201         if (getBody() instanceof EmptyStmt) {
202             return getAST().makeEmptyStmt().setSource(this);
203         } else {
204             return this;
205         }
206     }
207
208     // ------------------------------
209
// bcg
210

211     protected void cgStmt(CodeBuilder cb) {
212         Label startBody = cb.genAnchor();
213         Label endBody = cb.genAnchor();
214         Label end = cb.genLabel();
215         cb.emitLabel(startBody);
216         getBody().cgTop(cb);
217         cb.emitLabel(endBody);
218         if (body.completesNormally()) cb.emitJump(end);
219         for (int i = 0, len = catches.size(); i < len; i++ ) {
220             CatchClause clause = catches.get(i);
221             Label exnStart = cb.genAnchor();
222             FormalDec clauseFormal = clause.getFormal();
223             Stmt clauseBody = clause.getBody();
224
225             cb.enterBlock();
226             cb.enterVar(clauseFormal);
227             cb.emitLabel(exnStart);
228             cb.pushStack(1); // there's an exn on the stack
229
cb.emitASTORE(clauseFormal.getFrameLoc()); // store it
230
clauseBody.cgTop(cb);
231             if (clauseBody.completesNormally()) cb.emitJump(end);
232             cb.addHandler(startBody, endBody, exnStart, (NameType) clauseFormal.getType());
233             cb.exitBlock();
234         }
235         cb.emitLabel(end);
236     }
237     
238     //BEGIN: Generated from @child and @property
239
protected Stmt body;
240     public Stmt getBody() { return body; }
241     public void setBody(Stmt _body) {
242         if (_body != null) _body.setParent(this);
243         body = _body;
244     }
245     
246     protected CatchClauses catches;
247     public CatchClauses getCatches() { return catches; }
248     public void setCatches(CatchClauses _catches) {
249         if (_catches != null) _catches.setParent(this);
250         catches = _catches;
251     }
252     
253     public TryCatchStmt(SourceLocation location, Stmt _body, CatchClauses _catches) {
254         super(location);
255         setBody(_body);
256         setCatches(_catches);
257     }
258     protected TryCatchStmt(SourceLocation source) {
259         super(source);
260     }
261     
262     public ASTObject copyWalk(CopyWalker walker) {
263         TryCatchStmt ret = new TryCatchStmt(getSourceLocation());
264         ret.preCopy(walker, this);
265         if (body != null) ret.setBody( (Stmt)walker.process(body) );
266         if (catches != null) ret.setCatches( (CatchClauses)walker.process(catches) );
267         return ret;
268     }
269     
270     public ASTObject getChildAt(int childIndex) {
271         switch(childIndex) {
272         case 0: return body;
273         case 1: return catches;
274         default: return super.getChildAt(childIndex);
275         }
276     }
277      public String JavaDoc getChildNameAt(int childIndex) {
278         switch(childIndex) {
279         case 0: return "body";
280         case 1: return "catches";
281         default: return super.getChildNameAt(childIndex);
282         }
283     }
284      public void setChildAt(int childIndex, ASTObject child) {
285         switch(childIndex) {
286         case 0: setBody((Stmt)child); return;
287         case 1: setCatches((CatchClauses)child); return;
288         default: super.setChildAt(childIndex, child); return;
289         }
290     }
291      public int getChildCount() {
292         return 2;
293     }
294     
295     public String JavaDoc getDefaultDisplayName() {
296         return "TryCatchStmt()";
297     }
298     
299     //END: Generated from @child and @property
300
}
301
302
303
Popular Tags