KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* -*- 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.*;
28 import org.aspectj.compiler.crosscuts.*;
29 import org.aspectj.compiler.base.cst.*;
30
31 import org.aspectj.compiler.base.bcg.CodeBuilder;
32
33 /**
34  * @grammar enclosingInstanceExpr.new typeD(args) { typeDec }
35  * @child Expr enclosingInstanceExpr @before typeD
36  * @child Exprs args
37  * @child TypeDec typeDec
38  * @property Constructor constructor
39  */

40
41 public class NewInstanceExpr extends NewExpr implements SOLink {
42
43     public CodeDec getCodeDec() { return getConstructorDec(); }
44     public ConstructorDec getConstructorDec() {
45         return getConstructor().getConstructorDec();
46     }
47     public void setConstructorDec(ConstructorDec md) {
48         setConstructor((Constructor)md.getCorrespondingSemanticObject());
49     }
50     public SemanticObject getTarget() { return getConstructor(); }
51     public void setTarget(SemanticObject newTarget) {
52         setConstructor((Constructor)newTarget);
53     }
54
55     public boolean isLegalStmt() {
56         return true;
57     }
58
59     // ------------------------------
60
// INTRO from InnerInfoPass
61

62     public void walkInnerInfo(InnerInfoPass w) {
63 // if (typeDec != null && ! (enclosingInstanceExpr instanceof ThisExpr)) {
64
// final AST ast = getAST();
65
// // we're a qualified anonymous type, so let's do the rewrite now.
66
// ConstructorDec dec = getConstructorDec();
67
// ConstructorCallExpr cc =
68
// ((ConstructorBody) dec.getBody()).getConstructorCall();
69
// FormalDec f = ast.makeFormal(enclosingInstanceExpr.getType(),
70
// "super$enc$obj");
71
// dec.getFormals().add(0, f);
72
// dec.setEnclosingInstanceFormal(null);
73
// cc.setEnclosingInstanceExpr(ast.makeVar(f));
74
// getArgs().add(0, enclosingInstanceExpr);
75
// setEnclosingInstanceExpr(null);
76
// }
77
super.walkInnerInfo(w);
78
79     }
80
81     public void postInnerInfo(InnerInfoPass w) {
82         // the only time getConstructor() can be null is if we've
83
// already signalled an error for this expression that we
84
// couldn't find the constructor. In such cases, we'll just
85
// punt since we're about to exit anyway.
86
if (getConstructor() == null) return;
87         NameType target = (NameType) getConstructor().getDeclaringType();
88         if (w.isInner(target) && getEnclosingInstanceExpr() == null) {
89             NameType enclosingTarget = target.getEnclosingType();
90             if (! w.isAccessible(enclosingTarget)) {
91                 showError("no enclosing instance available");
92             } else {
93                 setEnclosingInstanceExpr(getAST().makePrimary(enclosingTarget,
94                                                               w.currentType(),
95                                                               false));
96             }
97         }
98     }
99
100     // ------------------------------
101
// INTRO from spec checker pass
102

103     public void checkSpec() {
104         if (getEnclosingInstanceExpr() != null) {
105             NameType ty;
106             if (getTypeDec() == null || ! (this instanceof NewInnerInstanceExpr)) {
107                 ty = (NameType) getConstructorDec().getDeclaringType();
108             } else {
109                 ty = (NameType) getTypeD().getType();
110             }
111             if (! ty.isInner()) {
112                 showError("Type " + ty.getId() + " is not an inner class");
113             }
114             // if the primary is not of the correct type then we wouldn't
115
// have resolved the constructor.
116
}
117         super.checkSpec();
118     }
119
120     //INTRO from AccessFixer
121
public ASTObject fixAccessPost(AccessFixer fixer) {
122         if (getConstructor() == null) return this; //XXX should be error
123
//TypeDec fromTypeDec = getBytecodeTypeDec(); //fixer.fromTypeDec;
124
if (getTypeDec() != null || getConstructor().isAccessible(this, true)) return this;
125
126         getCompiler().showMessage(" fixing privileged new: " +
127                                   getConstructor().toShortString());
128         //this.getParent().getParent().display(2);
129

130         getConstructor().getConstructorDec().makePublicAccessible();
131         return this;
132     }
133
134
135     // ------------------------------
136
// INTRO from FlowCheckerPass
137

138     public void walkFlow(FlowCheckerPass w) {
139         super.walkFlow(w); // walks the args and the inner class dec
140
if (getConstructor().getThrows() != null) {
141             TypeDs ts = getConstructor().getThrows();
142             for (int i = 0, len = ts.size(); i < len; i++) {
143                 w.setExns(w.getExns().add((NameType) ts.get(i).getType()));
144             }
145         }
146     }
147
148     /**
149      * Section 6.6.2.2 from JLSv2
150      * access to protected is only allowed from outside package
151      * if typeDec != null
152      */

153     public boolean hasLegalProtectedAccess(Type fromType) {
154         return typeDec != null;
155     }
156
157     //INTRO from MovingWalker
158
public ASTObject postMove(MovingWalker walker) {
159         //System.out.println("moving: " + this.unparse());
160
walker.moveLink(this);
161
162         /* !!!This nonsense is to make local type in around advice to "move"
163            nicely. */

164         if (enclosingInstanceExpr != null && walker.getToType() != null &&
165             (getTypeDec() != null || getType().getTypeDec().isLocal())) {
166             if (!walker.isStatic) {
167                 enclosingInstanceExpr = getAST().makeThis(walker.getToType());
168             } else {
169                 enclosingInstanceExpr = null;
170             }
171         }
172
173         if (getTypeDec() != null) {
174             setType(null);
175             getType();
176         }
177
178         return this;
179     }
180
181     //INTRO from ScopeWalker
182
public ASTObject postScope(ScopeWalker walker) {
183         if (constructor != null) return this;
184
185         Type myType;
186         if (typeDec != null) {
187             myType = typeDec.getType();
188         } else {
189             myType = typeD.getType();
190         }
191
192         if (typeDec == null) {
193             if (typeD.getType().isInterface()) {
194                 showError("can't instantiate interface " + myType.toShortString()); }
195             else {
196                 constructor = typeD.getType().getConstructor(this, args, true);
197             }
198         } else {
199             Constructor superConstructor;
200             if (typeD.getType().isInterface()) {
201                 superConstructor =
202                     getTypeManager().getObjectType().getConstructor(this, args, true);
203             } else {
204                 superConstructor =
205                     typeD.getType().getConstructor(typeDec.getBody(), args, true);
206             }
207             ConstructorDec dec = buildAnonDec(superConstructor);
208             //dec.setLanguageVisible();
209
dec.setAllEnclosingTypes(typeDec.getType());
210             typeDec.addConstructorDec(dec);
211             typeDec.getBody().add(dec);
212             typeDec.setSoleConstructorDec(dec);
213             constructor = (Constructor) dec.getCorrespondingSemanticObject();
214             if (getEnclosingInstanceExpr() != null) {
215                 // we've already made the constructor to take the enclosing
216
// instance expression as an argument, so let's make
217
// it an argument
218
getArgs().add(0, enclosingInstanceExpr);
219                 setEnclosingInstanceExpr(null);
220             }
221         }
222
223         if (fromSource() && myType.isAspect()) {
224             showError("can't explicitly instantiate an aspect");
225         }
226
227         if (myType.getTypeDec().isAbstract()) {
228             showError("can't instantiate abstract type " + myType.toShortString());
229         }
230         type = discoverType();
231
232         return this;
233     }
234
235     private ConstructorDec buildAnonDec(Constructor superConstructor) {
236         final AST ast = superConstructor.getAST();
237         Formals oldFormals = superConstructor.getFormals();
238         TypeDs oldThrows = superConstructor.getThrows();
239
240         Formals newFormals = ast.makeFormals();
241         Exprs newArgs = ast.makeExprs();
242           TypeDs newThrows =
243               oldThrows == null ? ast.makeTypeDs() : (TypeDs) oldThrows.copy();
244
245         final int len = oldFormals.size();
246         for (int i = 0; i < len; i++) {
247             FormalDec newFormal = (FormalDec) oldFormals.get(i).copy();
248             newFormal.getModifiers().setFinal(true);
249             Expr newArg = ast.makeVar(newFormal);
250             newFormals.add(newFormal);
251             newArgs.add(newArg);
252         }
253
254         Expr enclosingExpr = null;
255         ConstructorCallExpr cce = null;
256         if (getEnclosingInstanceExpr() != null) {
257             FormalDec newFormal =
258                 // ??? Is it wise to use getType() in this pass (scope
259
// walker)? Shouldn't we use
260
// ((NameType) superConstructor.getDeclaringType())
261
// .getEnclosingType()
262
// instead?
263
ast.makeFinalFormal(getEnclosingInstanceExpr().getType(),
264                                     "super$enc$obj");
265             newFormals.add(0, newFormal);
266             enclosingExpr = ast.makeVar(newFormal);
267             cce = new ConstructorCallExpr(ast.getSourceLocation(), enclosingExpr,
268                                           true, newArgs, superConstructor);
269         } else {
270             cce = ast.makeSuperConstructorCall(newArgs, superConstructor);
271         }
272
273         return
274             ast.makeConstructor(ast.makeModifiers(0),
275                                 newFormals,
276                                 newThrows,
277                                 cce,
278                                 ast.makeStmts());
279     }
280
281     public Type discoverType() {
282         if (typeDec == null) {
283             return typeD.getType();
284         } else {
285             return typeDec.getType();
286         }
287     }
288
289     public Type getCalledType() {
290         return getType();
291     }
292
293     public void fixForIntroductions() {
294 // System.out.println("fixing: " + constructor.toShortString() + System.identityHashCode(this));
295
Expr extraArg = null;
296         if (constructor != null) extraArg = constructor.getExtraArgExpr();
297 // System.out.println(" :" + extraArg);
298
// this.showError("fixing");
299
if (extraArg != null) args.add(extraArg);
300     }
301
302
303     //INTRO from ASTFixerPass
304
public ASTObject postFixAST(ASTFixerPass fixer) {
305         fixForIntroductions();
306         return this; //super.postFixAST(fixer);
307
}
308
309     public void unparse(CodeWriter writer) {
310         if (getEnclosingInstanceExpr() == null) {
311             writer.writeKeyword("new");
312             writer.requiredSpace();
313             writer.write(typeD);
314             writer.parenExprs(args);
315         } else {
316             writer.write(enclosingInstanceExpr);
317             writer.write('.');
318             writer.writeKeyword("new");
319             writer.requiredSpace();
320             writer.write(getTypeD().getType().getId());
321             writer.openParen('(');
322             writer.write(args);
323             writer.closeParen(')');
324         }
325         if (typeDec != null) {
326             writer.openBlock();
327             writer.write(typeDec.getBody());
328             writer.closeBlock();
329         }
330     }
331
332     // ------------------------------
333
//INTRO from InnerAccessFixer
334

335     public ASTObject postInnerAccess(InnerAccessFixer w) {
336         ConstructorDec dec = getConstructorDec();
337         if (! w.isAccessible(dec, this)) {
338             // perhaps should be creating a cookie, but won't for now.
339
dec.getModifiers().setPrivate(false);
340         }
341         return this;
342     }
343
344     // ------------------------------
345
// bcg
346

347     protected void cgValue(CodeBuilder cb) {
348         cgValueEffect(cb, true);
349     }
350     protected void cgEffect(CodeBuilder cb) {
351         cgValueEffect(cb, false);
352     }
353     private void cgValueEffect(CodeBuilder cb, boolean needsValue) {
354         cb.enterLocation(getSourceLocation());
355         NameType declaringType = (NameType) constructor.getDeclaringType();
356         cb.emitNEW(declaringType);
357         if (needsValue) cb.emitDUP();
358         if (enclosingInstanceExpr != null) {
359             enclosingInstanceExpr
360                 .cgValue(cb, constructor.getEnclosingInstanceFormal().getType());
361         if (! (getEnclosingInstanceExpr() instanceof ThisExpr)) {
362                 cb.emitDUP();
363                 cb.emitINVOKEVIRTUAL(getTypeManager().getObjectType(), "getClass",
364                                      "()Ljava/lang/Class;", 0);
365                 cb.emitPOP();
366             }
367         }
368         getArgs().cgValues(cb, constructor.getFormals());
369         cb.emitINVOKESPECIAL(declaringType, "<init>",
370                              constructor.getDescriptor(),
371                              constructor.getStackDelta());
372     }
373
374     // ------------------------------
375
// INTRO: LocalClassPass.LiftWalker
376

377     public void preLift(LocalClassPass.LiftWalker walker) {
378         TypeDec anonTypeDec = getTypeDec();
379         if (anonTypeDec == null) return;
380         NameType nameType = anonTypeDec.getNameType();
381         // XXX isn't this done in scopeWalker now?
382
this.setTypeD(nameType.makeTypeD());
383     }
384
385     // ------------------------------
386
// INTRO: LocalClassPass.ThreadingWalker
387

388     public void preThreading(LocalClassPass.ThreadingWalker walker) {
389         walker.addArgs(getArgs(),
390                        getConstructor().getDeclaringType().getTypeDec());
391     }
392
393     // ------------------------------
394
//XXX HACK
395

396     public void remove(int index) {
397         if (index == 3) {
398             setTypeDec(null);
399         } else {
400             super.remove(index);
401         }
402     }
403
404     // ------------------------------
405
// convienience constructors
406

407     public NewInstanceExpr(SourceLocation location, TypeD _typeD,
408                            Exprs _args, TypeDec _typeDec, Constructor _constructor) {
409         this(location, null, _typeD, _args, _typeDec, _constructor);
410     }
411
412     public NewInstanceExpr(SourceLocation source, Constructor constructor, Exprs args) {
413         this(source, null, constructor.getDeclaringType().makeTypeD(), args, null,
414              constructor);
415     }
416
417     public NewInstanceExpr(SourceLocation source, TypeD typeD, Exprs args) {
418         this(source, null, typeD, args, null, null);
419     }
420
421     //BEGIN: Generated from @child and @property
422
protected Expr enclosingInstanceExpr;
423     public Expr getEnclosingInstanceExpr() { return enclosingInstanceExpr; }
424     public void setEnclosingInstanceExpr(Expr _enclosingInstanceExpr) {
425         if (_enclosingInstanceExpr != null) _enclosingInstanceExpr.setParent(this);
426         enclosingInstanceExpr = _enclosingInstanceExpr;
427     }
428
429     protected Exprs args;
430     public Exprs getArgs() { return args; }
431     public void setArgs(Exprs _args) {
432         if (_args != null) _args.setParent(this);
433         args = _args;
434     }
435
436     protected TypeDec typeDec;
437     public TypeDec getTypeDec() { return typeDec; }
438     public void setTypeDec(TypeDec _typeDec) {
439         if (_typeDec != null) _typeDec.setParent(this);
440         typeDec = _typeDec;
441     }
442
443     protected Constructor constructor;
444     public Constructor getConstructor() { return constructor; }
445     public void setConstructor(Constructor _constructor) { constructor = _constructor; }
446
447     public NewInstanceExpr(SourceLocation location, Expr _enclosingInstanceExpr, TypeD _typeD, Exprs _args, TypeDec _typeDec, Constructor _constructor) {
448         super(location, _typeD);
449         setEnclosingInstanceExpr(_enclosingInstanceExpr);
450         setArgs(_args);
451         setTypeDec(_typeDec);
452         setConstructor(_constructor);
453     }
454     protected NewInstanceExpr(SourceLocation source) {
455         super(source);
456     }
457
458     public ASTObject copyWalk(CopyWalker walker) {
459         NewInstanceExpr ret = new NewInstanceExpr(getSourceLocation());
460         ret.preCopy(walker, this);
461         if (enclosingInstanceExpr != null) ret.setEnclosingInstanceExpr( (Expr)walker.process(enclosingInstanceExpr) );
462         if (typeD != null) ret.setTypeD( (TypeD)walker.process(typeD) );
463         if (args != null) ret.setArgs( (Exprs)walker.process(args) );
464         if (typeDec != null) ret.setTypeDec( (TypeDec)walker.process(typeDec) );
465         ret.constructor = constructor;
466         return ret;
467     }
468
469     public ASTObject getChildAt(int childIndex) {
470         switch(childIndex) {
471         case 0: return enclosingInstanceExpr;
472         case 1: return typeD;
473         case 2: return args;
474         case 3: return typeDec;
475         default: return super.getChildAt(childIndex);
476         }
477     }
478      public String JavaDoc getChildNameAt(int childIndex) {
479         switch(childIndex) {
480         case 0: return "enclosingInstanceExpr";
481         case 1: return "typeD";
482         case 2: return "args";
483         case 3: return "typeDec";
484         default: return super.getChildNameAt(childIndex);
485         }
486     }
487      public void setChildAt(int childIndex, ASTObject child) {
488         switch(childIndex) {
489         case 0: setEnclosingInstanceExpr((Expr)child); return;
490         case 1: setTypeD((TypeD)child); return;
491         case 2: setArgs((Exprs)child); return;
492         case 3: setTypeDec((TypeDec)child); return;
493         default: super.setChildAt(childIndex, child); return;
494         }
495     }
496      public int getChildCount() {
497         return 4;
498     }
499
500     public String JavaDoc getDefaultDisplayName() {
501         return "NewInstanceExpr(constructor: "+constructor+")";
502     }
503
504     //END: Generated from @child and @property
505
}
506
Popular Tags