001    /* This file was generated with JastAdd2 (http://jastadd.org) version R20130213 */
002    package AST;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.*;
007    import beaver.*;
008    import java.util.ArrayList;
009    import java.util.zip.*;
010    import java.io.*;
011    import java.io.FileNotFoundException;
012    import java.util.Collection;
013    /**
014     * @production LUBType : {@link ReferenceType} ::= <span class="component">{@link Modifiers}</span> <span class="component">&lt;ID:String&gt;</span> <span class="component">{@link BodyDecl}*</span> <span class="component">TypeBound:{@link Access}*</span>;
015     * @ast node
016     * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/Generics.ast:46
017     */
018    public class LUBType extends ReferenceType implements Cloneable {
019      /**
020       * @apilevel low-level
021       */
022      public void flushCache() {
023      }
024      /**
025       * @apilevel internal
026       */
027      public void flushCollectionCache() {
028      }
029      /**
030       * @apilevel internal
031       */
032      @SuppressWarnings({"unchecked", "cast"})
033      public LUBType clone() throws CloneNotSupportedException {
034        LUBType node = (LUBType)super.clone();
035        node.lub_computed = false;
036        node.lub_value = null;
037        node.subtype_TypeDecl_values = null;
038        node.in$Circle(false);
039        node.is$Final(false);
040        return node;
041      }
042    /**
043     * @apilevel internal
044     */
045      @SuppressWarnings({"unchecked", "cast"})
046    public LUBType copy() {
047      
048      try {
049        LUBType node = (LUBType) clone();
050        node.parent = null;
051        if(children != null)
052          node.children = (ASTNode[]) children.clone();
053        
054        return node;
055      } catch (CloneNotSupportedException e) {
056        throw new Error("Error: clone not supported for " + getClass().getName());
057      }
058      
059    }/**
060     * Create a deep copy of the AST subtree at this node.
061     * The copy is dangling, i.e. has no parent.
062     * @return dangling copy of the subtree at this node
063     * @apilevel low-level
064     */
065      @SuppressWarnings({"unchecked", "cast"})
066    public LUBType fullCopy() {
067      
068      LUBType tree = (LUBType) copy();
069      if (children != null) {
070        for (int i = 0; i < children.length; ++i) {
071          
072          ASTNode child = (ASTNode) children[i];
073          if(child != null) {
074            child = child.fullCopy();
075            tree.setChild(child, i);
076          }
077        }
078      }
079      return tree;
080      
081    }  /**
082       * @ast method 
083       * @aspect GenericMethodsInference
084       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:668
085       */
086      public static HashSet EC(ArrayList list) {
087          HashSet result = new HashSet();
088          boolean first = true;
089          for(Iterator iter = list.iterator(); iter.hasNext(); ) {
090            TypeDecl U = (TypeDecl)iter.next();
091            // erased supertype set of U
092            HashSet EST = LUBType.EST(U); 
093            if(first) {
094              result.addAll(EST);
095              first = false;
096            }
097            else
098              result.retainAll(EST);
099          }
100          return result;
101        }
102      /**
103         * The minimal erased candidate set for Tj
104         * is MEC = {V | V in EC, forall  W != V in EC, not W <: V}
105         * @return minimal erased candidate set for Tj
106         * @ast method 
107       * @aspect GenericMethodsInference
108       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:690
109       */
110      public static HashSet MEC(ArrayList list) {
111          HashSet EC = LUBType.EC(list);
112          if(EC.size() == 1)
113            return EC;
114          HashSet MEC = new HashSet();
115          for(Iterator iter = EC.iterator(); iter.hasNext(); ) {
116            TypeDecl V = (TypeDecl)iter.next();
117            boolean keep = true;
118            for(Iterator i2 = EC.iterator(); i2.hasNext(); ) {
119              TypeDecl W = (TypeDecl)i2.next();
120              if(!(V instanceof TypeVariable) && V != W && W.instanceOf(V))
121                keep = false;
122            }
123            if(keep)
124              MEC.add(V);
125          }
126          return MEC;
127        }
128      /**
129         * relevant invocations of G, Inv(G)
130         * Inv(G) = {V | 1 <= i <= k, V in ST(Ui), V = G<...>}
131         * @return set of relevant invocations of G, Inv(G)
132         * @ast method 
133       * @aspect GenericMethodsInference
134       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:714
135       */
136      public static HashSet Inv(TypeDecl G, ArrayList Us) {
137          HashSet result = new HashSet();
138          for(Iterator iter = Us.iterator(); iter.hasNext(); ) {
139            TypeDecl U = (TypeDecl)iter.next();
140            for(Iterator i2 = LUBType.ST(U).iterator(); i2.hasNext(); ) {
141              TypeDecl V = (TypeDecl)i2.next();
142              if(V instanceof ParTypeDecl && !V.isRawType() && ((ParTypeDecl)V).genericDecl() == G)
143                result.add(V);
144            }
145          }
146          return result;
147        }
148      /**
149         * @return least containing invocation (lci)
150         * @ast method 
151       * @aspect GenericMethodsInference
152       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:730
153       */
154      public TypeDecl lci(HashSet set, TypeDecl G) {
155          ArrayList list = new ArrayList();
156          boolean first = true;
157          for(Iterator iter = set.iterator(); iter.hasNext(); ) {
158            ParTypeDecl decl = (ParTypeDecl)iter.next();
159            if(first) {
160              first = false;
161              for(int i = 0; i < decl.getNumArgument(); i++)
162                list.add(decl.getArgument(i).type());
163            }
164            else {
165              for(int i = 0; i < decl.getNumArgument(); i++)
166                list.set(i, lcta((TypeDecl)list.get(i), decl.getArgument(i).type()));
167            }
168          }
169          return ((GenericTypeDecl)G).lookupParTypeDecl(list);
170        }
171      /**
172         * least containing type arguments
173         * @ast method 
174       * @aspect GenericMethodsInference
175       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:751
176       */
177      public TypeDecl lcta(TypeDecl X, TypeDecl Y) {
178          //System.err.println("Computing lcta for " + X.typeName() + " and " + Y.typeName());
179          if(!X.isWildcard() && !Y.isWildcard()) {
180            TypeDecl U = X;
181            TypeDecl V = Y;
182            return U == V ? U : lub(U, V).asWildcardExtends();
183          }
184          else if(!X.isWildcard() && Y instanceof WildcardExtendsType) {
185            TypeDecl U = X;
186            TypeDecl V = ((WildcardExtendsType)Y).getAccess().type();
187            return lub(U, V).asWildcardExtends();
188          }
189          else if(!X.isWildcard() && Y instanceof WildcardSuperType) {
190            TypeDecl U = X;
191            TypeDecl V = ((WildcardSuperType)Y).getAccess().type();
192            ArrayList bounds = new ArrayList();
193            bounds.add(U);
194            bounds.add(V);
195            return GLBTypeFactory.glb(bounds).asWildcardSuper();
196          }
197          else if(X instanceof WildcardExtendsType && Y instanceof WildcardExtendsType) {
198            TypeDecl U = ((WildcardExtendsType)X).getAccess().type();
199            TypeDecl V = ((WildcardExtendsType)Y).getAccess().type();
200            return lub(U, V).asWildcardExtends();
201          }
202          else if(X instanceof WildcardExtendsType && Y instanceof WildcardSuperType) {
203            TypeDecl U = ((WildcardExtendsType)X).getAccess().type();
204            TypeDecl V = ((WildcardSuperType)Y).getAccess().type();
205            return U == V ? U : U.typeWildcard();
206          }
207          else if(X instanceof WildcardSuperType && Y instanceof WildcardSuperType) {
208            TypeDecl U = ((WildcardSuperType)X).getAccess().type();
209            TypeDecl V = ((WildcardSuperType)Y).getAccess().type();
210            ArrayList bounds = new ArrayList();
211            bounds.add(U);
212            bounds.add(V);
213            return GLBTypeFactory.glb(bounds).asWildcardSuper();
214          }
215          else
216            throw new Error("lcta not defined for (" + X.getClass().getName() + ", " + Y.getClass().getName());
217        }
218      /**
219       * @ast method 
220       * @aspect GenericMethodsInference
221       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:793
222       */
223      public TypeDecl lub(TypeDecl X, TypeDecl Y) {
224          ArrayList list = new ArrayList(2);
225          list.add(X);
226          list.add(Y);
227          return lub(list);
228        }
229      /**
230       * @ast method 
231       * @aspect GenericMethodsInference
232       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:800
233       */
234      public TypeDecl lub(ArrayList list) {
235          return lookupLUBType(list);
236        }
237      /**
238       * @ast method 
239       * @aspect GenericMethodsInference
240       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:805
241       */
242      public static HashSet EST(TypeDecl t) {
243          HashSet result = new HashSet();
244          for(Iterator iter = LUBType.ST(t).iterator(); iter.hasNext(); ) {
245            TypeDecl typeDecl = (TypeDecl)iter.next();
246            if(typeDecl instanceof TypeVariable)
247              result.add(typeDecl);
248            else
249              result.add(typeDecl.erasure());
250          }
251          return result;
252        }
253      /**
254         * @return supertype set of T
255         * @ast method 
256       * @aspect GenericMethodsInference
257       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:820
258       */
259      public static HashSet ST(TypeDecl t) {
260          HashSet result = new HashSet();
261          LUBType.addSupertypes(result, t);
262          return result;
263        }
264      /**
265       * @ast method 
266       * @aspect GenericMethodsInference
267       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:826
268       */
269      public static void addSupertypes(HashSet set, TypeDecl t) {
270          set.add(t);
271          if(t instanceof ClassDecl) {
272            ClassDecl type = (ClassDecl)t;
273            if(type.hasSuperclass()) {
274              addSupertypes(set, type.superclass());
275            }
276            for(int i = 0; i < type.getNumImplements(); i++) {
277              addSupertypes(set, type.getImplements(i).type());
278            }
279          }
280          else if(t instanceof InterfaceDecl) {
281            InterfaceDecl type = (InterfaceDecl)t;
282            for(int i = 0; i < type.getNumSuperInterfaceId(); i++) {
283              addSupertypes(set, type.getSuperInterfaceId(i).type());
284            }
285            if(type.getNumSuperInterfaceId() == 0)
286              set.add(type.typeObject());
287          }
288          else if(t instanceof TypeVariable) {
289            TypeVariable type = (TypeVariable)t;
290            for(int i = 0; i < type.getNumTypeBound(); i++) {
291              addSupertypes(set, type.getTypeBound(i).type());
292            }
293            if(type.getNumTypeBound() == 0)
294              set.add(type.typeObject());
295          }
296          else if(t instanceof LUBType) {
297            LUBType type = (LUBType)t;
298            for(int i = 0; i < type.getNumTypeBound(); i++) {
299              addSupertypes(set, type.getTypeBound(i).type());
300            }
301            if(type.getNumTypeBound() == 0)
302              set.add(type.typeObject());
303          }
304          else
305            throw new Error("Operation not supported for " + t.fullName() + ", " + t.getClass().getName());
306        }
307      /**
308       * @ast method 
309       * @aspect LookupParTypeDecl
310       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/Generics.jrag:1444
311       */
312      public HashSet implementedInterfaces(){
313           HashSet ret = new HashSet();
314           for (int i = 0; i < getNumTypeBound(); i++) {
315               ret.addAll(getTypeBound(i).type().implementedInterfaces());
316           }
317           return ret;
318       }
319      /**
320       * @ast method 
321       * 
322       */
323      public LUBType() {
324        super();
325    
326    
327      }
328      /**
329       * Initializes the child array to the correct size.
330       * Initializes List and Opt nta children.
331       * @apilevel internal
332       * @ast method
333       * @ast method 
334       * 
335       */
336      public void init$Children() {
337        children = new ASTNode[3];
338        setChild(new List(), 1);
339        setChild(new List(), 2);
340      }
341      /**
342       * @ast method 
343       * 
344       */
345      public LUBType(Modifiers p0, String p1, List<BodyDecl> p2, List<Access> p3) {
346        setChild(p0, 0);
347        setID(p1);
348        setChild(p2, 1);
349        setChild(p3, 2);
350      }
351      /**
352       * @ast method 
353       * 
354       */
355      public LUBType(Modifiers p0, beaver.Symbol p1, List<BodyDecl> p2, List<Access> p3) {
356        setChild(p0, 0);
357        setID(p1);
358        setChild(p2, 1);
359        setChild(p3, 2);
360      }
361      /**
362       * @apilevel low-level
363       * @ast method 
364       * 
365       */
366      protected int numChildren() {
367        return 3;
368      }
369      /**
370       * @apilevel internal
371       * @ast method 
372       * 
373       */
374      public boolean mayHaveRewrite() {
375        return false;
376      }
377      /**
378       * Replaces the Modifiers child.
379       * @param node The new node to replace the Modifiers child.
380       * @apilevel high-level
381       * @ast method 
382       * 
383       */
384      public void setModifiers(Modifiers node) {
385        setChild(node, 0);
386      }
387      /**
388       * Retrieves the Modifiers child.
389       * @return The current node used as the Modifiers child.
390       * @apilevel high-level
391       * @ast method 
392       * 
393       */
394      public Modifiers getModifiers() {
395        return (Modifiers)getChild(0);
396      }
397      /**
398       * Retrieves the Modifiers child.
399       * <p><em>This method does not invoke AST transformations.</em></p>
400       * @return The current node used as the Modifiers child.
401       * @apilevel low-level
402       * @ast method 
403       * 
404       */
405      public Modifiers getModifiersNoTransform() {
406        return (Modifiers)getChildNoTransform(0);
407      }
408      /**
409       * Replaces the lexeme ID.
410       * @param value The new value for the lexeme ID.
411       * @apilevel high-level
412       * @ast method 
413       * 
414       */
415      public void setID(String value) {
416        tokenString_ID = value;
417      }
418      /**
419       * JastAdd-internal setter for lexeme ID using the Beaver parser.
420       * @apilevel internal
421       * @ast method 
422       * 
423       */
424      public void setID(beaver.Symbol symbol) {
425        if(symbol.value != null && !(symbol.value instanceof String))
426          throw new UnsupportedOperationException("setID is only valid for String lexemes");
427        tokenString_ID = (String)symbol.value;
428        IDstart = symbol.getStart();
429        IDend = symbol.getEnd();
430      }
431      /**
432       * Retrieves the value for the lexeme ID.
433       * @return The value for the lexeme ID.
434       * @apilevel high-level
435       * @ast method 
436       * 
437       */
438      public String getID() {
439        return tokenString_ID != null ? tokenString_ID : "";
440      }
441      /**
442       * Replaces the BodyDecl list.
443       * @param list The new list node to be used as the BodyDecl list.
444       * @apilevel high-level
445       * @ast method 
446       * 
447       */
448      public void setBodyDeclList(List<BodyDecl> list) {
449        setChild(list, 1);
450      }
451      /**
452       * Retrieves the number of children in the BodyDecl list.
453       * @return Number of children in the BodyDecl list.
454       * @apilevel high-level
455       * @ast method 
456       * 
457       */
458      public int getNumBodyDecl() {
459        return getBodyDeclList().getNumChild();
460      }
461      /**
462       * Retrieves the number of children in the BodyDecl list.
463       * Calling this method will not trigger rewrites..
464       * @return Number of children in the BodyDecl list.
465       * @apilevel low-level
466       * @ast method 
467       * 
468       */
469      public int getNumBodyDeclNoTransform() {
470        return getBodyDeclListNoTransform().getNumChildNoTransform();
471      }
472      /**
473       * Retrieves the element at index {@code i} in the BodyDecl list..
474       * @param i Index of the element to return.
475       * @return The element at position {@code i} in the BodyDecl list.
476       * @apilevel high-level
477       * @ast method 
478       * 
479       */
480      @SuppressWarnings({"unchecked", "cast"})
481      public BodyDecl getBodyDecl(int i) {
482        return (BodyDecl)getBodyDeclList().getChild(i);
483      }
484      /**
485       * Append an element to the BodyDecl list.
486       * @param node The element to append to the BodyDecl list.
487       * @apilevel high-level
488       * @ast method 
489       * 
490       */
491      public void addBodyDecl(BodyDecl node) {
492        List<BodyDecl> list = (parent == null || state == null) ? getBodyDeclListNoTransform() : getBodyDeclList();
493        list.addChild(node);
494      }
495      /**
496       * @apilevel low-level
497       * @ast method 
498       * 
499       */
500      public void addBodyDeclNoTransform(BodyDecl node) {
501        List<BodyDecl> list = getBodyDeclListNoTransform();
502        list.addChild(node);
503      }
504      /**
505       * Replaces the BodyDecl list element at index {@code i} with the new node {@code node}.
506       * @param node The new node to replace the old list element.
507       * @param i The list index of the node to be replaced.
508       * @apilevel high-level
509       * @ast method 
510       * 
511       */
512      public void setBodyDecl(BodyDecl node, int i) {
513        List<BodyDecl> list = getBodyDeclList();
514        list.setChild(node, i);
515      }
516      /**
517       * Retrieves the BodyDecl list.
518       * @return The node representing the BodyDecl list.
519       * @apilevel high-level
520       * @ast method 
521       * 
522       */
523      public List<BodyDecl> getBodyDecls() {
524        return getBodyDeclList();
525      }
526      /**
527       * Retrieves the BodyDecl list.
528       * <p><em>This method does not invoke AST transformations.</em></p>
529       * @return The node representing the BodyDecl list.
530       * @apilevel low-level
531       * @ast method 
532       * 
533       */
534      public List<BodyDecl> getBodyDeclsNoTransform() {
535        return getBodyDeclListNoTransform();
536      }
537      /**
538       * Retrieves the BodyDecl list.
539       * @return The node representing the BodyDecl list.
540       * @apilevel high-level
541       * @ast method 
542       * 
543       */
544      @SuppressWarnings({"unchecked", "cast"})
545      public List<BodyDecl> getBodyDeclList() {
546        List<BodyDecl> list = (List<BodyDecl>)getChild(1);
547        list.getNumChild();
548        return list;
549      }
550      /**
551       * Retrieves the BodyDecl list.
552       * <p><em>This method does not invoke AST transformations.</em></p>
553       * @return The node representing the BodyDecl list.
554       * @apilevel low-level
555       * @ast method 
556       * 
557       */
558      @SuppressWarnings({"unchecked", "cast"})
559      public List<BodyDecl> getBodyDeclListNoTransform() {
560        return (List<BodyDecl>)getChildNoTransform(1);
561      }
562      /**
563       * Replaces the TypeBound list.
564       * @param list The new list node to be used as the TypeBound list.
565       * @apilevel high-level
566       * @ast method 
567       * 
568       */
569      public void setTypeBoundList(List<Access> list) {
570        setChild(list, 2);
571      }
572      /**
573       * Retrieves the number of children in the TypeBound list.
574       * @return Number of children in the TypeBound list.
575       * @apilevel high-level
576       * @ast method 
577       * 
578       */
579      public int getNumTypeBound() {
580        return getTypeBoundList().getNumChild();
581      }
582      /**
583       * Retrieves the number of children in the TypeBound list.
584       * Calling this method will not trigger rewrites..
585       * @return Number of children in the TypeBound list.
586       * @apilevel low-level
587       * @ast method 
588       * 
589       */
590      public int getNumTypeBoundNoTransform() {
591        return getTypeBoundListNoTransform().getNumChildNoTransform();
592      }
593      /**
594       * Retrieves the element at index {@code i} in the TypeBound list..
595       * @param i Index of the element to return.
596       * @return The element at position {@code i} in the TypeBound list.
597       * @apilevel high-level
598       * @ast method 
599       * 
600       */
601      @SuppressWarnings({"unchecked", "cast"})
602      public Access getTypeBound(int i) {
603        return (Access)getTypeBoundList().getChild(i);
604      }
605      /**
606       * Append an element to the TypeBound list.
607       * @param node The element to append to the TypeBound list.
608       * @apilevel high-level
609       * @ast method 
610       * 
611       */
612      public void addTypeBound(Access node) {
613        List<Access> list = (parent == null || state == null) ? getTypeBoundListNoTransform() : getTypeBoundList();
614        list.addChild(node);
615      }
616      /**
617       * @apilevel low-level
618       * @ast method 
619       * 
620       */
621      public void addTypeBoundNoTransform(Access node) {
622        List<Access> list = getTypeBoundListNoTransform();
623        list.addChild(node);
624      }
625      /**
626       * Replaces the TypeBound list element at index {@code i} with the new node {@code node}.
627       * @param node The new node to replace the old list element.
628       * @param i The list index of the node to be replaced.
629       * @apilevel high-level
630       * @ast method 
631       * 
632       */
633      public void setTypeBound(Access node, int i) {
634        List<Access> list = getTypeBoundList();
635        list.setChild(node, i);
636      }
637      /**
638       * Retrieves the TypeBound list.
639       * @return The node representing the TypeBound list.
640       * @apilevel high-level
641       * @ast method 
642       * 
643       */
644      public List<Access> getTypeBounds() {
645        return getTypeBoundList();
646      }
647      /**
648       * Retrieves the TypeBound list.
649       * <p><em>This method does not invoke AST transformations.</em></p>
650       * @return The node representing the TypeBound list.
651       * @apilevel low-level
652       * @ast method 
653       * 
654       */
655      public List<Access> getTypeBoundsNoTransform() {
656        return getTypeBoundListNoTransform();
657      }
658      /**
659       * Retrieves the TypeBound list.
660       * @return The node representing the TypeBound list.
661       * @apilevel high-level
662       * @ast method 
663       * 
664       */
665      @SuppressWarnings({"unchecked", "cast"})
666      public List<Access> getTypeBoundList() {
667        List<Access> list = (List<Access>)getChild(2);
668        list.getNumChild();
669        return list;
670      }
671      /**
672       * Retrieves the TypeBound list.
673       * <p><em>This method does not invoke AST transformations.</em></p>
674       * @return The node representing the TypeBound list.
675       * @apilevel low-level
676       * @ast method 
677       * 
678       */
679      @SuppressWarnings({"unchecked", "cast"})
680      public List<Access> getTypeBoundListNoTransform() {
681        return (List<Access>)getChildNoTransform(2);
682      }
683      /**
684       * @apilevel internal
685       */
686      protected boolean lub_computed = false;
687      /**
688       * @apilevel internal
689       */
690      protected TypeDecl lub_value;
691      /**
692       * @attribute syn
693       * @aspect GenericMethodsInference
694       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericMethodsInference.jrag:650
695       */
696      @SuppressWarnings({"unchecked", "cast"})
697      public TypeDecl lub() {
698        if(lub_computed) {
699          return lub_value;
700        }
701          ASTNode$State state = state();
702      int num = state.boundariesCrossed;
703      boolean isFinal = this.is$Final();
704        lub_value = lub_compute();
705      if(isFinal && num == state().boundariesCrossed){ lub_computed = true; }
706            return lub_value;
707      }
708      /**
709       * @apilevel internal
710       */
711      private TypeDecl lub_compute() {
712        ArrayList list = new ArrayList();
713        for(int i = 0; i < getNumTypeBound(); i++)
714          list.add(getTypeBound(i).type());
715        ArrayList bounds = new ArrayList();
716        for(Iterator iter = LUBType.MEC(list).iterator(); iter.hasNext(); ) {
717          TypeDecl W = (TypeDecl)iter.next();
718          TypeDecl C = W instanceof GenericTypeDecl ? lci(Inv(W, list), W) : W;
719          bounds.add(C);
720        }
721        if(bounds.size() == 1)
722          return (TypeDecl)bounds.iterator().next();
723        return lookupLUBType(bounds);
724      }
725      /**
726       * @attribute syn
727       * @aspect LookupParTypeDecl
728       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/Generics.jrag:1434
729       */
730      public String typeName() {
731        ASTNode$State state = state();
732        try {
733        if(getNumTypeBound() == 0)
734          return "<NOTYPE>";
735        StringBuffer s = new StringBuffer();
736        s.append(getTypeBound(0).type().typeName());
737        for(int i = 1; i < getNumTypeBound(); i++)
738          s.append(" & " + getTypeBound(i).type().typeName());
739        return s.toString();
740      }
741        finally {
742        }
743      }
744      protected java.util.Map subtype_TypeDecl_values;
745      /**
746       * @attribute syn
747       * @aspect GenericsSubtype
748       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericsSubtype.jrag:346
749       */
750      @SuppressWarnings({"unchecked", "cast"})
751      public boolean subtype(TypeDecl type) {
752        Object _parameters = type;
753        if(subtype_TypeDecl_values == null) subtype_TypeDecl_values = new java.util.HashMap(4);
754        ASTNode$State.CircularValue _value;
755        if(subtype_TypeDecl_values.containsKey(_parameters)) {
756          Object _o = subtype_TypeDecl_values.get(_parameters);
757          if(!(_o instanceof ASTNode$State.CircularValue)) {
758            return ((Boolean)_o).booleanValue();
759          }
760          else
761            _value = (ASTNode$State.CircularValue)_o;
762        }
763        else {
764          _value = new ASTNode$State.CircularValue();
765          subtype_TypeDecl_values.put(_parameters, _value);
766          _value.value = Boolean.valueOf(true);
767        }
768        ASTNode$State state = state();
769        if (!state.IN_CIRCLE) {
770          state.IN_CIRCLE = true;
771          int num = state.boundariesCrossed;
772          boolean isFinal = this.is$Final();
773          boolean new_subtype_TypeDecl_value;
774          do {
775            _value.visited = new Integer(state.CIRCLE_INDEX);
776            state.CHANGE = false;
777            new_subtype_TypeDecl_value = subtype_compute(type);
778            if (new_subtype_TypeDecl_value!=((Boolean)_value.value).booleanValue()) {
779              state.CHANGE = true;
780              _value.value = Boolean.valueOf(new_subtype_TypeDecl_value);
781            }
782            state.CIRCLE_INDEX++;
783          } while (state.CHANGE);
784            if(isFinal && num == state().boundariesCrossed) {
785            subtype_TypeDecl_values.put(_parameters, new_subtype_TypeDecl_value);
786          }
787          else {
788            subtype_TypeDecl_values.remove(_parameters);
789          state.RESET_CYCLE = true;
790          subtype_compute(type);
791          state.RESET_CYCLE = false;
792          }
793          state.IN_CIRCLE = false; 
794          return new_subtype_TypeDecl_value;
795        }
796        if(!new Integer(state.CIRCLE_INDEX).equals(_value.visited)) {
797          _value.visited = new Integer(state.CIRCLE_INDEX);
798          boolean new_subtype_TypeDecl_value = subtype_compute(type);
799          if (state.RESET_CYCLE) {
800            subtype_TypeDecl_values.remove(_parameters);
801          }
802          else if (new_subtype_TypeDecl_value!=((Boolean)_value.value).booleanValue()) {
803            state.CHANGE = true;
804            _value.value = new_subtype_TypeDecl_value;
805          }
806          return new_subtype_TypeDecl_value;
807        }
808        return ((Boolean)_value.value).booleanValue();
809      }
810      /**
811       * @apilevel internal
812       */
813      private boolean subtype_compute(TypeDecl type) {  return type.supertypeLUBType(this);  }
814      /**
815       * @attribute syn
816       * @aspect GenericsSubtype
817       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericsSubtype.jrag:421
818       */
819      public boolean supertypeClassDecl(ClassDecl type) {
820        ASTNode$State state = state();
821        try {  return type.subtype(lub());  }
822        finally {
823        }
824      }
825      /**
826       * @attribute syn
827       * @aspect GenericsSubtype
828       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericsSubtype.jrag:437
829       */
830      public boolean supertypeInterfaceDecl(InterfaceDecl type) {
831        ASTNode$State state = state();
832        try {  return type.subtype(lub());  }
833        finally {
834        }
835      }
836      /**
837       * @attribute syn
838       * @aspect GenericsSubtype
839       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/GenericsSubtype.jrag:366
840       */
841      public boolean supertypeGLBType(GLBType type) {
842        ASTNode$State state = state();
843        try {
844        ArrayList bounds = new ArrayList(getNumTypeBound());
845        for (int i = 0; i < getNumTypeBound(); i++) {
846          bounds.add(getTypeBound(i));
847        }
848        return type == lookupGLBType(bounds);
849      }
850        finally {
851        }
852      }
853      /**
854       * @apilevel internal
855       */
856      public ASTNode rewriteTo() {
857        return super.rewriteTo();
858      }
859    }