KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > AscriptionVisitor


1 package polyglot.visit;
2
3 import polyglot.ast.*;
4 import polyglot.types.*;
5 import polyglot.util.*;
6 import polyglot.frontend.Job;
7 import java.util.*;
8
9 /** Visitor which allows type information to be utilized to perform AST
10     modifications.
11     
12     The major advantage of this visitor is the new <code>ascribe()</code>
13     method, which allows AST translations based on the expression
14     and also the type that is expected. For the base translation (standard
15     Java), the type of the expression and the type that is expceted
16     are the same. Language extensions however may not have this property,
17     and can take advantage of the <code>ascribe</code> method to transform
18     the AST into a different form that will pass Java type-checking.
19     
20     @see #ascribe
21     */

22 public class AscriptionVisitor extends ContextVisitor
23 {
24     Type type;
25     AscriptionVisitor outer;
26
27     /**
28      * Default constructor. See the constructor in <code> ErrorHandingVisitor
29      * </code> for more details.
30      *
31      * @see polyglot.visit.ErrorHandlingVisitor#ErrorHandlingVisitor
32      */

33     public AscriptionVisitor(Job job, TypeSystem ts, NodeFactory nf) {
34         super(job, ts, nf);
35         type = null;
36         outer = null;
37     }
38
39     // FIXME: what does this do?
40
/**
41      */

42     public AscriptionVisitor pop() {
43         return outer;
44     }
45
46     /** Returns the type that is expected of the expression that is being
47      * visited.
48      */

49     public Type toType() {
50         return type;
51     }
52
53     // TODO is this comment revealing too much implementation?
54
/** Sets up the expected type information for later calls to
55      * <code>ascribe()</code>. Other than that, plays the same role
56      * as the <code>enterCall</code> method in
57      * <code>ErrorHandlingVisitor</code>.
58      */

59     public NodeVisitor enterCall(Node parent, Node n) throws SemanticException {
60         Type t = null;
61
62         if (parent != null && n instanceof Expr) {
63             t = parent.childExpectedType((Expr) n, this);
64         }
65
66         AscriptionVisitor v = (AscriptionVisitor) copy();
67         v.outer = this;
68         v.type = t;
69
70         return v;
71     }
72
73     /** The <code>ascribe()</code> method is called for each expression
74       * and is passed the type the expression is <i>used at</i> rather
75       * than the type the type
76       * checker assigns to it.
77       *
78       * For instance, with the following code:
79       *
80       * <code>Object o = new Integer(3);</code>
81       *
82       * <code>ascribe()</code> will be called with expression
83       * <code>new Integer(3)</code> and type <code>Object</code>.
84       *
85       * @param e The expression that is being visited
86       * @param toType The type that the parent node is expecting.
87       * @return The new translated Expr node, or if nothing has changed, just
88       * e.
89       */

90     public Expr ascribe(Expr e, Type toType) throws SemanticException {
91         return e;
92     }
93
94     // TODO is this comment revealing too much implementation?
95
/** Calls <code>ascribe()<code> with the expected type and expression
96      * as appropriate. Otherwise functionally the same as the <code>
97      * leaveCall</code> method in <code>ErrorHandlingVisitor</code>.
98      */

99     public Node leaveCall(Node old, Node n, NodeVisitor v)
100         throws SemanticException {
101
102         if (n instanceof Expr) {
103             Expr e = (Expr) n;
104             Type type = ((AscriptionVisitor) v).type;
105             return ascribe(e, type);
106         }
107
108     return n;
109     }
110 }
111
Popular Tags