KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > crosscuts > ast > AfterThrowingAdviceDec


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.crosscuts.ast;
26
27 import org.aspectj.compiler.base.ast.*;
28 import org.aspectj.compiler.crosscuts.joinpoints.*;
29 import org.aspectj.compiler.base.*;
30
31 import java.util.*;
32
33 /**
34  * @grammar after (formals) throwing (formal)
35  * @child FormalDec extraFormal @after formals
36  */

37
38 public class AfterThrowingAdviceDec extends AdviceDec {
39     protected String JavaDoc getAdviceKind() { return "afterThrowing"; }
40
41     protected boolean isAfterAdvice() { return true; }
42     
43     protected Stmts wrapStmts(Stmts stmts, AdvicePlan plan) {
44         return wrapAfterThrowingCall(plan, stmts);
45     }
46     
47     Stmt makeSingleRethrow(VarDec formal, Type excType, boolean needTest) {
48         final AST ast = getAST();
49         
50         Expr castExpr = ast.makeCast(excType, ast.makeVar(formal));
51
52         Stmt rethrow = ast.makeThrow(castExpr);
53         if (needTest) {
54             return ast.makeIf(ast.makeInstanceof(ast.makeVar(formal), excType), rethrow);
55         } else {
56             return rethrow;
57         }
58     }
59
60     Stmts makeRethrows(VarDec formal, Set exceptions) {
61         Stmts stmts = getAST().makeStmts();
62
63         exceptions = Type.filterSubTypes(formal.getType(), exceptions);
64         exceptions = Type.filterTopTypes(exceptions);
65
66         if (exceptions.size() == 1) {
67             Type checkType = (Type)exceptions.iterator().next();
68             stmts.add(makeSingleRethrow(formal, checkType, false));
69             return stmts;
70         }
71
72         for(Iterator iter = exceptions.iterator(); iter.hasNext(); ) {
73             Type checkType = (Type)iter.next();
74             stmts.add(makeSingleRethrow(formal, checkType, iter.hasNext()));
75         }
76         return stmts;
77     }
78
79     private static int excIndex = 0;
80     private CatchClause makeCatchClause(Type catchType, AdvicePlan plan, int index, Set exceptions) {
81         final AST ast = getAST();
82         
83         String JavaDoc newName = "ajcexc$" + excIndex++;
84         FormalDec newFormal = ast.makeFormal(catchType, newName);
85         Stmt doCall = plan.makeCall(ast.makeVar(newFormal));
86
87         Stmts rethrows = makeRethrows(newFormal, exceptions);
88
89         rethrows.add(0, doCall);
90         return ast.makeCatch(newFormal, ast.makeBlock(rethrows));
91     }
92
93     boolean isUncheckedException(Type baseType) {
94         return baseType.isSubtypeOf(getTypeManager().getRuntimeExceptionType())
95           || baseType.isSubtypeOf(getTypeManager().getErrorType());
96     }
97
98
99     boolean canThrow(Set types, Type baseType) {
100 // if (isUncheckedException(baseType)) {
101
// return true;
102
// }
103

104         for(Iterator iter = types.iterator(); iter.hasNext(); ) {
105             Type checkType = (Type)iter.next();
106             if (checkType != null && checkType.isSubtypeOf(baseType) ||
107                 baseType.isSubtypeOf(checkType)) {
108                 return true;
109             }
110         }
111         return false;
112     }
113
114     public Stmts wrapAfterThrowingCall(AdvicePlan plan, Stmts baseStmts) {
115         FormalDec formal = ((AfterThrowingAdviceDec)plan.getAdviceDec()).getExtraFormal();
116
117         Set exceptions = ExceptionFinder.getPossibleExceptions(baseStmts, true);
118         exceptions.add(getTypeManager().getRuntimeExceptionType());
119         exceptions.add(getTypeManager().getErrorType());
120         //System.out.println("body might throw: "+exceptions);
121

122         Type catchType;
123         if (formal != null) {
124             catchType = formal.getType();
125         } else {
126             catchType = getTypeManager().getThrowableType();
127         }
128
129         if (!canThrow(exceptions, catchType)) {
130             //System.out.println("can't throw: " + formal.getType());
131
return baseStmts;
132         }
133
134         int index = 0; //XXX this doesn't quite work...
135
CatchClause catches = makeCatchClause(catchType, plan, index, exceptions);
136         
137         final AST ast = getAST();
138         return ast.makeStmts(ast.makeTryCatch(ast.makeBlock(baseStmts), catches));
139     }
140     
141     // ------------------------------
142
// INTRO from FlowCheckerPass
143

144     protected void setupFlowWalker(FlowCheckerPass w) {
145         if (getExtraFormal() != null)
146             w.setVars(w.getVars().addAssigned(getExtraFormal()));
147         super.setupFlowWalker(w);
148     }
149     
150     //BEGIN: Generated from @child and @property
151
protected FormalDec extraFormal;
152     public FormalDec getExtraFormal() { return extraFormal; }
153     public void setExtraFormal(FormalDec _extraFormal) {
154         if (_extraFormal != null) _extraFormal.setParent(this);
155         extraFormal = _extraFormal;
156     }
157     
158     public AfterThrowingAdviceDec(SourceLocation location, Modifiers _modifiers, Formals _formals, FormalDec _extraFormal, TypeDs __throws, Pcd _pcd, CodeBody _body) {
159         super(location, _modifiers, _formals, __throws, _pcd, _body);
160         setExtraFormal(_extraFormal);
161     }
162     protected AfterThrowingAdviceDec(SourceLocation source) {
163         super(source);
164     }
165     
166     public ASTObject copyWalk(CopyWalker walker) {
167         AfterThrowingAdviceDec ret = new AfterThrowingAdviceDec(getSourceLocation());
168         ret.preCopy(walker, this);
169         if (modifiers != null) ret.setModifiers( (Modifiers)walker.process(modifiers) );
170         if (formals != null) ret.setFormals( (Formals)walker.process(formals) );
171         if (extraFormal != null) ret.setExtraFormal( (FormalDec)walker.process(extraFormal) );
172         if (_throws != null) ret.setThrows( (TypeDs)walker.process(_throws) );
173         if (pcd != null) ret.setPcd( (Pcd)walker.process(pcd) );
174         if (body != null) ret.setBody( (CodeBody)walker.process(body) );
175         return ret;
176     }
177     
178     public ASTObject getChildAt(int childIndex) {
179         switch(childIndex) {
180         case 0: return modifiers;
181         case 1: return formals;
182         case 2: return extraFormal;
183         case 3: return _throws;
184         case 4: return pcd;
185         case 5: return body;
186         default: return super.getChildAt(childIndex);
187         }
188     }
189      public String JavaDoc getChildNameAt(int childIndex) {
190         switch(childIndex) {
191         case 0: return "modifiers";
192         case 1: return "formals";
193         case 2: return "extraFormal";
194         case 3: return "throws";
195         case 4: return "pcd";
196         case 5: return "body";
197         default: return super.getChildNameAt(childIndex);
198         }
199     }
200      public void setChildAt(int childIndex, ASTObject child) {
201         switch(childIndex) {
202         case 0: setModifiers((Modifiers)child); return;
203         case 1: setFormals((Formals)child); return;
204         case 2: setExtraFormal((FormalDec)child); return;
205         case 3: setThrows((TypeDs)child); return;
206         case 4: setPcd((Pcd)child); return;
207         case 5: setBody((CodeBody)child); return;
208         default: super.setChildAt(childIndex, child); return;
209         }
210     }
211      public int getChildCount() {
212         return 6;
213     }
214     
215     public String JavaDoc getDefaultDisplayName() {
216         return "AfterThrowingAdviceDec()";
217     }
218     
219     //END: Generated from @child and @property
220
}
221
Popular Tags