KickJava   Java API By Example, From Geeks To Geeks.

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


1 package polyglot.ext.jl.ast;
2
3 import java.util.Iterator JavaDoc;
4 import java.util.List JavaDoc;
5
6 import polyglot.ast.*;
7 import polyglot.types.*;
8 import polyglot.util.CodeWriter;
9 import polyglot.util.Position;
10 import polyglot.util.SubtypeSet;
11 import polyglot.visit.*;
12
13 /**
14  * An <code>Initializer</code> is an immutable representation of an
15  * initializer block in a Java class (which appears outside of any
16  * method). Such a block is executed before the code for any of the
17  * constructors. Such a block can optionally be static, in which case
18  * it is executed when the class is loaded.
19  */

20 public class Initializer_c extends Term_c implements Initializer
21 {
22     protected Flags flags;
23     protected Block body;
24     protected InitializerInstance ii;
25
26     public Initializer_c(Position pos, Flags flags, Block body) {
27     super(pos);
28     this.flags = flags;
29     this.body = body;
30     }
31
32     /** Get the flags of the initializer. */
33     public Flags flags() {
34     return this.flags;
35     }
36
37     /** Set the flags of the initializer. */
38     public Initializer flags(Flags flags) {
39     Initializer_c n = (Initializer_c) copy();
40     n.flags = flags;
41     return n;
42     }
43
44     /** Get the initializer instance of the initializer. */
45     public InitializerInstance initializerInstance() {
46         return ii;
47     }
48
49     public CodeInstance codeInstance() {
50     return initializerInstance();
51     }
52
53     /** Set the initializer instance of the initializer. */
54     public Initializer initializerInstance(InitializerInstance ii) {
55     Initializer_c n = (Initializer_c) copy();
56     n.ii = ii;
57     return n;
58     }
59
60     /** Get the body of the initializer. */
61     public Block body() {
62     return this.body;
63     }
64
65     /** Set the body of the initializer. */
66     public CodeDecl body(Block body) {
67     Initializer_c n = (Initializer_c) copy();
68     n.body = body;
69     return n;
70     }
71
72     /** Reconstruct the initializer. */
73     protected Initializer_c reconstruct(Block body) {
74     if (body != this.body) {
75         Initializer_c n = (Initializer_c) copy();
76         n.body = body;
77         return n;
78     }
79
80     return this;
81     }
82
83     /** Visit the children of the initializer. */
84     public Node visitChildren(NodeVisitor v) {
85     Block body = (Block) visitChild(this.body, v);
86     return reconstruct(body);
87     }
88
89     public Context enterScope(Context c) {
90     return c.pushCode(ii);
91     }
92
93     public NodeVisitor buildTypesEnter(TypeBuilder tb) throws SemanticException {
94         return tb.pushCode();
95     }
96
97     /**
98      * Return the first (sub)term performed when evaluating this
99      * term.
100      */

101     public Term entry() {
102         return this.body().entry();
103     }
104
105     public List JavaDoc acceptCFG(CFGBuilder v, List JavaDoc succs) {
106         v.visitCFG(this.body(), this);
107         return succs;
108     }
109
110     /** Build type objects for the method. */
111     public Node buildTypes(TypeBuilder tb) throws SemanticException {
112         TypeSystem ts = tb.typeSystem();
113         ClassType ct = tb.currentClass();
114         InitializerInstance ii = ts.initializerInstance(position(), ct, flags);
115         return initializerInstance(ii);
116     }
117
118     public NodeVisitor addMembersEnter(AddMemberVisitor am) {
119         // do not add members for the children of this node.
120
return am.bypassChildren(this);
121     }
122
123     public NodeVisitor disambiguateEnter(AmbiguityRemover ar) throws SemanticException {
124         // Do not visit body on the clean-super and clean-signatures passes.
125
if (ar.kind() == AmbiguityRemover.SUPER ||
126             ar.kind() == AmbiguityRemover.SIGNATURES) {
127             return ar.bypassChildren(this);
128         }
129         return ar;
130     }
131
132     /** Type check the initializer. */
133     public Node typeCheck(TypeChecker tc) throws SemanticException {
134     TypeSystem ts = tc.typeSystem();
135
136     try {
137         ts.checkInitializerFlags(flags());
138     }
139     catch (SemanticException e) {
140         throw new SemanticException(e.getMessage(), position());
141     }
142
143         // check that inner classes do not declare static initializers
144
if (flags().isStatic() &&
145               initializerInstance().container().toClass().isInnerClass()) {
146             // it's a static initializer in an inner class.
147
throw new SemanticException("Inner classes cannot declare " +
148                     "static initializers.", this.position());
149         }
150
151     return this;
152     }
153
154     /** Check exceptions thrown by the initializer. */
155     public Node exceptionCheck(ExceptionChecker ec) throws SemanticException {
156         TypeSystem ts = ec.typeSystem();
157
158     SubtypeSet s = (SubtypeSet) ec.throwsSet();
159
160     for (Iterator JavaDoc i = s.iterator(); i.hasNext(); ) {
161         Type t = (Type) i.next();
162
163         if (! t.isUncheckedException()) {
164                 // TODO: This should agree with Java Language Spec 2nd Ed. 8.6
165
// An instance initializer of a named class may not throw
166
// a checked exception unless that exception or one of its
167
// superclasses is explicitly declared in the throws clause
168
// of each contructor or its class, and the class has at least
169
// one explicitly declared constructor.
170
if (initializerInstance().flags().isStatic()) {
171                     throw new SemanticException(
172                         "A static initializer block may not throw a " + t + ".",
173                         ec.exceptionPosition(t));
174                 }
175                 
176                 if (!initializerInstance().container().toClass().isAnonymous()) {
177                         // XXX should only throw this if it is not common to all
178
// declared constructors, and there is at least one
179
// declared constructor.
180
throw new SemanticException(
181                     "An instance initializer block may not throw a " + t + ".",
182                             ec.exceptionPosition(t));
183                 }
184         }
185     }
186
187     return super.exceptionCheck(ec);
188     }
189
190     /** Write the initializer to an output file. */
191     public void prettyPrint(CodeWriter w, PrettyPrinter tr) {
192     w.write(flags.translate());
193     printBlock(body, w, tr);
194     }
195
196     public void dump(CodeWriter w) {
197     super.dump(w);
198
199     if (ii != null) {
200         w.allowBreak(4, " ");
201         w.begin(0);
202         w.write("(instance " + ii + ")");
203         w.end();
204     }
205     }
206
207     public String JavaDoc toString() {
208     return flags.translate() + "{ ... }";
209     }
210 }
211
Popular Tags