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     * @ast node
026     * @declaredat /home/jesper/git/extendj/java4/grammar/Java.ast:221
027     * @production TryStmt : {@link Stmt} ::= <span class="component">{@link Block}</span> <span class="component">{@link CatchClause}*</span> <span class="component">[Finally:{@link Block}]</span> <span class="component">ExceptionHandler:{@link Block}</span>;
028    
029     */
030    public class TryStmt extends Stmt implements Cloneable, FinallyHost {
031      /**
032       * @aspect BranchTarget
033       * @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:112
034       */
035      public void collectBranches(Collection<Stmt> c) {
036        c.addAll(escapedBranches());
037      }
038      /**
039       * @aspect DU
040       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1042
041       */
042      public Block getFinallyBlock() {
043        return getFinally();
044      }
045      /**
046       * @aspect ExceptionHandling
047       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:280
048       */
049      protected boolean reachedException(TypeDecl type) {
050        boolean found = false;
051        // found is true if the exception type is caught by a catch clause
052        for (int i = 0; i < getNumCatchClause() && !found; i++) {
053          if (getCatchClause(i).handles(type)) {
054            found = true;
055          }
056        }
057        // if an exception is thrown in the block and the exception is not caught and
058        // either there is no finally block or the finally block can complete normally
059        if (!found && (!hasNonEmptyFinally() || getFinally().canCompleteNormally()) ) {
060          if (getBlock().reachedException(type)) {
061            return true;
062          }
063        }
064        // even if the exception is caught by the catch clauses they may
065        // throw new exceptions
066        for (int i = 0; i < getNumCatchClause(); i++) {
067          if (getCatchClause(i).reachedException(type)) {
068            return true;
069          }
070        }
071        return hasNonEmptyFinally() && getFinally().reachedException(type);
072      }
073      /**
074       * @aspect Java4PrettyPrint
075       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:440
076       */
077      public void prettyPrint(PrettyPrinter out) {
078        out.print("try ");
079        out.print(getBlock());
080        out.print(" ");
081        out.join(getCatchClauseList(), new PrettyPrinter.Joiner() {
082          @Override
083          public void printSeparator(PrettyPrinter out) {
084            out.print(" ");
085          }
086        });
087        if (hasFinally()) {
088          out.print(" finally ");
089          out.print(getFinally());
090        }
091      }
092      /**
093       * @aspect CreateBCode
094       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1714
095       */
096      public void createBCode(CodeGeneration gen) {
097        int block_top_lbl = gen.constantPool().newLabel();
098        int block_end_lbl = gen.constantPool().newLabel();
099        int fallthrough_lbl = fallthrough_label();
100        int handler_lbl = gen.constantPool().newLabel();
101        boolean needsHandler = false;
102    
103        super.createBCode(gen);
104        gen.addLabel(block_top_lbl);
105        getBlock().createBCode(gen);
106        gen.addLabel(block_end_lbl);
107    
108        if (getBlock().canCompleteNormally()) {
109          gen.emitGoto(fallthrough_lbl);
110        }
111    
112        for (int i = 0; i < getNumCatchClause(); i++) {
113          CatchClause cc = getCatchClause(i);
114          cc.createBCode(gen);
115          cc.exceptionTableEntries(gen, block_top_lbl, block_end_lbl);
116          if (cc.getBlock().canCompleteNormally()) {
117            gen.emitGoto(fallthrough_lbl);
118          }
119          if (hasNonEmptyFinally()) {
120            int cc_end_lbl = gen.constantPool().newLabel();
121            gen.addLabel(cc_end_lbl);
122            needsHandler = true;
123            gen.addException(cc.label(), cc_end_lbl, handler_lbl,
124                CodeGeneration.ExceptionEntry.CATCH_ALL);
125          }
126        }
127    
128        if (hasNonEmptyFinally()) {
129    
130          emitExceptionHandler(gen, block_top_lbl, block_end_lbl, handler_lbl,
131              needsHandler);
132    
133          // fallthrough finally
134          gen.addLabel(fallthrough_lbl);
135          getFinally().createBCode(gen);
136        }
137    
138        gen.addLabel(label_end());
139      }
140      /**
141       * Generate catch-all (finally)
142       * @aspect CreateBCode
143       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1775
144       */
145      public void emitExceptionHandler(CodeGeneration gen, int start_lbl, int end_lbl, int handler_lbl, boolean needsHandler) {
146        int top_pc = gen.addressOf(start_lbl);
147        int end_pc = gen.addressOf(end_lbl);
148        if (needsHandler || top_pc != end_pc) {
149          // catch-all exception handler (finally)
150          gen.addLabel(handler_lbl);
151          gen.changeStackDepth(1);
152          int num = getBlock().localNum();
153          gen.emitStoreReference(num);
154          getExceptionHandler().createBCode(gen);
155          gen.emitLoadReference(num);
156          gen.emit(Bytecode.ATHROW);
157    
158          gen.addException(start_lbl, end_lbl, handler_lbl,
159              CodeGeneration.ExceptionEntry.CATCH_ALL);
160        }
161      }
162      /**
163       * @declaredat ASTNode:1
164       */
165      public TryStmt() {
166        super();
167      }
168      /**
169       * Initializes the child array to the correct size.
170       * Initializes List and Opt nta children.
171       * @apilevel internal
172       * @ast method
173       * @declaredat ASTNode:10
174       */
175      public void init$Children() {
176        children = new ASTNode[4];
177        setChild(new List(), 1);
178        setChild(new Opt(), 2);
179      }
180      /**
181       * @declaredat ASTNode:15
182       */
183      public TryStmt(Block p0, List<CatchClause> p1, Opt<Block> p2) {
184        setChild(p0, 0);
185        setChild(p1, 1);
186        setChild(p2, 2);
187      }
188      /**
189       * @apilevel low-level
190       * @declaredat ASTNode:23
191       */
192      protected int numChildren() {
193        return 3;
194      }
195      /**
196       * @apilevel internal
197       * @declaredat ASTNode:29
198       */
199      public boolean mayHaveRewrite() {
200        return false;
201      }
202      /**
203       * @apilevel internal
204       * @declaredat ASTNode:35
205       */
206      public void flushAttrCache() {
207        super.flushAttrCache();
208        branches_reset();
209        escapedBranches_reset();
210        isDAafter_Variable_reset();
211        isDUbefore_Variable_reset();
212        isDUafter_Variable_reset();
213        hasNonEmptyFinally_reset();
214        catchableException_TypeDecl_reset();
215        getExceptionHandler_reset();
216        canCompleteNormally_reset();
217        fallthrough_label_reset();
218        label_end_reset();
219        handlesException_TypeDecl_reset();
220        typeError_reset();
221        typeRuntimeException_reset();
222      }
223      /**
224       * @apilevel internal
225       * @declaredat ASTNode:55
226       */
227      public void flushCollectionCache() {
228        super.flushCollectionCache();
229      }
230      /**
231       * @apilevel internal
232       * @declaredat ASTNode:61
233       */
234      public void flushRewriteCache() {
235        super.flushRewriteCache();
236      }
237      /**
238       * @apilevel internal
239       * @declaredat ASTNode:67
240       */
241      public TryStmt clone() throws CloneNotSupportedException {
242        TryStmt node = (TryStmt) super.clone();
243        return node;
244      }
245      /**
246       * @apilevel internal
247       * @declaredat ASTNode:74
248       */
249      public TryStmt copy() {
250        try {
251          TryStmt node = (TryStmt) clone();
252          node.parent = null;
253          if (children != null) {
254            node.children = (ASTNode[]) children.clone();
255          }
256          return node;
257        } catch (CloneNotSupportedException e) {
258          throw new Error("Error: clone not supported for " + getClass().getName());
259        }
260      }
261      /**
262       * Create a deep copy of the AST subtree at this node.
263       * The copy is dangling, i.e. has no parent.
264       * @return dangling copy of the subtree at this node
265       * @apilevel low-level
266       * @deprecated Please use treeCopy or treeCopyNoTransform instead
267       * @declaredat ASTNode:93
268       */
269      @Deprecated
270      public TryStmt fullCopy() {
271        return treeCopyNoTransform();
272      }
273      /**
274       * Create a deep copy of the AST subtree at this node.
275       * The copy is dangling, i.e. has no parent.
276       * @return dangling copy of the subtree at this node
277       * @apilevel low-level
278       * @declaredat ASTNode:103
279       */
280      public TryStmt treeCopyNoTransform() {
281        TryStmt tree = (TryStmt) copy();
282        if (children != null) {
283          for (int i = 0; i < children.length; ++i) {
284            switch (i) {
285            case 3:
286              tree.children[i] = null;
287              continue;
288            }
289            ASTNode child = (ASTNode) children[i];
290            if (child != null) {
291              child = child.treeCopyNoTransform();
292              tree.setChild(child, i);
293            }
294          }
295        }
296        return tree;
297      }
298      /**
299       * Create a deep copy of the AST subtree at this node.
300       * The subtree of this node is traversed to trigger rewrites before copy.
301       * The copy is dangling, i.e. has no parent.
302       * @return dangling copy of the subtree at this node
303       * @apilevel low-level
304       * @declaredat ASTNode:128
305       */
306      public TryStmt treeCopy() {
307        doFullTraversal();
308        return treeCopyNoTransform();
309      }
310      /**
311       * @apilevel internal
312       * @declaredat ASTNode:135
313       */
314      protected boolean is$Equal(ASTNode node) {
315        return super.is$Equal(node);    
316      }
317      /**
318       * Replaces the Block child.
319       * @param node The new node to replace the Block child.
320       * @apilevel high-level
321       */
322      public void setBlock(Block node) {
323        setChild(node, 0);
324      }
325      /**
326       * Retrieves the Block child.
327       * @return The current node used as the Block child.
328       * @apilevel high-level
329       */
330      @ASTNodeAnnotation.Child(name="Block")
331      public Block getBlock() {
332        return (Block) getChild(0);
333      }
334      /**
335       * Retrieves the Block child.
336       * <p><em>This method does not invoke AST transformations.</em></p>
337       * @return The current node used as the Block child.
338       * @apilevel low-level
339       */
340      public Block getBlockNoTransform() {
341        return (Block) getChildNoTransform(0);
342      }
343      /**
344       * Replaces the CatchClause list.
345       * @param list The new list node to be used as the CatchClause list.
346       * @apilevel high-level
347       */
348      public void setCatchClauseList(List<CatchClause> list) {
349        setChild(list, 1);
350      }
351      /**
352       * Retrieves the number of children in the CatchClause list.
353       * @return Number of children in the CatchClause list.
354       * @apilevel high-level
355       */
356      public int getNumCatchClause() {
357        return getCatchClauseList().getNumChild();
358      }
359      /**
360       * Retrieves the number of children in the CatchClause list.
361       * Calling this method will not trigger rewrites.
362       * @return Number of children in the CatchClause list.
363       * @apilevel low-level
364       */
365      public int getNumCatchClauseNoTransform() {
366        return getCatchClauseListNoTransform().getNumChildNoTransform();
367      }
368      /**
369       * Retrieves the element at index {@code i} in the CatchClause list.
370       * @param i Index of the element to return.
371       * @return The element at position {@code i} in the CatchClause list.
372       * @apilevel high-level
373       */
374      public CatchClause getCatchClause(int i) {
375        return (CatchClause) getCatchClauseList().getChild(i);
376      }
377      /**
378       * Check whether the CatchClause list has any children.
379       * @return {@code true} if it has at least one child, {@code false} otherwise.
380       * @apilevel high-level
381       */
382      public boolean hasCatchClause() {
383        return getCatchClauseList().getNumChild() != 0;
384      }
385      /**
386       * Append an element to the CatchClause list.
387       * @param node The element to append to the CatchClause list.
388       * @apilevel high-level
389       */
390      public void addCatchClause(CatchClause node) {
391        List<CatchClause> list = (parent == null) ? getCatchClauseListNoTransform() : getCatchClauseList();
392        list.addChild(node);
393      }
394      /**
395       * @apilevel low-level
396       */
397      public void addCatchClauseNoTransform(CatchClause node) {
398        List<CatchClause> list = getCatchClauseListNoTransform();
399        list.addChild(node);
400      }
401      /**
402       * Replaces the CatchClause list element at index {@code i} with the new node {@code node}.
403       * @param node The new node to replace the old list element.
404       * @param i The list index of the node to be replaced.
405       * @apilevel high-level
406       */
407      public void setCatchClause(CatchClause node, int i) {
408        List<CatchClause> list = getCatchClauseList();
409        list.setChild(node, i);
410      }
411      /**
412       * Retrieves the CatchClause list.
413       * @return The node representing the CatchClause list.
414       * @apilevel high-level
415       */
416      @ASTNodeAnnotation.ListChild(name="CatchClause")
417      public List<CatchClause> getCatchClauseList() {
418        List<CatchClause> list = (List<CatchClause>) getChild(1);
419        return list;
420      }
421      /**
422       * Retrieves the CatchClause list.
423       * <p><em>This method does not invoke AST transformations.</em></p>
424       * @return The node representing the CatchClause list.
425       * @apilevel low-level
426       */
427      public List<CatchClause> getCatchClauseListNoTransform() {
428        return (List<CatchClause>) getChildNoTransform(1);
429      }
430      /**
431       * Retrieves the CatchClause list.
432       * @return The node representing the CatchClause list.
433       * @apilevel high-level
434       */
435      public List<CatchClause> getCatchClauses() {
436        return getCatchClauseList();
437      }
438      /**
439       * Retrieves the CatchClause list.
440       * <p><em>This method does not invoke AST transformations.</em></p>
441       * @return The node representing the CatchClause list.
442       * @apilevel low-level
443       */
444      public List<CatchClause> getCatchClausesNoTransform() {
445        return getCatchClauseListNoTransform();
446      }
447      /**
448       * Replaces the optional node for the Finally child. This is the <code>Opt</code>
449       * node containing the child Finally, not the actual child!
450       * @param opt The new node to be used as the optional node for the Finally child.
451       * @apilevel low-level
452       */
453      public void setFinallyOpt(Opt<Block> opt) {
454        setChild(opt, 2);
455      }
456      /**
457       * Replaces the (optional) Finally child.
458       * @param node The new node to be used as the Finally child.
459       * @apilevel high-level
460       */
461      public void setFinally(Block node) {
462        getFinallyOpt().setChild(node, 0);
463      }
464      /**
465       * Check whether the optional Finally child exists.
466       * @return {@code true} if the optional Finally child exists, {@code false} if it does not.
467       * @apilevel high-level
468       */
469      public boolean hasFinally() {
470        return getFinallyOpt().getNumChild() != 0;
471      }
472      /**
473       * Retrieves the (optional) Finally child.
474       * @return The Finally child, if it exists. Returns {@code null} otherwise.
475       * @apilevel low-level
476       */
477      public Block getFinally() {
478        return (Block) getFinallyOpt().getChild(0);
479      }
480      /**
481       * Retrieves the optional node for the Finally child. This is the <code>Opt</code> node containing the child Finally, not the actual child!
482       * @return The optional node for child the Finally child.
483       * @apilevel low-level
484       */
485      @ASTNodeAnnotation.OptChild(name="Finally")
486      public Opt<Block> getFinallyOpt() {
487        return (Opt<Block>) getChild(2);
488      }
489      /**
490       * Retrieves the optional node for child Finally. This is the <code>Opt</code> node containing the child Finally, not the actual child!
491       * <p><em>This method does not invoke AST transformations.</em></p>
492       * @return The optional node for child Finally.
493       * @apilevel low-level
494       */
495      public Opt<Block> getFinallyOptNoTransform() {
496        return (Opt<Block>) getChildNoTransform(2);
497      }
498      /**
499       * Retrieves the ExceptionHandler child.
500       * <p><em>This method does not invoke AST transformations.</em></p>
501       * @return The current node used as the ExceptionHandler child.
502       * @apilevel low-level
503       */
504      public Block getExceptionHandlerNoTransform() {
505        return (Block) getChildNoTransform(3);
506      }
507      /**
508       * Retrieves the child position of the optional child ExceptionHandler.
509       * @return The the child position of the optional child ExceptionHandler.
510       * @apilevel low-level
511       */
512      protected int getExceptionHandlerChildPosition() {
513        return 3;
514      }
515      /**
516       * @apilevel internal
517       */
518      protected boolean branches_computed = false;
519      /**
520       * @apilevel internal
521       */
522      protected Collection<Stmt> branches_value;
523      /**
524       * @apilevel internal
525       */
526      private void branches_reset() {
527        branches_computed = false;
528        branches_value = null;
529      }
530      /**
531       * All branches that reach this node.
532       * @attribute syn
533       * @aspect BranchTarget
534       * @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:159
535       */
536      @ASTNodeAnnotation.Attribute
537      public Collection<Stmt> branches() {
538        ASTNode$State state = state();
539        if (branches_computed) {
540          return branches_value;
541        }
542        boolean intermediate = state.INTERMEDIATE_VALUE;
543        state.INTERMEDIATE_VALUE = false;
544        int num = state.boundariesCrossed;
545        boolean isFinal = this.is$Final();
546        branches_value = branches_compute();
547        if (isFinal && num == state().boundariesCrossed) {
548          branches_computed = true;
549        } else {
550        }
551        state.INTERMEDIATE_VALUE |= intermediate;
552    
553        return branches_value;
554      }
555      /**
556       * @apilevel internal
557       */
558      private Collection<Stmt> branches_compute() {
559          Collection<Stmt> set = new HashSet<Stmt>();
560          getBlock().collectBranches(set);
561          for (int i = 0; i < getNumCatchClause(); i++) {
562            getCatchClause(i).collectBranches(set);
563          }
564          return set;
565        }
566      /**
567       * @apilevel internal
568       */
569      protected boolean escapedBranches_computed = false;
570      /**
571       * @apilevel internal
572       */
573      protected Collection<Stmt> escapedBranches_value;
574      /**
575       * @apilevel internal
576       */
577      private void escapedBranches_reset() {
578        escapedBranches_computed = false;
579        escapedBranches_value = null;
580      }
581      /**
582       * All branches that escape this node
583       * @attribute syn
584       * @aspect BranchTarget
585       * @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:171
586       */
587      @ASTNodeAnnotation.Attribute
588      public Collection<Stmt> escapedBranches() {
589        ASTNode$State state = state();
590        if (escapedBranches_computed) {
591          return escapedBranches_value;
592        }
593        boolean intermediate = state.INTERMEDIATE_VALUE;
594        state.INTERMEDIATE_VALUE = false;
595        int num = state.boundariesCrossed;
596        boolean isFinal = this.is$Final();
597        escapedBranches_value = escapedBranches_compute();
598        if (isFinal && num == state().boundariesCrossed) {
599          escapedBranches_computed = true;
600        } else {
601        }
602        state.INTERMEDIATE_VALUE |= intermediate;
603    
604        return escapedBranches_value;
605      }
606      /**
607       * @apilevel internal
608       */
609      private Collection<Stmt> escapedBranches_compute() {
610          Collection<Stmt> set = new HashSet<Stmt>();
611          if (hasNonEmptyFinally()) {
612            // branches from finally
613            getFinally().collectBranches(set);
614          }
615          if (!hasFinally() || getFinally().canCompleteNormally()) {
616            set.addAll(branches());
617          }
618          return set;
619        }
620      /**
621       * @apilevel internal
622       */
623      protected java.util.Map isDAafter_Variable_values;
624      /**
625       * @apilevel internal
626       */
627      private void isDAafter_Variable_reset() {
628        isDAafter_Variable_values = null;
629      }
630      /**
631       * @attribute syn
632       * @aspect DA
633       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:257
634       */
635      @ASTNodeAnnotation.Attribute
636      public boolean isDAafter(Variable v) {
637        Object _parameters = v;
638        if (isDAafter_Variable_values == null) isDAafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
639        ASTNode$State state = state();
640        if (isDAafter_Variable_values.containsKey(_parameters)) {
641          return (Boolean) isDAafter_Variable_values.get(_parameters);
642        }
643        boolean intermediate = state.INTERMEDIATE_VALUE;
644        state.INTERMEDIATE_VALUE = false;
645        int num = state.boundariesCrossed;
646        boolean isFinal = this.is$Final();
647        boolean isDAafter_Variable_value = isDAafter_compute(v);
648        if (isFinal && num == state().boundariesCrossed) {
649          isDAafter_Variable_values.put(_parameters, isDAafter_Variable_value);
650        } else {
651        }
652        state.INTERMEDIATE_VALUE |= intermediate;
653    
654        return isDAafter_Variable_value;
655      }
656      /**
657       * @apilevel internal
658       */
659      private boolean isDAafter_compute(Variable v) {
660          // 16.2.15 4th bullet
661          if (!hasNonEmptyFinally()) {
662            if (!getBlock().isDAafter(v)) {
663              return false;
664            }
665            for (int i = 0; i < getNumCatchClause(); i++) {
666              if (!getCatchClause(i).getBlock().isDAafter(v)) {
667                return false;
668              }
669            }
670            return true;
671          } else {
672            // 16.2.15 5th bullet
673            if (getFinally().isDAafter(v)) {
674              return true;
675            }
676            if (!getBlock().isDAafter(v)) {
677              return false;
678            }
679            for (int i = 0; i < getNumCatchClause(); i++) {
680              if (!getCatchClause(i).getBlock().isDAafter(v)) {
681                return false;
682              }
683            }
684            return true;
685          }
686        }
687      /**
688       * @attribute syn
689       * @aspect DU
690       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1050
691       */
692      @ASTNodeAnnotation.Attribute
693      public boolean isDUafterFinally(Variable v) {
694        boolean isDUafterFinally_Variable_value = getFinally().isDUafter(v);
695    
696        return isDUafterFinally_Variable_value;
697      }
698      /**
699       * @attribute syn
700       * @aspect DU
701       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1053
702       */
703      @ASTNodeAnnotation.Attribute
704      public boolean isDAafterFinally(Variable v) {
705        boolean isDAafterFinally_Variable_value = getFinally().isDAafter(v);
706    
707        return isDAafterFinally_Variable_value;
708      }
709      /**
710       * @apilevel internal
711       */
712      private void isDUbefore_Variable_reset() {
713        isDUbefore_Variable_values = null;
714      }
715      protected java.util.Map isDUbefore_Variable_values;
716      @ASTNodeAnnotation.Attribute
717      public boolean isDUbefore(Variable v) {
718        Object _parameters = v;
719        if (isDUbefore_Variable_values == null) isDUbefore_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
720        ASTNode$State.CircularValue _value;
721        if (isDUbefore_Variable_values.containsKey(_parameters)) {
722          Object _o = isDUbefore_Variable_values.get(_parameters);
723          if (!(_o instanceof ASTNode$State.CircularValue)) {
724            return (Boolean) _o;
725          } else {
726            _value = (ASTNode$State.CircularValue) _o;
727          }
728        } else {
729          _value = new ASTNode$State.CircularValue();
730          isDUbefore_Variable_values.put(_parameters, _value);
731          _value.value = true;
732        }
733        ASTNode$State state = state();
734        boolean new_isDUbefore_Variable_value;
735        if (!state.IN_CIRCLE) {
736          state.IN_CIRCLE = true;
737          int num = state.boundariesCrossed;
738          boolean isFinal = this.is$Final();
739          // TODO: fixme
740          // state().CIRCLE_INDEX = 1;
741          do {
742            _value.visited = state.CIRCLE_INDEX;
743            state.CHANGE = false;
744            new_isDUbefore_Variable_value = super.isDUbefore(v);
745            if (new_isDUbefore_Variable_value != ((Boolean)_value.value)) {
746              state.CHANGE = true;
747              _value.value = new_isDUbefore_Variable_value;
748            }
749            state.CIRCLE_INDEX++;
750          } while (state.CHANGE);
751          if (isFinal && num == state().boundariesCrossed) {
752            isDUbefore_Variable_values.put(_parameters, new_isDUbefore_Variable_value);
753          } else {
754            isDUbefore_Variable_values.remove(_parameters);
755            state.RESET_CYCLE = true;
756            boolean $tmp = super.isDUbefore(v);
757            state.RESET_CYCLE = false;
758          }
759          state.IN_CIRCLE = false;
760          state.INTERMEDIATE_VALUE = false;
761          return new_isDUbefore_Variable_value;
762        }
763        if (state.CIRCLE_INDEX != _value.visited) {
764          _value.visited = state.CIRCLE_INDEX;
765          new_isDUbefore_Variable_value = super.isDUbefore(v);
766          if (state.RESET_CYCLE) {
767            isDUbefore_Variable_values.remove(_parameters);
768          }
769          else if (new_isDUbefore_Variable_value != ((Boolean)_value.value)) {
770            state.CHANGE = true;
771            _value.value = new_isDUbefore_Variable_value;
772          }
773          state.INTERMEDIATE_VALUE = true;
774          return new_isDUbefore_Variable_value;
775        }
776        state.INTERMEDIATE_VALUE = true;
777        return (Boolean) _value.value;
778      }
779      /**
780       * @apilevel internal
781       */
782      protected java.util.Map isDUafter_Variable_values;
783      /**
784       * @apilevel internal
785       */
786      private void isDUafter_Variable_reset() {
787        isDUafter_Variable_values = null;
788      }
789      /**
790       * @attribute syn
791       * @aspect DU
792       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:781
793       */
794      @ASTNodeAnnotation.Attribute
795      public boolean isDUafter(Variable v) {
796        Object _parameters = v;
797        if (isDUafter_Variable_values == null) isDUafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
798        ASTNode$State state = state();
799        if (isDUafter_Variable_values.containsKey(_parameters)) {
800          return (Boolean) isDUafter_Variable_values.get(_parameters);
801        }
802        boolean intermediate = state.INTERMEDIATE_VALUE;
803        state.INTERMEDIATE_VALUE = false;
804        int num = state.boundariesCrossed;
805        boolean isFinal = this.is$Final();
806        boolean isDUafter_Variable_value = isDUafter_compute(v);
807        if (isFinal && num == state().boundariesCrossed) {
808          isDUafter_Variable_values.put(_parameters, isDUafter_Variable_value);
809        } else {
810        }
811        state.INTERMEDIATE_VALUE |= intermediate;
812    
813        return isDUafter_Variable_value;
814      }
815      /**
816       * @apilevel internal
817       */
818      private boolean isDUafter_compute(Variable v) {
819          // 16.2.14 4th bullet
820          if (!hasNonEmptyFinally()) {
821            if (!getBlock().isDUafter(v)) {
822              return false;
823            }
824            for (int i = 0; i < getNumCatchClause(); i++) {
825              if (!getCatchClause(i).getBlock().isDUafter(v)) {
826                return false;
827              }
828            }
829            return true;
830          } else {
831            return getFinally().isDUafter(v);
832          }
833        }
834      /**
835       * @apilevel internal
836       */
837      protected boolean hasNonEmptyFinally_computed = false;
838      /**
839       * @apilevel internal
840       */
841      protected boolean hasNonEmptyFinally_value;
842      /**
843       * @apilevel internal
844       */
845      private void hasNonEmptyFinally_reset() {
846        hasNonEmptyFinally_computed = false;
847      }
848      /**
849       * @return <code>true</code> if this TyStmt has a non-empty finally block
850       * @attribute syn
851       * @aspect ExceptionHandling
852       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:36
853       */
854      @ASTNodeAnnotation.Attribute
855      public boolean hasNonEmptyFinally() {
856        ASTNode$State state = state();
857        if (hasNonEmptyFinally_computed) {
858          return hasNonEmptyFinally_value;
859        }
860        boolean intermediate = state.INTERMEDIATE_VALUE;
861        state.INTERMEDIATE_VALUE = false;
862        int num = state.boundariesCrossed;
863        boolean isFinal = this.is$Final();
864        hasNonEmptyFinally_value = hasFinally() && getFinally().getNumStmt() > 0;
865        if (isFinal && num == state().boundariesCrossed) {
866          hasNonEmptyFinally_computed = true;
867        } else {
868        }
869        state.INTERMEDIATE_VALUE |= intermediate;
870    
871        return hasNonEmptyFinally_value;
872      }
873      /**
874       * @apilevel internal
875       */
876      protected java.util.Map catchableException_TypeDecl_values;
877      /**
878       * @apilevel internal
879       */
880      private void catchableException_TypeDecl_reset() {
881        catchableException_TypeDecl_values = null;
882      }
883      /**
884       * The block of the try statement can throw an exception of
885       * a type assignable to the given type.
886       * @attribute syn
887       * @aspect ExceptionHandling
888       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:268
889       */
890      @ASTNodeAnnotation.Attribute
891      public boolean catchableException(TypeDecl type) {
892        Object _parameters = type;
893        if (catchableException_TypeDecl_values == null) catchableException_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
894        ASTNode$State state = state();
895        if (catchableException_TypeDecl_values.containsKey(_parameters)) {
896          return (Boolean) catchableException_TypeDecl_values.get(_parameters);
897        }
898        boolean intermediate = state.INTERMEDIATE_VALUE;
899        state.INTERMEDIATE_VALUE = false;
900        int num = state.boundariesCrossed;
901        boolean isFinal = this.is$Final();
902        boolean catchableException_TypeDecl_value = getBlock().reachedException(type);
903        if (isFinal && num == state().boundariesCrossed) {
904          catchableException_TypeDecl_values.put(_parameters, catchableException_TypeDecl_value);
905        } else {
906        }
907        state.INTERMEDIATE_VALUE |= intermediate;
908    
909        return catchableException_TypeDecl_value;
910      }
911      /**
912       * @apilevel internal
913       */
914      protected boolean getExceptionHandler_computed = false;
915      /**
916       * @apilevel internal
917       */
918      protected Block getExceptionHandler_value;
919      /**
920       * @apilevel internal
921       */
922      private void getExceptionHandler_reset() {
923        getExceptionHandler_computed = false;
924        getExceptionHandler_value = null;
925      }
926      /**
927       * Copy of the finally block for catch-all exception handling.
928       * @attribute syn nta
929       * @aspect NTAFinally
930       * @declaredat /home/jesper/git/extendj/java4/frontend/NTAFinally.jrag:68
931       */
932      @ASTNodeAnnotation.Attribute
933      public Block getExceptionHandler() {
934        ASTNode$State state = state();
935        if (getExceptionHandler_computed) {
936          return (Block) getChild(getExceptionHandlerChildPosition());
937        }
938        boolean intermediate = state.INTERMEDIATE_VALUE;
939        state.INTERMEDIATE_VALUE = false;
940        int num = state.boundariesCrossed;
941        boolean isFinal = this.is$Final();
942        getExceptionHandler_value = getExceptionHandler_compute();
943        setChild(getExceptionHandler_value, getExceptionHandlerChildPosition());
944        if (isFinal && num == state().boundariesCrossed) {
945          getExceptionHandler_computed = true;
946        } else {
947        }
948        state.INTERMEDIATE_VALUE |= intermediate;
949    
950        Block node = (Block) this.getChild(getExceptionHandlerChildPosition());
951        return node;
952      }
953      /**
954       * @apilevel internal
955       */
956      private Block getExceptionHandler_compute() {
957          if (hasNonEmptyFinally()) {
958            NTAFinallyBlock ntaBlock = new NTAFinallyBlock(this);
959            ntaBlock.addStmt((Block) getFinally().treeCopyNoTransform());
960            return ntaBlock;
961          } else {
962            return new NTAFinallyBlock();
963          }
964        }
965      /**
966       * @apilevel internal
967       */
968      protected boolean canCompleteNormally_computed = false;
969      /**
970       * @apilevel internal
971       */
972      protected boolean canCompleteNormally_value;
973      /**
974       * @apilevel internal
975       */
976      private void canCompleteNormally_reset() {
977        canCompleteNormally_computed = false;
978      }
979      /**
980       * @attribute syn
981       * @aspect UnreachableStatements
982       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:53
983       */
984      @ASTNodeAnnotation.Attribute
985      public boolean canCompleteNormally() {
986        ASTNode$State state = state();
987        if (canCompleteNormally_computed) {
988          return canCompleteNormally_value;
989        }
990        boolean intermediate = state.INTERMEDIATE_VALUE;
991        state.INTERMEDIATE_VALUE = false;
992        int num = state.boundariesCrossed;
993        boolean isFinal = this.is$Final();
994        canCompleteNormally_value = canCompleteNormally_compute();
995        if (isFinal && num == state().boundariesCrossed) {
996          canCompleteNormally_computed = true;
997        } else {
998        }
999        state.INTERMEDIATE_VALUE |= intermediate;
1000    
1001        return canCompleteNormally_value;
1002      }
1003      /**
1004       * @apilevel internal
1005       */
1006      private boolean canCompleteNormally_compute() {
1007           boolean anyCatchClauseCompleteNormally = false;
1008           for (int i = 0; i < getNumCatchClause() && !anyCatchClauseCompleteNormally; i++) {
1009             anyCatchClauseCompleteNormally = getCatchClause(i).getBlock().canCompleteNormally();
1010           }
1011           return (getBlock().canCompleteNormally() || anyCatchClauseCompleteNormally) &&
1012             (!hasNonEmptyFinally() || getFinally().canCompleteNormally());
1013        }
1014      /**
1015       * @attribute syn
1016       * @aspect CreateBCode
1017       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1621
1018       */
1019      @ASTNodeAnnotation.Attribute
1020      public int break_label() {
1021        int break_label_value = label_end();
1022    
1023        return break_label_value;
1024      }
1025      /**
1026       * @attribute syn
1027       * @aspect CreateBCode
1028       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1645
1029       */
1030      @ASTNodeAnnotation.Attribute
1031      public int continue_label() {
1032        int continue_label_value = label_end();
1033    
1034        return continue_label_value;
1035      }
1036      /**
1037       * @apilevel internal
1038       */
1039      protected boolean fallthrough_label_computed = false;
1040      /**
1041       * @apilevel internal
1042       */
1043      protected int fallthrough_label_value;
1044      /**
1045       * @apilevel internal
1046       */
1047      private void fallthrough_label_reset() {
1048        fallthrough_label_computed = false;
1049      }
1050      /**
1051       * @attribute syn
1052       * @aspect CreateBCode
1053       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1711
1054       */
1055      @ASTNodeAnnotation.Attribute
1056      public int fallthrough_label() {
1057        ASTNode$State state = state();
1058        if (fallthrough_label_computed) {
1059          return fallthrough_label_value;
1060        }
1061        boolean intermediate = state.INTERMEDIATE_VALUE;
1062        state.INTERMEDIATE_VALUE = false;
1063        int num = state.boundariesCrossed;
1064        boolean isFinal = this.is$Final();
1065        fallthrough_label_value = hasNonEmptyFinally() ? hostType().constantPool().newLabel() : label_end();
1066        if (isFinal && num == state().boundariesCrossed) {
1067          fallthrough_label_computed = true;
1068        } else {
1069        }
1070        state.INTERMEDIATE_VALUE |= intermediate;
1071    
1072        return fallthrough_label_value;
1073      }
1074      /**
1075       * Outer finally host with a finally block that can complete normally
1076       * @attribute syn
1077       * @aspect CreateBCode
1078       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1762
1079       */
1080      @ASTNodeAnnotation.Attribute
1081      public FinallyHost outerFinallyHost() {
1082        {
1083            // find outer finally
1084            FinallyHost outer = this;
1085            Iterator<FinallyHost> iter = finallyIterator();
1086            while (iter.hasNext()) {
1087              outer = iter.next();
1088            }
1089            return outer;
1090          }
1091      }
1092      /**
1093       * @attribute syn
1094       * @aspect PreciseRethrow
1095       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:84
1096       */
1097      @ASTNodeAnnotation.Attribute
1098      public boolean modifiedInScope(Variable var) {
1099        {
1100            if (getBlock().modifiedInScope(var)) {
1101              return true;
1102            }
1103            for (CatchClause cc : getCatchClauseList()) {
1104              if (cc.modifiedInScope(var)) {
1105                return true;
1106              }
1107            }
1108            return hasNonEmptyFinally() && getFinally().modifiedInScope(var);
1109          }
1110      }
1111      /**
1112       * @apilevel internal
1113       */
1114      protected boolean label_end_computed = false;
1115      /**
1116       * @apilevel internal
1117       */
1118      protected int label_end_value;
1119      /**
1120       * @apilevel internal
1121       */
1122      private void label_end_reset() {
1123        label_end_computed = false;
1124      }
1125      /**
1126       * @attribute syn
1127       * @aspect NTAFinally
1128       * @declaredat /home/jesper/git/extendj/java4/backend/NTAFinally.jrag:32
1129       */
1130      @ASTNodeAnnotation.Attribute
1131      public int label_end() {
1132        ASTNode$State state = state();
1133        if (label_end_computed) {
1134          return label_end_value;
1135        }
1136        boolean intermediate = state.INTERMEDIATE_VALUE;
1137        state.INTERMEDIATE_VALUE = false;
1138        int num = state.boundariesCrossed;
1139        boolean isFinal = this.is$Final();
1140        label_end_value = hostType().constantPool().newLabel();
1141        if (isFinal && num == state().boundariesCrossed) {
1142          label_end_computed = true;
1143        } else {
1144        }
1145        state.INTERMEDIATE_VALUE |= intermediate;
1146    
1147        return label_end_value;
1148      }
1149      /**
1150       * @attribute inh
1151       * @aspect ExceptionHandling
1152       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:82
1153       */
1154      /**
1155       * @attribute inh
1156       * @aspect ExceptionHandling
1157       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:82
1158       */
1159      @ASTNodeAnnotation.Attribute
1160      public boolean handlesException(TypeDecl exceptionType) {
1161        Object _parameters = exceptionType;
1162        if (handlesException_TypeDecl_values == null) handlesException_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
1163        ASTNode$State state = state();
1164        if (handlesException_TypeDecl_values.containsKey(_parameters)) {
1165          return (Boolean) handlesException_TypeDecl_values.get(_parameters);
1166        }
1167        boolean intermediate = state.INTERMEDIATE_VALUE;
1168        state.INTERMEDIATE_VALUE = false;
1169        int num = state.boundariesCrossed;
1170        boolean isFinal = this.is$Final();
1171        boolean handlesException_TypeDecl_value = getParent().Define_handlesException(this, null, exceptionType);
1172        if (isFinal && num == state().boundariesCrossed) {
1173          handlesException_TypeDecl_values.put(_parameters, handlesException_TypeDecl_value);
1174        } else {
1175        }
1176        state.INTERMEDIATE_VALUE |= intermediate;
1177    
1178        return handlesException_TypeDecl_value;
1179      }
1180      /**
1181       * @apilevel internal
1182       */
1183      protected java.util.Map handlesException_TypeDecl_values;
1184      /**
1185       * @apilevel internal
1186       */
1187      private void handlesException_TypeDecl_reset() {
1188        handlesException_TypeDecl_values = null;
1189      }
1190      /**
1191       * @attribute inh
1192       * @aspect UnreachableStatements
1193       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:200
1194       */
1195      /**
1196       * @attribute inh
1197       * @aspect UnreachableStatements
1198       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:200
1199       */
1200      @ASTNodeAnnotation.Attribute
1201      public TypeDecl typeError() {
1202        ASTNode$State state = state();
1203        if (typeError_computed) {
1204          return typeError_value;
1205        }
1206        boolean intermediate = state.INTERMEDIATE_VALUE;
1207        state.INTERMEDIATE_VALUE = false;
1208        int num = state.boundariesCrossed;
1209        boolean isFinal = this.is$Final();
1210        typeError_value = getParent().Define_typeError(this, null);
1211        if (isFinal && num == state().boundariesCrossed) {
1212          typeError_computed = true;
1213        } else {
1214        }
1215        state.INTERMEDIATE_VALUE |= intermediate;
1216    
1217        return typeError_value;
1218      }
1219      /**
1220       * @apilevel internal
1221       */
1222      protected boolean typeError_computed = false;
1223      /**
1224       * @apilevel internal
1225       */
1226      protected TypeDecl typeError_value;
1227      /**
1228       * @apilevel internal
1229       */
1230      private void typeError_reset() {
1231        typeError_computed = false;
1232        typeError_value = null;
1233      }
1234      /**
1235       * @attribute inh
1236       * @aspect UnreachableStatements
1237       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:201
1238       */
1239      /**
1240       * @attribute inh
1241       * @aspect UnreachableStatements
1242       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:201
1243       */
1244      @ASTNodeAnnotation.Attribute
1245      public TypeDecl typeRuntimeException() {
1246        ASTNode$State state = state();
1247        if (typeRuntimeException_computed) {
1248          return typeRuntimeException_value;
1249        }
1250        boolean intermediate = state.INTERMEDIATE_VALUE;
1251        state.INTERMEDIATE_VALUE = false;
1252        int num = state.boundariesCrossed;
1253        boolean isFinal = this.is$Final();
1254        typeRuntimeException_value = getParent().Define_typeRuntimeException(this, null);
1255        if (isFinal && num == state().boundariesCrossed) {
1256          typeRuntimeException_computed = true;
1257        } else {
1258        }
1259        state.INTERMEDIATE_VALUE |= intermediate;
1260    
1261        return typeRuntimeException_value;
1262      }
1263      /**
1264       * @apilevel internal
1265       */
1266      protected boolean typeRuntimeException_computed = false;
1267      /**
1268       * @apilevel internal
1269       */
1270      protected TypeDecl typeRuntimeException_value;
1271      /**
1272       * @apilevel internal
1273       */
1274      private void typeRuntimeException_reset() {
1275        typeRuntimeException_computed = false;
1276        typeRuntimeException_value = null;
1277      }
1278      /**
1279       * @attribute inh
1280       * @aspect CodeGeneration
1281       * @declaredat /home/jesper/git/extendj/java4/backend/CodeGeneration.jrag:479
1282       */
1283      /**
1284       * @attribute inh
1285       * @aspect CodeGeneration
1286       * @declaredat /home/jesper/git/extendj/java4/backend/CodeGeneration.jrag:479
1287       */
1288      @ASTNodeAnnotation.Attribute
1289      public TypeDecl typeThrowable() {
1290        TypeDecl typeThrowable_value = getParent().Define_typeThrowable(this, null);
1291    
1292        return typeThrowable_value;
1293      }
1294      /**
1295       * @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:262
1296       * @apilevel internal
1297       */
1298      public FinallyHost Define_enclosingFinally(ASTNode caller, ASTNode child, Stmt branch) {
1299        if (caller == getFinallyOptNoTransform()) {
1300          // @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:269
1301          return enclosingFinally(branch);
1302        }
1303        else {
1304          int childIndex = this.getIndexOfChild(caller);
1305          return hasNonEmptyFinally() ? this : enclosingFinally(branch);
1306        }
1307      }
1308      protected boolean canDefine_enclosingFinally(ASTNode caller, ASTNode child, Stmt branch) {
1309        return true;
1310      }
1311      /**
1312       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:255
1313       * @apilevel internal
1314       */
1315      public boolean Define_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
1316        if (caller == getFinallyOptNoTransform()) {
1317          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:747
1318          return isDAbefore(v);
1319        }
1320        else if (caller == getCatchClauseListNoTransform()) {
1321          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:744
1322          int childIndex = caller.getIndexOfChild(child);
1323          return getBlock().isDAbefore(v);
1324        }
1325        else if (caller == getBlockNoTransform()) {
1326          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:742
1327          return isDAbefore(v);
1328        }
1329        else {
1330          return getParent().Define_isDAbefore(this, caller, v);
1331        }
1332      }
1333      protected boolean canDefine_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
1334        return true;
1335      }
1336      /**
1337       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:779
1338       * @apilevel internal
1339       */
1340      public boolean Define_isDUbefore(ASTNode caller, ASTNode child, Variable v) {
1341        if (caller == getFinallyOptNoTransform()) {
1342          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1377
1343          {
1344              if (!getBlock().isDUeverywhere(v)) {
1345                return false;
1346             }
1347              for (int i = 0; i < getNumCatchClause(); i++) {
1348                if (!getCatchClause(i).getBlock().checkDUeverywhere(v)) {
1349                  return false;
1350               }
1351             }
1352              return true;
1353            }
1354        }
1355        else if (caller == getCatchClauseListNoTransform()) {
1356          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1366
1357          int childIndex = caller.getIndexOfChild(child);
1358          {
1359              if (!getBlock().isDUafter(v)) {
1360                return false;
1361              }
1362              if (!getBlock().isDUeverywhere(v)) {
1363                return false;
1364              }
1365              return true;
1366            }
1367        }
1368        else if (caller == getBlockNoTransform()) {
1369          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1361
1370          return isDUbefore(v);
1371        }
1372        else {
1373          return getParent().Define_isDUbefore(this, caller, v);
1374        }
1375      }
1376      protected boolean canDefine_isDUbefore(ASTNode caller, ASTNode child, Variable v) {
1377        return true;
1378      }
1379      /**
1380       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:113
1381       * @apilevel internal
1382       */
1383      public boolean Define_handlesException(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1384        if (caller == getBlockNoTransform()) {
1385          // @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:246
1386          {
1387              for (int i = 0; i < getNumCatchClause(); i++) {
1388                if (getCatchClause(i).handles(exceptionType)) {
1389                  return true;
1390                }
1391              }
1392              if (hasNonEmptyFinally() && !getFinally().canCompleteNormally()) {
1393                return true;
1394              }
1395              return handlesException(exceptionType);
1396            }
1397        }
1398        else if (caller == getCatchClauseListNoTransform()) {
1399          // @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:239
1400          int childIndex = caller.getIndexOfChild(child);
1401          {
1402              if (hasNonEmptyFinally() && !getFinally().canCompleteNormally()) {
1403                return true;
1404              }
1405              return handlesException(exceptionType);
1406            }
1407        }
1408        else {
1409          return getParent().Define_handlesException(this, caller, exceptionType);
1410        }
1411      }
1412      protected boolean canDefine_handlesException(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1413        return true;
1414      }
1415      /**
1416       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:52
1417       * @apilevel internal
1418       */
1419      public boolean Define_reachable(ASTNode caller, ASTNode child) {
1420        if (caller == getFinallyOptNoTransform()) {
1421          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:179
1422          return reachable();
1423        }
1424        else if (caller == getBlockNoTransform()) {
1425          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:178
1426          return reachable();
1427        }
1428        else {
1429          return getParent().Define_reachable(this, caller);
1430        }
1431      }
1432      protected boolean canDefine_reachable(ASTNode caller, ASTNode child) {
1433        return true;
1434      }
1435      /**
1436       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:185
1437       * @apilevel internal
1438       */
1439      public boolean Define_reachableCatchClause(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1440        if (caller == getCatchClauseListNoTransform()) {
1441          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:186
1442          int childIndex = caller.getIndexOfChild(child);
1443          {
1444              for (int i = 0; i < childIndex; i++) {
1445                if (getCatchClause(i).handles(exceptionType)) {
1446                  return false;
1447                }
1448              }
1449              if (catchableException(exceptionType)) {
1450                return true;
1451              }
1452              if (exceptionType.mayCatch(typeError()) || exceptionType.mayCatch(typeRuntimeException())) {
1453                return true;
1454              }
1455              return false;
1456            }
1457        }
1458        else {
1459          return getParent().Define_reachableCatchClause(this, caller, exceptionType);
1460        }
1461      }
1462      protected boolean canDefine_reachableCatchClause(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1463        return true;
1464      }
1465      /**
1466       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:283
1467       * @apilevel internal
1468       */
1469      public boolean Define_reportUnreachable(ASTNode caller, ASTNode child) {
1470        if (caller == getFinallyOptNoTransform()) {
1471          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:218
1472          return reachable();
1473        }
1474        else if (caller == getCatchClauseListNoTransform()) {
1475          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:217
1476          int childIndex = caller.getIndexOfChild(child);
1477          return reachable();
1478        }
1479        else if (caller == getBlockNoTransform()) {
1480          // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:216
1481          return reachable();
1482        }
1483        else {
1484          return getParent().Define_reportUnreachable(this, caller);
1485        }
1486      }
1487      protected boolean canDefine_reportUnreachable(ASTNode caller, ASTNode child) {
1488        return true;
1489      }
1490      /**
1491       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:64
1492       * @apilevel internal
1493       */
1494      public int Define_localNum(ASTNode caller, ASTNode child) {
1495        if (caller == getExceptionHandlerNoTransform()) {
1496          // @declaredat /home/jesper/git/extendj/java4/backend/LocalNum.jrag:193
1497          return localNum() + 1;
1498        }
1499        else if (caller == getFinallyOptNoTransform()) {
1500          // @declaredat /home/jesper/git/extendj/java4/backend/LocalNum.jrag:192
1501          return localNum();
1502        }
1503        else {
1504          int childIndex = this.getIndexOfChild(caller);
1505          return localNum();
1506        }
1507      }
1508      protected boolean canDefine_localNum(ASTNode caller, ASTNode child) {
1509        return true;
1510      }
1511      /**
1512       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:221
1513       * @apilevel internal
1514       */
1515      public Collection<TypeDecl> Define_caughtExceptions(ASTNode caller, ASTNode child) {
1516        if (caller == getCatchClauseListNoTransform()) {
1517          // @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:223
1518          int index = caller.getIndexOfChild(child);
1519          {
1520              Collection<TypeDecl> excp = new HashSet<TypeDecl>();
1521              getBlock().collectExceptions(excp, this);
1522              Collection<TypeDecl> caught = new LinkedList<TypeDecl>();
1523              Iterator<TypeDecl> iter = excp.iterator();
1524              while (iter.hasNext()) {
1525                TypeDecl exception = iter.next();
1526                // this catch clause handles the exception
1527                if (!getCatchClause(index).handles(exception)) {
1528                  continue;
1529                }
1530                // no previous catch clause handles the exception
1531                boolean already = false;
1532                for (int i = 0; i < index; ++i) {
1533                  if (getCatchClause(i).handles(exception)) {
1534                    already = true;
1535                    break;
1536                  }
1537                }
1538                if (!already) {
1539                  caught.add(exception);
1540                }
1541              }
1542              return caught;
1543            }
1544        }
1545        else {
1546          return getParent().Define_caughtExceptions(this, caller);
1547        }
1548      }
1549      protected boolean canDefine_caughtExceptions(ASTNode caller, ASTNode child) {
1550        return true;
1551      }
1552      /**
1553       * @apilevel internal
1554       */
1555      public ASTNode rewriteTo() {
1556        return super.rewriteTo();
1557      }
1558    }