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/PicoJavaMethods/spec/picojava-method.ast:2
010     * @production MethodDecl : {@link Decl} ::= <span class="component">Type:{@link Access}</span> <span class="component">{@link ParamDecl}*</span> <span class="component">Body:{@link Block}</span>;
011    
012     */
013    public class MethodDecl extends Decl implements Cloneable {
014      /**
015       * @apilevel internal
016       */
017      public MethodDecl clone() throws CloneNotSupportedException {
018        MethodDecl node = (MethodDecl) super.clone();
019        node.endsWithReturn_visited = -1;
020        node.declarationOf_String_List_visited = null;
021        node.declarationOf_String_List_values = null;
022        node.type_visited = -1;
023        node.type_computed = false;
024        node.type_value = null;
025        node.hasEnclosingClass_visited = -1;
026        node.enclosingClassDecl_visited = -1;
027        node.in$Circle(false);
028        node.is$Final(false);
029        return node;
030      }
031      /**
032       * @apilevel internal
033       */
034      public MethodDecl copy() {
035        try {
036          MethodDecl node = (MethodDecl) clone();
037          node.parent = null;
038          if(children != null) {
039            node.children = (ASTNode[]) children.clone();
040          }
041          return node;
042        } catch (CloneNotSupportedException e) {
043          throw new Error("Error: clone not supported for " + getClass().getName());
044        }
045      }
046      /**
047       * Create a deep copy of the AST subtree at this node.
048       * The copy is dangling, i.e. has no parent.
049       * @return dangling copy of the subtree at this node
050       * @apilevel low-level
051       */
052      public MethodDecl fullCopy() {
053        MethodDecl tree = (MethodDecl) copy();
054        if (children != null) {
055          for (int i = 0; i < children.length; ++i) {
056            ASTNode child = (ASTNode) children[i];
057            if(child != null) {
058              child = child.fullCopy();
059              tree.setChild(child, i);
060            }
061          }
062        }
063        return tree;
064      }
065      /**
066       * @aspect ErrorCheck
067       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/ErrorCheck.jrag:5
068       */
069      public void collectErrors(Collection c) {
070        super.collectErrors(c);
071        if(!endsWithReturn())
072          error(c, "Missing return in method " + getName());
073      }
074      /**
075       * @aspect PrettyPrint
076       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/PrettyPrint.jadd:2
077       */
078      public void prettyPrint(StringBuilder sb, int t) {
079                sb.append(getIndent(t)).append(getType()).append(" ").append(getName()).append("(");
080                boolean first = true;
081                for (ParamDecl p: getParamDecls()) {
082                        if (!first) {
083                                sb.append(", ");
084                        }
085                        first = false;
086                        sb.append(p.getType()).append(" ").append(p.getName());
087                }
088                sb.append(") ");
089                getBody().prettyPrint(sb, t);
090        }
091      /**
092       */
093      public MethodDecl() {
094        super();
095      }
096      /**
097       * Initializes the child array to the correct size.
098       * Initializes List and Opt nta children.
099       * @apilevel internal
100       * @ast method
101       */
102      public void init$Children() {
103        children = new ASTNode[3];
104        setChild(new List(), 1);
105      }
106      /**
107       */
108      public MethodDecl(String p0, Access p1, List<ParamDecl> p2, Block p3) {
109        setName(p0);
110        setChild(p1, 0);
111        setChild(p2, 1);
112        setChild(p3, 2);
113      }
114      /**
115       * @apilevel low-level
116       */
117      protected int numChildren() {
118        return 3;
119      }
120      /**
121       * @apilevel internal
122       */
123      public boolean mayHaveRewrite() {
124        return false;
125      }
126      /**
127       * @apilevel low-level
128       */
129      public void flushCache() {
130        super.flushCache();
131        endsWithReturn_visited = -1;
132        declarationOf_String_List_visited = null;
133        declarationOf_String_List_values = null;
134        type_visited = -1;
135        type_computed = false;
136        type_value = null;
137        hasEnclosingClass_visited = -1;
138        enclosingClassDecl_visited = -1;
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 Type child.
164       * @param node The new node to replace the Type child.
165       * @apilevel high-level
166       */
167      public void setType(Access node) {
168        setChild(node, 0);
169      }
170      /**
171       * Retrieves the Type child.
172       * @return The current node used as the Type child.
173       * @apilevel high-level
174       */
175      public Access getType() {
176        return (Access) getChild(0);
177      }
178      /**
179       * Retrieves the Type child.
180       * <p><em>This method does not invoke AST transformations.</em></p>
181       * @return The current node used as the Type child.
182       * @apilevel low-level
183       */
184      public Access getTypeNoTransform() {
185        return (Access) getChildNoTransform(0);
186      }
187      /**
188       * Replaces the ParamDecl list.
189       * @param list The new list node to be used as the ParamDecl list.
190       * @apilevel high-level
191       */
192      public void setParamDeclList(List<ParamDecl> list) {
193        setChild(list, 1);
194      }
195      /**
196       * Retrieves the number of children in the ParamDecl list.
197       * @return Number of children in the ParamDecl list.
198       * @apilevel high-level
199       */
200      public int getNumParamDecl() {
201        return getParamDeclList().getNumChild();
202      }
203      /**
204       * Retrieves the number of children in the ParamDecl list.
205       * Calling this method will not trigger rewrites.
206       * @return Number of children in the ParamDecl list.
207       * @apilevel low-level
208       */
209      public int getNumParamDeclNoTransform() {
210        return getParamDeclListNoTransform().getNumChildNoTransform();
211      }
212      /**
213       * Retrieves the element at index {@code i} in the ParamDecl list.
214       * @param i Index of the element to return.
215       * @return The element at position {@code i} in the ParamDecl list.
216       * @apilevel high-level
217       */
218      public ParamDecl getParamDecl(int i) {
219        return (ParamDecl) getParamDeclList().getChild(i);
220      }
221      /**
222       * Check whether the ParamDecl list has any children.
223       * @return {@code true} if it has at least one child, {@code false} otherwise.
224       * @apilevel high-level
225       */
226      public boolean hasParamDecl() {
227        return getParamDeclList().getNumChild() != 0;
228      }
229      /**
230       * Append an element to the ParamDecl list.
231       * @param node The element to append to the ParamDecl list.
232       * @apilevel high-level
233       */
234      public void addParamDecl(ParamDecl node) {
235        List<ParamDecl> list = (parent == null || state == null) ? getParamDeclListNoTransform() : getParamDeclList();
236        list.addChild(node);
237      }
238      /**
239       * @apilevel low-level
240       */
241      public void addParamDeclNoTransform(ParamDecl node) {
242        List<ParamDecl> list = getParamDeclListNoTransform();
243        list.addChild(node);
244      }
245      /**
246       * Replaces the ParamDecl list element at index {@code i} with the new node {@code node}.
247       * @param node The new node to replace the old list element.
248       * @param i The list index of the node to be replaced.
249       * @apilevel high-level
250       */
251      public void setParamDecl(ParamDecl node, int i) {
252        List<ParamDecl> list = getParamDeclList();
253        list.setChild(node, i);
254      }
255      /**
256       * Retrieves the ParamDecl list.
257       * @return The node representing the ParamDecl list.
258       * @apilevel high-level
259       */
260      public List<ParamDecl> getParamDeclList() {
261        List<ParamDecl> list = (List<ParamDecl>) getChild(1);
262        list.getNumChild();
263        return list;
264      }
265      /**
266       * Retrieves the ParamDecl list.
267       * <p><em>This method does not invoke AST transformations.</em></p>
268       * @return The node representing the ParamDecl list.
269       * @apilevel low-level
270       */
271      public List<ParamDecl> getParamDeclListNoTransform() {
272        return (List<ParamDecl>) getChildNoTransform(1);
273      }
274      /**
275       * Retrieves the ParamDecl list.
276       * @return The node representing the ParamDecl list.
277       * @apilevel high-level
278       */
279      public List<ParamDecl> getParamDecls() {
280        return getParamDeclList();
281      }
282      /**
283       * Retrieves the ParamDecl list.
284       * <p><em>This method does not invoke AST transformations.</em></p>
285       * @return The node representing the ParamDecl list.
286       * @apilevel low-level
287       */
288      public List<ParamDecl> getParamDeclsNoTransform() {
289        return getParamDeclListNoTransform();
290      }
291      /**
292       * Replaces the Body child.
293       * @param node The new node to replace the Body child.
294       * @apilevel high-level
295       */
296      public void setBody(Block node) {
297        setChild(node, 2);
298      }
299      /**
300       * Retrieves the Body child.
301       * @return The current node used as the Body child.
302       * @apilevel high-level
303       */
304      public Block getBody() {
305        return (Block) getChild(2);
306      }
307      /**
308       * Retrieves the Body child.
309       * <p><em>This method does not invoke AST transformations.</em></p>
310       * @return The current node used as the Body child.
311       * @apilevel low-level
312       */
313      public Block getBodyNoTransform() {
314        return (Block) getChildNoTransform(2);
315      }
316      /**
317       * @apilevel internal
318       */
319      protected int endsWithReturn_visited = -1;
320      /**
321       * @attribute syn
322       * @aspect ErrorCheck
323       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/ErrorCheck.jrag:11
324       */
325      public boolean endsWithReturn() {
326        ASTNode$State state = state();
327        if (endsWithReturn_visited == state().boundariesCrossed) {
328          throw new RuntimeException("Circular definition of attr: endsWithReturn in class: org.jastadd.ast.AST.SynDecl");
329        }
330        endsWithReturn_visited = state().boundariesCrossed;
331        try {  return getBody().endsWithReturn();  }
332        finally {
333          endsWithReturn_visited = -1;
334        }
335      }
336      /**
337       * @apilevel internal
338       */
339      protected java.util.Map declarationOf_String_List_visited;
340      protected java.util.Map declarationOf_String_List_values;
341      /**
342       * @attribute syn
343       * @aspect NameResolution
344       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/NameResolution.jrag:58
345       */
346      public Decl declarationOf(String name, List argList) {
347        java.util.List _parameters = new java.util.ArrayList(2);
348        _parameters.add(name);
349        _parameters.add(argList);
350        if(declarationOf_String_List_visited == null) declarationOf_String_List_visited = new java.util.HashMap(4);
351        if(declarationOf_String_List_values == null) declarationOf_String_List_values = new java.util.HashMap(4);
352        if(declarationOf_String_List_values.containsKey(_parameters)) {
353          return (Decl)declarationOf_String_List_values.get(_parameters);
354        }
355        ASTNode$State state = state();
356        if (Integer.valueOf(state().boundariesCrossed).equals(declarationOf_String_List_visited.get(_parameters))) {
357          throw new RuntimeException("Circular definition of attr: declarationOf in class: org.jastadd.ast.AST.SynDecl");
358        }
359        declarationOf_String_List_visited.put(_parameters, Integer.valueOf(state().boundariesCrossed));
360        int num = state.boundariesCrossed;
361        boolean isFinal = this.is$Final();
362        Decl declarationOf_String_List_value = declarationOf_compute(name, argList);
363        if(isFinal && num == state().boundariesCrossed) {
364          declarationOf_String_List_values.put(_parameters, declarationOf_String_List_value);
365        } else {
366        }
367    
368        declarationOf_String_List_visited.remove(_parameters);
369        return declarationOf_String_List_value;
370      }
371      /**
372       * @apilevel internal
373       */
374      private Decl declarationOf_compute(String name, List argList) {
375               if (!getName().equals(name) || 
376                       getNumParamDecl() != argList.getNumChild()) {
377                       return null;
378               }
379               for (int i = 0; i < getNumParamDecl(); i++) {
380                       if (getParamDecl(i).type() != ((Exp)argList.getChild(i)).type()) {
381                               return null;
382                       }
383               }
384               return this;
385       }
386      /**
387       * @apilevel internal
388       */
389      protected int type_visited = -1;
390      /**
391       * @apilevel internal
392       */
393      protected boolean type_computed = false;
394      /**
395       * @apilevel internal
396       */
397      protected TypeDecl type_value;
398      /**
399       * @attribute syn
400       * @aspect TypeAnalysis
401       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/TypeAnalysis.jrag:4
402       */
403      public TypeDecl type() {
404        if(type_computed) {
405          return type_value;
406        }
407        ASTNode$State state = state();
408        if (type_visited == state().boundariesCrossed) {
409          throw new RuntimeException("Circular definition of attr: type in class: org.jastadd.ast.AST.SynDecl");
410        }
411        type_visited = state().boundariesCrossed;
412        int num = state.boundariesCrossed;
413        boolean isFinal = this.is$Final();
414        type_value = type_compute();
415        if(isFinal && num == state().boundariesCrossed) {
416          type_computed = true;
417        } else {
418        }
419    
420        type_visited = -1;
421        return type_value;
422      }
423      /**
424       * @apilevel internal
425       */
426      private TypeDecl type_compute() {  return getType().decl().type();  }
427      /**
428       * @apilevel internal
429       */
430      protected int hasEnclosingClass_visited = -1;
431      /**
432       * @attribute syn
433       * @aspect TypeAnalysis
434       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/TypeAnalysis.jrag:11
435       */
436      public boolean hasEnclosingClass() {
437        ASTNode$State state = state();
438        if (hasEnclosingClass_visited == state().boundariesCrossed) {
439          throw new RuntimeException("Circular definition of attr: hasEnclosingClass in class: org.jastadd.ast.AST.SynDecl");
440        }
441        hasEnclosingClass_visited = state().boundariesCrossed;
442        try {  return enclosingClassDecl() != null;  }
443        finally {
444          hasEnclosingClass_visited = -1;
445        }
446      }
447      /**
448       * @attribute inh
449       * @aspect TypeAnalysis
450       * @declaredat /home/csz-naf/examples/PicoJavaMethods/spec/TypeAnalysis.jrag:8
451       */
452      public ClassDecl enclosingClassDecl() {
453        ASTNode$State state = state();
454        if (enclosingClassDecl_visited == state().boundariesCrossed) {
455          throw new RuntimeException("Circular definition of attr: enclosingClassDecl in class: org.jastadd.ast.AST.InhDecl");
456        }
457        enclosingClassDecl_visited = state().boundariesCrossed;
458        ClassDecl enclosingClassDecl_value = getParent().Define_ClassDecl_enclosingClassDecl(this, null);
459    
460        enclosingClassDecl_visited = -1;
461        return enclosingClassDecl_value;
462      }
463      /**
464       * @apilevel internal
465       */
466      protected int enclosingClassDecl_visited = -1;
467      /**
468       * @apilevel internal
469       */
470      public ASTNode rewriteTo() {    return super.rewriteTo();
471      }}