KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > ExceptionChecker


1 package polyglot.visit;
2
3 import java.util.HashMap JavaDoc;
4 import java.util.Map JavaDoc;
5
6 import polyglot.ast.Node;
7 import polyglot.ast.NodeFactory;
8 import polyglot.frontend.Job;
9 import polyglot.types.SemanticException;
10 import polyglot.types.Type;
11 import polyglot.types.TypeSystem;
12 import polyglot.util.ErrorQueue;
13 import polyglot.util.InternalCompilerError;
14 import polyglot.util.Position;
15 import polyglot.util.SubtypeSet;
16
17 /** Visitor which checks if exceptions are caught or declared properly. */
18 public class ExceptionChecker extends ErrorHandlingVisitor
19 {
20     protected ExceptionChecker outer;
21     /**
22      * Lazily instantiate the SubtypeSet in the getter method
23      */

24     private SubtypeSet scope = null;
25     protected Map JavaDoc exceptionPositions;
26
27     public ExceptionChecker(Job job, TypeSystem ts, NodeFactory nf) {
28     super(job, ts, nf);
29     this.outer = null;
30         this.exceptionPositions = new HashMap JavaDoc();
31     }
32
33     public ExceptionChecker push() {
34         ExceptionChecker ec = (ExceptionChecker) this.visitChildren();
35         ec.outer = this;
36         ec.exceptionPositions = new HashMap JavaDoc();
37         return ec;
38     }
39
40     public ExceptionChecker pop() {
41         return outer;
42     }
43
44     /**
45      * This method is called when we are to perform a "normal" traversal of
46      * a subtree rooted at <code>n</code>. At every node, we will push a
47      * stack frame. Each child node will add the exceptions that it throws
48      * to this stack frame. For most nodes ( excdeption for the try / catch)
49      * will just aggregate the stack frames.
50      *
51      * @param n The root of the subtree to be traversed.
52      * @return The <code>NodeVisitor</code> which should be used to visit the
53      * children of <code>n</code>.
54      *
55      */

56     protected NodeVisitor enterCall(Node n) throws SemanticException {
57     return n.exceptionCheckEnter(push());
58     }
59
60     protected NodeVisitor enterError(Node n) {
61     return push();
62     }
63
64     /**
65      * Here, we pop the stack frame that we pushed in enter and agregate the
66      * exceptions.
67      *
68      * @param old The original state of root of the current subtree.
69      * @param n The current state of the root of the current subtree.
70      * @param v The <code>NodeVisitor</code> object used to visit the children.
71      * @return The final result of the traversal of the tree rooted at
72      * <code>n</code>.
73      */

74     protected Node leaveCall(Node old, Node n, NodeVisitor v)
75     throws SemanticException {
76         
77         ExceptionChecker inner = (ExceptionChecker) v;
78         
79         if (inner.outer != this) throw new InternalCompilerError("oops!");
80         
81         // gather exceptions from this node.
82
n = n.del().exceptionCheck(inner);
83         
84         // Merge results from the children and free the checker used for the
85
// children.
86
SubtypeSet t = inner.throwsSet();
87         throwsSet().addAll(t);
88         exceptionPositions.putAll(inner.exceptionPositions);
89
90     return n;
91     }
92
93     /**
94      * The ast nodes will use this callback to notify us that they throw an
95      * exception of type t. This should only be called by MethodExpr node,
96      * and throw node, since they are the only node which can generate
97      * exceptions.
98      *
99      * @param t The type of exception that the node throws.
100      */

101     public void throwsException(Type t, Position pos) {
102     throwsSet().add(t) ;
103         exceptionPositions.put(t, pos);
104     }
105     
106     /**
107      * Method to allow the throws clause and method body to inspect and
108      * modify the throwsSet.
109      */

110     public SubtypeSet throwsSet() {
111         if (scope == null) {
112             this.scope = new SubtypeSet(ts.Throwable());
113         }
114         return scope;
115     }
116     
117     /**
118      * Method to determine the position at which a particular exception is
119      * thrown
120      */

121     public Position exceptionPosition(Type t) {
122         return (Position)exceptionPositions.get(t);
123     }
124 }
125
Popular Tags