KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > ext > jl > ast > Switch_c


1 package polyglot.ext.jl.ast;
2
3 import polyglot.ast.*;
4 import polyglot.types.*;
5 import polyglot.visit.*;
6 import polyglot.util.*;
7 import java.util.*;
8
9 /**
10  * A <code>Switch</code> is an immutable representation of a Java
11  * <code>switch</code> statement. Such a statement has an expression which
12  * is evaluated to determine where to branch to, an a list of labels
13  * and block statements which are conditionally evaluated. One of the
14  * labels, rather than having a constant expression, may be lablled
15  * default.
16  */

17 public class Switch_c extends Stmt_c implements Switch
18 {
19     protected Expr expr;
20     protected List elements;
21
22     public Switch_c(Position pos, Expr expr, List elements) {
23     super(pos);
24     this.expr = expr;
25     this.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true);
26     }
27
28     /** Get the expression to switch on. */
29     public Expr expr() {
30     return this.expr;
31     }
32
33     /** Set the expression to switch on. */
34     public Switch expr(Expr expr) {
35     Switch_c n = (Switch_c) copy();
36     n.expr = expr;
37     return n;
38     }
39
40     /** Get the switch elements of the statement. */
41     public List elements() {
42     return Collections.unmodifiableList(this.elements);
43     }
44
45     /** Set the switch elements of the statement. */
46     public Switch elements(List elements) {
47     Switch_c n = (Switch_c) copy();
48     n.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true);
49     return n;
50     }
51
52     /** Reconstruct the statement. */
53     protected Switch_c reconstruct(Expr expr, List elements) {
54     if (expr != this.expr || ! CollectionUtil.equals(elements, this.elements)) {
55         Switch_c n = (Switch_c) copy();
56         n.expr = expr;
57         n.elements = TypedList.copyAndCheck(elements, SwitchElement.class, true);
58         return n;
59     }
60
61     return this;
62     }
63
64     public Context enterScope(Context c) {
65         return c.pushBlock();
66     }
67
68     /** Visit the children of the statement. */
69     public Node visitChildren(NodeVisitor v) {
70     Expr expr = (Expr) visitChild(this.expr, v);
71     List elements = visitList(this.elements, v);
72     return reconstruct(expr, elements);
73     }
74
75     /** Type check the statement. */
76     public Node typeCheck(TypeChecker tc) throws SemanticException {
77         TypeSystem ts = tc.typeSystem();
78
79         if (! ts.isImplicitCastValid(expr.type(), ts.Int())) {
80             throw new SemanticException("Switch index must be an integer.",
81                                         position());
82         }
83
84         Collection labels = new HashSet();
85
86     for (Iterator i = elements.iterator(); i.hasNext();) {
87        SwitchElement s = (SwitchElement) i.next();
88
89        if (s instanceof Case) {
90            Case c = (Case) s;
91            Object JavaDoc key;
92            String JavaDoc str;
93
94            if (c.isDefault()) {
95            key = "default";
96            str = "default";
97            }
98                else if (c.expr().isConstant()) {
99            key = new Long JavaDoc(c.value());
100            str = c.expr().toString() + " (" + c.value() + ")";
101            }
102                else {
103                     continue;
104                }
105
106            if (labels.contains(key)) {
107            throw new SemanticException("Duplicate case label: " +
108                str + ".", c.position());
109            }
110
111            labels.add(key);
112        }
113     }
114
115     return this;
116     }
117
118     public Type childExpectedType(Expr child, AscriptionVisitor av) {
119         TypeSystem ts = av.typeSystem();
120
121         if (child == expr) {
122             return ts.Int();
123         }
124
125         return child.type();
126     }
127
128     public String JavaDoc toString() {
129     return "switch (" + expr + ") { ... }";
130     }
131
132     /** Write the statement to an output file. */
133     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
134     w.write("switch (");
135     printBlock(expr, w, tr);
136     w.write(") {");
137         w.allowBreak(4, " ");
138     w.begin(0);
139
140         boolean lastWasCase = false;
141         boolean first = true;
142
143     for (Iterator i = elements.iterator(); i.hasNext();) {
144             SwitchElement s = (SwitchElement) i.next();
145             if (s instanceof Case) {
146                 if (lastWasCase) w.newline(0);
147                 else if (! first) w.allowBreak(0, " ");
148                 printBlock(s, w, tr);
149                 lastWasCase = true;
150             }
151             else {
152                 w.allowBreak(4," ");
153                 print(s, w, tr);
154                 lastWasCase = false;
155             }
156
157             first = false;
158     }
159
160     w.end();
161         w.allowBreak(0, " ");
162     w.write("}");
163     }
164
165     public Term entry() {
166         return expr.entry();
167     }
168
169     public List acceptCFG(CFGBuilder v, List succs) {
170         SwitchElement prev = null;
171
172         List cases = new LinkedList();
173         boolean hasDefault = false;
174
175         for (Iterator i = elements.iterator(); i.hasNext(); ) {
176             SwitchElement s = (SwitchElement) i.next();
177
178             if (s instanceof Case) {
179                 cases.add(s.entry());
180                 if (((Case) s).expr() == null) {
181                     hasDefault = true;
182                 }
183             }
184         }
185
186         // If there is no default case, add an edge to the end of the switch.
187
if (! hasDefault) {
188             cases.add(this);
189         }
190
191         v.visitCFG(expr, FlowGraph.EDGE_KEY_OTHER, cases);
192         v.push(this).visitCFGList(elements, this);
193
194         return succs;
195     }
196 }
197
Popular Tags