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/Annotations.ast:6
027     * @production Annotation : {@link Modifier} ::= <span class="component">&lt;ID:String&gt;</span> <span class="component">{@link Access}</span> <span class="component">{@link ElementValuePair}*</span>;
028    
029     */
030    public class Annotation extends Modifier implements Cloneable {
031      /**
032       * @aspect Annotations
033       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:63
034       */
035      public void checkModifiers() {
036        super.checkModifiers();
037        if (decl() instanceof AnnotationDecl) {
038          AnnotationDecl T = (AnnotationDecl) decl();
039          Annotation m = T.annotation(lookupType("java.lang.annotation", "Target"));
040          if (m != null && m.getNumElementValuePair() == 1 && m.getElementValuePair(0).getName().equals("value")) {
041            ElementValue v = m.getElementValuePair(0).getElementValue();
042            //System.out.println("ElementValue: \n" + v.dumpTree());
043            //System.out.println("Annotation: \n" + dumpTree());
044            if (!v.validTarget(this)) {
045              errorf("annotation type %s is not applicable to this kind of declaration", T.typeName());
046            }
047          }
048        }
049      }
050      /**
051       * @aspect Annotations
052       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:460
053       */
054      public void typeCheck() {
055        if (!decl().isAnnotationDecl()) {
056          /* TypeName names the annotation type corresponding to the annotation. It is a
057          compile-time error if TypeName does not name an annotation type.*/
058          if (!decl().isUnknown()) {
059            errorf("%s is not an annotation type", decl().typeName());
060          }
061        } else {
062          TypeDecl typeDecl = decl();
063          /* It is a compile-time error if a declaration is annotated with more than one
064          annotation for a given annotation type.*/
065          if (lookupAnnotation(typeDecl) != this) {
066            errorf("duplicate annotation %s", typeDecl.typeName());
067          }
068          /* Annotations must contain an element-value pair for every element of the
069          corresponding annotation type, except for those elements with default
070          values, or a compile-time error occurs. Annotations may, but are not
071          required to, contain element-value pairs for elements with default values.*/
072          for (int i = 0; i < typeDecl.getNumBodyDecl(); i++) {
073            if (typeDecl.getBodyDecl(i) instanceof MethodDecl) {
074              MethodDecl decl = (MethodDecl) typeDecl.getBodyDecl(i);
075              if (elementValueFor(decl.name()) == null && (!(decl instanceof AnnotationMethodDecl) || !((AnnotationMethodDecl) decl).hasDefaultValue())) {
076                errorf("missing value for %s", decl.name());
077              }
078            }
079          }
080          /* The Identifier in an ElementValuePair must be the simple name of one of the
081          elements of the annotation type identified by TypeName in the containing
082          annotation. Otherwise, a compile-time error occurs. (In other words, the
083          identifier in an element-value pair must also be a method name in the interface
084          identified by TypeName.) */
085          for (int i = 0; i < getNumElementValuePair(); i++) {
086            ElementValuePair pair = getElementValuePair(i);
087            if (typeDecl.memberMethods(pair.getName()).isEmpty()) {
088              errorf("can not find element named %s in %s", pair.getName(), typeDecl.typeName());
089            }
090          }
091        }
092        checkOverride();
093      }
094      /**
095       * @aspect Java5PrettyPrint
096       * @declaredat /home/jesper/git/extendj/java5/frontend/PrettyPrint.jadd:311
097       */
098      public void prettyPrint(PrettyPrinter out) {
099        out.print("@");
100        out.print(getAccess());
101        if (hasElementValuePair()) {
102          out.print("(");
103          out.join(getElementValuePairList(), new PrettyPrinter.Joiner() {
104            @Override
105            public void printSeparator(PrettyPrinter out) {
106              out.print(", ");
107            }
108          });
109          out.print(")");
110        }
111      }
112      /**
113       * @aspect AnnotationsCodegen
114       * @declaredat /home/jesper/git/extendj/java5/backend/AnnotationsCodegen.jrag:191
115       */
116      public void appendAsAttributeTo(Attribute buf) {
117        ConstantPool cp = hostType().constantPool();
118        String typeDescriptor = decl().typeDescriptor();
119        int type_index = cp.addUtf8(typeDescriptor);
120        buf.u2(type_index);
121        buf.u2(getNumElementValuePair());
122        for (int i = 0; i < getNumElementValuePair(); i++) {
123          int name_index = cp.addUtf8(getElementValuePair(i).getName());
124          buf.u2(name_index);
125          getElementValuePair(i).getElementValue().appendAsAttributeTo(buf);
126        }
127      }
128      /**
129       * @declaredat ASTNode:1
130       */
131      public Annotation() {
132        super();
133      }
134      /**
135       * Initializes the child array to the correct size.
136       * Initializes List and Opt nta children.
137       * @apilevel internal
138       * @ast method
139       * @declaredat ASTNode:10
140       */
141      public void init$Children() {
142        children = new ASTNode[2];
143        setChild(new List(), 1);
144      }
145      /**
146       * @declaredat ASTNode:14
147       */
148      public Annotation(String p0, Access p1, List<ElementValuePair> p2) {
149        setID(p0);
150        setChild(p1, 0);
151        setChild(p2, 1);
152      }
153      /**
154       * @declaredat ASTNode:19
155       */
156      public Annotation(beaver.Symbol p0, Access p1, List<ElementValuePair> p2) {
157        setID(p0);
158        setChild(p1, 0);
159        setChild(p2, 1);
160      }
161      /**
162       * @apilevel low-level
163       * @declaredat ASTNode:27
164       */
165      protected int numChildren() {
166        return 2;
167      }
168      /**
169       * @apilevel internal
170       * @declaredat ASTNode:33
171       */
172      public boolean mayHaveRewrite() {
173        return false;
174      }
175      /**
176       * @apilevel internal
177       * @declaredat ASTNode:39
178       */
179      public void flushAttrCache() {
180        super.flushAttrCache();
181        decl_reset();
182      }
183      /**
184       * @apilevel internal
185       * @declaredat ASTNode:46
186       */
187      public void flushCollectionCache() {
188        super.flushCollectionCache();
189      }
190      /**
191       * @apilevel internal
192       * @declaredat ASTNode:52
193       */
194      public void flushRewriteCache() {
195        super.flushRewriteCache();
196      }
197      /**
198       * @apilevel internal
199       * @declaredat ASTNode:58
200       */
201      public Annotation clone() throws CloneNotSupportedException {
202        Annotation node = (Annotation) super.clone();
203        return node;
204      }
205      /**
206       * @apilevel internal
207       * @declaredat ASTNode:65
208       */
209      public Annotation copy() {
210        try {
211          Annotation node = (Annotation) clone();
212          node.parent = null;
213          if (children != null) {
214            node.children = (ASTNode[]) children.clone();
215          }
216          return node;
217        } catch (CloneNotSupportedException e) {
218          throw new Error("Error: clone not supported for " + getClass().getName());
219        }
220      }
221      /**
222       * Create a deep copy of the AST subtree at this node.
223       * The copy is dangling, i.e. has no parent.
224       * @return dangling copy of the subtree at this node
225       * @apilevel low-level
226       * @deprecated Please use treeCopy or treeCopyNoTransform instead
227       * @declaredat ASTNode:84
228       */
229      @Deprecated
230      public Annotation fullCopy() {
231        return treeCopyNoTransform();
232      }
233      /**
234       * Create a deep copy of the AST subtree at this node.
235       * The copy is dangling, i.e. has no parent.
236       * @return dangling copy of the subtree at this node
237       * @apilevel low-level
238       * @declaredat ASTNode:94
239       */
240      public Annotation treeCopyNoTransform() {
241        Annotation tree = (Annotation) copy();
242        if (children != null) {
243          for (int i = 0; i < children.length; ++i) {
244            ASTNode child = (ASTNode) children[i];
245            if (child != null) {
246              child = child.treeCopyNoTransform();
247              tree.setChild(child, i);
248            }
249          }
250        }
251        return tree;
252      }
253      /**
254       * Create a deep copy of the AST subtree at this node.
255       * The subtree of this node is traversed to trigger rewrites before copy.
256       * The copy is dangling, i.e. has no parent.
257       * @return dangling copy of the subtree at this node
258       * @apilevel low-level
259       * @declaredat ASTNode:114
260       */
261      public Annotation treeCopy() {
262        doFullTraversal();
263        return treeCopyNoTransform();
264      }
265      /**
266       * @apilevel internal
267       * @declaredat ASTNode:121
268       */
269      protected boolean is$Equal(ASTNode node) {
270        return super.is$Equal(node) && (tokenString_ID == ((Annotation)node).tokenString_ID);    
271      }
272      /**
273       * Replaces the lexeme ID.
274       * @param value The new value for the lexeme ID.
275       * @apilevel high-level
276       */
277      public void setID(String value) {
278        tokenString_ID = value;
279      }
280      /**
281       * JastAdd-internal setter for lexeme ID using the Beaver parser.
282       * @param symbol Symbol containing the new value for the lexeme ID
283       * @apilevel internal
284       */
285      public void setID(beaver.Symbol symbol) {
286        if (symbol.value != null && !(symbol.value instanceof String))
287        throw new UnsupportedOperationException("setID is only valid for String lexemes");
288        tokenString_ID = (String)symbol.value;
289        IDstart = symbol.getStart();
290        IDend = symbol.getEnd();
291      }
292      /**
293       * Retrieves the value for the lexeme ID.
294       * @return The value for the lexeme ID.
295       * @apilevel high-level
296       */
297      @ASTNodeAnnotation.Token(name="ID")
298      public String getID() {
299        return tokenString_ID != null ? tokenString_ID : "";
300      }
301      /**
302       * Replaces the Access child.
303       * @param node The new node to replace the Access child.
304       * @apilevel high-level
305       */
306      public void setAccess(Access node) {
307        setChild(node, 0);
308      }
309      /**
310       * Retrieves the Access child.
311       * @return The current node used as the Access child.
312       * @apilevel high-level
313       */
314      @ASTNodeAnnotation.Child(name="Access")
315      public Access getAccess() {
316        return (Access) getChild(0);
317      }
318      /**
319       * Retrieves the Access child.
320       * <p><em>This method does not invoke AST transformations.</em></p>
321       * @return The current node used as the Access child.
322       * @apilevel low-level
323       */
324      public Access getAccessNoTransform() {
325        return (Access) getChildNoTransform(0);
326      }
327      /**
328       * Replaces the ElementValuePair list.
329       * @param list The new list node to be used as the ElementValuePair list.
330       * @apilevel high-level
331       */
332      public void setElementValuePairList(List<ElementValuePair> list) {
333        setChild(list, 1);
334      }
335      /**
336       * Retrieves the number of children in the ElementValuePair list.
337       * @return Number of children in the ElementValuePair list.
338       * @apilevel high-level
339       */
340      public int getNumElementValuePair() {
341        return getElementValuePairList().getNumChild();
342      }
343      /**
344       * Retrieves the number of children in the ElementValuePair list.
345       * Calling this method will not trigger rewrites.
346       * @return Number of children in the ElementValuePair list.
347       * @apilevel low-level
348       */
349      public int getNumElementValuePairNoTransform() {
350        return getElementValuePairListNoTransform().getNumChildNoTransform();
351      }
352      /**
353       * Retrieves the element at index {@code i} in the ElementValuePair list.
354       * @param i Index of the element to return.
355       * @return The element at position {@code i} in the ElementValuePair list.
356       * @apilevel high-level
357       */
358      public ElementValuePair getElementValuePair(int i) {
359        return (ElementValuePair) getElementValuePairList().getChild(i);
360      }
361      /**
362       * Check whether the ElementValuePair list has any children.
363       * @return {@code true} if it has at least one child, {@code false} otherwise.
364       * @apilevel high-level
365       */
366      public boolean hasElementValuePair() {
367        return getElementValuePairList().getNumChild() != 0;
368      }
369      /**
370       * Append an element to the ElementValuePair list.
371       * @param node The element to append to the ElementValuePair list.
372       * @apilevel high-level
373       */
374      public void addElementValuePair(ElementValuePair node) {
375        List<ElementValuePair> list = (parent == null) ? getElementValuePairListNoTransform() : getElementValuePairList();
376        list.addChild(node);
377      }
378      /**
379       * @apilevel low-level
380       */
381      public void addElementValuePairNoTransform(ElementValuePair node) {
382        List<ElementValuePair> list = getElementValuePairListNoTransform();
383        list.addChild(node);
384      }
385      /**
386       * Replaces the ElementValuePair list element at index {@code i} with the new node {@code node}.
387       * @param node The new node to replace the old list element.
388       * @param i The list index of the node to be replaced.
389       * @apilevel high-level
390       */
391      public void setElementValuePair(ElementValuePair node, int i) {
392        List<ElementValuePair> list = getElementValuePairList();
393        list.setChild(node, i);
394      }
395      /**
396       * Retrieves the ElementValuePair list.
397       * @return The node representing the ElementValuePair list.
398       * @apilevel high-level
399       */
400      @ASTNodeAnnotation.ListChild(name="ElementValuePair")
401      public List<ElementValuePair> getElementValuePairList() {
402        List<ElementValuePair> list = (List<ElementValuePair>) getChild(1);
403        return list;
404      }
405      /**
406       * Retrieves the ElementValuePair list.
407       * <p><em>This method does not invoke AST transformations.</em></p>
408       * @return The node representing the ElementValuePair list.
409       * @apilevel low-level
410       */
411      public List<ElementValuePair> getElementValuePairListNoTransform() {
412        return (List<ElementValuePair>) getChildNoTransform(1);
413      }
414      /**
415       * Retrieves the ElementValuePair list.
416       * @return The node representing the ElementValuePair list.
417       * @apilevel high-level
418       */
419      public List<ElementValuePair> getElementValuePairs() {
420        return getElementValuePairList();
421      }
422      /**
423       * Retrieves the ElementValuePair list.
424       * <p><em>This method does not invoke AST transformations.</em></p>
425       * @return The node representing the ElementValuePair list.
426       * @apilevel low-level
427       */
428      public List<ElementValuePair> getElementValuePairsNoTransform() {
429        return getElementValuePairListNoTransform();
430      }
431      /**
432       * @aspect Annotations
433       * @declaredat /home/jesper/git/extendj/java6/frontend/Override.jrag:45
434       */
435       
436      public void checkOverride() {
437        if (decl().fullName().equals("java.lang.Override") &&
438            enclosingBodyDecl() instanceof MethodDecl) {
439    
440          MethodDecl method = (MethodDecl)enclosingBodyDecl();
441          TypeDecl host = method.hostType();
442          SimpleSet ancestors = host.ancestorMethods(method.signature());
443          boolean found = false;
444          for (Iterator iter = ancestors.iterator(); iter.hasNext(); ) {
445            MethodDecl decl = (MethodDecl)iter.next();
446            if (method.overrides(decl)) {
447              found = true;
448              break;
449            }
450          }
451          if (!found) {
452            TypeDecl typeObject = lookupType("java.lang", "Object");
453            SimpleSet overrides = typeObject.localMethodsSignature(method.signature());
454            if (overrides.isEmpty() ||
455                !((MethodDecl) overrides.iterator().next()).isPublic())
456              error("method does not override a method from a supertype");
457          }
458        }
459      }
460      /**
461       * @attribute syn
462       * @aspect Annotations
463       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:285
464       */
465      @ASTNodeAnnotation.Attribute
466      public boolean isAnnotation(String packageName, String name) {
467        boolean isAnnotation_String_String_value = decl().isType(packageName, name);
468    
469        return isAnnotation_String_String_value;
470      }
471      /**
472       * @apilevel internal
473       */
474      protected boolean decl_computed = false;
475      /**
476       * @apilevel internal
477       */
478      protected TypeDecl decl_value;
479      /**
480       * @apilevel internal
481       */
482      private void decl_reset() {
483        decl_computed = false;
484        decl_value = null;
485      }
486      /**
487       * @attribute syn
488       * @aspect Annotations
489       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:501
490       */
491      @ASTNodeAnnotation.Attribute
492      public TypeDecl decl() {
493        ASTNode$State state = state();
494        if (decl_computed) {
495          return decl_value;
496        }
497        boolean intermediate = state.INTERMEDIATE_VALUE;
498        state.INTERMEDIATE_VALUE = false;
499        int num = state.boundariesCrossed;
500        boolean isFinal = this.is$Final();
501        decl_value = getAccess().type();
502        if (isFinal && num == state().boundariesCrossed) {
503          decl_computed = true;
504        } else {
505        }
506        state.INTERMEDIATE_VALUE |= intermediate;
507    
508        return decl_value;
509      }
510      /**
511       * @attribute syn
512       * @aspect Annotations
513       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:513
514       */
515      @ASTNodeAnnotation.Attribute
516      public ElementValue elementValueFor(String name) {
517        {
518            for (int i = 0; i < getNumElementValuePair(); i++) {
519              ElementValuePair pair = getElementValuePair(i);
520              if (pair.getName().equals(name)) {
521                return pair.getElementValue();
522              }
523            }
524            return null;
525          }
526      }
527      /**
528       * @attribute syn
529       * @aspect Annotations
530       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:611
531       */
532      @ASTNodeAnnotation.Attribute
533      public TypeDecl type() {
534        TypeDecl type_value = getAccess().type();
535    
536        return type_value;
537      }
538      /**
539       * @attribute syn
540       * @aspect Annotations
541       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:640
542       */
543      @ASTNodeAnnotation.Attribute
544      public boolean isMetaAnnotation() {
545        boolean isMetaAnnotation_value = hostType().isAnnotationDecl();
546    
547        return isMetaAnnotation_value;
548      }
549      /**
550       * @attribute syn
551       * @aspect AnnotationsCodegen
552       * @declaredat /home/jesper/git/extendj/java5/backend/AnnotationsCodegen.jrag:88
553       */
554      @ASTNodeAnnotation.Attribute
555      public boolean isRuntimeVisible() {
556        {
557            Annotation a = decl().annotation(lookupType("java.lang.annotation", "Retention"));
558            if (a == null) {
559              return false;
560            }
561            ElementConstantValue value = (ElementConstantValue) a.getElementValuePair(0).getElementValue();
562            Variable v = value.getExpr().varDecl();
563            return v != null && v.name().equals("RUNTIME");
564          }
565      }
566      /**
567       * @attribute syn
568       * @aspect AnnotationsCodegen
569       * @declaredat /home/jesper/git/extendj/java5/backend/AnnotationsCodegen.jrag:100
570       */
571      @ASTNodeAnnotation.Attribute
572      public boolean isRuntimeInvisible() {
573        {
574            Annotation a = decl().annotation(lookupType("java.lang.annotation", "Retention"));
575            if (a == null) return true; // default bahavior if not annotated
576            ElementConstantValue value = (ElementConstantValue) a.getElementValuePair(0).getElementValue();
577            Variable v = value.getExpr().varDecl();
578            return v != null &&  v.name().equals("CLASS");
579          }
580      }
581      /**
582       * @attribute inh
583       * @aspect Annotations
584       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:78
585       */
586      /**
587       * @attribute inh
588       * @aspect Annotations
589       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:78
590       */
591      @ASTNodeAnnotation.Attribute
592      public TypeDecl lookupType(String packageName, String typeName) {
593        TypeDecl lookupType_String_String_value = getParent().Define_lookupType(this, null, packageName, typeName);
594    
595        return lookupType_String_String_value;
596      }
597      /**
598       * @attribute inh
599       * @aspect Annotations
600       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:96
601       */
602      /**
603       * @attribute inh
604       * @aspect Annotations
605       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:96
606       */
607      @ASTNodeAnnotation.Attribute
608      public boolean mayUseAnnotationTarget(String name) {
609        boolean mayUseAnnotationTarget_String_value = getParent().Define_mayUseAnnotationTarget(this, null, name);
610    
611        return mayUseAnnotationTarget_String_value;
612      }
613      /**
614       * @attribute inh
615       * @aspect Annotations
616       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:330
617       */
618      /**
619       * @attribute inh
620       * @aspect Annotations
621       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:330
622       */
623      @ASTNodeAnnotation.Attribute
624      public BodyDecl enclosingBodyDecl() {
625        BodyDecl enclosingBodyDecl_value = getParent().Define_enclosingBodyDecl(this, null);
626    
627        return enclosingBodyDecl_value;
628      }
629      /**
630       * @attribute inh
631       * @aspect Annotations
632       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:503
633       */
634      /**
635       * @attribute inh
636       * @aspect Annotations
637       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:503
638       */
639      @ASTNodeAnnotation.Attribute
640      public Annotation lookupAnnotation(TypeDecl typeDecl) {
641        Annotation lookupAnnotation_TypeDecl_value = getParent().Define_lookupAnnotation(this, null, typeDecl);
642    
643        return lookupAnnotation_TypeDecl_value;
644      }
645      /**
646       * @attribute inh
647       * @aspect Annotations
648       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:641
649       */
650      /**
651       * @attribute inh
652       * @aspect Annotations
653       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:641
654       */
655      @ASTNodeAnnotation.Attribute
656      public TypeDecl hostType() {
657        TypeDecl hostType_value = getParent().Define_hostType(this, null);
658    
659        return hostType_value;
660      }
661      /**
662       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:544
663       * @apilevel internal
664       */
665      public TypeDecl Define_enclosingAnnotationDecl(ASTNode caller, ASTNode child) {
666        if (caller == getElementValuePairListNoTransform()) {
667          // @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:545
668          int childIndex = caller.getIndexOfChild(child);
669          return decl();
670        }
671        else {
672          return getParent().Define_enclosingAnnotationDecl(this, caller);
673        }
674      }
675      protected boolean canDefine_enclosingAnnotationDecl(ASTNode caller, ASTNode child) {
676        return true;
677      }
678      /**
679       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:36
680       * @apilevel internal
681       */
682      public NameType Define_nameType(ASTNode caller, ASTNode child) {
683        if (caller == getAccessNoTransform()) {
684          // @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:646
685          return NameType.TYPE_NAME;
686        }
687        else {
688          return getParent().Define_nameType(this, caller);
689        }
690      }
691      protected boolean canDefine_nameType(ASTNode caller, ASTNode child) {
692        return true;
693      }
694      /**
695       * @apilevel internal
696       */
697      public ASTNode rewriteTo() {
698        return super.rewriteTo();
699      }
700    }