001    /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */
002    package org.extendj.ast;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.Set;
007    import java.util.Collections;
008    import java.util.Collection;
009    import java.util.ArrayList;
010    import beaver.*;
011    import java.util.*;
012    import java.io.ByteArrayOutputStream;
013    import java.io.PrintStream;
014    import java.lang.reflect.InvocationTargetException;
015    import java.lang.reflect.Method;
016    import org.jastadd.util.*;
017    import java.util.zip.*;
018    import java.io.*;
019    import org.jastadd.util.PrettyPrintable;
020    import org.jastadd.util.PrettyPrinter;
021    import java.io.FileNotFoundException;
022    import java.io.BufferedInputStream;
023    import java.io.DataInputStream;
024    /**
025     * A catch clause that can catch a multiple exception types.
026     * @ast node
027     * @declaredat /home/jesper/git/extendj/java7/grammar/MultiCatch.ast:14
028     * @production MultiCatch : {@link CatchClause} ::= <span class="component">Parameter:{@link CatchParameterDeclaration}</span> <span class="component">{@link Block}</span>;
029    
030     */
031    public class MultiCatch extends CatchClause implements Cloneable {
032      /**
033       * @aspect PreciseRethrow
034       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:293
035       */
036      void checkUnreachableStmt() {
037        if (!getBlock().reachable() && reportUnreachable()) {
038          errorf("the exception %s is not thrown in the body of the try statement",
039              getParameter().type().fullName());
040        }
041      }
042      /**
043       * @aspect Java7PrettyPrint
044       * @declaredat /home/jesper/git/extendj/java7/frontend/PrettyPrint.jadd:75
045       */
046      public void prettyPrint(PrettyPrinter out) {
047        out.print("catch (");
048        out.print(getParameter());
049        out.print(") ");
050        out.print(getBlock());
051      }
052      /**
053       * The Multi-Catch clause has two or more exception table entries
054       * which all point to the same exception handler.
055       * @aspect MultiCatch
056       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:37
057       */
058      public void exceptionTableEntries(CodeGeneration gen, int begin_lbl, int end_lbl) {
059        for (int i = 0; i < getParameter().getNumTypeAccess(); ++i) {
060          TypeDecl type = getParameter().getTypeAccess(i).type();
061    
062          gen.addException(
063            begin_lbl,
064            end_lbl,
065            label(),
066            gen.constantPool().addClass(type.constantPoolName())
067            );
068        }
069      }
070      /**
071       * Code gen.
072       * @aspect MultiCatch
073       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:53
074       */
075      public void createBCode(CodeGeneration gen) {
076        gen.addLabel(label());
077        // add 1 to stack depth
078        gen.changeStackDepth(1);
079        getParameter().type().emitStoreLocal(gen, localNum());
080        getBlock().createBCode(gen);
081      }
082      /**
083       * @declaredat ASTNode:1
084       */
085      public MultiCatch() {
086        super();
087      }
088      /**
089       * Initializes the child array to the correct size.
090       * Initializes List and Opt nta children.
091       * @apilevel internal
092       * @ast method
093       * @declaredat ASTNode:10
094       */
095      public void init$Children() {
096        children = new ASTNode[2];
097      }
098      /**
099       * @declaredat ASTNode:13
100       */
101      public MultiCatch(CatchParameterDeclaration p0, Block p1) {
102        setChild(p0, 0);
103        setChild(p1, 1);
104      }
105      /**
106       * @apilevel low-level
107       * @declaredat ASTNode:20
108       */
109      protected int numChildren() {
110        return 2;
111      }
112      /**
113       * @apilevel internal
114       * @declaredat ASTNode:26
115       */
116      public boolean mayHaveRewrite() {
117        return false;
118      }
119      /**
120       * @apilevel internal
121       * @declaredat ASTNode:32
122       */
123      public void flushAttrCache() {
124        super.flushAttrCache();
125        parameterDeclaration_String_reset();
126        localNum_reset();
127      }
128      /**
129       * @apilevel internal
130       * @declaredat ASTNode:40
131       */
132      public void flushCollectionCache() {
133        super.flushCollectionCache();
134      }
135      /**
136       * @apilevel internal
137       * @declaredat ASTNode:46
138       */
139      public void flushRewriteCache() {
140        super.flushRewriteCache();
141      }
142      /**
143       * @apilevel internal
144       * @declaredat ASTNode:52
145       */
146      public MultiCatch clone() throws CloneNotSupportedException {
147        MultiCatch node = (MultiCatch) super.clone();
148        return node;
149      }
150      /**
151       * @apilevel internal
152       * @declaredat ASTNode:59
153       */
154      public MultiCatch copy() {
155        try {
156          MultiCatch node = (MultiCatch) clone();
157          node.parent = null;
158          if (children != null) {
159            node.children = (ASTNode[]) children.clone();
160          }
161          return node;
162        } catch (CloneNotSupportedException e) {
163          throw new Error("Error: clone not supported for " + getClass().getName());
164        }
165      }
166      /**
167       * Create a deep copy of the AST subtree at this node.
168       * The copy is dangling, i.e. has no parent.
169       * @return dangling copy of the subtree at this node
170       * @apilevel low-level
171       * @deprecated Please use treeCopy or treeCopyNoTransform instead
172       * @declaredat ASTNode:78
173       */
174      @Deprecated
175      public MultiCatch fullCopy() {
176        return treeCopyNoTransform();
177      }
178      /**
179       * Create a deep copy of the AST subtree at this node.
180       * The copy is dangling, i.e. has no parent.
181       * @return dangling copy of the subtree at this node
182       * @apilevel low-level
183       * @declaredat ASTNode:88
184       */
185      public MultiCatch treeCopyNoTransform() {
186        MultiCatch tree = (MultiCatch) copy();
187        if (children != null) {
188          for (int i = 0; i < children.length; ++i) {
189            ASTNode child = (ASTNode) children[i];
190            if (child != null) {
191              child = child.treeCopyNoTransform();
192              tree.setChild(child, i);
193            }
194          }
195        }
196        return tree;
197      }
198      /**
199       * Create a deep copy of the AST subtree at this node.
200       * The subtree of this node is traversed to trigger rewrites before copy.
201       * The copy is dangling, i.e. has no parent.
202       * @return dangling copy of the subtree at this node
203       * @apilevel low-level
204       * @declaredat ASTNode:108
205       */
206      public MultiCatch treeCopy() {
207        doFullTraversal();
208        return treeCopyNoTransform();
209      }
210      /**
211       * @apilevel internal
212       * @declaredat ASTNode:115
213       */
214      protected boolean is$Equal(ASTNode node) {
215        return super.is$Equal(node);    
216      }
217      /**
218       * Replaces the Parameter child.
219       * @param node The new node to replace the Parameter child.
220       * @apilevel high-level
221       */
222      public void setParameter(CatchParameterDeclaration node) {
223        setChild(node, 0);
224      }
225      /**
226       * Retrieves the Parameter child.
227       * @return The current node used as the Parameter child.
228       * @apilevel high-level
229       */
230      @ASTNodeAnnotation.Child(name="Parameter")
231      public CatchParameterDeclaration getParameter() {
232        return (CatchParameterDeclaration) getChild(0);
233      }
234      /**
235       * Retrieves the Parameter child.
236       * <p><em>This method does not invoke AST transformations.</em></p>
237       * @return The current node used as the Parameter child.
238       * @apilevel low-level
239       */
240      public CatchParameterDeclaration getParameterNoTransform() {
241        return (CatchParameterDeclaration) getChildNoTransform(0);
242      }
243      /**
244       * Replaces the Block child.
245       * @param node The new node to replace the Block child.
246       * @apilevel high-level
247       */
248      public void setBlock(Block node) {
249        setChild(node, 1);
250      }
251      /**
252       * Retrieves the Block child.
253       * @return The current node used as the Block child.
254       * @apilevel high-level
255       */
256      @ASTNodeAnnotation.Child(name="Block")
257      public Block getBlock() {
258        return (Block) getChild(1);
259      }
260      /**
261       * Retrieves the Block child.
262       * <p><em>This method does not invoke AST transformations.</em></p>
263       * @return The current node used as the Block child.
264       * @apilevel low-level
265       */
266      public Block getBlockNoTransform() {
267        return (Block) getChildNoTransform(1);
268      }
269      /**
270       * @apilevel internal
271       */
272      protected java.util.Map parameterDeclaration_String_values;
273      /**
274       * @apilevel internal
275       */
276      private void parameterDeclaration_String_reset() {
277        parameterDeclaration_String_values = null;
278      }
279      /**
280       * @attribute syn
281       * @aspect VariableScope
282       * @declaredat /home/jesper/git/extendj/java4/frontend/LookupVariable.jrag:179
283       */
284      @ASTNodeAnnotation.Attribute
285      public SimpleSet parameterDeclaration(String name) {
286        Object _parameters = name;
287        if (parameterDeclaration_String_values == null) parameterDeclaration_String_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
288        ASTNode$State state = state();
289        if (parameterDeclaration_String_values.containsKey(_parameters)) {
290          return (SimpleSet) parameterDeclaration_String_values.get(_parameters);
291        }
292        boolean intermediate = state.INTERMEDIATE_VALUE;
293        state.INTERMEDIATE_VALUE = false;
294        int num = state.boundariesCrossed;
295        boolean isFinal = this.is$Final();
296        SimpleSet parameterDeclaration_String_value = getParameter().name().equals(name) ? getParameter() : SimpleSet.emptySet;
297        if (isFinal && num == state().boundariesCrossed) {
298          parameterDeclaration_String_values.put(_parameters, parameterDeclaration_String_value);
299        } else {
300        }
301        state.INTERMEDIATE_VALUE |= intermediate;
302    
303        return parameterDeclaration_String_value;
304      }
305      /**
306       * @attribute syn
307       * @aspect ExceptionHandling
308       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:259
309       */
310      @ASTNodeAnnotation.Attribute
311      public boolean handles(TypeDecl exceptionType) {
312        {
313            CatchParameterDeclaration param = getParameter();
314            for (int i = 0; i < param.getNumTypeAccess(); ++i) {
315              TypeDecl type = param.getTypeAccess(i).type();
316              if (!type.isUnknown() && exceptionType.instanceOf(type)) {
317                return true;
318              }
319            }
320            return false;
321          }
322      }
323      /**
324       * @attribute inh
325       * @aspect MultiCatch
326       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:65
327       */
328      /**
329       * @attribute inh
330       * @aspect MultiCatch
331       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:65
332       */
333      @ASTNodeAnnotation.Attribute
334      public int localNum() {
335        ASTNode$State state = state();
336        if (localNum_computed) {
337          return localNum_value;
338        }
339        boolean intermediate = state.INTERMEDIATE_VALUE;
340        state.INTERMEDIATE_VALUE = false;
341        int num = state.boundariesCrossed;
342        boolean isFinal = this.is$Final();
343        localNum_value = getParent().Define_localNum(this, null);
344        if (isFinal && num == state().boundariesCrossed) {
345          localNum_computed = true;
346        } else {
347        }
348        state.INTERMEDIATE_VALUE |= intermediate;
349    
350        return localNum_value;
351      }
352      /**
353       * @apilevel internal
354       */
355      protected boolean localNum_computed = false;
356      /**
357       * @apilevel internal
358       */
359      protected int localNum_value;
360      /**
361       * @apilevel internal
362       */
363      private void localNum_reset() {
364        localNum_computed = false;
365      }
366      /**
367       * @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:44
368       * @apilevel internal
369       */
370      public boolean Define_isMethodParameter(ASTNode caller, ASTNode child) {
371        if (caller == getParameterNoTransform()) {
372          // @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:49
373          return false;
374        }
375        else {
376          return getParent().Define_isMethodParameter(this, caller);
377        }
378      }
379      protected boolean canDefine_isMethodParameter(ASTNode caller, ASTNode child) {
380        return true;
381      }
382      /**
383       * @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:45
384       * @apilevel internal
385       */
386      public boolean Define_isConstructorParameter(ASTNode caller, ASTNode child) {
387        if (caller == getParameterNoTransform()) {
388          // @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:50
389          return false;
390        }
391        else {
392          return getParent().Define_isConstructorParameter(this, caller);
393        }
394      }
395      protected boolean canDefine_isConstructorParameter(ASTNode caller, ASTNode child) {
396        return true;
397      }
398      /**
399       * @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:46
400       * @apilevel internal
401       */
402      public boolean Define_isExceptionHandlerParameter(ASTNode caller, ASTNode child) {
403        if (caller == getParameterNoTransform()) {
404          // @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:51
405          return true;
406        }
407        else {
408          return getParent().Define_isExceptionHandlerParameter(this, caller);
409        }
410      }
411      protected boolean canDefine_isExceptionHandlerParameter(ASTNode caller, ASTNode child) {
412        return true;
413      }
414      /**
415       * @declaredat /home/jesper/git/extendj/java8/frontend/LookupVariable.jrag:30
416       * @apilevel internal
417       */
418      public SimpleSet Define_lookupVariable(ASTNode caller, ASTNode child, String name) {
419        if (caller == getParameterNoTransform()) {
420          // @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:102
421          return parameterDeclaration(name);
422        }
423        else {
424          return super.Define_lookupVariable(caller, child, name);
425        }
426      }
427      protected boolean canDefine_lookupVariable(ASTNode caller, ASTNode child, String name) {
428        return true;
429      }
430      /**
431       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:52
432       * @apilevel internal
433       */
434      public boolean Define_reachable(ASTNode caller, ASTNode child) {
435        if (caller == getBlockNoTransform()) {
436          // @declaredat /home/jesper/git/extendj/java7/frontend/MultiCatch.jrag:152
437          {
438              boolean anyReachable = false;
439              CatchParameterDeclaration param = getParameter();
440              for (int i = 0; i < param.getNumTypeAccess(); ++i) {
441                TypeDecl type = param.getTypeAccess(i).type();
442                if (!reachableCatchClause(type)) {
443                  errorf("The exception type %s can not be caught by this multi-catch clause",
444                      type.fullName());
445                } else {
446                  anyReachable = true;
447                }
448              }
449              return anyReachable;
450            }
451        }
452        else {
453          return getParent().Define_reachable(this, caller);
454        }
455      }
456      protected boolean canDefine_reachable(ASTNode caller, ASTNode child) {
457        return true;
458      }
459      /**
460       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:64
461       * @apilevel internal
462       */
463      public int Define_localNum(ASTNode caller, ASTNode child) {
464        if (caller == getParameterNoTransform()) {
465          // @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:68
466          return localNum();
467        }
468        else if (caller == getBlockNoTransform()) {
469          // @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:67
470          return localNum() + getParameter().type().variableSize();
471        }
472        else {
473          return getParent().Define_localNum(this, caller);
474        }
475      }
476      protected boolean canDefine_localNum(ASTNode caller, ASTNode child) {
477        return true;
478      }
479      /**
480       * @apilevel internal
481       */
482      public ASTNode rewriteTo() {
483        return super.rewriteTo();
484      }
485    }