KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > CanThrowWalker


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;
26
27 import org.aspectj.compiler.base.ast.*;
28
29
30 import java.util.*;
31
32
33 public class CanThrowWalker extends Walker {
34     Stack canThrow = null;
35     
36     public static void checkThrows(CodeDec codeDec) {
37         if (codeDec.isSoftThrowable()) return ;
38         
39         CanThrowWalker walker = new CanThrowWalker(codeDec);
40         walker.canThrow.push(makeThrowableSet(codeDec.getThrows()));
41         
42         if (codeDec instanceof InitializerDec && !codeDec.isStatic()) {
43             TypeDec inTypeDec = codeDec.getBytecodeTypeDec();
44             if (inTypeDec.isAnonymous()) {
45                 Set set = new HashSet();
46                 walker.collectBadThrows(set);
47                 walker.process(codeDec);
48                 //System.out.println(inTypeDec.getPrettyString() + " bad throws: " + set);
49
inTypeDec.getSoleConstructorDec().addThrows(set);
50             } else {
51                 Set set = null;
52                 for (Iterator i = inTypeDec.getNameType().getConstructors().iterator(); i.hasNext(); ) {
53                     Constructor c = (Constructor)i.next();
54                     if (set == null) {
55                         set = makeThrowableSet(c.getThrows());
56                     } else {
57                         set = Type.intersect(set, makeThrowableSet(c.getThrows()));
58                     }
59                 }
60                 //System.out.println("legal throws: " + set);
61
codeDec.addThrows(set);
62                 walker.canThrow.push(makeThrowableSet(codeDec.getThrows()));
63                 walker.process(codeDec);
64             }
65         } else {
66             walker.process(codeDec);
67         }
68     }
69     
70     
71     private Set badThrows = null;
72     
73     private CanThrowWalker(CodeDec codeDec) {
74         super(codeDec.getCompiler());
75         canThrow = new Stack();
76     }
77     
78     void collectBadThrows(Set set) {
79         badThrows = set;
80     }
81     
82     
83     static Set makeThrowableSet(TypeDs _throws) {
84         if (_throws == null) return Collections.EMPTY_SET;
85
86         Set ret = new HashSet();
87         
88         final int N = _throws.size();
89         for(int i=0; i<N; i++) {
90             Type exceptionType = _throws.get(i).getType();
91             ret.add(exceptionType);
92         }
93         return ret;
94     }
95     
96     Collection makeThrowableSet(CatchClauses catchClauses) {
97         if (catchClauses == null) return Collections.EMPTY_SET;
98
99         Collection ret = new HashSet();
100         
101         final int N = catchClauses.size();
102         for(int i=0; i<N; i++) {
103             Type exceptionType = catchClauses.get(i).getFormal().getType();
104             ret.add(exceptionType);
105         }
106         return ret;
107     }
108
109     
110     boolean checkLegalThrow(ASTObject where, Type throwType) {
111         if (throwType.isUncheckedThrowable()) return true;
112         
113         for (Iterator i = canThrow.iterator(); i.hasNext(); ) {
114             if (Type.hasMatchingType((Collection)i.next(), throwType)) {
115                 return true;
116             }
117         }
118         
119         if (badThrows != null) {
120             badThrows.add(throwType);
121             return true;
122         } else {
123             where.showError("unreported exception " + throwType.getString() +
124                     "; must be caught or declared to be thrown");
125             return false;
126         }
127     }
128     
129     
130     void checkLegalThrows(ASTObject where, TypeDs throwTypeDs) {
131         if (throwTypeDs == null) return;
132         
133         for (int i = 0; i < throwTypeDs.size(); i++) {
134             if (!checkLegalThrow(where, throwTypeDs.get(i).getType())) return;
135         }
136     }
137         
138     public ASTObject process(ASTObject node) {
139         if (node instanceof TryCatchStmt) {
140             TryCatchStmt tryStmt = (TryCatchStmt)node;
141             canThrow.push(makeThrowableSet(tryStmt.getCatches()));
142             super.process(tryStmt.getBody());
143             canThrow.pop();
144             super.process(tryStmt.getCatches());
145             return node;
146         }
147
148         if (node instanceof ThrowStmt) {
149             ThrowStmt throwStmt = (ThrowStmt)node;
150             checkLegalThrow(throwStmt, throwStmt.getExpr().getType());
151         } else if (node instanceof CallExpr) {
152             CallExpr callExpr = (CallExpr)node;
153             if (callExpr.isSoftThrowable()) return super.process(node);
154             if (callExpr.getId().equals("aspectOf")) {
155                 return super.process(node);
156             }
157
158             Method method = callExpr.getMethod();
159
160             if (method == null) {
161                 //System.out.println(">>>>>>>>>>>>>>>>>>>>>unbound call to: " + callExpr.getId());
162
return super.process(node);
163             }
164             checkLegalThrows(callExpr, method.getThrows());
165         } else if (node instanceof NewInstanceExpr) {
166             NewInstanceExpr newExpr = (NewInstanceExpr)node;
167             if (newExpr.isSoftThrowable()) return super.process(node);
168             
169             Constructor init = newExpr.getConstructor();
170             checkLegalThrows(newExpr, init.getThrows());
171         } else if (node instanceof ConstructorCallExpr) {
172             ConstructorCallExpr newExpr = (ConstructorCallExpr)node;
173             //if (newExpr.isSoftThrowable()) return super.process(node);
174

175             Constructor init = newExpr.getConstructor();
176             checkLegalThrows(newExpr, init.getThrows());
177             
178         }
179         if (node instanceof TypeDec) return node;
180         return super.process(node);
181     }
182 }
183
184
Popular Tags