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:3
027     * @production EnumConstant : {@link FieldDeclaration} ::= <span class="component">{@link Modifiers}</span> <span class="component">&lt;ID:String&gt;</span> <span class="component">Arg:{@link Expr}*</span> <span class="component">[Init:{@link Expr}]</span> <span class="component">TypeAccess:{@link Access}</span>;
028    
029     */
030    public class EnumConstant extends FieldDeclaration implements Cloneable {
031      /**
032       * @aspect Enums
033       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:229
034       */
035      public EnumConstant(Modifiers mods, String name, List<Expr> args, List<BodyDecl> bds) {
036        this(mods, name, args, new Opt<Expr>(new EnumInstanceExpr(createOptAnonymousDecl(bds))));
037      }
038      /**
039       * @aspect Enums
040       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:270
041       */
042      private static Opt<TypeDecl> createOptAnonymousDecl(List<BodyDecl> bds) {
043        if (bds.getNumChildNoTransform() == 0) {
044          return new Opt<TypeDecl>();
045        }
046        return new Opt<TypeDecl>(
047          new AnonymousDecl(
048            new Modifiers(),
049            "Anonymous",
050            bds
051          )
052        );
053      }
054      /**
055       * @aspect Enums
056       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:284
057       */
058      public int getNumBodyDecl() {
059        int cnt = 0;
060        ClassInstanceExpr init = (ClassInstanceExpr) getInit();
061        if (!init.hasTypeDecl()) {
062          return 0;
063        }
064        for (BodyDecl bd : init.getTypeDecl().getBodyDecls()) {
065          if (!(bd instanceof ConstructorDecl)) {
066            ++cnt;
067          }
068        }
069        return cnt;
070      }
071      /**
072       * @aspect Enums
073       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:298
074       */
075      public BodyDecl getBodyDecl(int i) {
076        ClassInstanceExpr init = (ClassInstanceExpr) getInit();
077        if (init.hasTypeDecl()) {
078          for (BodyDecl bd : init.getTypeDecl().getBodyDecls()) {
079            if (!(bd instanceof ConstructorDecl)) {
080              if (i-- == 0) {
081                return bd;
082              }
083            }
084          }
085        }
086        throw new ArrayIndexOutOfBoundsException(i);
087      }
088      /**
089       * @aspect Enums
090       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:635
091       */
092      public void prettyPrint(PrettyPrinter out) {
093        out.println();
094        out.print(getModifiers());
095        out.print(getID());
096        out.print("(");
097        if (getNumArg() > 0) {
098          out.join(getArgList(), new PrettyPrinter.Joiner() {
099            @Override
100            public void printSeparator(PrettyPrinter out) {
101              out.print(", ");
102            }
103          });
104        }
105        out.print(")");
106        if (getNumBodyDecl() > 0) {
107          out.print(" {");
108          for (int i=0; i < getNumBodyDecl(); i++) {
109            BodyDecl d = getBodyDecl(i);
110            out.print(d);
111          }
112          out.print("}");
113        }
114        out.print(",");
115      }
116      /**
117       * @declaredat ASTNode:1
118       */
119      public EnumConstant() {
120        super();
121      }
122      /**
123       * Initializes the child array to the correct size.
124       * Initializes List and Opt nta children.
125       * @apilevel internal
126       * @ast method
127       * @declaredat ASTNode:10
128       */
129      public void init$Children() {
130        children = new ASTNode[4];
131        setChild(new List(), 1);
132        setChild(new Opt(), 2);
133      }
134      /**
135       * @declaredat ASTNode:15
136       */
137      public EnumConstant(Modifiers p0, String p1, List<Expr> p2, Opt<Expr> p3) {
138        setChild(p0, 0);
139        setID(p1);
140        setChild(p2, 1);
141        setChild(p3, 2);
142      }
143      /**
144       * @declaredat ASTNode:21
145       */
146      public EnumConstant(Modifiers p0, beaver.Symbol p1, List<Expr> p2, Opt<Expr> p3) {
147        setChild(p0, 0);
148        setID(p1);
149        setChild(p2, 1);
150        setChild(p3, 2);
151      }
152      /**
153       * @apilevel low-level
154       * @declaredat ASTNode:30
155       */
156      protected int numChildren() {
157        return 3;
158      }
159      /**
160       * @apilevel internal
161       * @declaredat ASTNode:36
162       */
163      public boolean mayHaveRewrite() {
164        return false;
165      }
166      /**
167       * @apilevel internal
168       * @declaredat ASTNode:42
169       */
170      public void flushAttrCache() {
171        super.flushAttrCache();
172        getTypeAccess_reset();
173        localMethodsSignatureMap_reset();
174        flags_reset();
175      }
176      /**
177       * @apilevel internal
178       * @declaredat ASTNode:51
179       */
180      public void flushCollectionCache() {
181        super.flushCollectionCache();
182      }
183      /**
184       * @apilevel internal
185       * @declaredat ASTNode:57
186       */
187      public void flushRewriteCache() {
188        super.flushRewriteCache();
189      }
190      /**
191       * @apilevel internal
192       * @declaredat ASTNode:63
193       */
194      public EnumConstant clone() throws CloneNotSupportedException {
195        EnumConstant node = (EnumConstant) super.clone();
196        return node;
197      }
198      /**
199       * @apilevel internal
200       * @declaredat ASTNode:70
201       */
202      public EnumConstant copy() {
203        try {
204          EnumConstant node = (EnumConstant) clone();
205          node.parent = null;
206          if (children != null) {
207            node.children = (ASTNode[]) children.clone();
208          }
209          return node;
210        } catch (CloneNotSupportedException e) {
211          throw new Error("Error: clone not supported for " + getClass().getName());
212        }
213      }
214      /**
215       * Create a deep copy of the AST subtree at this node.
216       * The copy is dangling, i.e. has no parent.
217       * @return dangling copy of the subtree at this node
218       * @apilevel low-level
219       * @deprecated Please use treeCopy or treeCopyNoTransform instead
220       * @declaredat ASTNode:89
221       */
222      @Deprecated
223      public EnumConstant fullCopy() {
224        return treeCopyNoTransform();
225      }
226      /**
227       * Create a deep copy of the AST subtree at this node.
228       * The copy is dangling, i.e. has no parent.
229       * @return dangling copy of the subtree at this node
230       * @apilevel low-level
231       * @declaredat ASTNode:99
232       */
233      public EnumConstant treeCopyNoTransform() {
234        EnumConstant tree = (EnumConstant) copy();
235        if (children != null) {
236          for (int i = 0; i < children.length; ++i) {
237            switch (i) {
238            case 3:
239              tree.children[i] = null;
240              continue;
241            }
242            ASTNode child = (ASTNode) children[i];
243            if (child != null) {
244              child = child.treeCopyNoTransform();
245              tree.setChild(child, i);
246            }
247          }
248        }
249        return tree;
250      }
251      /**
252       * Create a deep copy of the AST subtree at this node.
253       * The subtree of this node is traversed to trigger rewrites before copy.
254       * The copy is dangling, i.e. has no parent.
255       * @return dangling copy of the subtree at this node
256       * @apilevel low-level
257       * @declaredat ASTNode:124
258       */
259      public EnumConstant treeCopy() {
260        doFullTraversal();
261        return treeCopyNoTransform();
262      }
263      /**
264       * @apilevel internal
265       * @declaredat ASTNode:131
266       */
267      protected boolean is$Equal(ASTNode node) {
268        return super.is$Equal(node) && (tokenString_ID == ((EnumConstant)node).tokenString_ID);    
269      }
270      /**
271       * Replaces the Modifiers child.
272       * @param node The new node to replace the Modifiers child.
273       * @apilevel high-level
274       */
275      public void setModifiers(Modifiers node) {
276        setChild(node, 0);
277      }
278      /**
279       * Retrieves the Modifiers child.
280       * @return The current node used as the Modifiers child.
281       * @apilevel high-level
282       */
283      @ASTNodeAnnotation.Child(name="Modifiers")
284      public Modifiers getModifiers() {
285        return (Modifiers) getChild(0);
286      }
287      /**
288       * Retrieves the Modifiers child.
289       * <p><em>This method does not invoke AST transformations.</em></p>
290       * @return The current node used as the Modifiers child.
291       * @apilevel low-level
292       */
293      public Modifiers getModifiersNoTransform() {
294        return (Modifiers) getChildNoTransform(0);
295      }
296      /**
297       * Replaces the lexeme ID.
298       * @param value The new value for the lexeme ID.
299       * @apilevel high-level
300       */
301      public void setID(String value) {
302        tokenString_ID = value;
303      }
304      /**
305       * JastAdd-internal setter for lexeme ID using the Beaver parser.
306       * @param symbol Symbol containing the new value for the lexeme ID
307       * @apilevel internal
308       */
309      public void setID(beaver.Symbol symbol) {
310        if (symbol.value != null && !(symbol.value instanceof String))
311        throw new UnsupportedOperationException("setID is only valid for String lexemes");
312        tokenString_ID = (String)symbol.value;
313        IDstart = symbol.getStart();
314        IDend = symbol.getEnd();
315      }
316      /**
317       * Retrieves the value for the lexeme ID.
318       * @return The value for the lexeme ID.
319       * @apilevel high-level
320       */
321      @ASTNodeAnnotation.Token(name="ID")
322      public String getID() {
323        return tokenString_ID != null ? tokenString_ID : "";
324      }
325      /**
326       * Replaces the Arg list.
327       * @param list The new list node to be used as the Arg list.
328       * @apilevel high-level
329       */
330      public void setArgList(List<Expr> list) {
331        setChild(list, 1);
332      }
333      /**
334       * Retrieves the number of children in the Arg list.
335       * @return Number of children in the Arg list.
336       * @apilevel high-level
337       */
338      public int getNumArg() {
339        return getArgList().getNumChild();
340      }
341      /**
342       * Retrieves the number of children in the Arg list.
343       * Calling this method will not trigger rewrites.
344       * @return Number of children in the Arg list.
345       * @apilevel low-level
346       */
347      public int getNumArgNoTransform() {
348        return getArgListNoTransform().getNumChildNoTransform();
349      }
350      /**
351       * Retrieves the element at index {@code i} in the Arg list.
352       * @param i Index of the element to return.
353       * @return The element at position {@code i} in the Arg list.
354       * @apilevel high-level
355       */
356      public Expr getArg(int i) {
357        return (Expr) getArgList().getChild(i);
358      }
359      /**
360       * Check whether the Arg list has any children.
361       * @return {@code true} if it has at least one child, {@code false} otherwise.
362       * @apilevel high-level
363       */
364      public boolean hasArg() {
365        return getArgList().getNumChild() != 0;
366      }
367      /**
368       * Append an element to the Arg list.
369       * @param node The element to append to the Arg list.
370       * @apilevel high-level
371       */
372      public void addArg(Expr node) {
373        List<Expr> list = (parent == null) ? getArgListNoTransform() : getArgList();
374        list.addChild(node);
375      }
376      /**
377       * @apilevel low-level
378       */
379      public void addArgNoTransform(Expr node) {
380        List<Expr> list = getArgListNoTransform();
381        list.addChild(node);
382      }
383      /**
384       * Replaces the Arg list element at index {@code i} with the new node {@code node}.
385       * @param node The new node to replace the old list element.
386       * @param i The list index of the node to be replaced.
387       * @apilevel high-level
388       */
389      public void setArg(Expr node, int i) {
390        List<Expr> list = getArgList();
391        list.setChild(node, i);
392      }
393      /**
394       * Retrieves the Arg list.
395       * @return The node representing the Arg list.
396       * @apilevel high-level
397       */
398      @ASTNodeAnnotation.ListChild(name="Arg")
399      public List<Expr> getArgList() {
400        List<Expr> list = (List<Expr>) getChild(1);
401        return list;
402      }
403      /**
404       * Retrieves the Arg list.
405       * <p><em>This method does not invoke AST transformations.</em></p>
406       * @return The node representing the Arg list.
407       * @apilevel low-level
408       */
409      public List<Expr> getArgListNoTransform() {
410        return (List<Expr>) getChildNoTransform(1);
411      }
412      /**
413       * Retrieves the Arg list.
414       * @return The node representing the Arg list.
415       * @apilevel high-level
416       */
417      public List<Expr> getArgs() {
418        return getArgList();
419      }
420      /**
421       * Retrieves the Arg list.
422       * <p><em>This method does not invoke AST transformations.</em></p>
423       * @return The node representing the Arg list.
424       * @apilevel low-level
425       */
426      public List<Expr> getArgsNoTransform() {
427        return getArgListNoTransform();
428      }
429      /**
430       * Replaces the optional node for the Init child. This is the <code>Opt</code>
431       * node containing the child Init, not the actual child!
432       * @param opt The new node to be used as the optional node for the Init child.
433       * @apilevel low-level
434       */
435      public void setInitOpt(Opt<Expr> opt) {
436        setChild(opt, 2);
437      }
438      /**
439       * Replaces the (optional) Init child.
440       * @param node The new node to be used as the Init child.
441       * @apilevel high-level
442       */
443      public void setInit(Expr node) {
444        getInitOpt().setChild(node, 0);
445      }
446      /**
447       * Check whether the optional Init child exists.
448       * @return {@code true} if the optional Init child exists, {@code false} if it does not.
449       * @apilevel high-level
450       */
451      public boolean hasInit() {
452        return getInitOpt().getNumChild() != 0;
453      }
454      /**
455       * Retrieves the (optional) Init child.
456       * @return The Init child, if it exists. Returns {@code null} otherwise.
457       * @apilevel low-level
458       */
459      public Expr getInit() {
460        return (Expr) getInitOpt().getChild(0);
461      }
462      /**
463       * Retrieves the optional node for the Init child. This is the <code>Opt</code> node containing the child Init, not the actual child!
464       * @return The optional node for child the Init child.
465       * @apilevel low-level
466       */
467      @ASTNodeAnnotation.OptChild(name="Init")
468      public Opt<Expr> getInitOpt() {
469        return (Opt<Expr>) getChild(2);
470      }
471      /**
472       * Retrieves the optional node for child Init. This is the <code>Opt</code> node containing the child Init, not the actual child!
473       * <p><em>This method does not invoke AST transformations.</em></p>
474       * @return The optional node for child Init.
475       * @apilevel low-level
476       */
477      public Opt<Expr> getInitOptNoTransform() {
478        return (Opt<Expr>) getChildNoTransform(2);
479      }
480      /**
481       * This method should not be called. This method throws an exception due to
482       * the corresponding child being an NTA shadowing a non-NTA child.
483       * @param node
484       * @apilevel internal
485       */
486      public void setTypeAccess(Access node) {
487        throw new Error("Can not replace NTA child TypeAccess in EnumConstant!");
488      }
489      /**
490       * Retrieves the TypeAccess child.
491       * <p><em>This method does not invoke AST transformations.</em></p>
492       * @return The current node used as the TypeAccess child.
493       * @apilevel low-level
494       */
495      public Access getTypeAccessNoTransform() {
496        return (Access) getChildNoTransform(3);
497      }
498      /**
499       * Retrieves the child position of the optional child TypeAccess.
500       * @return The the child position of the optional child TypeAccess.
501       * @apilevel low-level
502       */
503      protected int getTypeAccessChildPosition() {
504        return 3;
505      }
506      /**
507       * @attribute syn
508       * @aspect Enums
509       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:48
510       */
511      @ASTNodeAnnotation.Attribute
512      public boolean isEnumConstant() {
513        boolean isEnumConstant_value = true;
514    
515        return isEnumConstant_value;
516      }
517      /**
518       * @attribute syn
519       * @aspect Modifiers
520       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:280
521       */
522      @ASTNodeAnnotation.Attribute
523      public boolean isPublic() {
524        boolean isPublic_value = true;
525    
526        return isPublic_value;
527      }
528      /**
529       * @attribute syn
530       * @aspect Modifiers
531       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:283
532       */
533      @ASTNodeAnnotation.Attribute
534      public boolean isStatic() {
535        boolean isStatic_value = true;
536    
537        return isStatic_value;
538      }
539      /**
540       * @attribute syn
541       * @aspect Modifiers
542       * @declaredat /home/jesper/git/extendj/java4/frontend/Modifiers.jrag:285
543       */
544      @ASTNodeAnnotation.Attribute
545      public boolean isFinal() {
546        boolean isFinal_value = true;
547    
548        return isFinal_value;
549      }
550      /**
551       * @apilevel internal
552       */
553      protected boolean getTypeAccess_computed = false;
554      /**
555       * @apilevel internal
556       */
557      protected Access getTypeAccess_value;
558      /**
559       * @apilevel internal
560       */
561      private void getTypeAccess_reset() {
562        getTypeAccess_computed = false;
563        getTypeAccess_value = null;
564      }
565      /**
566       * @attribute syn nta
567       * @aspect Enums
568       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:225
569       */
570      @ASTNodeAnnotation.Attribute
571      public Access getTypeAccess() {
572        ASTNode$State state = state();
573        if (getTypeAccess_computed) {
574          return (Access) getChild(getTypeAccessChildPosition());
575        }
576        boolean intermediate = state.INTERMEDIATE_VALUE;
577        state.INTERMEDIATE_VALUE = false;
578        int num = state.boundariesCrossed;
579        boolean isFinal = this.is$Final();
580        getTypeAccess_value = getTypeAccess_compute();
581        setChild(getTypeAccess_value, getTypeAccessChildPosition());
582        if (isFinal && num == state().boundariesCrossed) {
583          getTypeAccess_computed = true;
584        } else {
585        }
586        state.INTERMEDIATE_VALUE |= intermediate;
587    
588        Access node = (Access) this.getChild(getTypeAccessChildPosition());
589        return node;
590      }
591      /**
592       * @apilevel internal
593       */
594      private Access getTypeAccess_compute() {
595          return hostType().createQualifiedAccess();
596        }
597      /**
598       * @attribute syn
599       * @aspect Enums
600       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:737
601       */
602      @ASTNodeAnnotation.Attribute
603      public SimpleSet localMethodsSignature(String signature) {
604        {
605            SimpleSet set = localMethodsSignatureMap().get(signature);
606            if (set != null) {
607              return set;
608            }
609            return SimpleSet.emptySet;
610          }
611      }
612      /**
613       * @apilevel internal
614       */
615      protected boolean localMethodsSignatureMap_computed = false;
616      /**
617       * @apilevel internal
618       */
619      protected Map<String,SimpleSet> localMethodsSignatureMap_value;
620      /**
621       * @apilevel internal
622       */
623      private void localMethodsSignatureMap_reset() {
624        localMethodsSignatureMap_computed = false;
625        localMethodsSignatureMap_value = null;
626      }
627      /**
628       * @attribute syn
629       * @aspect Enums
630       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:746
631       */
632      @ASTNodeAnnotation.Attribute
633      public Map<String,SimpleSet> localMethodsSignatureMap() {
634        ASTNode$State state = state();
635        if (localMethodsSignatureMap_computed) {
636          return localMethodsSignatureMap_value;
637        }
638        boolean intermediate = state.INTERMEDIATE_VALUE;
639        state.INTERMEDIATE_VALUE = false;
640        int num = state.boundariesCrossed;
641        boolean isFinal = this.is$Final();
642        localMethodsSignatureMap_value = localMethodsSignatureMap_compute();
643        if (isFinal && num == state().boundariesCrossed) {
644          localMethodsSignatureMap_computed = true;
645        } else {
646        }
647        state.INTERMEDIATE_VALUE |= intermediate;
648    
649        return localMethodsSignatureMap_value;
650      }
651      /**
652       * @apilevel internal
653       */
654      private Map<String,SimpleSet> localMethodsSignatureMap_compute() {
655          HashMap map = new HashMap(getNumBodyDecl());
656          for (int i = 0; i < getNumBodyDecl(); i++) {
657            if (getBodyDecl(i) instanceof MethodDecl) {
658              MethodDecl decl = (MethodDecl) getBodyDecl(i);
659              putSimpleSetElement(map, decl.signature(), decl);
660            }
661          }
662          return map;
663        }
664      /**
665       * @attribute syn
666       * @aspect Enums
667       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:757
668       */
669      @ASTNodeAnnotation.Attribute
670      public boolean implementsMethod(MethodDecl method) {
671        {
672            SimpleSet set = (SimpleSet) localMethodsSignature(method.signature());
673            if (set.size() == 1) {
674              MethodDecl n = (MethodDecl) set.iterator().next();
675              if (!n.isAbstract()) {
676                return true;
677              }
678            }
679            return false;
680          }
681      }
682      /**
683       * @apilevel internal
684       */
685      protected boolean flags_computed = false;
686      /**
687       * @apilevel internal
688       */
689      protected int flags_value;
690      /**
691       * @apilevel internal
692       */
693      private void flags_reset() {
694        flags_computed = false;
695      }
696      /**
697       * @attribute syn
698       * @aspect Flags
699       * @declaredat /home/jesper/git/extendj/java4/backend/Flags.jrag:134
700       */
701      @ASTNodeAnnotation.Attribute
702      public int flags() {
703        ASTNode$State state = state();
704        if (flags_computed) {
705          return flags_value;
706        }
707        boolean intermediate = state.INTERMEDIATE_VALUE;
708        state.INTERMEDIATE_VALUE = false;
709        int num = state.boundariesCrossed;
710        boolean isFinal = this.is$Final();
711        flags_value = super.flags() | Modifiers.ACC_ENUM;
712        if (isFinal && num == state().boundariesCrossed) {
713          flags_computed = true;
714        } else {
715        }
716        state.INTERMEDIATE_VALUE |= intermediate;
717    
718        return flags_value;
719      }
720      /**
721       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:36
722       * @apilevel internal
723       */
724      public NameType Define_nameType(ASTNode caller, ASTNode child) {
725        if (caller == getTypeAccessNoTransform()) {
726          // @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:564
727          return NameType.TYPE_NAME;
728        }
729        else {
730          return super.Define_nameType(caller, child);
731        }
732      }
733      protected boolean canDefine_nameType(ASTNode caller, ASTNode child) {
734        return true;
735      }
736      /**
737       * @apilevel internal
738       */
739      public ASTNode rewriteTo() {
740        return super.rewriteTo();
741      }
742    }