001    /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.3 */
002    package AST;
003    
004    import java.util.Collection;
005    import java.util.ArrayList;
006    import java.util.HashSet;
007    /**
008     * @ast node
009     * @declaredat /home/csz-naf/examples/PicoJava/spec/picojava.ast:8
010     * @production ClassDecl : {@link TypeDecl} ::= <span class="component">[Superclass:{@link IdUse}]</span> <span class="component">Body:{@link Block}</span>;
011    
012     */
013    public class ClassDecl extends TypeDecl implements Cloneable {
014      /**
015       * @apilevel internal
016       */
017      public ClassDecl clone() throws CloneNotSupportedException {
018        ClassDecl node = (ClassDecl) super.clone();
019        node.remoteLookup_String_visited = null;
020        node.isSubtypeOf_TypeDecl_visited = null;
021        node.isSubtypeOf_TypeDecl_values = null;
022        node.superClass_visited = -1;
023        node.superClass_computed = false;
024        node.superClass_value = null;
025        node.hasCycleOnSuperclassChain_visited = -1;
026        node.hasCycleOnSuperclassChain_computed = false;
027        node.hasCycleOnSuperclassChain_initialized = false;
028        node.remoteLookupMethod_String_List_visited = null;
029        node.lookupMethod_String_List_visited = null;
030        node.in$Circle(false);
031        node.is$Final(false);
032        return node;
033      }
034      /**
035       * @apilevel internal
036       */
037      public ClassDecl copy() {
038        try {
039          ClassDecl node = (ClassDecl) clone();
040          node.parent = null;
041          if(children != null) {
042            node.children = (ASTNode[]) children.clone();
043          }
044          return node;
045        } catch (CloneNotSupportedException e) {
046          throw new Error("Error: clone not supported for " + getClass().getName());
047        }
048      }
049      /**
050       * Create a deep copy of the AST subtree at this node.
051       * The copy is dangling, i.e. has no parent.
052       * @return dangling copy of the subtree at this node
053       * @apilevel low-level
054       */
055      public ClassDecl fullCopy() {
056        ClassDecl tree = (ClassDecl) copy();
057        if (children != null) {
058          for (int i = 0; i < children.length; ++i) {
059            ASTNode child = (ASTNode) children[i];
060            if(child != null) {
061              child = child.fullCopy();
062              tree.setChild(child, i);
063            }
064          }
065        }
066        return tree;
067      }
068      /**
069       * @aspect ErrorCheck
070       * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:32
071       */
072      public void collectErrors(Collection c) {
073        super.collectErrors(c);
074        if(hasCycleOnSuperclassChain())
075          error(c, "Cyclic inheritance chain for class " + getName());
076      }
077      /**
078       * @aspect PrettyPrint
079       * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:40
080       */
081      public void prettyPrint(StringBuilder sb, int t) {
082                sb.append(getIndent(t)).append("class ").append(getName());
083                if (hasSuperclass()) {
084                        sb.append(" extends ").append(getSuperclass());
085                }
086                sb.append(" ");
087                getBody().prettyPrint(sb, t);
088        }
089      /**
090       */
091      public ClassDecl() {
092        super();
093      }
094      /**
095       * Initializes the child array to the correct size.
096       * Initializes List and Opt nta children.
097       * @apilevel internal
098       * @ast method
099       */
100      public void init$Children() {
101        children = new ASTNode[2];
102        setChild(new Opt(), 0);
103      }
104      /**
105       */
106      public ClassDecl(String p0, Opt<IdUse> p1, Block p2) {
107        setName(p0);
108        setChild(p1, 0);
109        setChild(p2, 1);
110      }
111      /**
112       * @apilevel low-level
113       */
114      protected int numChildren() {
115        return 2;
116      }
117      /**
118       * @apilevel internal
119       */
120      public boolean mayHaveRewrite() {
121        return false;
122      }
123      /**
124       * @apilevel low-level
125       */
126      public void flushCache() {
127        super.flushCache();
128        remoteLookup_String_visited = null;
129        isSubtypeOf_TypeDecl_visited = null;
130        isSubtypeOf_TypeDecl_values = null;
131        superClass_visited = -1;
132        superClass_computed = false;
133        superClass_value = null;
134        hasCycleOnSuperclassChain_visited = -1;
135        hasCycleOnSuperclassChain_computed = false;
136        hasCycleOnSuperclassChain_initialized = false;
137        remoteLookupMethod_String_List_visited = null;
138        lookupMethod_String_List_visited = null;
139      }
140      /**
141       * @apilevel internal
142       */
143      public void flushCollectionCache() {
144        super.flushCollectionCache();
145      }
146      /**
147       * Replaces the lexeme Name.
148       * @param value The new value for the lexeme Name.
149       * @apilevel high-level
150       */
151      public void setName(String value) {
152        tokenString_Name = value;
153      }
154      /**
155       * Retrieves the value for the lexeme Name.
156       * @return The value for the lexeme Name.
157       * @apilevel high-level
158       */
159      public String getName() {
160        return tokenString_Name != null ? tokenString_Name : "";
161      }
162      /**
163       * Replaces the optional node for the Superclass child. This is the <code>Opt</code>
164       * node containing the child Superclass, not the actual child!
165       * @param opt The new node to be used as the optional node for the Superclass child.
166       * @apilevel low-level
167       */
168      public void setSuperclassOpt(Opt<IdUse> opt) {
169        setChild(opt, 0);
170      }
171      /**
172       * Replaces the (optional) Superclass child.
173       * @param node The new node to be used as the Superclass child.
174       * @apilevel high-level
175       */
176      public void setSuperclass(IdUse node) {
177        getSuperclassOpt().setChild(node, 0);
178      }
179      /**
180       * Check whether the optional Superclass child exists.
181       * @return {@code true} if the optional Superclass child exists, {@code false} if it does not.
182       * @apilevel high-level
183       */
184      public boolean hasSuperclass() {
185        return getSuperclassOpt().getNumChild() != 0;
186      }
187      /**
188       * Retrieves the (optional) Superclass child.
189       * @return The Superclass child, if it exists. Returns {@code null} otherwise.
190       * @apilevel low-level
191       */
192      public IdUse getSuperclass() {
193        return (IdUse) getSuperclassOpt().getChild(0);
194      }
195      /**
196       * Retrieves the optional node for the Superclass child. This is the <code>Opt</code> node containing the child Superclass, not the actual child!
197       * @return The optional node for child the Superclass child.
198       * @apilevel low-level
199       */
200      public Opt<IdUse> getSuperclassOpt() {
201        return (Opt<IdUse>) getChild(0);
202      }
203      /**
204       * Retrieves the optional node for child Superclass. This is the <code>Opt</code> node containing the child Superclass, not the actual child!
205       * <p><em>This method does not invoke AST transformations.</em></p>
206       * @return The optional node for child Superclass.
207       * @apilevel low-level
208       */
209      public Opt<IdUse> getSuperclassOptNoTransform() {
210        return (Opt<IdUse>) getChildNoTransform(0);
211      }
212      /**
213       * Replaces the Body child.
214       * @param node The new node to replace the Body child.
215       * @apilevel high-level
216       */
217      public void setBody(Block node) {
218        setChild(node, 1);
219      }
220      /**
221       * Retrieves the Body child.
222       * @return The current node used as the Body child.
223       * @apilevel high-level
224       */
225      public Block getBody() {
226        return (Block) getChild(1);
227      }
228      /**
229       * Retrieves the Body child.
230       * <p><em>This method does not invoke AST transformations.</em></p>
231       * @return The current node used as the Body child.
232       * @apilevel low-level
233       */
234      public Block getBodyNoTransform() {
235        return (Block) getChildNoTransform(1);
236      }
237      /**
238       * @apilevel internal
239       */
240      protected java.util.Map remoteLookup_String_visited;
241      /**
242       * @attribute syn
243       * @aspect NameResolution
244       * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:62
245       */
246      public Decl remoteLookup(String name) {
247        Object _parameters = name;
248        if(remoteLookup_String_visited == null) remoteLookup_String_visited = new java.util.HashMap(4);
249        ASTNode$State state = state();
250        if (Integer.valueOf(state().boundariesCrossed).equals(remoteLookup_String_visited.get(_parameters))) {
251          throw new RuntimeException("Circular definition of attr: remoteLookup in class: org.jastadd.ast.AST.SynDecl");
252        }
253        remoteLookup_String_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
254        try {
255            // First, look in local declarations
256            if (!getBody().localLookup(name).isUnknown())
257              return getBody().localLookup(name); 
258            // Then, look in the superclass chain
259            if (superClass() != null && superClass().remoteLookup(name) != null 
260               && !superClass().remoteLookup(name).isUnknown())
261              return superClass().remoteLookup(name);
262            // Otherwise, return null object unknown
263            return unknownDecl();
264          }
265        finally {
266          remoteLookup_String_visited.remove(_parameters);
267        }
268      }
269      /**
270       * @apilevel internal
271       */
272      protected java.util.Map isSubtypeOf_TypeDecl_visited;
273      protected java.util.Map isSubtypeOf_TypeDecl_values;
274      /**
275       * @attribute syn
276       * @aspect TypeAnalysis
277       * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:44
278       */
279      public boolean isSubtypeOf(TypeDecl typeDecl) {
280        Object _parameters = typeDecl;
281        if(isSubtypeOf_TypeDecl_visited == null) isSubtypeOf_TypeDecl_visited = new java.util.HashMap(4);
282        if(isSubtypeOf_TypeDecl_values == null) isSubtypeOf_TypeDecl_values = new java.util.HashMap(4);
283        if(isSubtypeOf_TypeDecl_values.containsKey(_parameters)) {
284          return ((Boolean)isSubtypeOf_TypeDecl_values.get(_parameters)).booleanValue();
285        }
286        ASTNode$State state = state();
287        if (Integer.valueOf(state().boundariesCrossed).equals(isSubtypeOf_TypeDecl_visited.get(_parameters))) {
288          throw new RuntimeException("Circular definition of attr: isSubtypeOf in class: org.jastadd.ast.AST.SynDecl");
289        }
290        isSubtypeOf_TypeDecl_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
291        int num = state.boundariesCrossed;
292        boolean isFinal = this.is$Final();
293        boolean isSubtypeOf_TypeDecl_value = isSubtypeOf_compute(typeDecl);
294        if(isFinal && num == state().boundariesCrossed) {
295          isSubtypeOf_TypeDecl_values.put(_parameters, Boolean.valueOf(isSubtypeOf_TypeDecl_value));
296        } else {
297        }
298    
299        isSubtypeOf_TypeDecl_visited.remove(_parameters);
300        return isSubtypeOf_TypeDecl_value;
301      }
302      /**
303       * @apilevel internal
304       */
305      private boolean isSubtypeOf_compute(TypeDecl typeDecl) {  return typeDecl.isSuperTypeOfClassDecl(this);  }
306      /**
307       * @apilevel internal
308       */
309      protected int superClass_visited = -1;
310      /**
311       * @apilevel internal
312       */
313      protected boolean superClass_computed = false;
314      /**
315       * @apilevel internal
316       */
317      protected ClassDecl superClass_value;
318      /**
319       * @attribute syn
320       * @aspect TypeAnalysis
321       * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:51
322       */
323      public ClassDecl superClass() {
324        if(superClass_computed) {
325          return superClass_value;
326        }
327        ASTNode$State state = state();
328        if (superClass_visited == state().boundariesCrossed) {
329          throw new RuntimeException("Circular definition of attr: superClass in class: org.jastadd.ast.AST.SynDecl");
330        }
331        superClass_visited = state().boundariesCrossed;
332        int num = state.boundariesCrossed;
333        boolean isFinal = this.is$Final();
334        superClass_value = superClass_compute();
335        if(isFinal && num == state().boundariesCrossed) {
336          superClass_computed = true;
337        } else {
338        }
339    
340        superClass_visited = -1;
341        return superClass_value;
342      }
343      /**
344       * @apilevel internal
345       */
346      private ClassDecl superClass_compute() {
347          if (hasSuperclass() && getSuperclass().decl() instanceof ClassDecl && !hasCycleOnSuperclassChain())
348            return (ClassDecl) getSuperclass().decl();
349          else
350            return null;
351        }
352      /**
353       * @apilevel internal
354       */
355      protected int hasCycleOnSuperclassChain_visited = -1;
356      /**
357       * @apilevel internal
358       */
359      protected boolean hasCycleOnSuperclassChain_computed = false;
360      /**
361       * @apilevel internal
362       */
363      protected boolean hasCycleOnSuperclassChain_initialized = false;
364      /**
365       * @apilevel internal
366       */
367      protected boolean hasCycleOnSuperclassChain_value;
368      /**
369       * @attribute syn
370       * @aspect TypeAnalysis
371       * @declaredat /home/csz-naf/examples/PicoJava/spec/TypeAnalysis.jrag:59
372       */
373      public boolean hasCycleOnSuperclassChain() {
374        if(hasCycleOnSuperclassChain_computed) {
375          return hasCycleOnSuperclassChain_value;
376        }
377        ASTNode$State state = state();
378        if (!hasCycleOnSuperclassChain_initialized) {
379          hasCycleOnSuperclassChain_initialized = true;
380          hasCycleOnSuperclassChain_value = true;
381        }
382        if (!state.IN_CIRCLE) {
383          state.IN_CIRCLE = true;
384          int num = state.boundariesCrossed;
385          boolean isFinal = this.is$Final();
386          // TODO: fixme
387          // state().CIRCLE_INDEX = 1;
388          do {
389            hasCycleOnSuperclassChain_visited = state.CIRCLE_INDEX;
390            state.CHANGE = false;
391            boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute();
392            if (new_hasCycleOnSuperclassChain_value != hasCycleOnSuperclassChain_value) {
393              state.CHANGE = true;
394            }
395            hasCycleOnSuperclassChain_value = new_hasCycleOnSuperclassChain_value;
396            state.CIRCLE_INDEX++;
397          } while (state.CHANGE);
398          if(isFinal && num == state().boundariesCrossed) {
399            hasCycleOnSuperclassChain_computed = true;
400            state.LAST_CYCLE = true;
401            hasCycleOnSuperclassChain_compute();
402            state.LAST_CYCLE = false;
403          } else {
404            state.RESET_CYCLE = true;
405            hasCycleOnSuperclassChain_compute();
406            state.RESET_CYCLE = false;
407            hasCycleOnSuperclassChain_computed = false;
408            hasCycleOnSuperclassChain_initialized = false;
409          }
410          state.IN_CIRCLE = false;
411          return hasCycleOnSuperclassChain_value;
412        }
413        if(hasCycleOnSuperclassChain_visited != state.CIRCLE_INDEX) {
414          hasCycleOnSuperclassChain_visited = state.CIRCLE_INDEX;
415          if (state.LAST_CYCLE) {
416          hasCycleOnSuperclassChain_computed = true;
417            boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute();
418            return new_hasCycleOnSuperclassChain_value;
419          }
420          if (state.RESET_CYCLE) {
421            hasCycleOnSuperclassChain_computed = false;
422            hasCycleOnSuperclassChain_initialized = false;
423            hasCycleOnSuperclassChain_visited = -1;
424            return hasCycleOnSuperclassChain_value;
425          }
426          boolean new_hasCycleOnSuperclassChain_value = hasCycleOnSuperclassChain_compute();
427          if (new_hasCycleOnSuperclassChain_value != hasCycleOnSuperclassChain_value) {
428            state.CHANGE = true;
429          }
430          hasCycleOnSuperclassChain_value = new_hasCycleOnSuperclassChain_value;
431          return hasCycleOnSuperclassChain_value;
432        }
433        return hasCycleOnSuperclassChain_value;
434      }
435      /**
436       * @apilevel internal
437       */
438      private boolean hasCycleOnSuperclassChain_compute() {
439          if (hasSuperclass() && getSuperclass().decl() instanceof ClassDecl) //First, check if there is a superclass
440            return ((ClassDecl) getSuperclass().decl()).hasCycleOnSuperclassChain();
441          else
442            return false;
443        }
444      /**
445       * @apilevel internal
446       */
447      protected java.util.Map remoteLookupMethod_String_List_visited;
448      /**
449       * @attribute syn
450       * @aspect NameResolution
451       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/NameResolution.jrag:43
452       */
453      public Decl remoteLookupMethod(String name, List argList) {
454        java.util.List _parameters = new java.util.ArrayList(2);
455        _parameters.add(name);
456        _parameters.add(argList);
457        if(remoteLookupMethod_String_List_visited == null) remoteLookupMethod_String_List_visited = new java.util.HashMap(4);
458        ASTNode$State state = state();
459        if (Integer.valueOf(state().boundariesCrossed).equals(remoteLookupMethod_String_List_visited.get(_parameters))) {
460          throw new RuntimeException("Circular definition of attr: remoteLookupMethod in class: org.jastadd.ast.AST.SynDecl");
461        }
462        remoteLookupMethod_String_List_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
463        try {
464                   // First, look in local declarations
465               if (!getBody().localLookupMethod(name, argList).isUnknown())
466                       return getBody().localLookupMethod(name, argList); 
467                       // Then, look in the superclass chain
468               if (superClass() != null && 
469                       superClass().remoteLookupMethod(name, argList) != null && 
470                       !superClass().remoteLookupMethod(name, argList).isUnknown())
471                     return superClass().remoteLookupMethod(name, argList);
472                       return unknownDecl();
473               }
474        finally {
475          remoteLookupMethod_String_List_visited.remove(_parameters);
476        }
477      }
478      /**
479       * @attribute inh
480       * @aspect NameResolution
481       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/NameResolution.jrag:8
482       */
483      public Decl lookupMethod(String name, List argList) {
484        java.util.List _parameters = new java.util.ArrayList(2);
485        _parameters.add(name);
486        _parameters.add(argList);
487        if(lookupMethod_String_List_visited == null) lookupMethod_String_List_visited = new java.util.HashMap(4);
488        ASTNode$State state = state();
489        if (Integer.valueOf(state().boundariesCrossed).equals(lookupMethod_String_List_visited.get(_parameters))) {
490          throw new RuntimeException("Circular definition of attr: lookupMethod in class: org.jastadd.ast.AST.InhDecl");
491        }
492        lookupMethod_String_List_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
493        Decl lookupMethod_String_List_value = getParent().Define_Decl_lookupMethod(this, null, name, argList);
494    
495        lookupMethod_String_List_visited.remove(_parameters);
496        return lookupMethod_String_List_value;
497      }
498      /**
499       * @apilevel internal
500       */
501      protected java.util.Map lookupMethod_String_List_visited;
502      /**
503       * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:31
504       * @apilevel internal
505       */
506      public Decl Define_Decl_lookup(ASTNode caller, ASTNode child, String name) {
507        if (caller == getBodyNoTransform()){
508        // First, look in superclass chain
509        
510        // EMMA: alternative impl. for debugging
511        ClassDecl superClass = superClass();
512        if (superClass != null) {
513               Decl remoteDecl = ((TypeDecl)superClass).remoteLookup(name);
514               if (remoteDecl != null) {
515                       if (!remoteDecl.isUnknown()) 
516                               return remoteDecl;      
517               }
518        } 
519        return lookup(name);
520        
521        
522        /*
523        EMMA: old impl before debugging
524        if (superClass() != null && !superClass().remoteLookup(name).isUnknown())
525          return superClass().remoteLookup(name);
526        // Then, look in surrounding context
527        return lookup(name);
528        */
529      }
530        else {
531          return getParent().Define_Decl_lookup(this, caller, name);
532        }
533      }
534      /**
535       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/NameResolution.jrag:16
536       * @apilevel internal
537       */
538      public Decl Define_Decl_lookupMethod(ASTNode caller, ASTNode child, String name, List argList) {
539         {
540          int childIndex = this.getIndexOfChild(caller);
541    {
542               ClassDecl superClass = superClass();
543               if (superClass != null) {
544                       Decl remoteDecl = ((TypeDecl)superClass).remoteLookupMethod(name, argList);
545               if (remoteDecl != null && !remoteDecl.isUnknown()) {
546                                       return remoteDecl;      
547                       }
548               } 
549               return lookupMethod(name, argList);
550       }
551        }
552      }
553      /**
554       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/TypeAnalysis.jrag:9
555       * @apilevel internal
556       */
557      public ClassDecl Define_ClassDecl_enclosingClassDecl(ASTNode caller, ASTNode child) {
558        if (caller == getBodyNoTransform()) {
559          return this;
560        }
561        else {
562          return getParent().Define_ClassDecl_enclosingClassDecl(this, caller);
563        }
564      }
565      /**
566       * @apilevel internal
567       */
568      public ASTNode rewriteTo() {    return super.rewriteTo();
569      }}