001    /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */
002    package org.extendj.ast;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.Set;
007    import java.util.Collections;
008    import java.util.Collection;
009    import java.util.ArrayList;
010    import beaver.*;
011    import java.util.*;
012    import java.io.ByteArrayOutputStream;
013    import java.io.PrintStream;
014    import java.lang.reflect.InvocationTargetException;
015    import java.lang.reflect.Method;
016    import org.jastadd.util.*;
017    import java.util.zip.*;
018    import java.io.*;
019    import org.jastadd.util.PrettyPrintable;
020    import org.jastadd.util.PrettyPrinter;
021    import java.io.FileNotFoundException;
022    import java.io.BufferedInputStream;
023    import java.io.DataInputStream;
024    /**
025     * @ast node
026     * @declaredat /home/jesper/git/extendj/java5/grammar/Enums.ast:1
027     * @production EnumDecl : {@link ClassDecl} ::= <span class="component">{@link Modifiers}</span> <span class="component">&lt;ID:String&gt;</span> <span class="component">[SuperClass:{@link Access}]</span> <span class="component">Implements:{@link Access}*</span> <span class="component">{@link BodyDecl}*</span>;
028    
029     */
030    public class EnumDecl extends ClassDecl implements Cloneable {
031      /**
032       * @aspect Enums
033       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:68
034       */
035      public void typeCheck() {
036        super.typeCheck();
037        for (Iterator iter = memberMethods("finalize").iterator(); iter.hasNext(); ) {
038          MethodDecl m = (MethodDecl) iter.next();
039          if (m.getNumParameter() == 0 && m.hostType() == this) {
040            error("an enum may not declare a finalizer");
041          }
042        }
043        checkEnum(this);
044      }
045      /**
046       * @aspect Enums
047       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:105
048       */
049      private boolean done = false;
050      /**
051       * @aspect Enums
052       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:106
053       */
054      private boolean done() {
055        if (done) {
056          return true;
057        }
058        done = true;
059        return false;
060      }
061      /**
062       * @aspect Enums
063       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:354
064       */
065      private void addValues() {
066        int numConstants = enumConstants().size();
067        List initValues = new List();
068        for (Iterator iter = enumConstants().iterator(); iter.hasNext(); ) {
069          EnumConstant c = (EnumConstant) iter.next();
070          initValues.add(c.createBoundFieldAccess());
071        }
072        FieldDeclaration values = new FieldDeclaration(
073          new Modifiers(new List().add(
074            new Modifier("private")).add(
075            new Modifier("static")).add(
076            new Modifier("final")).add(
077            new Modifier("synthetic"))
078          ),
079          arrayType().createQualifiedAccess(),
080          "$VALUES",
081          new Opt(
082              new ArrayCreationExpr(
083                new ArrayTypeWithSizeAccess(
084                  createQualifiedAccess(),
085                  Literal.buildIntegerLiteral(enumConstants().size())
086                ),
087                new Opt(
088                  new ArrayInit(
089                    initValues
090                  )
091                )
092              )
093          )
094        );
095        addBodyDecl(values);
096        // public static final Test[] values() { return (Test[])$VALUES.clone(); }
097        addBodyDecl(
098          new MethodDecl(
099            new Modifiers(new List().add(
100              new Modifier("public")).add(
101              new Modifier("static")).add(
102              new Modifier("final")).add(
103              new Modifier("synthetic"))
104            ),
105            arrayType().createQualifiedAccess(),
106            "values",
107            new List(),
108            new List(),
109            new Opt(
110              new Block(
111                new List().add(
112                  new ReturnStmt(
113                    new Opt(
114                      new CastExpr(
115                        arrayType().createQualifiedAccess(),
116                        values.createBoundFieldAccess().qualifiesAccess(
117                          new MethodAccess(
118                            "clone",
119                            new List()
120                          )
121                        )
122                      )
123                    )
124                  )
125                )
126              )
127            )
128          )
129        );
130        // public static Test valueOf(String s) { return (Test) java.lang.Enum.valueOf(Test.class, s); }
131        addBodyDecl(
132          new MethodDecl(
133            new Modifiers(new List().add(
134              new Modifier("public")).add(
135              new Modifier("static")).add(
136              new Modifier("synthetic"))
137            ),
138            createQualifiedAccess(),
139            "valueOf",
140            new List().add(
141              new ParameterDeclaration(
142                new Modifiers(new List()),
143                typeString().createQualifiedAccess(),
144                "s"
145              )
146            ),
147            new List(),
148            new Opt(
149              new Block(
150                new List().add(
151                  new ReturnStmt(
152                    new Opt(
153                      new CastExpr(
154                        createQualifiedAccess(),
155                        lookupType("java.lang", "Enum").createQualifiedAccess().qualifiesAccess(
156                          new MethodAccess(
157                            "valueOf",
158                            new List().add(
159                              createQualifiedAccess().qualifiesAccess(new ClassAccess())
160                            ).add(
161                              new VarAccess(
162                                "s"
163                              )
164                            )
165                          )
166                        )
167                      )
168                    )
169                  )
170                )
171              )
172            )
173          )
174        );
175      }
176      /**
177       * @aspect Enums
178       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:496
179       */
180      protected void checkEnum(EnumDecl enumDecl) {
181        for (int i = 0; i < getNumBodyDecl(); i++) {
182          if (getBodyDecl(i) instanceof ConstructorDecl) {
183            getBodyDecl(i).checkEnum(enumDecl);
184          } else if (getBodyDecl(i) instanceof InstanceInitializer) {
185            getBodyDecl(i).checkEnum(enumDecl);
186          } else if (getBodyDecl(i) instanceof FieldDeclaration) {
187            FieldDeclaration f = (FieldDeclaration) getBodyDecl(i);
188            if (!f.isStatic() && f.hasInit()) {
189              f.checkEnum(enumDecl);
190            }
191          }
192        }
193      }
194      /**
195       * @aspect Enums
196       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:605
197       */
198      public void prettyPrint(PrettyPrinter out) {
199        if (!docComment.isEmpty()) {
200          out.print(docComment);
201        }
202        out.print(getModifiers());
203        out.print("enum " + name());
204        if (getNumImplements() > 0) {
205          out.print(" implements ");
206          out.join(getImplementsList(), new PrettyPrinter.Joiner() {
207            @Override
208            public void printSeparator(PrettyPrinter out) {
209              out.print(", ");
210            }
211          });
212        }
213        out.print(" {");
214        for (int i = 0; i < getNumBodyDecl(); i++) {
215          BodyDecl d = getBodyDecl(i);
216          out.print(d);
217          if (d instanceof EnumConstant) {
218            if (i + 1 < getNumBodyDecl() && !(getBodyDecl(i + 1) instanceof EnumConstant)) {
219              out.println();
220              out.print(";");
221            }
222          }
223        }
224        out.println();
225        out.print("}");
226      }
227      /**
228       * Check that the enum does not contain unimplemented abstract methods.
229       * @aspect Enums
230       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:723
231       */
232      public void checkModifiers() {
233        super.checkModifiers();
234        if (!unimplementedMethods().isEmpty()) {
235          StringBuilder sb = new StringBuilder();
236          sb.append("" + name() + " lacks implementations in one or more "
237              + "enum constants for the following methods:\n");
238          for (Iterator iter = unimplementedMethods().iterator(); iter.hasNext(); ) {
239            MethodDecl m = (MethodDecl) iter.next();
240            sb.append("  " + m.signature() + " in " + m.hostType().typeName() + "\n");
241          }
242          error(sb.toString());
243        }
244      }
245      /**
246       * @declaredat ASTNode:1
247       */
248      public EnumDecl() {
249        super();
250      }
251      /**
252       * Initializes the child array to the correct size.
253       * Initializes List and Opt nta children.
254       * @apilevel internal
255       * @ast method
256       * @declaredat ASTNode:10
257       */
258      public void init$Children() {
259        children = new ASTNode[5];
260        setChild(new List(), 1);
261        setChild(new List(), 2);
262        setChild(new Opt(), 3);
263        setChild(new Opt(), 4);
264      }
265      /**
266       * @declaredat ASTNode:17
267       */
268      public EnumDecl(Modifiers p0, String p1, List<Access> p2, List<BodyDecl> p3) {
269        setChild(p0, 0);
270        setID(p1);
271        setChild(p2, 1);
272        setChild(p3, 2);
273      }
274      /**
275       * @declaredat ASTNode:23
276       */
277      public EnumDecl(Modifiers p0, beaver.Symbol p1, List<Access> p2, List<BodyDecl> p3) {
278        setChild(p0, 0);
279        setID(p1);
280        setChild(p2, 1);
281        setChild(p3, 2);
282      }
283      /**
284       * @apilevel low-level
285       * @declaredat ASTNode:32
286       */
287      protected int numChildren() {
288        return 3;
289      }
290      /**
291       * @apilevel internal
292       * @declaredat ASTNode:38
293       */
294      public boolean mayHaveRewrite() {
295        return true;
296      }
297      /**
298       * @apilevel internal
299       * @declaredat ASTNode:44
300       */
301      public void flushAttrCache() {
302        super.flushAttrCache();
303        isStatic_reset();
304        getSuperClassOpt_reset();
305        getImplicitConstructorOpt_reset();
306        enumConstants_reset();
307        unimplementedMethods_reset();
308        flags_reset();
309      }
310      /**
311       * @apilevel internal
312       * @declaredat ASTNode:56
313       */
314      public void flushCollectionCache() {
315        super.flushCollectionCache();
316      }
317      /**
318       * @apilevel internal
319       * @declaredat ASTNode:62
320       */
321      public void flushRewriteCache() {
322        super.flushRewriteCache();
323      }
324      /**
325       * @apilevel internal
326       * @declaredat ASTNode:68
327       */
328      public EnumDecl clone() throws CloneNotSupportedException {
329        EnumDecl node = (EnumDecl) super.clone();
330        return node;
331      }
332      /**
333       * @apilevel internal
334       * @declaredat ASTNode:75
335       */
336      public EnumDecl copy() {
337        try {
338          EnumDecl node = (EnumDecl) clone();
339          node.parent = null;
340          if (children != null) {
341            node.children = (ASTNode[]) children.clone();
342          }
343          return node;
344        } catch (CloneNotSupportedException e) {
345          throw new Error("Error: clone not supported for " + getClass().getName());
346        }
347      }
348      /**
349       * Create a deep copy of the AST subtree at this node.
350       * The copy is dangling, i.e. has no parent.
351       * @return dangling copy of the subtree at this node
352       * @apilevel low-level
353       * @deprecated Please use treeCopy or treeCopyNoTransform instead
354       * @declaredat ASTNode:94
355       */
356      @Deprecated
357      public EnumDecl fullCopy() {
358        return treeCopyNoTransform();
359      }
360      /**
361       * Create a deep copy of the AST subtree at this node.
362       * The copy is dangling, i.e. has no parent.
363       * @return dangling copy of the subtree at this node
364       * @apilevel low-level
365       * @declaredat ASTNode:104
366       */
367      public EnumDecl treeCopyNoTransform() {
368        EnumDecl tree = (EnumDecl) copy();
369        if (children != null) {
370          for (int i = 0; i < children.length; ++i) {
371            switch (i) {
372            case 3:
373            case 4:
374              tree.children[i] = new Opt();
375              continue;
376            }
377            ASTNode child = (ASTNode) children[i];
378            if (child != null) {
379              child = child.treeCopyNoTransform();
380              tree.setChild(child, i);
381            }
382          }
383        }
384        return tree;
385      }
386      /**
387       * Create a deep copy of the AST subtree at this node.
388       * The subtree of this node is traversed to trigger rewrites before copy.
389       * The copy is dangling, i.e. has no parent.
390       * @return dangling copy of the subtree at this node
391       * @apilevel low-level
392       * @declaredat ASTNode:130
393       */
394      public EnumDecl treeCopy() {
395        doFullTraversal();
396        return treeCopyNoTransform();
397      }
398      /**
399       * @apilevel internal
400       * @declaredat ASTNode:137
401       */
402      protected boolean is$Equal(ASTNode node) {
403        return super.is$Equal(node) && (tokenString_ID == ((EnumDecl)node).tokenString_ID);    
404      }
405      /**
406       * Replaces the Modifiers child.
407       * @param node The new node to replace the Modifiers child.
408       * @apilevel high-level
409       */
410      public void setModifiers(Modifiers node) {
411        setChild(node, 0);
412      }
413      /**
414       * Retrieves the Modifiers child.
415       * @return The current node used as the Modifiers child.
416       * @apilevel high-level
417       */
418      @ASTNodeAnnotation.Child(name="Modifiers")
419      public Modifiers getModifiers() {
420        return (Modifiers) getChild(0);
421      }
422      /**
423       * Retrieves the Modifiers child.
424       * <p><em>This method does not invoke AST transformations.</em></p>
425       * @return The current node used as the Modifiers child.
426       * @apilevel low-level
427       */
428      public Modifiers getModifiersNoTransform() {
429        return (Modifiers) getChildNoTransform(0);
430      }
431      /**
432       * Replaces the lexeme ID.
433       * @param value The new value for the lexeme ID.
434       * @apilevel high-level
435       */
436      public void setID(String value) {
437        tokenString_ID = value;
438      }
439      /**
440       * JastAdd-internal setter for lexeme ID using the Beaver parser.
441       * @param symbol Symbol containing the new value for the lexeme ID
442       * @apilevel internal
443       */
444      public void setID(beaver.Symbol symbol) {
445        if (symbol.value != null && !(symbol.value instanceof String))
446        throw new UnsupportedOperationException("setID is only valid for String lexemes");
447        tokenString_ID = (String)symbol.value;
448        IDstart = symbol.getStart();
449        IDend = symbol.getEnd();
450      }
451      /**
452       * Retrieves the value for the lexeme ID.
453       * @return The value for the lexeme ID.
454       * @apilevel high-level
455       */
456      @ASTNodeAnnotation.Token(name="ID")
457      public String getID() {
458        return tokenString_ID != null ? tokenString_ID : "";
459      }
460      /**
461       * Replaces the Implements list.
462       * @param list The new list node to be used as the Implements list.
463       * @apilevel high-level
464       */
465      public void setImplementsList(List<Access> list) {
466        setChild(list, 1);
467      }
468      /**
469       * Retrieves the number of children in the Implements list.
470       * @return Number of children in the Implements list.
471       * @apilevel high-level
472       */
473      public int getNumImplements() {
474        return getImplementsList().getNumChild();
475      }
476      /**
477       * Retrieves the number of children in the Implements list.
478       * Calling this method will not trigger rewrites.
479       * @return Number of children in the Implements list.
480       * @apilevel low-level
481       */
482      public int getNumImplementsNoTransform() {
483        return getImplementsListNoTransform().getNumChildNoTransform();
484      }
485      /**
486       * Retrieves the element at index {@code i} in the Implements list.
487       * @param i Index of the element to return.
488       * @return The element at position {@code i} in the Implements list.
489       * @apilevel high-level
490       */
491      public Access getImplements(int i) {
492        return (Access) getImplementsList().getChild(i);
493      }
494      /**
495       * Check whether the Implements list has any children.
496       * @return {@code true} if it has at least one child, {@code false} otherwise.
497       * @apilevel high-level
498       */
499      public boolean hasImplements() {
500        return getImplementsList().getNumChild() != 0;
501      }
502      /**
503       * Append an element to the Implements list.
504       * @param node The element to append to the Implements list.
505       * @apilevel high-level
506       */
507      public void addImplements(Access node) {
508        List<Access> list = (parent == null) ? getImplementsListNoTransform() : getImplementsList();
509        list.addChild(node);
510      }
511      /**
512       * @apilevel low-level
513       */
514      public void addImplementsNoTransform(Access node) {
515        List<Access> list = getImplementsListNoTransform();
516        list.addChild(node);
517      }
518      /**
519       * Replaces the Implements list element at index {@code i} with the new node {@code node}.
520       * @param node The new node to replace the old list element.
521       * @param i The list index of the node to be replaced.
522       * @apilevel high-level
523       */
524      public void setImplements(Access node, int i) {
525        List<Access> list = getImplementsList();
526        list.setChild(node, i);
527      }
528      /**
529       * Retrieves the Implements list.
530       * @return The node representing the Implements list.
531       * @apilevel high-level
532       */
533      @ASTNodeAnnotation.ListChild(name="Implements")
534      public List<Access> getImplementsList() {
535        List<Access> list = (List<Access>) getChild(1);
536        return list;
537      }
538      /**
539       * Retrieves the Implements list.
540       * <p><em>This method does not invoke AST transformations.</em></p>
541       * @return The node representing the Implements list.
542       * @apilevel low-level
543       */
544      public List<Access> getImplementsListNoTransform() {
545        return (List<Access>) getChildNoTransform(1);
546      }
547      /**
548       * Retrieves the Implements list.
549       * @return The node representing the Implements list.
550       * @apilevel high-level
551       */
552      public List<Access> getImplementss() {
553        return getImplementsList();
554      }
555      /**
556       * Retrieves the Implements list.
557       * <p><em>This method does not invoke AST transformations.</em></p>
558       * @return The node representing the Implements list.
559       * @apilevel low-level
560       */
561      public List<Access> getImplementssNoTransform() {
562        return getImplementsListNoTransform();
563      }
564      /**
565       * Replaces the BodyDecl list.
566       * @param list The new list node to be used as the BodyDecl list.
567       * @apilevel high-level
568       */
569      public void setBodyDeclList(List<BodyDecl> list) {
570        setChild(list, 2);
571      }
572      /**
573       * Retrieves the number of children in the BodyDecl list.
574       * @return Number of children in the BodyDecl list.
575       * @apilevel high-level
576       */
577      public int getNumBodyDecl() {
578        return getBodyDeclList().getNumChild();
579      }
580      /**
581       * Retrieves the number of children in the BodyDecl list.
582       * Calling this method will not trigger rewrites.
583       * @return Number of children in the BodyDecl list.
584       * @apilevel low-level
585       */
586      public int getNumBodyDeclNoTransform() {
587        return getBodyDeclListNoTransform().getNumChildNoTransform();
588      }
589      /**
590       * Retrieves the element at index {@code i} in the BodyDecl list.
591       * @param i Index of the element to return.
592       * @return The element at position {@code i} in the BodyDecl list.
593       * @apilevel high-level
594       */
595      public BodyDecl getBodyDecl(int i) {
596        return (BodyDecl) getBodyDeclList().getChild(i);
597      }
598      /**
599       * Check whether the BodyDecl list has any children.
600       * @return {@code true} if it has at least one child, {@code false} otherwise.
601       * @apilevel high-level
602       */
603      public boolean hasBodyDecl() {
604        return getBodyDeclList().getNumChild() != 0;
605      }
606      /**
607       * Append an element to the BodyDecl list.
608       * @param node The element to append to the BodyDecl list.
609       * @apilevel high-level
610       */
611      public void addBodyDecl(BodyDecl node) {
612        List<BodyDecl> list = (parent == null) ? getBodyDeclListNoTransform() : getBodyDeclList();
613        list.addChild(node);
614      }
615      /**
616       * @apilevel low-level
617       */
618      public void addBodyDeclNoTransform(BodyDecl node) {
619        List<BodyDecl> list = getBodyDeclListNoTransform();
620        list.addChild(node);
621      }
622      /**
623       * Replaces the BodyDecl list element at index {@code i} with the new node {@code node}.
624       * @param node The new node to replace the old list element.
625       * @param i The list index of the node to be replaced.
626       * @apilevel high-level
627       */
628      public void setBodyDecl(BodyDecl node, int i) {
629        List<BodyDecl> list = getBodyDeclList();
630        list.setChild(node, i);
631      }
632      /**
633       * Retrieves the BodyDecl list.
634       * @return The node representing the BodyDecl list.
635       * @apilevel high-level
636       */
637      @ASTNodeAnnotation.ListChild(name="BodyDecl")
638      public List<BodyDecl> getBodyDeclList() {
639        List<BodyDecl> list = (List<BodyDecl>) getChild(2);
640        return list;
641      }
642      /**
643       * Retrieves the BodyDecl list.
644       * <p><em>This method does not invoke AST transformations.</em></p>
645       * @return The node representing the BodyDecl list.
646       * @apilevel low-level
647       */
648      public List<BodyDecl> getBodyDeclListNoTransform() {
649        return (List<BodyDecl>) getChildNoTransform(2);
650      }
651      /**
652       * Retrieves the BodyDecl list.
653       * @return The node representing the BodyDecl list.
654       * @apilevel high-level
655       */
656      public List<BodyDecl> getBodyDecls() {
657        return getBodyDeclList();
658      }
659      /**
660       * Retrieves the BodyDecl list.
661       * <p><em>This method does not invoke AST transformations.</em></p>
662       * @return The node representing the BodyDecl list.
663       * @apilevel low-level
664       */
665      public List<BodyDecl> getBodyDeclsNoTransform() {
666        return getBodyDeclListNoTransform();
667      }
668      /**
669       * Replaces the (optional) ImplicitConstructor child.
670       * @param node The new node to be used as the ImplicitConstructor child.
671       * @apilevel high-level
672       */
673      public void setImplicitConstructor(ConstructorDecl node) {
674        getImplicitConstructorOpt().setChild(node, 0);
675      }
676      /**
677       * Check whether the optional ImplicitConstructor child exists.
678       * @return {@code true} if the optional ImplicitConstructor child exists, {@code false} if it does not.
679       * @apilevel high-level
680       */
681      public boolean hasImplicitConstructor() {
682        return getImplicitConstructorOpt().getNumChild() != 0;
683      }
684      /**
685       * Retrieves the (optional) ImplicitConstructor child.
686       * @return The ImplicitConstructor child, if it exists. Returns {@code null} otherwise.
687       * @apilevel low-level
688       */
689      public ConstructorDecl getImplicitConstructor() {
690        return (ConstructorDecl) getImplicitConstructorOpt().getChild(0);
691      }
692      /**
693       * Retrieves the optional node for child ImplicitConstructor. This is the <code>Opt</code> node containing the child ImplicitConstructor, not the actual child!
694       * <p><em>This method does not invoke AST transformations.</em></p>
695       * @return The optional node for child ImplicitConstructor.
696       * @apilevel low-level
697       */
698      public Opt<ConstructorDecl> getImplicitConstructorOptNoTransform() {
699        return (Opt<ConstructorDecl>) getChildNoTransform(3);
700      }
701      /**
702       * Retrieves the child position of the optional child ImplicitConstructor.
703       * @return The the child position of the optional child ImplicitConstructor.
704       * @apilevel low-level
705       */
706      protected int getImplicitConstructorOptChildPosition() {
707        return 3;
708      }
709      /**
710       * This method should not be called. This method throws an exception due to
711       * the corresponding child being an NTA shadowing a non-NTA child.
712       * @param node
713       * @apilevel internal
714       */
715      public void setSuperClassOpt(Opt<Access> node) {
716        throw new Error("Can not replace NTA child SuperClassOpt in EnumDecl!");
717      }
718      /**
719       * Replaces the (optional) SuperClass child.
720       * @param node The new node to be used as the SuperClass child.
721       * @apilevel high-level
722       */
723      public void setSuperClass(Access node) {
724        getSuperClassOpt().setChild(node, 0);
725      }
726      /**
727       * Check whether the optional SuperClass child exists.
728       * @return {@code true} if the optional SuperClass child exists, {@code false} if it does not.
729       * @apilevel high-level
730       */
731      public boolean hasSuperClass() {
732        return getSuperClassOpt().getNumChild() != 0;
733      }
734      /**
735       * Retrieves the (optional) SuperClass child.
736       * @return The SuperClass child, if it exists. Returns {@code null} otherwise.
737       * @apilevel low-level
738       */
739      public Access getSuperClass() {
740        return (Access) getSuperClassOpt().getChild(0);
741      }
742      /**
743       * Retrieves the optional node for child SuperClass. This is the <code>Opt</code> node containing the child SuperClass, not the actual child!
744       * <p><em>This method does not invoke AST transformations.</em></p>
745       * @return The optional node for child SuperClass.
746       * @apilevel low-level
747       */
748      public Opt<Access> getSuperClassOptNoTransform() {
749        return (Opt<Access>) getChildNoTransform(4);
750      }
751      /**
752       * Retrieves the child position of the optional child SuperClass.
753       * @return The the child position of the optional child SuperClass.
754       * @apilevel low-level
755       */
756      protected int getSuperClassOptChildPosition() {
757        return 4;
758      }
759      /**
760       * @attribute syn
761       * @aspect Annotations
762       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:151
763       */
764      @ASTNodeAnnotation.Attribute
765      public boolean isValidAnnotationMethodReturnType() {
766        boolean isValidAnnotationMethodReturnType_value = true;
767    
768        return isValidAnnotationMethodReturnType_value;
769      }
770      /**
771       * @attribute syn
772       * @aspect Enums
773       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:37
774       */
775      @ASTNodeAnnotation.Attribute
776      public boolean isEnumDecl() {
777        boolean isEnumDecl_value = true;
778    
779        return isEnumDecl_value;
780      }
781      /**
782       * @apilevel internal
783       */
784      protected boolean isStatic_computed = false;
785      /**
786       * @apilevel internal
787       */
788      protected boolean isStatic_value;
789      /**
790       * @apilevel internal
791       */
792      private void isStatic_reset() {
793        isStatic_computed = false;
794      }
795      /**
796       * @attribute syn
797       * @aspect Modifiers
798       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:247
799       */
800      @ASTNodeAnnotation.Attribute
801      public boolean isStatic() {
802        ASTNode$State state = state();
803        if (isStatic_computed) {
804          return isStatic_value;
805        }
806        boolean intermediate = state.INTERMEDIATE_VALUE;
807        state.INTERMEDIATE_VALUE = false;
808        int num = state.boundariesCrossed;
809        boolean isFinal = this.is$Final();
810        isStatic_value = isNestedType();
811        if (isFinal && num == state().boundariesCrossed) {
812          isStatic_computed = true;
813        } else {
814        }
815        state.INTERMEDIATE_VALUE |= intermediate;
816    
817        return isStatic_value;
818      }
819      /**
820       * @apilevel internal
821       */
822      protected boolean getSuperClassOpt_computed = false;
823      /**
824       * @apilevel internal
825       */
826      protected Opt getSuperClassOpt_value;
827      /**
828       * @apilevel internal
829       */
830      private void getSuperClassOpt_reset() {
831        getSuperClassOpt_computed = false;
832        getSuperClassOpt_value = null;
833      }
834      /**
835       * @attribute syn nta
836       * @aspect Enums
837       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:83
838       */
839      @ASTNodeAnnotation.Attribute
840      public Opt getSuperClassOpt() {
841        ASTNode$State state = state();
842        if (getSuperClassOpt_computed) {
843          return (Opt) getChild(getSuperClassOptChildPosition());
844        }
845        boolean intermediate = state.INTERMEDIATE_VALUE;
846        state.INTERMEDIATE_VALUE = false;
847        int num = state.boundariesCrossed;
848        boolean isFinal = this.is$Final();
849        getSuperClassOpt_value = getSuperClassOpt_compute();
850        setChild(getSuperClassOpt_value, getSuperClassOptChildPosition());
851        if (isFinal && num == state().boundariesCrossed) {
852          getSuperClassOpt_computed = true;
853        } else {
854        }
855        state.INTERMEDIATE_VALUE |= intermediate;
856    
857        Opt node = (Opt) this.getChild(getSuperClassOptChildPosition());
858        return node;
859      }
860      /**
861       * @apilevel internal
862       */
863      private Opt getSuperClassOpt_compute() {
864          return new Opt(
865            new ParTypeAccess(
866              new TypeAccess(
867                "java.lang",
868                "Enum"
869              ),
870              new List().add(createQualifiedAccess())
871            )
872          );
873        }
874      /**
875       * @apilevel internal
876       */
877      protected boolean getImplicitConstructorOpt_computed = false;
878      /**
879       * @apilevel internal
880       */
881      protected Opt<ConstructorDecl> getImplicitConstructorOpt_value;
882      /**
883       * @apilevel internal
884       */
885      private void getImplicitConstructorOpt_reset() {
886        getImplicitConstructorOpt_computed = false;
887        getImplicitConstructorOpt_value = null;
888      }
889      /**
890       * @attribute syn nta
891       * @aspect Enums
892       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:124
893       */
894      @ASTNodeAnnotation.Attribute
895      public Opt<ConstructorDecl> getImplicitConstructorOpt() {
896        ASTNode$State state = state();
897        if (getImplicitConstructorOpt_computed) {
898          return (Opt<ConstructorDecl>) getChild(getImplicitConstructorOptChildPosition());
899        }
900        boolean intermediate = state.INTERMEDIATE_VALUE;
901        state.INTERMEDIATE_VALUE = false;
902        int num = state.boundariesCrossed;
903        boolean isFinal = this.is$Final();
904        getImplicitConstructorOpt_value = getImplicitConstructorOpt_compute();
905        setChild(getImplicitConstructorOpt_value, getImplicitConstructorOptChildPosition());
906        if (isFinal && num == state().boundariesCrossed) {
907          getImplicitConstructorOpt_computed = true;
908        } else {
909        }
910        state.INTERMEDIATE_VALUE |= intermediate;
911    
912        Opt<ConstructorDecl> node = (Opt<ConstructorDecl>) this.getChild(getImplicitConstructorOptChildPosition());
913        return node;
914      }
915      /**
916       * @apilevel internal
917       */
918      private Opt<ConstructorDecl> getImplicitConstructorOpt_compute() {
919          if (needsImplicitConstructor()) {
920            List parameterList = new List();
921            parameterList.add(
922                new ParameterDeclaration(new TypeAccess("java.lang", "String"), "p0")
923            );
924            parameterList.add(
925                new ParameterDeclaration(new TypeAccess("int"), "p1")
926            );
927            ConstructorDecl constructor = new ConstructorDecl(
928                new Modifiers(new List()
929                  .add(new Modifier("private"))
930                  .add(new Modifier("synthetic"))
931                  ),
932                name(),
933                parameterList,
934                new List(),
935                new Opt(
936                  new ExprStmt(
937                    new SuperConstructorAccess(
938                      "super",
939                      new List()
940                      .add(new VarAccess("p0"))
941                      .add(new VarAccess("p1"))
942                      )
943                    )
944                  ),
945                new Block(new List())
946                );
947            return new Opt<ConstructorDecl>(constructor);
948          } else {
949            return new Opt<ConstructorDecl>();
950          }
951        }
952      /**
953       * @attribute syn
954       * @aspect Modifiers
955       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:250
956       */
957      @ASTNodeAnnotation.Attribute
958      public boolean isFinal() {
959        {
960            for (Iterator iter = enumConstants().iterator(); iter.hasNext(); ) {
961              EnumConstant c = (EnumConstant) iter.next();
962              ClassInstanceExpr e = (ClassInstanceExpr) c.getInit();
963              if (e.hasTypeDecl()) {
964                return false;
965              }
966            }
967            return true;
968          }
969      }
970      /**
971       * @apilevel internal
972       */
973      protected boolean enumConstants_computed = false;
974      /**
975       * @apilevel internal
976       */
977      protected ArrayList enumConstants_value;
978      /**
979       * @apilevel internal
980       */
981      private void enumConstants_reset() {
982        enumConstants_computed = false;
983        enumConstants_value = null;
984      }
985      /**
986       * @attribute syn
987       * @aspect Enums
988       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:337
989       */
990      @ASTNodeAnnotation.Attribute
991      public ArrayList enumConstants() {
992        ASTNode$State state = state();
993        if (enumConstants_computed) {
994          return enumConstants_value;
995        }
996        boolean intermediate = state.INTERMEDIATE_VALUE;
997        state.INTERMEDIATE_VALUE = false;
998        int num = state.boundariesCrossed;
999        boolean isFinal = this.is$Final();
1000        enumConstants_value = enumConstants_compute();
1001        if (isFinal && num == state().boundariesCrossed) {
1002          enumConstants_computed = true;
1003        } else {
1004        }
1005        state.INTERMEDIATE_VALUE |= intermediate;
1006    
1007        return enumConstants_value;
1008      }
1009      /**
1010       * @apilevel internal
1011       */
1012      private ArrayList enumConstants_compute() {
1013          ArrayList list = new ArrayList();
1014          for (int i = 0; i < getNumBodyDecl(); i++) {
1015            if (getBodyDecl(i).isEnumConstant()) {
1016              list.add(getBodyDecl(i));
1017            }
1018          }
1019          return list;
1020        }
1021      /**
1022       * @attribute syn
1023       * @aspect Modifiers
1024       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:245
1025       */
1026      @ASTNodeAnnotation.Attribute
1027      public boolean isAbstract() {
1028        {
1029            for (int i = 0; i < getNumBodyDecl(); i++) {
1030              if (getBodyDecl(i) instanceof MethodDecl) {
1031                MethodDecl m = (MethodDecl) getBodyDecl(i);
1032                if (m.isAbstract()) {
1033                  return true;
1034                }
1035              }
1036            }
1037            return false;
1038          }
1039      }
1040      /**
1041       * @apilevel internal
1042       */
1043      protected boolean unimplementedMethods_computed = false;
1044      /**
1045       * @apilevel internal
1046       */
1047      protected Collection unimplementedMethods_value;
1048      /**
1049       * @apilevel internal
1050       */
1051      private void unimplementedMethods_reset() {
1052        unimplementedMethods_computed = false;
1053        unimplementedMethods_value = null;
1054      }
1055      /**
1056       * @attribute syn
1057       * @aspect Modifiers
1058       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:37
1059       */
1060      @ASTNodeAnnotation.Attribute
1061      public Collection unimplementedMethods() {
1062        ASTNode$State state = state();
1063        if (unimplementedMethods_computed) {
1064          return unimplementedMethods_value;
1065        }
1066        boolean intermediate = state.INTERMEDIATE_VALUE;
1067        state.INTERMEDIATE_VALUE = false;
1068        int num = state.boundariesCrossed;
1069        boolean isFinal = this.is$Final();
1070        unimplementedMethods_value = unimplementedMethods_compute();
1071        if (isFinal && num == state().boundariesCrossed) {
1072          unimplementedMethods_computed = true;
1073        } else {
1074        }
1075        state.INTERMEDIATE_VALUE |= intermediate;
1076    
1077        return unimplementedMethods_value;
1078      }
1079      /**
1080       * @apilevel internal
1081       */
1082      private Collection unimplementedMethods_compute() {
1083          Collection<MethodDecl> methods = new LinkedList<MethodDecl>();
1084          for (Iterator iter = interfacesMethodsIterator(); iter.hasNext(); ) {
1085            MethodDecl method = (MethodDecl) iter.next();
1086            SimpleSet set = (SimpleSet) localMethodsSignature(method.signature());
1087            if (set.size() == 1) {
1088              MethodDecl n = (MethodDecl) set.iterator().next();
1089              if (!n.isAbstract()) {
1090                continue;
1091              }
1092            }
1093            boolean implemented = false;
1094            set = (SimpleSet) ancestorMethods(method.signature());
1095            for (Iterator i2 = set.iterator(); i2.hasNext(); ) {
1096              MethodDecl n = (MethodDecl) i2.next();
1097              if (!n.isAbstract()) {
1098                implemented = true;
1099                break;
1100              }
1101            }
1102            if (!implemented) {
1103              methods.add(method);
1104            }
1105          }
1106      
1107          for (Iterator iter = localMethodsIterator(); iter.hasNext(); ) {
1108            MethodDecl method = (MethodDecl) iter.next();
1109            if (method.isAbstract()) {
1110              methods.add(method);
1111            }
1112          }
1113      
1114          Collection unimplemented = new ArrayList();
1115          for (MethodDecl method : methods) {
1116            if (enumConstants().isEmpty()) {
1117              unimplemented.add(method);
1118              continue;
1119            }
1120            boolean missing = false;
1121            for (Iterator iter = enumConstants().iterator(); iter.hasNext(); ) {
1122              if (!((EnumConstant) iter.next()).implementsMethod(method)) {
1123                missing = true;
1124                break;
1125              }
1126            }
1127            if (missing) {
1128              unimplemented.add(method);
1129            }
1130          }
1131      
1132          return unimplemented;
1133        }
1134      /**
1135       * @apilevel internal
1136       */
1137      protected boolean flags_computed = false;
1138      /**
1139       * @apilevel internal
1140       */
1141      protected int flags_value;
1142      /**
1143       * @apilevel internal
1144       */
1145      private void flags_reset() {
1146        flags_computed = false;
1147      }
1148      /**
1149       * @attribute syn
1150       * @aspect Flags
1151       * @declaredat /home/jesper/git/extendj/java4/backend/Flags.jrag:110
1152       */
1153      @ASTNodeAnnotation.Attribute
1154      public int flags() {
1155        ASTNode$State state = state();
1156        if (flags_computed) {
1157          return flags_value;
1158        }
1159        boolean intermediate = state.INTERMEDIATE_VALUE;
1160        state.INTERMEDIATE_VALUE = false;
1161        int num = state.boundariesCrossed;
1162        boolean isFinal = this.is$Final();
1163        flags_value = super.flags() | Modifiers.ACC_ENUM;
1164        if (isFinal && num == state().boundariesCrossed) {
1165          flags_computed = true;
1166        } else {
1167        }
1168        state.INTERMEDIATE_VALUE |= intermediate;
1169    
1170        return flags_value;
1171      }
1172      /**
1173       * @attribute inh
1174       * @aspect Enums
1175       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:466
1176       */
1177      /**
1178       * @attribute inh
1179       * @aspect Enums
1180       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:466
1181       */
1182      @ASTNodeAnnotation.Attribute
1183      public TypeDecl typeString() {
1184        TypeDecl typeString_value = getParent().Define_typeString(this, null);
1185    
1186        return typeString_value;
1187      }
1188      /**
1189       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:424
1190       * @apilevel internal
1191       */
1192      public boolean Define_mayBeAbstract(ASTNode caller, ASTNode child) {
1193        if (caller == getModifiersNoTransform()) {
1194          // @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:55
1195          return false;
1196        }
1197        else {
1198          return super.Define_mayBeAbstract(caller, child);
1199        }
1200      }
1201      protected boolean canDefine_mayBeAbstract(ASTNode caller, ASTNode child) {
1202        return true;
1203      }
1204      /**
1205       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:422
1206       * @apilevel internal
1207       */
1208      public boolean Define_mayBeStatic(ASTNode caller, ASTNode child) {
1209        if (caller == getModifiersNoTransform()) {
1210          // @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:62
1211          return isNestedType();
1212        }
1213        else {
1214          return super.Define_mayBeStatic(caller, child);
1215        }
1216      }
1217      protected boolean canDefine_mayBeStatic(ASTNode caller, ASTNode child) {
1218        return true;
1219      }
1220      /**
1221       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:423
1222       * @apilevel internal
1223       */
1224      public boolean Define_mayBeFinal(ASTNode caller, ASTNode child) {
1225        if (caller == getModifiersNoTransform()) {
1226          // @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:335
1227          return false;
1228        }
1229        else {
1230          return super.Define_mayBeFinal(caller, child);
1231        }
1232      }
1233      protected boolean canDefine_mayBeFinal(ASTNode caller, ASTNode child) {
1234        return true;
1235      }
1236      /**
1237       * @apilevel internal
1238       */
1239      public ASTNode rewriteTo() {
1240        // Declared at /home/jesper/git/extendj/java5/frontend/Enums.jrag:116
1241        if (!done()) {
1242          return rewriteRule0();
1243        }
1244        return super.rewriteTo();
1245      }
1246      /**
1247       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:116
1248       * @apilevel internal
1249       */
1250      private EnumDecl rewriteRule0() {
1251    {
1252          transformEnumConstructors();
1253          addValues(); // Add the values() and getValue(String s) methods
1254          return this;
1255        }  }
1256    }