KickJava   Java API By Example, From Geeks To Geeks.

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


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.*;
28 import org.aspectj.compiler.base.cst.*;
29
30 import org.aspectj.compiler.base.bcg.ClassfileBuilder;
31
32 import java.io.*;
33 import java.util.*;
34
35 import java.lang.reflect.Modifier JavaDoc;
36
37 // INTRO from crosscuts
38
import org.aspectj.compiler.crosscuts.ast.PointcutDec;
39 import org.aspectj.compiler.crosscuts.*;
40
41 /**
42  * Represents declared classes, interfaces and aspects
43  *
44  * One per declaration in the source or in the bytecodes
45  * ??? Should bytecodes produce something else ???
46  *
47  * @grammar ...
48  * @child Modifiers modifiers
49  * @property String id
50  * @child TypeDs superInterfaces
51  * @child Decs body
52  */

53 public abstract class TypeDec extends Dec {
54     // ------------------------------
55
// InnerInfo stuff
56

57     public void walkInnerInfo(InnerInfoPass w) {
58         int context = w.inType(this instanceof InterfaceDec);
59         w.enterType(this);
60         super.walkInnerInfo(w);
61         w.leaveType();
62         w.restoreContext(context);
63     }
64
65     // ------------------------------
66
// some spec checking
67

68     public void checkSpec() {
69         super.checkSpec();
70         checkConstructorLoops();
71         checkParentNonFinal();
72         if (isInner() || isLocal()) {
73             checkNoStaticMembers();
74         }
75         if (!isAnonymous()) {
76             TypeDec td = getEnclosingTypeDec();
77             while (td != null) {
78                 if (td.getId().equals(getId())) {
79                     showError("the name of this inner type conflicts with the name of an enclosing type: " + getId());
80                 }
81                 td = td.getEnclosingTypeDec();
82             }
83         }
84
85         if (fromSource()) {
86             if (!getType().isAbstract()) {
87                 getNameType().ensureNoAbstractDecs();
88             }
89             if (isPackageMember()) {
90                 PackageSO p = getTypeManager().findPackage(getPackageName());
91                 if (p.containsSubPackage(getId())) {
92                     showError(getFullName() + " clashes with package of same name");
93                 }
94             }
95         }
96     }
97
98     private void checkNoStaticMembers() {
99         for (int i=0, N=body.size(); i < N; i++) {
100             Dec dec = body.get(i);
101             if (!dec.isStatic()) continue;
102             if (dec instanceof FieldDec) {
103                 FieldDec fd = (FieldDec)dec;
104                 if (!fd.isConstant()) {
105                     dec.showError("all static fields in inners must be constant static finals");
106                 }
107             } else {
108                 dec.showError("inner classes cannot have static declarations");
109             }
110         }
111     }
112
113     private void checkParentNonFinal() {
114         if (((NameType)getSuperClassType()).isFinal()) {
115             showError("May not extend a final class");
116         }
117     }
118
119     private void checkConstructorLoops() {
120         for (int i = 0, len = body.size(); i < len; i++) {
121             Dec d = body.get(i);
122             if (! (d instanceof ConstructorDec)) continue;
123             ConstructorDec cd = (ConstructorDec) d;
124             Set alreadySeen = new java.util.HashSet JavaDoc();
125             while (! cd.isSuper()) {
126                 if (alreadySeen.contains(cd)) {
127                     ((ConstructorBody)cd.getBody()).getConstructorCall()
128                         .showError("a constructor may not directly or indirectly invoke itself");
129                     break;
130                 }
131                 alreadySeen.add(cd);
132                 cd = cd.getNextConstructorDec();
133             }
134         }
135     }
136
137     // ------------------------------
138
// INTRO from MemberClassMunger
139

140     public ASTObject walkMemberMunger(MemberClassMunger w) {
141         w.enterType(getNameType());
142         if (isInner()) {
143             final AST ast = getAST();
144             NameType enclosingInstanceType = getEnclosingInstanceType();
145             FieldDec enclosingInstanceField =
146                 ast.makeField(ast.makeModifiers(Modifiers.FINAL | Modifiers.PRIVATE),
147                               enclosingInstanceType,
148                               "this$" + enclosingInstanceType.getId());
149             w.pushField(enclosingInstanceField);
150             super.walkMemberMunger(w);
151             w.popField();
152
153             addFieldDec(enclosingInstanceField);
154             getBody().add(0, enclosingInstanceField);
155         } else {
156             List fields = w.saveFields();
157             super.walkMemberMunger(w);
158             w.restoreFields(fields);
159         }
160         w.leaveType();
161         return this;
162     }
163
164     // ------------------------------
165
// INTRO from FlowCheckerPass
166
public void walkFlow(FlowCheckerPass ww) {
167         // ------------------------------
168
// load up the body and the length into locals
169

170         Decs body = getBody();
171         int len = body.size();
172
173         // ------------------------------
174
// first collect up the static and non-static final fields
175

176         FlowCheckerPass.Set staticFinalFields = FlowCheckerPass.Set.getNone();
177         FlowCheckerPass.Set dynamicFinalFields = FlowCheckerPass.Set.getNone();
178
179         for (int i = 0; i < len; i++) {
180             Dec d = body.get(i);
181             if ((d instanceof FieldDec) && d.isFinal()) {
182                 FieldDec dd = (FieldDec) d;
183                 if (d.isStatic()) {
184                     staticFinalFields = staticFinalFields.add(dd);
185                 } else {
186                     dynamicFinalFields = dynamicFinalFields.add(dd);
187                 }
188             }
189         }
190
191 // System.err.println("S: " + staticFinalFields);
192
// System.err.println("D: " + dynamicFinalFields);
193

194         // ------------------------------
195
// start with an empty flow checker
196

197         FlowCheckerPass w = new FlowCheckerPass(getCompiler(), this);
198
199         // ------------------------------
200
// process the static world with no context
201

202         // process our static fields and initializers
203
for (int i = 0; i < len; i++) {
204             Dec d = body.get(i);
205             if (! d.isStatic()) continue;
206             if ((d instanceof FieldDec) && d.isFinal()) {
207                 FieldDec fd = (FieldDec) d;
208                 if (fd.getInitializer() != null) {
209                     // constants
210
w.setVars(w.getVars().addAssigned(fd));
211                 } else {
212                     w.setVars(w.getVars().addUnassigned(fd));
213                 }
214
215
216             } else if (d instanceof InitializerDec) {
217                 w.process(d);
218             }
219         }
220
221         // now, go through the static final fields and complain if any of them
222
// are uninitialized
223
FlowCheckerPass.Set staticAssigned = w.getVars().getDa();
224         for (FlowCheckerPass.Set x = staticFinalFields; ! x.isEmpty(); x = x.rest()) {
225             if (! staticAssigned.contains(x.first())) {
226                 w.showVarError(this,
227                                x.first(),
228                                "Field " + x.first().getId()
229                                + " might not be initialized");
230             }
231         }
232
233         // ------------------------------
234
// now, start with a flow-checker pass assuming all statics
235
// and whatever is coming in from our context are definitely
236
// assigned
237

238         staticAssigned = ww.getVars().getDa().union(staticFinalFields);
239         w = new FlowCheckerPass(getCompiler(), staticAssigned, this);
240
241         // process our non-static fields and initializers
242
for (int i = 0; i < len; i++) {
243             Dec d = body.get(i);
244             if (d.isStatic()) continue;
245             if ((d instanceof FieldDec) && d.isFinal()) {
246                 FieldDec fd = (FieldDec) d;
247                 if (fd.getInitializer() != null) {
248                     // constants
249
w.setVars(w.getVars().addAssigned(fd));
250                 } else {
251                     w.setVars(w.getVars().addUnassigned(fd));
252                 }
253             } else if (d instanceof InitializerDec) {
254                 w.process(d);
255             }
256         }
257
258         FlowCheckerPass.Vars preConstructorVars = w.getVars();
259
260         FlowCheckerPass.Set dynamicAssigned =
261             staticAssigned.union(dynamicFinalFields);
262
263         TypeDs initializerThrows = w.getCheckedExns();
264
265         // now process each of our constructors. For constructors
266
// calling super, start w/ preConstructorVars, and check after
267
// each super constructor that all the dynamicfinalfields are
268
// initialized. For constructors calling this, start w/
269
// dynamicAssigned and don't check anything afterward.
270
// also setup the throws clause if we're an anonymous
271
for (int i = 0; i < len; i++) {
272             Dec d = body.get(i);
273             if (! (d instanceof ConstructorDec)) continue;
274             ConstructorDec cd = (ConstructorDec) d;
275             if (isAnonymous()) {
276                 cd.setThrows(initializerThrows);
277             }
278             if (cd.isSuper()) {
279                 w = new FlowCheckerPass(getCompiler(), preConstructorVars, this);
280                 w.process(d);
281                 // check to make sure all dynamic finals are assigned
282
FlowCheckerPass.Set currentAssigned = w.getVars().getDa();
283                 for (FlowCheckerPass.Set x = dynamicFinalFields; ! x.isEmpty(); x = x.rest()) {
284                     if (! currentAssigned.contains(x.first())) {
285                         w.showVarError(this,
286                                        x.first(),
287                                        "Field " + x.first().getId()
288                                        + " might not be initialized");
289                     }
290                 }
291             } else {
292                 w = new FlowCheckerPass(getCompiler(), dynamicAssigned, this);
293                 w.process(d);
294             }
295         }
296
297         // ------------------------------
298
// now, start with all the other guys (methods, advice, etc),
299
// assuming all the fields are definitely assigned
300

301         for (int i = 0; i < len; i++) {
302             Dec d = body.get(i);
303             if ((d instanceof FieldDec)
304                     || (d instanceof InitializerDec)
305                     || (d instanceof ConstructorDec))
306                 continue;
307             w = new FlowCheckerPass(getCompiler(), dynamicAssigned, this);
308             w.process(d);
309         }
310
311         // and we're done, without side-effecting ww.
312
}
313
314     // a helper for AfterReturningAdviceDec and maybe others to generate unique labels
315
public int getDepth() {
316         if (getEnclosingTypeDec() == null) return 0;
317         else return 1 + getEnclosingTypeDec().getDepth();
318     }
319
320     public void preMove(MovingWalker walker) {
321         walker.pushLexicalType(getType());
322     }
323
324     public void preCopy(CopyWalker walker, ASTObject oldObject) {
325         walker.pushLexicalType(getType());
326     }
327
328     /**
329      * We now explicitly can't copy local types from one type dec to another
330      */

331     public ASTObject postCopy(CopyWalker walker, ASTObject oldObject) {
332         TypeDec oldTypeDec = (TypeDec)oldObject;
333         //this.isLocal = oldTypeDec.isLocal;
334
//this.isLocalFlag = oldTypeDec.isLocalFlag;
335
//this.isInnerFlag = oldTypeDec.isInnerFlag;
336
//this.isPackageMemberFlag = oldTypeDec.isPackageMemberFlag;
337
//this.hasBeenInnerDiscovered = oldTypeDec.hasBeenInnerDiscovered;
338
//System.out.println("walker: " + walker + " has " + walker.hasToType());
339
if (walker.hasToType()) {
340             //System.out.println(walker.getToType());
341
this.setEnclosingTypeDec(walker.getToType().getTypeDec());
342             //this.isInnerFlag = !walker.isStatic;
343
} else {
344             this.setEnclosingTypeDec(oldTypeDec.getEnclosingTypeDec());
345         }
346         return super.postCopy(walker, oldObject);
347     }
348
349     public ASTObject postMove(MovingWalker walker) {
350         // walk all decs and set my type as declaring type
351
for (int i = 0; i < body.size(); i++) {
352             body.get(i).setDeclaringType(getType());
353             //System.out.println(body.get(i).unparse());
354
}
355
356
357         walker.popLexicalType();
358         return super.postMove(walker);
359     }
360
361     public /* String */ Set memberTypeNames = null;
362
363     protected NameType type = null;
364     public Type getType() {
365         return getNameType();
366     }
367
368     public void setType(NameType type) {
369         this.type = type;
370     }
371
372     public NameType getNameType() {
373         if (type == null) {
374             type = new NameType(this);
375             //System.out.println("made type for: " + this.getExtendedId());
376
}
377         return type;
378     }
379
380     //XXX wrong
381
public TypeDec getBytecodeTypeDec() { return this; }
382
383     public SemanticObject makeCorrespondingSemanticObject() { return getType(); }
384
385     private Set extraWithinTypes = new HashSet();
386     public Set getExtraWithinTypes() { return extraWithinTypes; }
387     public void addExtraWithinType(Type type) { extraWithinTypes.add(type); }
388
389     public Type getSuperClassType() { return getTypeManager().getObjectType(); }
390
391     public Collection getSuperInterfaceTypes() {
392         return makeInterfaceTypesFromTypeDs(superInterfaces);
393     }
394
395     public void addSuperInterfaceType(Type newSuperType) {
396         TypeDs list = this.getSuperInterfaces();
397         if (list == null) {
398             list = getAST().makeTypeDs(); //new TypeDs(getCompiler());
399
this.setSuperInterfaces(list);
400         }
401         list.add(newSuperType.makeTypeD());
402     }
403
404
405
406     //public boolean isLocal = false;
407
private TypeDec enclosingTypeDec = null;
408
409     public void setEnclosingTypeDec(TypeDec dec) {
410         enclosingTypeDec = dec;
411         //??? add dec to enclosingTypeDecs inner types
412
}
413
414     public TypeDec getEnclosingTypeDec() {
415         return enclosingTypeDec;
416     }
417
418     public TypeDec getDeclaringTypeDec() {
419         return getEnclosingTypeDec();
420     }
421
422     public TypeDec getOutermostTypeDec() {
423         TypeDec immediateParent = getEnclosingTypeDec();
424         if (immediateParent == null) return this;
425         return immediateParent.getOutermostTypeDec();
426     }
427
428     public Type getOutermostType() {
429         TypeDec immediateParent = getEnclosingTypeDec();
430         if (immediateParent == null) return this.getType();
431         return immediateParent.getOutermostType();
432     }
433
434 // public Type getOutermostLexicalType() {
435
// Type parentLexicalType = getLexicalType();
436
// if (parentLexicalType == null) return getType();
437
// return parentLexicalType.getTypeDec().getOutermostLexicalType();
438
// }
439

440     public boolean isInnerType() {
441         return getDeclaringTypeDec() != null;
442     }
443
444     public boolean isInnerTypeOf(TypeDec parentType) {
445         TypeDec immediateParent = getDeclaringTypeDec();
446         if (immediateParent == null) return false;
447         if (immediateParent == parentType) return true;
448         return immediateParent.isInnerTypeOf(parentType);
449     }
450
451     /** Does this typeDec not have an accessible typeName from the
452         rest of the universe? That is, is it a local or anonymous
453         class, or is one of its declaring typedecs local or anonymous?
454     */

455     public boolean hasGlobalName() {
456         if (isLocal()) return false;
457         TypeDec immediateParent = getDeclaringTypeDec();
458         if (immediateParent == null) return true;
459         return immediateParent.hasGlobalName();
460     }
461
462     /** Is this typeDec in local context? A local or anonymous class? */
463     public boolean isLocallyDefined() {
464         return isLocal();
465     }
466
467     public abstract boolean isAnonymous();
468
469
470     public boolean canOverride(Dec otherDec) {
471         return true;
472     }
473
474     /*
475     public boolean isAccessible(ASTObject fromWhere, boolean inBytecode) {
476         if (!isPackageMember()) {
477             return super.isAccessible(fromWhere, inBytecode);
478         }
479
480         if (!inBytecode && hasPrivilegedAccess(fromWhere)) return true;
481         if (isPublic()) return true;
482
483         Type fromType;
484         if (inBytecode) {
485             if (fromWhere.getBytecodeTypeDec() == null) fromType = null;
486             else fromType = fromWhere.getBytecodeTypeDec().getType();
487         } else {
488             fromType = fromWhere.getLexicalType();
489         }
490
491         //???if (isPrivate() || isProtected()) return false;
492
493         String fromPackage=null;
494         if (fromType != null) fromPackage = fromType.getPackageName();
495         else fromPackage = fromWhere.getCompilationUnit().getPackageName();
496
497         return nameMatches(getCompilationUnit().getPackageName(), fromPackage);
498     }
499     */

500
501
502     public boolean isRoot() {
503         return this == getTypeManager().getObjectType().getTypeDec();
504     }
505
506     public boolean isConcrete() {
507         return !(this instanceof InterfaceDec);
508     }
509
510     private int localTypesCounter = 0;
511     public int allocateLocalTypeIndex() {
512         return ++localTypesCounter;
513     }
514
515
516     /**
517      * Returns the name of this class minus the package name
518      *
519      * uses '$' as a separator for inners
520      *
521      * java.util.Map.Entry goes to Map$Entry
522      */

523     public String JavaDoc getExtendedId() {
524         if (getEnclosingTypeDec() != null) {
525             return getEnclosingTypeDec().getExtendedId() + '$' + id;
526         } else {
527             return id;
528         }
529     }
530
531     /**
532      * Returns the name of this class minus the package name
533      *
534      * uses '.' as a separator for inners
535      *
536      * java.util.Map.Entry goes to Map.Entry
537      */

538     public String JavaDoc getSourceExtendedId() {
539         if (getEnclosingTypeDec() != null) {
540             return getEnclosingTypeDec().getSourceExtendedId() + '.' + id;
541         } else {
542             return id;
543         }
544     }
545
546     /** Assume that this method is called at least once per type
547      * to check some rules about interfaces
548      */

549     protected Collection makeInterfaceTypesFromTypeDs(TypeDs typeDs) {
550         if (typeDs == null || typeDs.size() == 0) return Collections.EMPTY_LIST;
551
552         List ret = new ArrayList(typeDs.size());
553
554         for (int i = 0; i < typeDs.size(); i++) {
555             Type type = typeDs.get(i).getType();
556             if (!type.isInterface()) {
557                 typeDs.get(i).showError("interface required, not " + type.toShortString());
558             } else if (ret.contains(type)) {
559                 typeDs.get(i).showError("repeated parent interface " + type.toShortString());
560             } else {
561                 ret.add(type);
562             }
563         }
564
565         return ret;
566     }
567
568     protected void addPointcutDec(PointcutDec pointcutDec) {
569         type.addPointcut(pointcutDec);
570     }
571
572     protected void addFieldDec(FieldDec fieldDec) {
573         type.addField(fieldDec);
574     }
575
576     protected void addMethodDec(MethodDec methodDec) {
577          if (getModifiers().isStrict() && !methodDec.getModifiers().isAbstract()) {
578              methodDec.getModifiers().setStrict(true);
579          }
580          type.addMethod(methodDec);
581     }
582
583     protected void addConstructorDec(ConstructorDec constructorDec) {
584         //System.out.println("adding: " + constructorDec.getId() + " to " + type);
585
if (getModifiers().isStrict()) constructorDec.getModifiers().setStrict(true);
586         type.addConstructor(constructorDec);
587     }
588
589     protected void addTypeDec(TypeDec typeDec) {
590         if (getModifiers().isStrict()) typeDec.getModifiers().setStrict(true);
591         typeDec.enclosingTypeDec = this;
592         typeDec.setAllEnclosingTypes(this.getType());
593         ((NameType)getType()).addInnerType(typeDec);
594     }
595
596     public void addMemberTypeDec(TypeDec memberDec) {
597         addTypeDec(memberDec);
598         getBody().add(memberDec);
599     }
600
601     public void addMemberMethodDec(MethodDec memberDec) {
602         addMethodDec(memberDec);
603         getBody().add(memberDec);
604     }
605
606     public void addIntroducedDec(Dec dec) {
607         getBody().add(dec);
608
609         SemanticObject oldSO = null;
610         if (dec instanceof MethodDec) {
611             oldSO = type.methods.addIntroduced(dec.getCorrespondingSemanticObject());
612         } else if (dec instanceof FieldDec) {
613             oldSO = type.fields.addIntroduced(dec.getCorrespondingSemanticObject());
614         } else if (dec instanceof ConstructorDec) {
615             oldSO = type.constructors.addIntroduced(dec.getCorrespondingSemanticObject());
616         }
617
618         if (oldSO != null) {
619             getBody().remove(oldSO.getCorrespondingDec());
620         }
621     }
622     
623     protected void addInitializerDec(InitializerDec dec) {
624         //XXX evaluate strict
625
}
626         
627
628     //??? don't like this being public
629
protected void addDec(Dec dec) {
630         //??? is this always right ???
631
if (!dec.isLanguageVisible() && !(
632             dec.getId().equals("aspectOf") || dec.getId().equals("hasAspect"))) return;
633
634          if (dec instanceof TypeDec) {
635             addTypeDec((TypeDec)dec);
636         } else if (dec instanceof MethodDec) {
637             addMethodDec((MethodDec)dec);
638         } else if (dec instanceof FieldDec) {
639             addFieldDec((FieldDec)dec);
640         } else if (dec instanceof ConstructorDec) {
641             addConstructorDec((ConstructorDec)dec);
642         } else if (dec instanceof PointcutDec) {
643             addPointcutDec((PointcutDec)dec);
644         } else if (dec instanceof InitializerDec) {
645             addInitializerDec((InitializerDec)dec);
646         } else if (dec instanceof VarDec) {
647             showWarning("shouldn't be found in a class");
648         } else {
649             dec.showWarning("shouldn't be found in " + this.toShortString());
650         }
651     }
652
653     public final String JavaDoc getPackageName() {
654         if (getEnclosingTypeDec() != null) {
655             return getEnclosingTypeDec().getPackageName();
656         } else {
657             return getCompilationUnit().getPackageName();
658         }
659     }
660     
661     private ConstructorDec soleConstructorDec;
662     public void setSoleConstructorDec(ConstructorDec d) {
663         soleConstructorDec = d;
664     }
665     
666     public ConstructorDec getSoleConstructorDec() {
667         return soleConstructorDec;
668     }
669
670
671     public void addInnerTypes() {
672         // first add any inner classes for .class classes
673
if (memberTypeNames != null) {
674             for (Iterator i = memberTypeNames.iterator(); i.hasNext(); ) {
675                 String JavaDoc name = (String JavaDoc)i.next();
676                 if (name == null || name.length() == 0 ||
677                         !Character.isJavaIdentifierStart(name.charAt(0))) {
678                     //??? should we show a message here ???
679
getCompiler().showMessage("ignoring invalid inner class attribute: " +
680                         getExtendedId()+'$'+name);
681                     continue;
682                 }
683
684                 //System.out.println("=============" + name);
685
Type innerType = getTypeManager().findType(getPackageName(),
686                                         getExtendedId()+'$'+name);
687                 if (innerType == null) {
688                     getCompiler().showMessage("ignoring invalid inner class attribute: " +
689                         getExtendedId()+'$'+name);
690                     continue;
691                 }
692                 addTypeDec(innerType.getTypeDec());
693             }
694         }
695
696         Decs decs = getBody();
697         if (decs == null) {
698             if (getOptions().torture) showWarning("no body for " + this);
699             return;
700         }
701         final int N = decs.size();
702         for(int i=0; i < N; i++) {
703             if (decs.get(i) instanceof TypeDec) {
704                 addDec(decs.get(i));
705             }
706         }
707     }
708
709
710     public void addDecs(NameType toThis) {
711         Decs decs = getBody();
712         if (decs == null) {
713             if (getOptions().torture) showWarning("no body for " + this);
714             return;
715         }
716         final int N = decs.size();
717         for(int i=0; i < N; i++) {
718             //System.out.println(">>>>" + decs.get(i));
719
if (! (decs.get(i) instanceof TypeDec) ) {
720                 addDec(decs.get(i));
721             }
722         }
723     }
724
725     private ConstructorDec makeDefaultConstructor() {
726         final AST ast = getAST();
727
728         ConstructorCallExpr superCall = null;
729         if (!isRoot()) {
730             Constructor superConstructor =
731                   getSuperClassType().getConstructor(getBody(), ast.makeExprs(), true);
732             superCall = ast.makeSuperConstructorCall(superConstructor);
733         }
734         ConstructorDec ret = ast.makeConstructor(
735                 // JLS 8.8.7 says to replace Modifiers.PUBLIC with
736
//the commented-out version
737
ast.makeModifiers(getModifiers().getAccessValue()),
738                 ast.makeFormals(), ast.makeTypeDs(),
739                 superCall, ast.makeStmts());
740         ret.setLanguageVisible();
741         //XXX this gets package protection to work "right", but it's ugly
742
ret.setSourceLocation(getSourceLocation());
743         return ret;
744     }
745
746     void addDefaultConstructor() {
747         //XXX should be an error
748
if (body == null || getType().isObject()) return;
749
750         //XXX
751
if (isAnonymous()) return;
752
753         //System.out.println("adding default constructor to: " + this + ", " + this.getBody().unparse());
754

755         ConstructorDec ret = makeDefaultConstructor();
756         addConstructorDec(ret);
757         body.add(ret);
758     }
759
760     // everybody gets a default constructor, even interfaces...
761
public void postIntroductionFinish() {
762         if (((NameType)getType()).getConstructors().size() == 0) {
763             if (!isAnonymous()) addDefaultConstructor();
764         } else if (isAnonymous()) {
765             showError("Anonymous classes cannot define constructors");
766         }
767     }
768
769     //XXX how much work should I do here?
770
public void addToBody(Dec dec) {
771         getBody().add(dec);
772     }
773
774     public void addToBodyAndType(Dec dec) {
775         addToBody(dec);
776         addDec(dec);
777     }
778
779
780     public String JavaDoc getPrettyString() {
781         return getType().getPrettyString();
782     }
783
784
785     public String JavaDoc toString() {
786         return getType().getString();
787     }
788
789     public String JavaDoc toShortString() {
790         return getType().getString();
791     }
792
793     public void fixAST(ASTFixerPass fixer) {
794         TypeDec saveTypeDec = fixer.getInTypeDec();
795         fixer.setInTypeDec(this);
796         this.walk(fixer);
797         fixer.setInTypeDec(saveTypeDec);
798
799         // if we inherit any methods from interfaces, build
800
// "concrete-abstract" versions in this class
801
if (getOptions().jvmTorture) return;
802
803         NameType myType = getNameType();
804         if (myType.isInterface()) return;
805         if (!myType.isAbstract()) return;
806
807         for (Iterator i = myType.getMethods().iterator(); i.hasNext(); ) {
808             Method m = (Method)i.next();
809             if (m.getDeclaringType().isInterface() &&
810                 m.getMethodDec().getBody() == null &&
811                 !m.getMethodDec().isIntroduced())
812             {
813                 getBody().add((MethodDec)m.getMethodDec().copy());
814             }
815         }
816     }
817
818     protected void walkExtendsAndImplements(ScopeWalker walker) {
819         if (superInterfaces != null) walker.process(superInterfaces);
820     }
821
822     protected void walkBody(ScopeWalker walker) {
823         walker.process(body);
824     }
825
826     //XXX very inefficient, but probably doesn't matter
827
protected Scope getEnclosingScope(boolean justTypeGraph) {
828         if (isLocal()) {
829             getCompiler().internalError(this, "trying to get simple scope for a local type");
830         }
831         TypeDec td = getEnclosingTypeDec();
832         if (td == null) {
833             return getCompilationUnit().getScope();
834         } else {
835             Scope ret = new TypeScope(getCompiler(), td.getEnclosingScope(justTypeGraph), td.getType());
836             if (justTypeGraph) td.addToTypeGraph();
837             else td.buildSignatures();
838             return ret;
839         }
840     }
841
842     //don't do any scope walks on synthetic type decs
843
public void addToTypeGraph() {
844         if (!fromSource()) getNameType().addToTypeGraph();
845         else addThisToTypeGraph(new ScopeWalker(getCompiler(), getEnclosingScope(true)));
846     }
847
848     public void buildSignatures() {
849         if (!fromSource()) getNameType().buildSignatures();
850         else buildThisSignatures(new ScopeWalker(getCompiler(), getEnclosingScope(false)));
851     }
852
853     private boolean isUnsupportedType() {
854         String JavaDoc p = getPackageName();
855         return p != null && p.equals("java.lang") &&
856             (getId().equals("Object") || getId().equals("String"));
857     }
858
859     private boolean addToTypeGraphDone = false;
860     private boolean addedInnersDone = false;
861     private boolean addToTypeGraphInProgress = false;
862
863     /**
864      * 1. Bind names in extends/implements clauses
865      * 2. Insert this type into type graph
866      * 3. Build maps of inner types including inherited inner types
867      */

868     public void addToTypeGraph(ScopeWalker walker) {
869         if (isUnsupportedType()) {
870             showError("can not compile " + getPrettyString() + " (compiler limitation)");
871             return;
872         }
873         
874         addThisToTypeGraph(walker);
875         addInnersToTypeGraph(walker);
876     }
877     
878     
879     private void addThisToTypeGraph(ScopeWalker walker) {
880         if (addToTypeGraphDone) return;
881         
882         
883         if (addToTypeGraphInProgress) {
884             StringBuffer JavaDoc message = new StringBuffer JavaDoc("cyclic inheritance, ");
885             
886             getWorld().getBuildingTypeGraph();
887             boolean foundThis = false;
888             List l = getWorld().getBuildingTypeGraph();
889             for (Iterator i = l.iterator(); i.hasNext(); ) {
890                 TypeDec td = (TypeDec)i.next();
891                 if (td == this) foundThis = true;
892                 if (foundThis) {
893                     message.append(td.toShortString());
894                 message.append(" -> ");
895                 }
896             }
897             message.append(this.toShortString());
898             
899             showError(message.toString());
900             return;
901         }
902         getWorld().pushBuildingTypeGraph(this);
903         addToTypeGraphInProgress = true;
904
905         walker.addTypeDec(this);
906
907         // bind names in extends and implements
908
walkExtendsAndImplements(walker);
909         getNameType().addToTypeGraph(); // includes building inner type map
910
//getType().buildInnerTypeMap();
911

912         getWorld().popBuildingTypeGraph();
913         addToTypeGraphDone = true;
914     }
915     
916     private void addInnersToTypeGraph(ScopeWalker walker) {
917         if (addedInnersDone) return;
918         addedInnersDone = true;
919                 
920         walker.pushScope(new TypeScope(getCompiler(), null, getType()));
921
922         Decs decs = getBody();
923         for (int i=0, N=decs.size(); i<N; i++) {
924             Dec dec = decs.get(i);
925             if (dec instanceof TypeDec) ((TypeDec)dec).addToTypeGraph(walker);
926         }
927
928         //??? the timing on this is not ideal...
929
//XXX really might want this to be a separate pass
930
boolean saveWalkBodies = walker.walkBodies();
931         walker.setWalkBodies(false);
932         walkBody(walker);
933         walker.setWalkBodies(saveWalkBodies);
934
935         walker.popScope();
936     }
937     
938
939
940     private boolean buildSignaturesDone = false;
941     private boolean buildSignaturesInProgress = false;
942     private boolean buildInnerSignaturesDone = false;
943
944     /**
945      * 1. Bind names in member signatures
946      * 2. Build maps of members of this type and of inherited members
947      * This step also handles introduced members
948      * 3. Add a default constructor if required
949      *
950      * 4. Do a spec check for no abstract decs in a concrete type
951      * ??? can we move this to checkSpec() method ???
952      */

953     public void buildSignatures(ScopeWalker walker) {
954         buildThisSignatures(walker);
955         buildInnerSignatures(walker);
956     }
957     
958     private void buildThisSignatures(ScopeWalker walker) {
959         if (buildSignaturesDone) return;
960         if (buildSignaturesInProgress) {
961             showError("circularity detected, already building signatures");
962             return;
963         }
964         buildSignaturesInProgress = true;
965
966         addToTypeGraph(walker);
967
968         getNameType().buildSignatures();
969         //getType().buildIntroductions();
970
//getType().buildInheritedSignatures();
971

972         postIntroductionFinish();
973
974         buildSignaturesDone = true;
975     }
976     
977     private void buildInnerSignatures(ScopeWalker walker) {
978         if (buildInnerSignaturesDone) return;
979         buildInnerSignaturesDone = true;
980         
981         walker.pushScope(new TypeScope(getCompiler(), null, getType()));
982
983         Decs decs = getBody();
984         for (int i=0, N=decs.size(); i<N; i++) {
985             Dec dec = decs.get(i);
986             if (dec instanceof TypeDec) ((TypeDec)dec).buildSignatures(walker);
987         }
988         walker.popScope();
989     }
990        
991
992     /**
993      * This is the simplest scope pass of them all.
994      * It just walks the body and binds all names (after ensuring that
995      * prvious name binding has been done).
996      */

997     public void walkScope(ScopeWalker walker) {
998         //System.out.println("top binding body: " + this + " in " + walker.getScope());
999
if (! (walker instanceof NameHygienePass) ) {
1000            if (walker.walkBodies()) buildSignatures(walker);
1001            else addToTypeGraph(walker);
1002        } else {
1003            walkExtendsAndImplements(walker);
1004        }
1005
1006        // bind names in bodies
1007
walker.pushScope(new TypeScope(getCompiler(), null, getType()));
1008
1009        //System.out.println("binding body: " + this + " in " + walker.getScope());
1010
walkBody(walker);
1011        //System.out.println("bound body: " + this);
1012
walker.popScope();
1013    }
1014
1015    // INTRO from JoinPoint
1016
public FieldDec joinPointFactoryDec = null;
1017
1018    // INTRO from JoinPointCollector
1019
public List joinPoints0 = new ArrayList();
1020    public List joinPoints1 = new ArrayList();
1021    public List joinPoints2 = new ArrayList();
1022
1023    //private String fullName = null;
1024
public String JavaDoc getFullName() {
1025        String JavaDoc fullName = null;
1026        //System.out.println("id: " + getId() + " in " + getEnclosingTypeDec());
1027

1028        if (fullName == null) {
1029            if (getEnclosingTypeDec() != null) {
1030                fullName = getEnclosingTypeDec().getFullName() + '$' + getId();
1031            } else {
1032                String JavaDoc packageName = getPackageName();
1033                String JavaDoc id = getId();
1034                fullName = packageName == null ? id : packageName + '.' + id;
1035            }
1036            //return "null"; //XXXthrow new RuntimeException("fullName of "+this+" == null");
1037
}
1038        return fullName;
1039    }
1040
1041    // ------------------------------
1042
// non-package-level type stuff
1043

1044    /** should only be called from ASTConnection (or here, I suppose) */
1045    public void setInnerDiscoveries(boolean a, boolean b, boolean c) {
1046        setIsInner(b);
1047    }
1048
1049    public void setIsInner(boolean b) {
1050        if (b) {
1051            throw new RuntimeException JavaDoc("TypeDec " + this + " should never be inner");
1052        }
1053    }
1054
1055    public Type getOutermostBytecodeType() {
1056        if (isPackageMember()) {
1057            return getType();
1058        } else {
1059            return super.getOutermostBytecodeType();
1060        }
1061    }
1062
1063    public Type getOutermostLexicalType() {
1064        if (isPackageMember()) {
1065            return getType();
1066        } else {
1067            return super.getOutermostLexicalType();
1068        }
1069    }
1070
1071
1072
1073    /**
1074     * Only classes can be inners, so this is overridden by ClassDec
1075     */

1076    public boolean isInner() { return false; }
1077    public void setLocal() { } //isLocalFlag = true; }
1078
public boolean isLocal() {
1079        ASTObject parent = getParent();
1080        if (parent == null) return false;
1081        parent = parent.getParent();
1082        if (parent == null || parent instanceof TypeDec
1083            || parent instanceof CompilationUnit) return false;
1084        return true;
1085    }
1086
1087    public boolean isPackageMember() {
1088        ASTObject parent = getParent();
1089        if (parent == null) return false;
1090        parent = parent.getParent();
1091        if (parent == null || !(parent instanceof CompilationUnit)) return false;
1092        return true;
1093    }
1094
1095    // Only valid if isInner()
1096
public NameType getEnclosingInstanceType() {
1097        return (NameType)getDeclaringType();
1098    }
1099    public TypeDec getEnclosingInstanceTypeDec() {
1100        return getEnclosingInstanceType().getTypeDec();
1101    }
1102
1103    //INTRO: InitializerExecutionPoint
1104
private Set initializerExecutionJoinPoints = new HashSet();
1105    public Set getInitializerExecutionJoinPoints() {
1106        return initializerExecutionJoinPoints;
1107    }
1108
1109    // ------------------------------
1110
// Intro: ForwardReferenceChecker
1111

1112    public void walkForwardReference(ForwardReferenceChecker w) {
1113        this.walk(w.createTypeChecker(this));
1114    }
1115
1116    // ------------------------------
1117
// INTRO: LocalClassPass.AnalysisWalker
1118

1119    public void walkAnalysis(LocalClassPass.AnalysisWalker walker) {
1120        if (isLocal()) {
1121            walker.enterTypeDec(this);
1122            setId(walker.makeNewId(this));
1123        }
1124        walker.inType();
1125        this.walk(walker);
1126        if (isLocal())
1127            walker.leaveTypeDec();
1128    }
1129
1130    // ------------------------------
1131
// INTRO: LocalClassPass.LiftWalker
1132

1133    public void preLift(LocalClassPass.LiftWalker walker) {
1134        walker.pushPendingDecs();
1135    }
1136
1137    public ASTObject postLift(LocalClassPass.LiftWalker walker) {
1138        initializersToConstructors();
1139        walker.popPendingDecsInto(this);
1140        if (isLocal()) {
1141            walker.addToPendingDecs(this);
1142            return null;
1143        } else {
1144            return this;
1145        }
1146    }
1147
1148    public void collectInitializers(boolean collectSynthetics) {
1149        collectInitializers(true, collectSynthetics);
1150        collectInitializers(false, collectSynthetics);
1151    }
1152
1153    Field assertionsDisabledField = null;
1154    /** This field is actually added in postFixAST
1155     */

1156    public Field getAssertionsDisabledField() {
1157        if (assertionsDisabledField != null) return assertionsDisabledField;
1158
1159        final AST ast = getAST();
1160        Modifiers mods =
1161            ast.makeModifiers(Modifiers.STATIC|Modifiers.FINAL);
1162        Type type = getTypeManager().booleanType;
1163        String JavaDoc id = "ajc$assertionsDisabled";
1164        Expr init = ast.makeUnop("!",
1165                                 ast.makeCall(ast.makeLiteral(getOutermostType()),
1166                                 "desiredAssertionStatus"));
1167        FieldDec adf = ast.makeField(mods, type, id, init);
1168        adf.setDeclaringType(getType());
1169        //getBody().add(0, adf);
1170
assertionsDisabledField = adf.getField();
1171        return assertionsDisabledField;
1172    }
1173
1174    public void addAssertionField() {
1175        if (assertionsDisabledField != null) {
1176            getBody().add(0, assertionsDisabledField.getFieldDec());
1177        }
1178    }
1179
1180    public void collectInitializers(boolean isStatic, boolean collectSynthetics) {
1181        // don't collect static initializers in interfaces if we're going to
1182
// be generating source code
1183
if (isStatic &&
1184            (!collectSynthetics || getCompiler().willGenerateSourceCode())) {
1185            if (this instanceof InterfaceDec) return;
1186        }
1187
1188
1189        final AST ast = getAST();
1190        Stmts stmts = ast.makeStmts();
1191        InitializerDec ret = null;
1192        boolean singleInitializer = true;
1193
1194        for (ListIterator i = body.iterator(); i.hasNext(); ) {
1195            Dec memDec = (Dec)i.next();
1196            if (isStatic != memDec.isStatic()) continue;
1197            //XXXif (!memDec.isLanguageVisible()) continue; //XXX trouble for bcg
1198

1199            if (memDec instanceof InitializerDec) {
1200                InitializerDec iDec = (InitializerDec)memDec;
1201                //if (iDec.isStatic() && inInterface) continue;
1202
//if (iDec.getBody().getStmts().size() == 0) continue;
1203
stmts.addAll(iDec.getBody().getStmts());
1204                if (ret == null) ret = iDec;
1205                else singleInitializer = false;
1206                i.remove();
1207            } else if (memDec instanceof FieldDec) {
1208                FieldDec fDec = (FieldDec)memDec;
1209                if (collectSynthetics || fDec.isLanguageVisible()) {
1210                    fDec.getAssignExpr(); // this creates the initializer code by magic
1211
}
1212            }
1213        }
1214
1215        if (ret == null || true) { // || !singleInitializer) {
1216
//System.out.println(stmts.size() + ": ");
1217
//if (stmts.size() == 1) System.out.println(stmts.get(0));
1218
if (stmts.size() == 1 && stmts.get(0) instanceof BlockStmt) {
1219                stmts = ((BlockStmt)stmts.get(0)).getStmts();
1220                //System.out.println("shrunk: " + stmts.unparse());
1221
}
1222
1223            if (isStatic) ret = ast.makeStaticInitializer(stmts);
1224            else ret = ast.makeInitializer(stmts);
1225            //ret.setLanguageVisible();
1226
}
1227        ret.setSourceLocation(getSourceLocation());
1228        body.add(ret);
1229        //return ret;
1230
}
1231
1232    public InitializerDec getSingleInitializerDec(boolean isStatic) {
1233        for (ListIterator i = body.iterator(); i.hasNext(); ) {
1234            Dec memDec = (Dec)i.next();
1235            if (memDec instanceof InitializerDec &&
1236                isStatic == memDec.isStatic()) return (InitializerDec)memDec;
1237        }
1238        showError("no initializer for: " + this);
1239        return null;
1240    }
1241
1242
1243    // Assumes there is zero or one static initializer, and leaves it
1244
// alone (or erase it if it's empty). also assumes that there are
1245
// NO field-decs in the initializers... i.e., that there are no
1246
// unlifted local/anonymous classes.
1247
private void initializersToConstructors() {
1248        final AST ast = getAST();
1249        Stmts stmts = ast.makeStmts();
1250
1251        // first collect the initializers
1252
for (Iterator i = getBody().iterator(); i.hasNext(); ) {
1253            Object JavaDoc o = i.next();
1254            if (o instanceof InitializerDec) {
1255                InitializerDec iDec = (InitializerDec) o;
1256                if (iDec.isStatic()) {
1257                    if (iDec.getBody().getStmts().size == 0) i.remove();
1258                    continue;
1259                }
1260                i.remove();
1261                Stmt iStmt = iDec.getBody();
1262                if (iStmt instanceof BlockStmt &&
1263                    ((BlockStmt)iStmt).getStmts().size() == 0)
1264                    continue;
1265                stmts.add(0, iStmt);
1266            }
1267        }
1268        // then stick them in the constructors
1269
for (Iterator i = getBody().iterator(); i.hasNext(); ) {
1270            Object JavaDoc o = i.next();
1271            if (o instanceof ConstructorDec) {
1272                ConstructorDec cDec = (ConstructorDec) o;
1273                // we only do this for constructors that don't call this
1274
ConstructorCallExpr call =
1275                                ((ConstructorBody)cDec.getBody()).getConstructorCall();
1276                if (call != null && !call.getIsSuper()) continue;
1277
1278                Stmts newStmts = (Stmts) CopyWalker.copy(stmts);
1279                // !!! this _must_ set up links to copied local vars.
1280
cDec.getBody().getStmts().addAll(0, newStmts);
1281            }
1282        }
1283    }
1284
1285    // ------------------------------
1286
// INTRO: LocalClassPass.ThreadingWalker
1287

1288    public void preThreading(LocalClassPass.ThreadingWalker walker) {
1289        walker.pushNonConstructorEnv();
1290        walker.pushTypeDec(this);
1291    }
1292
1293    public ASTObject postThreading(LocalClassPass.ThreadingWalker walker) {
1294        walker.popTypeDec();
1295        walker.popEnv();
1296        return this;
1297    }
1298
1299    // ------------------------------
1300
// bcg
1301

1302    protected void cgMember(ClassfileBuilder maker) {
1303        maker.delayInnerClassGeneration(this);
1304    }
1305
1306    /** Used to generate .class files in TypeDec.generateBytecode method
1307        Used to generate .java files in CodeGenerator.?
1308       */

1309    public File getPackageDir(File outputdir) {
1310        String JavaDoc packagename = getPackageName();
1311        if (getOptions().XtargetNearSource && (outputdir == Options.getDefaultOutputDir())) {
1312            return new File(getSourceDirectoryName());
1313        }
1314        //System.out.println(this + " p " + packagename);
1315

1316        if (packagename == null) return outputdir;
1317
1318        int lastDot = 0;
1319        int dot = 0;
1320        while ((dot = packagename.indexOf('.', lastDot)) != -1) {
1321            outputdir = new File(outputdir, packagename.substring(lastDot, dot));
1322            lastDot = dot+1;
1323        }
1324        return new File(outputdir, packagename.substring(lastDot));
1325    }
1326
1327
1328    /** should only be called from {@link CompilationUnit} and from
1329        {@link ClassfileBuilder} */

1330    public final void generateBytecode(File outputDir) throws IOException {
1331        String JavaDoc filename = getExtendedId()+".class";
1332        getCompiler().showMessage(" writing " + filename);
1333
1334        getCompiler().beginSection("bcg:AST-directed");
1335        // start AST-directed generation
1336
ClassfileBuilder cfb = new ClassfileBuilder(getCompiler());
1337        cfb.setSourceFile(getSourceLocation());
1338        if (!this.isConcrete()) getModifiers().setInterface(true);
1339        cfb.addAccessFlags(getModifiers().getAcceptableClassValue());
1340
1341        cfb.setClassName((NameType)getType());
1342        cfb.setSuperClassName((NameType)getSuperClassType());
1343        for (Iterator i = getSuperInterfaceTypes().iterator(); i.hasNext(); ) {
1344            NameType iface = (NameType)i.next();
1345            cfb.addInterface(iface);
1346        }
1347        for (Iterator i = getBody().iterator(); i.hasNext(); ) {
1348            Dec memberDec = (Dec)i.next();
1349            memberDec.cgMember(cfb);
1350        }
1351        //XXX get this right -- if (isSynthetic()) cfb.setSynthetic();
1352
// end AST-directed generation
1353

1354        // start assembly
1355
getCompiler().beginSection("bcg:assembly");
1356        cfb.resolve();
1357        // end assembly
1358

1359        // start IO
1360
getCompiler().beginSection("bcg:output");
1361        File packagedir = getPackageDir(outputDir);
1362        packagedir.mkdirs();
1363        File outFile = new File(packagedir, filename);
1364        FileOutputStream fileStream = new FileOutputStream(outFile);
1365        DataOutputStream stream =
1366            new DataOutputStream(new BufferedOutputStream(fileStream));
1367        cfb.writeTo(stream);
1368        stream.close();
1369        // end IO
1370

1371        cfb.generateBytecodeForDelayedInnerClasses(outputDir);
1372    }
1373
1374    //BEGIN: Generated from @child and @property
1375
protected Modifiers modifiers;
1376    public Modifiers getModifiers() { return modifiers; }
1377    public void setModifiers(Modifiers _modifiers) {
1378        if (_modifiers != null) _modifiers.setParent(this);
1379        modifiers = _modifiers;
1380    }
1381
1382    protected String JavaDoc id;
1383    public String JavaDoc getId() { return id; }
1384    public void setId(String JavaDoc _id) { id = _id; }
1385
1386    protected TypeDs superInterfaces;
1387    public TypeDs getSuperInterfaces() { return superInterfaces; }
1388    public void setSuperInterfaces(TypeDs _superInterfaces) {
1389        if (_superInterfaces != null) _superInterfaces.setParent(this);
1390        superInterfaces = _superInterfaces;
1391    }
1392
1393    protected Decs body;
1394    public Decs getBody() { return body; }
1395    public void setBody(Decs _body) {
1396        if (_body != null) _body.setParent(this);
1397        body = _body;
1398    }
1399
1400    public TypeDec(SourceLocation location, Modifiers _modifiers, String JavaDoc _id, TypeDs _superInterfaces, Decs _body) {
1401        super(location);
1402        setModifiers(_modifiers);
1403        setId(_id);
1404        setSuperInterfaces(_superInterfaces);
1405        setBody(_body);
1406    }
1407    protected TypeDec(SourceLocation source) {
1408        super(source);
1409    }
1410
1411    public ASTObject getChildAt(int childIndex) {
1412        switch(childIndex) {
1413        case 0: return modifiers;
1414        case 1: return superInterfaces;
1415        case 2: return body;
1416        default: return super.getChildAt(childIndex);
1417        }
1418    }
1419     public String JavaDoc getChildNameAt(int childIndex) {
1420        switch(childIndex) {
1421        case 0: return "modifiers";
1422        case 1: return "superInterfaces";
1423        case 2: return "body";
1424        default: return super.getChildNameAt(childIndex);
1425        }
1426    }
1427     public void setChildAt(int childIndex, ASTObject child) {
1428        switch(childIndex) {
1429        case 0: setModifiers((Modifiers)child); return;
1430        case 1: setSuperInterfaces((TypeDs)child); return;
1431        case 2: setBody((Decs)child); return;
1432        default: super.setChildAt(childIndex, child); return;
1433        }
1434    }
1435     public int getChildCount() {
1436        return 3;
1437    }
1438
1439    public String JavaDoc getDefaultDisplayName() {
1440        return "TypeDec(id: "+id+")";
1441    }
1442
1443    //END: Generated from @child and @property
1444
}
1445
Popular Tags