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:2
010     * @production Program : {@link ASTNode} ::= <span class="component">{@link Block}</span> <span class="component">PredefinedType:{@link TypeDecl}*</span>;
011    
012     */
013    public class Program extends ASTNode<ASTNode> implements Cloneable {
014      /**
015       * @apilevel internal
016       */
017      public Program clone() throws CloneNotSupportedException {
018        Program node = (Program) super.clone();
019        node.errors_visited = -1;
020        node.errors_computed = false;
021        node.errors_value = null;
022        node.localLookup_String_visited = null;
023        node.localLookup_String_values = null;
024        node.unknownDecl_visited = -1;
025        node.unknownDecl_computed = false;
026        node.unknownDecl_value = null;
027        node.getPredefinedTypeList_visited = -1;
028        node.getPredefinedTypeList_computed = false;
029        node.getPredefinedTypeList_value = null;
030        node.booleanType_visited = -1;
031        node.booleanType_computed = false;
032        node.booleanType_value = null;
033        node.in$Circle(false);
034        node.is$Final(false);
035        return node;
036      }
037      /**
038       * @apilevel internal
039       */
040      public Program copy() {
041        try {
042          Program node = (Program) clone();
043          node.parent = null;
044          if(children != null) {
045            node.children = (ASTNode[]) children.clone();
046          }
047          return node;
048        } catch (CloneNotSupportedException e) {
049          throw new Error("Error: clone not supported for " + getClass().getName());
050        }
051      }
052      /**
053       * Create a deep copy of the AST subtree at this node.
054       * The copy is dangling, i.e. has no parent.
055       * @return dangling copy of the subtree at this node
056       * @apilevel low-level
057       */
058      public Program fullCopy() {
059        Program tree = (Program) copy();
060        if (children != null) {
061          for (int i = 0; i < children.length; ++i) {
062            switch (i) {
063            case 1:
064              tree.children[i] = new List();
065              continue;
066            }
067            ASTNode child = (ASTNode) children[i];
068            if(child != null) {
069              child = child.fullCopy();
070              tree.setChild(child, i);
071            }
072          }
073        }
074        return tree;
075      }
076      /**
077       * Pretty print 
078       * @aspect PrettyPrint
079       * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:26
080       */
081      public String prettyPrint() {
082                StringBuilder sb = new StringBuilder();
083                getBlock().prettyPrint(sb, 0);
084                return sb.toString();
085        }
086      /**
087       */
088      public Program() {
089        super();
090        is$Final(true);
091      }
092      /**
093       * Initializes the child array to the correct size.
094       * Initializes List and Opt nta children.
095       * @apilevel internal
096       * @ast method
097       */
098      public void init$Children() {
099        children = new ASTNode[2];
100        setChild(new List(), 1);
101      }
102      /**
103       */
104      public Program(Block p0) {
105        setChild(p0, 0);
106        is$Final(true);
107      }
108      /**
109       * @apilevel low-level
110       */
111      protected int numChildren() {
112        return 1;
113      }
114      /**
115       * @apilevel internal
116       */
117      public boolean mayHaveRewrite() {
118        return false;
119      }
120      /**
121       * @apilevel low-level
122       */
123      public void flushCache() {
124        super.flushCache();
125        errors_visited = -1;
126        errors_computed = false;
127        errors_value = null;
128        localLookup_String_visited = null;
129        localLookup_String_values = null;
130        unknownDecl_visited = -1;
131        unknownDecl_computed = false;
132        unknownDecl_value = null;
133        getPredefinedTypeList_visited = -1;
134        getPredefinedTypeList_computed = false;
135        getPredefinedTypeList_value = null;
136        booleanType_visited = -1;
137        booleanType_computed = false;
138        booleanType_value = null;
139      }
140      /**
141       * @apilevel internal
142       */
143      public void flushCollectionCache() {
144        super.flushCollectionCache();
145      }
146      /**
147       * Replaces the Block child.
148       * @param node The new node to replace the Block child.
149       * @apilevel high-level
150       */
151      public void setBlock(Block node) {
152        setChild(node, 0);
153      }
154      /**
155       * Retrieves the Block child.
156       * @return The current node used as the Block child.
157       * @apilevel high-level
158       */
159      public Block getBlock() {
160        return (Block) getChild(0);
161      }
162      /**
163       * Retrieves the Block child.
164       * <p><em>This method does not invoke AST transformations.</em></p>
165       * @return The current node used as the Block child.
166       * @apilevel low-level
167       */
168      public Block getBlockNoTransform() {
169        return (Block) getChildNoTransform(0);
170      }
171      /**
172       * Replaces the PredefinedType list.
173       * @param list The new list node to be used as the PredefinedType list.
174       * @apilevel high-level
175       */
176      public void setPredefinedTypeList(List<TypeDecl> list) {
177        setChild(list, 1);
178      }
179      /**
180       * Retrieves the number of children in the PredefinedType list.
181       * @return Number of children in the PredefinedType list.
182       * @apilevel high-level
183       */
184      public int getNumPredefinedType() {
185        return getPredefinedTypeList().getNumChild();
186      }
187      /**
188       * Retrieves the number of children in the PredefinedType list.
189       * Calling this method will not trigger rewrites.
190       * @return Number of children in the PredefinedType list.
191       * @apilevel low-level
192       */
193      public int getNumPredefinedTypeNoTransform() {
194        return getPredefinedTypeListNoTransform().getNumChildNoTransform();
195      }
196      /**
197       * Retrieves the element at index {@code i} in the PredefinedType list.
198       * @param i Index of the element to return.
199       * @return The element at position {@code i} in the PredefinedType list.
200       * @apilevel high-level
201       */
202      public TypeDecl getPredefinedType(int i) {
203        return (TypeDecl) getPredefinedTypeList().getChild(i);
204      }
205      /**
206       * Check whether the PredefinedType list has any children.
207       * @return {@code true} if it has at least one child, {@code false} otherwise.
208       * @apilevel high-level
209       */
210      public boolean hasPredefinedType() {
211        return getPredefinedTypeList().getNumChild() != 0;
212      }
213      /**
214       * Append an element to the PredefinedType list.
215       * @param node The element to append to the PredefinedType list.
216       * @apilevel high-level
217       */
218      public void addPredefinedType(TypeDecl node) {
219        List<TypeDecl> list = (parent == null || state == null) ? getPredefinedTypeListNoTransform() : getPredefinedTypeList();
220        list.addChild(node);
221      }
222      /**
223       * @apilevel low-level
224       */
225      public void addPredefinedTypeNoTransform(TypeDecl node) {
226        List<TypeDecl> list = getPredefinedTypeListNoTransform();
227        list.addChild(node);
228      }
229      /**
230       * Replaces the PredefinedType list element at index {@code i} with the new node {@code node}.
231       * @param node The new node to replace the old list element.
232       * @param i The list index of the node to be replaced.
233       * @apilevel high-level
234       */
235      public void setPredefinedType(TypeDecl node, int i) {
236        List<TypeDecl> list = getPredefinedTypeList();
237        list.setChild(node, i);
238      }
239      /**
240       * Retrieves the child position of the PredefinedType list.
241       * @return The the child position of the PredefinedType list.
242       * @apilevel low-level
243       */
244      protected int getPredefinedTypeListChildPosition() {
245        return 1;
246      }
247      /**
248       * Retrieves the PredefinedType list.
249       * <p><em>This method does not invoke AST transformations.</em></p>
250       * @return The node representing the PredefinedType list.
251       * @apilevel low-level
252       */
253      public List<TypeDecl> getPredefinedTypeListNoTransform() {
254        return (List<TypeDecl>) getChildNoTransform(1);
255      }
256      /**
257       * Retrieves the PredefinedType list.
258       * @return The node representing the PredefinedType list.
259       * @apilevel high-level
260       */
261      public List<TypeDecl> getPredefinedTypes() {
262        return getPredefinedTypeList();
263      }
264      /**
265       * Retrieves the PredefinedType list.
266       * <p><em>This method does not invoke AST transformations.</em></p>
267       * @return The node representing the PredefinedType list.
268       * @apilevel low-level
269       */
270      public List<TypeDecl> getPredefinedTypesNoTransform() {
271        return getPredefinedTypeListNoTransform();
272      }
273      /**
274       * @apilevel internal
275       */
276      protected int errors_visited = -1;
277      /**
278       * @apilevel internal
279       */
280      protected boolean errors_computed = false;
281      /**
282       * @apilevel internal
283       */
284      protected Collection errors_value;
285      /**
286       * @attribute syn
287       * @aspect ErrorCheck
288       * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:5
289       */
290      public Collection errors() {
291        if(errors_computed) {
292          return errors_value;
293        }
294        ASTNode$State state = state();
295        if (errors_visited == state().boundariesCrossed) {
296          throw new RuntimeException("Circular definition of attr: errors in class: org.jastadd.ast.AST.SynDecl");
297        }
298        errors_visited = state().boundariesCrossed;
299        int num = state.boundariesCrossed;
300        boolean isFinal = this.is$Final();
301        errors_value = errors_compute();
302        if(isFinal && num == state().boundariesCrossed) {
303          errors_computed = true;
304        } else {
305        }
306    
307        errors_visited = -1;
308        return errors_value;
309      }
310      /**
311       * @apilevel internal
312       */
313      private Collection errors_compute() {
314          Collection c = new ArrayList();
315          collectErrors(c);
316          return c;
317        }
318      /**
319       * @apilevel internal
320       */
321      protected java.util.Map localLookup_String_visited;
322      protected java.util.Map localLookup_String_values;
323      /**
324       * @attribute syn
325       * @aspect NameResolution
326       * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:92
327       */
328      public Decl localLookup(String name) {
329        Object _parameters = name;
330        if(localLookup_String_visited == null) localLookup_String_visited = new java.util.HashMap(4);
331        if(localLookup_String_values == null) localLookup_String_values = new java.util.HashMap(4);
332        if(localLookup_String_values.containsKey(_parameters)) {
333          return (Decl)localLookup_String_values.get(_parameters);
334        }
335        ASTNode$State state = state();
336        if (Integer.valueOf(state().boundariesCrossed).equals(localLookup_String_visited.get(_parameters))) {
337          throw new RuntimeException("Circular definition of attr: localLookup in class: org.jastadd.ast.AST.SynDecl");
338        }
339        localLookup_String_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
340        int num = state.boundariesCrossed;
341        boolean isFinal = this.is$Final();
342        Decl localLookup_String_value = localLookup_compute(name);
343        if(isFinal && num == state().boundariesCrossed) {
344          localLookup_String_values.put(_parameters, localLookup_String_value);
345        } else {
346        }
347    
348        localLookup_String_visited.remove(_parameters);
349        return localLookup_String_value;
350      }
351      /**
352       * @apilevel internal
353       */
354      private Decl localLookup_compute(String name) {
355          for (int k = 0; k < getNumPredefinedType(); k++) {
356            Decl d = getPredefinedType(k).declarationOf(name);
357            if (d != null) return d;
358          }
359          return unknownDecl();
360        }
361      /**
362       * @apilevel internal
363       */
364      protected int unknownDecl_visited = -1;
365      /**
366       * @apilevel internal
367       */
368      protected boolean unknownDecl_computed = false;
369      /**
370       * @apilevel internal
371       */
372      protected UnknownDecl unknownDecl_value;
373      /**
374       * @attribute syn
375       * @aspect NullObjects
376       * @declaredat /home/csz-naf/examples/PicoJava/spec/NullObjects.jrag:16
377       */
378      public UnknownDecl unknownDecl() {
379        if(unknownDecl_computed) {
380          return unknownDecl_value;
381        }
382        ASTNode$State state = state();
383        if (unknownDecl_visited == state().boundariesCrossed) {
384          throw new RuntimeException("Circular definition of attr: unknownDecl in class: org.jastadd.ast.AST.SynDecl");
385        }
386        unknownDecl_visited = state().boundariesCrossed;
387        int num = state.boundariesCrossed;
388        boolean isFinal = this.is$Final();
389        unknownDecl_value = unknownDecl_compute();
390        if(isFinal && num == state().boundariesCrossed) {
391          unknownDecl_computed = true;
392        } else {
393        }
394    
395        unknownDecl_visited = -1;
396        return unknownDecl_value;
397      }
398      /**
399       * @apilevel internal
400       */
401      private UnknownDecl unknownDecl_compute() {  return (UnknownDecl) localLookup("$unknown");  }
402      /**
403       * @apilevel internal
404       */
405      protected int getPredefinedTypeList_visited = -1;
406      /**
407       * @apilevel internal
408       */
409      protected boolean getPredefinedTypeList_computed = false;
410      /**
411       * @apilevel internal
412       */
413      protected List getPredefinedTypeList_value;
414      /**
415       * @attribute syn nta
416       * @aspect PredefinedTypes
417       * @declaredat /home/csz-naf/examples/PicoJava/spec/PredefinedTypes.jrag:3
418       */
419      public List getPredefinedTypeList() {
420        if(getPredefinedTypeList_computed) {
421          return (List) getChild(getPredefinedTypeListChildPosition());
422        }
423        if(getPredefinedTypeList_computed) {
424          return getPredefinedTypeList_value;
425        }
426        ASTNode$State state = state();
427        if (getPredefinedTypeList_visited == state().boundariesCrossed) {
428          throw new RuntimeException("Circular definition of attr: getPredefinedTypeList in class: org.jastadd.ast.AST.SynDecl");
429        }
430        getPredefinedTypeList_visited = state().boundariesCrossed;
431        int num = state.boundariesCrossed;
432        boolean isFinal = this.is$Final();
433        getPredefinedTypeList_value = getPredefinedTypeList_compute();
434        setPredefinedTypeList(getPredefinedTypeList_value);
435        if(isFinal && num == state().boundariesCrossed) {
436          getPredefinedTypeList_computed = true;
437        } else {
438        }
439    
440        getPredefinedTypeList_visited = -1;
441        List node = (List) this.getChild(getPredefinedTypeListChildPosition());
442        return node;
443      }
444      /**
445       * @apilevel internal
446       */
447      private List getPredefinedTypeList_compute() {
448        return new List().
449          add(new UnknownDecl("$unknown")).
450          add(new PrimitiveDecl("boolean"));
451        }
452      /**
453       * @apilevel internal
454       */
455      protected int booleanType_visited = -1;
456      /**
457       * @apilevel internal
458       */
459      protected boolean booleanType_computed = false;
460      /**
461       * @apilevel internal
462       */
463      protected PrimitiveDecl booleanType_value;
464      /**
465       * @attribute syn
466       * @aspect PredefinedTypes
467       * @declaredat /home/csz-naf/examples/PicoJava/spec/PredefinedTypes.jrag:10
468       */
469      public PrimitiveDecl booleanType() {
470        if(booleanType_computed) {
471          return booleanType_value;
472        }
473        ASTNode$State state = state();
474        if (booleanType_visited == state().boundariesCrossed) {
475          throw new RuntimeException("Circular definition of attr: booleanType in class: org.jastadd.ast.AST.SynDecl");
476        }
477        booleanType_visited = state().boundariesCrossed;
478        int num = state.boundariesCrossed;
479        boolean isFinal = this.is$Final();
480        booleanType_value = booleanType_compute();
481        if(isFinal && num == state().boundariesCrossed) {
482          booleanType_computed = true;
483        } else {
484        }
485    
486        booleanType_visited = -1;
487        return booleanType_value;
488      }
489      /**
490       * @apilevel internal
491       */
492      private PrimitiveDecl booleanType_compute() {  return (PrimitiveDecl) localLookup("boolean");  }
493      /**
494       * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:56
495       * @apilevel internal
496       */
497      public boolean Define_boolean_isQualified(ASTNode caller, ASTNode child) {
498        if (caller == getPredefinedTypeListNoTransform()) {
499          int i = caller.getIndexOfChild(child);
500          return false;
501        }
502        else if (caller == getBlockNoTransform()) {
503          return false;
504        }
505        else {
506          return getParent().Define_boolean_isQualified(this, caller);
507        }
508      }
509      /**
510       * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:64
511       * @apilevel internal
512       */
513      public Access Define_Access_qualifier(ASTNode caller, ASTNode child) {
514        if (caller == getPredefinedTypeListNoTransform()) {
515          int i = caller.getIndexOfChild(child);
516          {
517        throw new Error("Can not compute qualifier for non qualified names");
518      }
519        }
520        else if (caller == getBlockNoTransform()){
521        throw new Error("Can not compute qualifier for non qualified names");
522      }
523        else {
524          return getParent().Define_Access_qualifier(this, caller);
525        }
526      }
527      /**
528       * @declaredat /home/csz-naf/examples/PicoJava/spec/NameResolution.jrag:21
529       * @apilevel internal
530       */
531      public Decl Define_Decl_lookup(ASTNode caller, ASTNode child, String name) {
532        if (caller == getPredefinedTypeListNoTransform()) {
533          int index = caller.getIndexOfChild(child);
534          return unknownDecl();
535        }
536        else if (caller == getBlockNoTransform()) {
537          return localLookup(name);
538        }
539        else {
540          return getParent().Define_Decl_lookup(this, caller, name);
541        }
542      }
543      /**
544       * @declaredat /home/csz-naf/examples/PicoJava/spec/NullObjects.jrag:18
545       * @apilevel internal
546       */
547      public Decl Define_Decl_unknownDecl(ASTNode caller, ASTNode child) {
548        if (caller == getPredefinedTypeListNoTransform()) {
549          int childIndex = caller.getIndexOfChild(child);
550          return unknownDecl();
551        }
552        else if (caller == getBlockNoTransform()) {
553          return unknownDecl();
554        }
555        else {
556          return getParent().Define_Decl_unknownDecl(this, caller);
557        }
558      }
559      /**
560       * @declaredat /home/csz-naf/examples/PicoJava/spec/PredefinedTypes.jrag:12
561       * @apilevel internal
562       */
563      public PrimitiveDecl Define_PrimitiveDecl_booleanType(ASTNode caller, ASTNode child) {
564        if (caller == getPredefinedTypeListNoTransform()) {
565          int childIndex = caller.getIndexOfChild(child);
566          return booleanType();
567        }
568        else if (caller == getBlockNoTransform()) {
569          return booleanType();
570        }
571        else {
572          return getParent().Define_PrimitiveDecl_booleanType(this, caller);
573        }
574      }
575      /**
576       * @apilevel internal
577       */
578      public ASTNode rewriteTo() {    return super.rewriteTo();
579      }}