KickJava   Java API By Example, From Geeks To Geeks.

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


1 package polyglot.ext.jl.ast;
2
3 import polyglot.ast.*;
4
5 import polyglot.types.*;
6 import polyglot.visit.*;
7 import polyglot.util.*;
8 import java.util.*;
9
10 /**
11  * A <code>LocalDecl</code> is an immutable representation of the declaration
12  * of a local variable.
13  */

14 public class LocalDecl_c extends Stmt_c implements LocalDecl {
15     Flags flags;
16     TypeNode type;
17     String JavaDoc name;
18     Expr init;
19     LocalInstance li;
20
21     public LocalDecl_c(Position pos, Flags flags, TypeNode type,
22                        String JavaDoc name, Expr init)
23     {
24         super(pos);
25         this.flags = flags;
26         this.type = type;
27         this.name = name;
28         this.init = init;
29     }
30
31     /** Get the type of the declaration. */
32     public Type declType() {
33         return type.type();
34     }
35
36     /** Get the flags of the declaration. */
37     public Flags flags() {
38         return flags;
39     }
40
41     /** Set the flags of the declaration. */
42     public LocalDecl flags(Flags flags) {
43         LocalDecl_c n = (LocalDecl_c) copy();
44         n.flags = flags;
45         return n;
46     }
47
48     /** Get the type node of the declaration. */
49     public TypeNode type() {
50         return type;
51     }
52
53     /** Set the type of the declaration. */
54     public LocalDecl type(TypeNode type) {
55         if (type == this.type) return this;
56         LocalDecl_c n = (LocalDecl_c) copy();
57         n.type = type;
58         return n;
59     }
60
61     /** Get the name of the declaration. */
62     public String JavaDoc name() {
63         return name;
64     }
65
66     /** Set the name of the declaration. */
67     public LocalDecl name(String JavaDoc name) {
68         if (name.equals(this.name)) return this;
69         LocalDecl_c n = (LocalDecl_c) copy();
70         n.name = name;
71         return n;
72     }
73
74     /** Get the initializer of the declaration. */
75     public Expr init() {
76         return init;
77     }
78
79     /** Set the initializer of the declaration. */
80     public LocalDecl init(Expr init) {
81         if (init == this.init) return this;
82         LocalDecl_c n = (LocalDecl_c) copy();
83         n.init = init;
84         return n;
85     }
86
87     /** Set the local instance of the declaration. */
88     public LocalDecl localInstance(LocalInstance li) {
89         if (li == this.li) return this;
90         LocalDecl_c n = (LocalDecl_c) copy();
91         n.li = li;
92         return n;
93     }
94
95     /** Get the local instance of the declaration. */
96     public LocalInstance localInstance() {
97         return li;
98     }
99
100     /** Reconstruct the declaration. */
101     protected LocalDecl_c reconstruct(TypeNode type, Expr init) {
102         if (this.type != type || this.init != init) {
103             LocalDecl_c n = (LocalDecl_c) copy();
104             n.type = type;
105             n.init = init;
106             return n;
107         }
108
109         return this;
110     }
111
112     /** Visit the children of the declaration. */
113     public Node visitChildren(NodeVisitor v) {
114         TypeNode type = (TypeNode) visitChild(this.type, v);
115         Expr init = (Expr) visitChild(this.init, v);
116         return reconstruct(type, init);
117     }
118
119     /**
120      * Add the declaration of the variable as we enter the scope of the
121      * intializer
122      */

123     public Context enterScope(Node child, Context c) {
124         if (child == init) {
125             c.addVariable(li);
126         }
127         return super.enterScope(child, c);
128     }
129
130     public void addDecls(Context c) {
131         // Add the declaration of the variable in case we haven't already done
132
// so in enterScope, when visiting the initializer.
133
c.addVariable(li);
134     }
135
136     public Node buildTypes(TypeBuilder tb) throws SemanticException {
137         LocalDecl_c n = (LocalDecl_c) super.buildTypes(tb);
138
139         TypeSystem ts = tb.typeSystem();
140
141         LocalInstance li = ts.localInstance(position(), Flags.NONE,
142                                             ts.unknownType(position()), name());
143         return n.localInstance(li);
144     }
145
146     public Node disambiguate(AmbiguityRemover ar) throws SemanticException {
147         TypeSystem ts = ar.typeSystem();
148
149         LocalInstance li = ts.localInstance(position(),
150                                             flags(), declType(), name());
151
152         return localInstance(li);
153     }
154
155     /**
156      * Override superclass behaviour to check if the variable is multiply
157      * defined.
158      */

159     public NodeVisitor typeCheckEnter(TypeChecker tc) throws SemanticException {
160         // Check if the variable is multiply defined.
161
// we do it in type check enter, instead of type check since
162
// we add the declaration before we enter the scope of the
163
// initializer.
164
Context c = tc.context();
165
166         LocalInstance outerLocal = null;
167
168         try {
169             outerLocal = c.findLocal(li.name());
170         }
171         catch (SemanticException e) {
172             // not found, so not multiply defined
173
}
174
175         if (outerLocal != null && c.isLocal(li.name())) {
176             throw new SemanticException(
177                 "Local variable \"" + name + "\" multiply defined. "
178                     + "Previous definition at " + outerLocal.position() + ".",
179                 position());
180         }
181         
182         return super.typeCheckEnter(tc);
183
184     }
185     
186     /** Type check the declaration. */
187     public Node typeCheck(TypeChecker tc) throws SemanticException {
188         TypeSystem ts = tc.typeSystem();
189
190         LocalInstance li = this.li;
191
192         if (li.flags().isFinal() && init() != null && init().isConstant()) {
193             Object JavaDoc value = init().constantValue();
194             li = (LocalInstance) li.constantValue(value);
195         }
196
197         try {
198             ts.checkLocalFlags(flags);
199         }
200         catch (SemanticException e) {
201             throw new SemanticException(e.getMessage(), position());
202         }
203
204         if (init != null) {
205             if (init instanceof ArrayInit) {
206                 ((ArrayInit) init).typeCheckElements(type.type());
207             }
208             else {
209                 if (! ts.isImplicitCastValid(init.type(), type.type()) &&
210                     ! ts.equals(init.type(), type.type()) &&
211                     ! ts.numericConversionValid(type.type(),
212                                                 init.constantValue())) {
213                     throw new SemanticException("The type of the variable " +
214                                                 "initializer \"" + init.type() +
215                                                 "\" does not match that of " +
216                                                 "the declaration \"" +
217                                                 type.type() + "\".",
218                                                 init.position());
219                 }
220             }
221         }
222
223         return localInstance(li);
224     }
225
226     public Type childExpectedType(Expr child, AscriptionVisitor av) {
227         if (child == init) {
228             TypeSystem ts = av.typeSystem();
229
230             // If the RHS is an integral constant, we can relax the expected
231
// type to the type of the constant.
232
if (ts.numericConversionValid(type.type(), child.constantValue())) {
233                 return child.type();
234             }
235             else {
236                 return type.type();
237             }
238         }
239
240         return child.type();
241     }
242
243     public String JavaDoc toString() {
244         return flags.translate() + type + " " + name +
245                 (init != null ? " = " + init : "") + ";";
246     }
247
248     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
249         boolean printSemi = tr.appendSemicolon(true);
250         boolean printType = tr.printType(true);
251
252         w.write(flags.translate());
253         if (printType) {
254             print(type, w, tr);
255             w.write(" ");
256         }
257         w.write(name);
258
259         if (init != null) {
260             w.write(" =");
261             w.allowBreak(2, " ");
262             print(init, w, tr);
263         }
264
265         if (printSemi) {
266             w.write(";");
267         }
268
269         tr.printType(printType);
270         tr.appendSemicolon(printSemi);
271     }
272
273     public void dump(CodeWriter w) {
274         super.dump(w);
275
276         if (li != null) {
277             w.allowBreak(4, " ");
278             w.begin(0);
279             w.write("(instance " + li + ")");
280             w.end();
281         }
282
283     w.allowBreak(4, " ");
284     w.begin(0);
285     w.write("(name " + name + ")");
286     w.end();
287     }
288
289     public Term entry() {
290         if (init() != null) {
291             return init().entry();
292         }
293         return this;
294     }
295
296     public List acceptCFG(CFGBuilder v, List succs) {
297         if (init() != null) {
298             v.visitCFG(init(), this);
299         }
300
301         return succs;
302     }
303 }
304
Popular Tags