KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > ast > NewArrayExpr


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.ast;
26
27 import org.aspectj.compiler.base.FlowCheckerPass;
28 import org.aspectj.compiler.base.AssignmentCheckerPass;
29 import org.aspectj.compiler.base.JavaCompiler;
30 import org.aspectj.compiler.base.CodeWriter;
31 import java.io.IOException JavaDoc;
32
33 import java.util.*;
34
35 import org.aspectj.compiler.base.bcg.CodeBuilder;
36 import org.aspectj.compiler.base.bcg.Label;
37
38 /**
39  * @grammar new typeD[dimExprs, ..] {initializers, ..}
40  * @child ArrayInitializer initializer
41  * @child Exprs dimExprs
42  */

43
44 // note carefully that typeD holds the ARRAY TYPED, not the typeD from
45
// the original concrete syntax.
46

47 // Also note that there are TWO distinct types hiding here, because of
48
// the invariant that either dimExprs or initializers (but never both)
49
// will be null. So we either have, from the concrete syntax:
50
// new TypeId[]... { Expr, ... }, or
51
// new TypeId[Expr]...[]...
52
public class NewArrayExpr extends NewExpr {
53
54     public Type discoverType() {
55         //System.out.println("discover type: " + this);
56
Exprs dimExprs = getDimExprs();
57         ArrayInitializer inits = getInitializer();
58         ArrayType type = (ArrayType)getTypeD().getType();
59
60         if (initializer == null) {
61             // at least one dimExpr, all dimExprs are ints followed by emptys
62
final int dimExprCount = dimExprs.size();
63             for (int i = 0; i < dimExprCount; i++) {
64                 Expr dimExpr = dimExprs.get(i);
65                 if (dimExpr instanceof EmptyExpr) break;
66                 if (! dimExpr.isAssignableTo(getTypeManager().intType)) {
67                     dimExpr.showTypeError(dimExpr.getType(), getTypeManager().intType);
68                 }
69             }
70         }
71         return type;
72     }
73
74     public Exprs getArgs() { return new Exprs(getSourceLocation()); }
75     public CodeDec getCodeDec() { return null; } //XXX this might be trouble
76
public Type getCalledType() {
77         return getTypeD().getType();
78     }
79
80
81     public void unparse(CodeWriter writer) throws IOException JavaDoc {
82         ArrayType arrayType = (ArrayType)getTypeD().getType();
83         Exprs exprs = getDimExprs();
84
85         writer.writeKeyword("new");
86         writer.requiredSpace();
87         if (exprs == null) {
88             writer.write(arrayType.getString());
89             writer.optionalSpace();
90             writer.write(initializer);
91         } else {
92             Type componentType = arrayType.getComponentType();
93             while (componentType instanceof ArrayType) {
94                 componentType = ((ArrayType)componentType).getComponentType();
95             }
96             writer.write(componentType.getString());
97
98             for(int i=0; i<exprs.size(); i++) {
99                 writer.write('['); writer.write(exprs.get(i)); writer.write(']');
100             }
101         }
102     }
103
104     // ------------------------------
105
// INTRO from AssignmentCheckerPass
106

107     public void preAssignmentCheck(AssignmentCheckerPass walker) {
108         if (getInitializer() != null) {
109             Type componentType = ((ArrayType)getType()).getComponentType();
110             if (componentType instanceof ArrayType) {
111                 ArrayType arrayComponentType = (ArrayType) componentType;
112                 Exprs exprs = initializer.getExprs();
113                 for (int i = exprs.size() - 1; i >= 0; i--) {
114                     Expr expr = exprs.get(i);
115                     if (expr instanceof ArrayInitializer) {
116                         exprs.set(i,
117                                   getAST().makeNewArray(arrayComponentType,
118                                                         (ArrayInitializer)expr));
119                     }
120                 }
121             }
122         }
123     }
124
125     public ASTObject postAssignmentCheck(AssignmentCheckerPass walker) {
126         if (getInitializer() != null) {
127             Type componentType = ((ArrayType)getType()).getComponentType();
128             Exprs exprs = initializer.getExprs();
129             for (int i = exprs.size() - 1; i >= 0; i--) {
130                 Expr expr = exprs.get(i);
131                 if (! expr.isAssignableTo(componentType)) {
132                     expr.showTypeError(expr.getType(), componentType);
133                 }
134             }
135         }
136         return this;
137     }
138
139     // ------------------------------
140
// bytecode generation fixing
141

142
143     /* We can't actually check that a varDec is typesafe until we
144        constant fold, due to the strange static downcast allowable
145        from integer constants. */

146     private void typeCheck(Type ty, Expr e) {
147         if (e instanceof ArrayInitializer) {
148             // ARRAY INITIALIZERS
149
if (! (ty instanceof ArrayType)) {
150                 showError("illegal initializer for " + ty.getString());
151             } else {
152                 Type componentTy = ((ArrayType)ty).getComponentType();
153                 Exprs exprs = ((ArrayInitializer)e).getExprs();
154                 // make sure expressions were scanned...
155
if (exprs != null) {
156                     int len = exprs.size();
157                     for (int i = 0; i < len; i++) {
158                         Expr arrayInit = exprs.get(i);
159                         typeCheck(componentTy, arrayInit);
160                     }
161                 }
162             }
163         } else {
164         }
165     }
166
167     // ------------------------------
168
// bcg
169
protected void cgValue(CodeBuilder cb) {
170         ArrayType type = (ArrayType)getTypeD().getType();
171         int dims = type.getArrayDimCount();
172         Type compTy = type.getComponentType();
173
174         if (initializer == null) {
175             // invariant: (dimExprs != null)
176
int filledDims = 0;
177             for (int i = 0; i < dims; i++) {
178                 Expr e = dimExprs.get(i);
179                 if (e instanceof EmptyExpr) break;
180                 e.cgValue(cb);
181                 filledDims++;
182             }
183             if (dims == 1) {
184                 compTy.emitNewarray(cb);
185             } else {
186                 type.emitMultiNewarray(cb, filledDims);
187             }
188         }
189         else {
190             // invariant: (dimExprs == null)
191
// assumption: we've desugared the array initializer
192
Exprs es = initializer.getExprs();
193             int size = es.size();
194             cb.emitIntConstant(size);
195             compTy.emitNewarray(cb);
196             for (int i = 0; i < size; i++) {
197                 Expr e = es.get(i);
198                 // optimizing new int[] {0, 0}.
199
// and new Int[][] {null, null, null}
200
if (e.isConstantZero()) continue;
201                 cb.emitDUP(); // dup the array
202
cb.emitIntConstant(i);
203                 e.cgValue(cb, compTy);
204                 compTy.emitAstore(cb);
205             }
206         }
207     }
208
209     //BEGIN: Generated from @child and @property
210
protected ArrayInitializer initializer;
211     public ArrayInitializer getInitializer() { return initializer; }
212     public void setInitializer(ArrayInitializer _initializer) {
213         if (_initializer != null) _initializer.setParent(this);
214         initializer = _initializer;
215     }
216
217     protected Exprs dimExprs;
218     public Exprs getDimExprs() { return dimExprs; }
219     public void setDimExprs(Exprs _dimExprs) {
220         if (_dimExprs != null) _dimExprs.setParent(this);
221         dimExprs = _dimExprs;
222     }
223
224     public NewArrayExpr(SourceLocation location, TypeD _typeD, ArrayInitializer _initializer, Exprs _dimExprs) {
225         super(location, _typeD);
226         setInitializer(_initializer);
227         setDimExprs(_dimExprs);
228     }
229     protected NewArrayExpr(SourceLocation source) {
230         super(source);
231     }
232
233     public ASTObject copyWalk(CopyWalker walker) {
234         NewArrayExpr ret = new NewArrayExpr(getSourceLocation());
235         ret.preCopy(walker, this);
236         if (typeD != null) ret.setTypeD( (TypeD)walker.process(typeD) );
237         if (initializer != null) ret.setInitializer( (ArrayInitializer)walker.process(initializer) );
238         if (dimExprs != null) ret.setDimExprs( (Exprs)walker.process(dimExprs) );
239         return ret;
240     }
241
242     public ASTObject getChildAt(int childIndex) {
243         switch(childIndex) {
244         case 1: return initializer;
245         case 2: return dimExprs;
246         default: return super.getChildAt(childIndex);
247         }
248     }
249      public String JavaDoc getChildNameAt(int childIndex) {
250         switch(childIndex) {
251         case 1: return "initializer";
252         case 2: return "dimExprs";
253         default: return super.getChildNameAt(childIndex);
254         }
255     }
256      public void setChildAt(int childIndex, ASTObject child) {
257         switch(childIndex) {
258         case 1: setInitializer((ArrayInitializer)child); return;
259         case 2: setDimExprs((Exprs)child); return;
260         default: super.setChildAt(childIndex, child); return;
261         }
262     }
263      public int getChildCount() {
264         return 3;
265     }
266
267     public String JavaDoc getDefaultDisplayName() {
268         return "NewArrayExpr()";
269     }
270
271     //END: Generated from @child and @property
272
}
273
Popular Tags