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     * The JSR 334 try with resources statement.
026     * @ast node
027     * @declaredat /home/jesper/git/extendj/java7/grammar/TryWithResources.ast:4
028     * @production TryWithResources : {@link TryStmt} ::= <span class="component">Resource:{@link ResourceDeclaration}*</span> <span class="component">{@link Block}</span> <span class="component">{@link CatchClause}*</span> <span class="component">[Finally:{@link Block}]</span>;
029    
030     */
031    public class TryWithResources extends TryStmt implements Cloneable, VariableScope {
032      /**
033       * @aspect Java7PrettyPrint
034       * @declaredat /home/jesper/git/extendj/java7/frontend/PrettyPrint.jadd:50
035       */
036      public void prettyPrint(PrettyPrinter out) {
037        out.print("try (");
038        out.join(getResourceList());
039        out.print(") ");
040        out.print(getBlock());
041        if (!out.isNewLine()) {
042          out.println();
043        }
044        if (hasCatchClause()) {
045          out.print(" ");
046          out.join(getCatchClauseList(), new PrettyPrinter.Joiner() {
047            @Override
048            public void printSeparator(PrettyPrinter out) {
049              out.print(" ");
050            }
051          });
052        }
053        if (!out.isNewLine()) {
054          out.println();
055        }
056        if (hasFinally()) {
057          out.print(" finally ");
058          out.print(getFinally());
059        }
060      }
061      /**
062       * Exception error checks.
063       * @aspect TryWithResources
064       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:63
065       */
066      public void exceptionHandling() {
067    
068        // Check exception handling of exceptions on auto closing of resource
069        for (ResourceDeclaration resource : getResourceList()) {
070          MethodDecl close = lookupClose(resource);
071          if (close == null) {
072            continue;
073          }
074          for (Access exception : close.getExceptionList()) {
075            TypeDecl exceptionType = exception.type();
076            if (!twrHandlesException(exceptionType)) {
077              error("automatic closing of resource " + resource.name()
078                  + " may raise the uncaught exception " + exceptionType.fullName() + "; "
079                  + "it must be caught or declared as being thrown");
080            }
081          }
082        }
083      }
084      /**
085       * Returns true if the try-with-resources statement can throw
086       * an exception of type (or a subtype of) catchType.
087       * @aspect TryWithResources
088       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:222
089       */
090      protected boolean reachedException(TypeDecl catchType) {
091        boolean found = false;
092        // found is true if the exception type is caught by a catch clause
093        for (int i = 0; i < getNumCatchClause() && !found; i++) {
094          if (getCatchClause(i).handles(catchType)) {
095            found = true;
096          }
097        }
098        // If an exception is thrown in the block and the exception is not caught and
099        // either there is no finally block or the finally block can complete normally.
100        if (!found && (!hasNonEmptyFinally() || getFinally().canCompleteNormally()) ) {
101          if (catchableException(catchType)) {
102            return true;
103          }
104        }
105        // Even if the exception is caught by the catch clauses they may
106        // throw new exceptions.
107        for (int i = 0; i < getNumCatchClause(); i++) {
108          if (getCatchClause(i).reachedException(catchType)) {
109            return true;
110          }
111        }
112        return hasNonEmptyFinally() && getFinally().reachedException(catchType);
113      }
114      /**
115       * Code generation for the try-with-resources statement.
116       * @aspect TryWithResources
117       * @declaredat /home/jesper/git/extendj/java7/backend/TryWithResources.jrag:81
118       */
119      public void createBCode(CodeGeneration gen) {
120    
121        getTransformed().createBCode(gen);
122      }
123      /**
124       * @declaredat ASTNode:1
125       */
126      public TryWithResources() {
127        super();
128      }
129      /**
130       * Initializes the child array to the correct size.
131       * Initializes List and Opt nta children.
132       * @apilevel internal
133       * @ast method
134       * @declaredat ASTNode:10
135       */
136      public void init$Children() {
137        children = new ASTNode[5];
138        setChild(new List(), 0);
139        setChild(new List(), 2);
140        setChild(new Opt(), 3);
141      }
142      /**
143       * @declaredat ASTNode:16
144       */
145      public TryWithResources(List<ResourceDeclaration> p0, Block p1, List<CatchClause> p2, Opt<Block> p3) {
146        setChild(p0, 0);
147        setChild(p1, 1);
148        setChild(p2, 2);
149        setChild(p3, 3);
150      }
151      /**
152       * @apilevel low-level
153       * @declaredat ASTNode:25
154       */
155      protected int numChildren() {
156        return 4;
157      }
158      /**
159       * @apilevel internal
160       * @declaredat ASTNode:31
161       */
162      public boolean mayHaveRewrite() {
163        return false;
164      }
165      /**
166       * @apilevel internal
167       * @declaredat ASTNode:37
168       */
169      public void flushAttrCache() {
170        super.flushAttrCache();
171        localLookup_String_reset();
172        localVariableDeclaration_String_reset();
173        isDAafter_Variable_reset();
174        catchableException_TypeDecl_reset();
175        getTransformed_reset();
176        handlesException_TypeDecl_reset();
177        typeError_reset();
178        typeRuntimeException_reset();
179        lookupVariable_String_reset();
180      }
181      /**
182       * @apilevel internal
183       * @declaredat ASTNode:52
184       */
185      public void flushCollectionCache() {
186        super.flushCollectionCache();
187      }
188      /**
189       * @apilevel internal
190       * @declaredat ASTNode:58
191       */
192      public void flushRewriteCache() {
193        super.flushRewriteCache();
194      }
195      /**
196       * @apilevel internal
197       * @declaredat ASTNode:64
198       */
199      public TryWithResources clone() throws CloneNotSupportedException {
200        TryWithResources node = (TryWithResources) super.clone();
201        return node;
202      }
203      /**
204       * @apilevel internal
205       * @declaredat ASTNode:71
206       */
207      public TryWithResources copy() {
208        try {
209          TryWithResources node = (TryWithResources) clone();
210          node.parent = null;
211          if (children != null) {
212            node.children = (ASTNode[]) children.clone();
213          }
214          return node;
215        } catch (CloneNotSupportedException e) {
216          throw new Error("Error: clone not supported for " + getClass().getName());
217        }
218      }
219      /**
220       * Create a deep copy of the AST subtree at this node.
221       * The copy is dangling, i.e. has no parent.
222       * @return dangling copy of the subtree at this node
223       * @apilevel low-level
224       * @deprecated Please use treeCopy or treeCopyNoTransform instead
225       * @declaredat ASTNode:90
226       */
227      @Deprecated
228      public TryWithResources fullCopy() {
229        return treeCopyNoTransform();
230      }
231      /**
232       * Create a deep copy of the AST subtree at this node.
233       * The copy is dangling, i.e. has no parent.
234       * @return dangling copy of the subtree at this node
235       * @apilevel low-level
236       * @declaredat ASTNode:100
237       */
238      public TryWithResources treeCopyNoTransform() {
239        TryWithResources tree = (TryWithResources) copy();
240        if (children != null) {
241          for (int i = 0; i < children.length; ++i) {
242            switch (i) {
243            case 4:
244              tree.children[i] = null;
245              continue;
246            }
247            ASTNode child = (ASTNode) children[i];
248            if (child != null) {
249              child = child.treeCopyNoTransform();
250              tree.setChild(child, i);
251            }
252          }
253        }
254        return tree;
255      }
256      /**
257       * Create a deep copy of the AST subtree at this node.
258       * The subtree of this node is traversed to trigger rewrites before copy.
259       * The copy is dangling, i.e. has no parent.
260       * @return dangling copy of the subtree at this node
261       * @apilevel low-level
262       * @declaredat ASTNode:125
263       */
264      public TryWithResources treeCopy() {
265        doFullTraversal();
266        return treeCopyNoTransform();
267      }
268      /**
269       * @apilevel internal
270       * @declaredat ASTNode:132
271       */
272      protected boolean is$Equal(ASTNode node) {
273        return super.is$Equal(node);    
274      }
275      /**
276       * Replaces the Resource list.
277       * @param list The new list node to be used as the Resource list.
278       * @apilevel high-level
279       */
280      public void setResourceList(List<ResourceDeclaration> list) {
281        setChild(list, 0);
282      }
283      /**
284       * Retrieves the number of children in the Resource list.
285       * @return Number of children in the Resource list.
286       * @apilevel high-level
287       */
288      public int getNumResource() {
289        return getResourceList().getNumChild();
290      }
291      /**
292       * Retrieves the number of children in the Resource list.
293       * Calling this method will not trigger rewrites.
294       * @return Number of children in the Resource list.
295       * @apilevel low-level
296       */
297      public int getNumResourceNoTransform() {
298        return getResourceListNoTransform().getNumChildNoTransform();
299      }
300      /**
301       * Retrieves the element at index {@code i} in the Resource list.
302       * @param i Index of the element to return.
303       * @return The element at position {@code i} in the Resource list.
304       * @apilevel high-level
305       */
306      public ResourceDeclaration getResource(int i) {
307        return (ResourceDeclaration) getResourceList().getChild(i);
308      }
309      /**
310       * Check whether the Resource list has any children.
311       * @return {@code true} if it has at least one child, {@code false} otherwise.
312       * @apilevel high-level
313       */
314      public boolean hasResource() {
315        return getResourceList().getNumChild() != 0;
316      }
317      /**
318       * Append an element to the Resource list.
319       * @param node The element to append to the Resource list.
320       * @apilevel high-level
321       */
322      public void addResource(ResourceDeclaration node) {
323        List<ResourceDeclaration> list = (parent == null) ? getResourceListNoTransform() : getResourceList();
324        list.addChild(node);
325      }
326      /**
327       * @apilevel low-level
328       */
329      public void addResourceNoTransform(ResourceDeclaration node) {
330        List<ResourceDeclaration> list = getResourceListNoTransform();
331        list.addChild(node);
332      }
333      /**
334       * Replaces the Resource list element at index {@code i} with the new node {@code node}.
335       * @param node The new node to replace the old list element.
336       * @param i The list index of the node to be replaced.
337       * @apilevel high-level
338       */
339      public void setResource(ResourceDeclaration node, int i) {
340        List<ResourceDeclaration> list = getResourceList();
341        list.setChild(node, i);
342      }
343      /**
344       * Retrieves the Resource list.
345       * @return The node representing the Resource list.
346       * @apilevel high-level
347       */
348      @ASTNodeAnnotation.ListChild(name="Resource")
349      public List<ResourceDeclaration> getResourceList() {
350        List<ResourceDeclaration> list = (List<ResourceDeclaration>) getChild(0);
351        return list;
352      }
353      /**
354       * Retrieves the Resource list.
355       * <p><em>This method does not invoke AST transformations.</em></p>
356       * @return The node representing the Resource list.
357       * @apilevel low-level
358       */
359      public List<ResourceDeclaration> getResourceListNoTransform() {
360        return (List<ResourceDeclaration>) getChildNoTransform(0);
361      }
362      /**
363       * Retrieves the Resource list.
364       * @return The node representing the Resource list.
365       * @apilevel high-level
366       */
367      public List<ResourceDeclaration> getResources() {
368        return getResourceList();
369      }
370      /**
371       * Retrieves the Resource list.
372       * <p><em>This method does not invoke AST transformations.</em></p>
373       * @return The node representing the Resource list.
374       * @apilevel low-level
375       */
376      public List<ResourceDeclaration> getResourcesNoTransform() {
377        return getResourceListNoTransform();
378      }
379      /**
380       * Replaces the Block child.
381       * @param node The new node to replace the Block child.
382       * @apilevel high-level
383       */
384      public void setBlock(Block node) {
385        setChild(node, 1);
386      }
387      /**
388       * Retrieves the Block child.
389       * @return The current node used as the Block child.
390       * @apilevel high-level
391       */
392      @ASTNodeAnnotation.Child(name="Block")
393      public Block getBlock() {
394        return (Block) getChild(1);
395      }
396      /**
397       * Retrieves the Block child.
398       * <p><em>This method does not invoke AST transformations.</em></p>
399       * @return The current node used as the Block child.
400       * @apilevel low-level
401       */
402      public Block getBlockNoTransform() {
403        return (Block) getChildNoTransform(1);
404      }
405      /**
406       * Replaces the CatchClause list.
407       * @param list The new list node to be used as the CatchClause list.
408       * @apilevel high-level
409       */
410      public void setCatchClauseList(List<CatchClause> list) {
411        setChild(list, 2);
412      }
413      /**
414       * Retrieves the number of children in the CatchClause list.
415       * @return Number of children in the CatchClause list.
416       * @apilevel high-level
417       */
418      public int getNumCatchClause() {
419        return getCatchClauseList().getNumChild();
420      }
421      /**
422       * Retrieves the number of children in the CatchClause list.
423       * Calling this method will not trigger rewrites.
424       * @return Number of children in the CatchClause list.
425       * @apilevel low-level
426       */
427      public int getNumCatchClauseNoTransform() {
428        return getCatchClauseListNoTransform().getNumChildNoTransform();
429      }
430      /**
431       * Retrieves the element at index {@code i} in the CatchClause list.
432       * @param i Index of the element to return.
433       * @return The element at position {@code i} in the CatchClause list.
434       * @apilevel high-level
435       */
436      public CatchClause getCatchClause(int i) {
437        return (CatchClause) getCatchClauseList().getChild(i);
438      }
439      /**
440       * Check whether the CatchClause list has any children.
441       * @return {@code true} if it has at least one child, {@code false} otherwise.
442       * @apilevel high-level
443       */
444      public boolean hasCatchClause() {
445        return getCatchClauseList().getNumChild() != 0;
446      }
447      /**
448       * Append an element to the CatchClause list.
449       * @param node The element to append to the CatchClause list.
450       * @apilevel high-level
451       */
452      public void addCatchClause(CatchClause node) {
453        List<CatchClause> list = (parent == null) ? getCatchClauseListNoTransform() : getCatchClauseList();
454        list.addChild(node);
455      }
456      /**
457       * @apilevel low-level
458       */
459      public void addCatchClauseNoTransform(CatchClause node) {
460        List<CatchClause> list = getCatchClauseListNoTransform();
461        list.addChild(node);
462      }
463      /**
464       * Replaces the CatchClause list element at index {@code i} with the new node {@code node}.
465       * @param node The new node to replace the old list element.
466       * @param i The list index of the node to be replaced.
467       * @apilevel high-level
468       */
469      public void setCatchClause(CatchClause node, int i) {
470        List<CatchClause> list = getCatchClauseList();
471        list.setChild(node, i);
472      }
473      /**
474       * Retrieves the CatchClause list.
475       * @return The node representing the CatchClause list.
476       * @apilevel high-level
477       */
478      @ASTNodeAnnotation.ListChild(name="CatchClause")
479      public List<CatchClause> getCatchClauseList() {
480        List<CatchClause> list = (List<CatchClause>) getChild(2);
481        return list;
482      }
483      /**
484       * Retrieves the CatchClause list.
485       * <p><em>This method does not invoke AST transformations.</em></p>
486       * @return The node representing the CatchClause list.
487       * @apilevel low-level
488       */
489      public List<CatchClause> getCatchClauseListNoTransform() {
490        return (List<CatchClause>) getChildNoTransform(2);
491      }
492      /**
493       * Retrieves the CatchClause list.
494       * @return The node representing the CatchClause list.
495       * @apilevel high-level
496       */
497      public List<CatchClause> getCatchClauses() {
498        return getCatchClauseList();
499      }
500      /**
501       * Retrieves the CatchClause list.
502       * <p><em>This method does not invoke AST transformations.</em></p>
503       * @return The node representing the CatchClause list.
504       * @apilevel low-level
505       */
506      public List<CatchClause> getCatchClausesNoTransform() {
507        return getCatchClauseListNoTransform();
508      }
509      /**
510       * Replaces the optional node for the Finally child. This is the <code>Opt</code>
511       * node containing the child Finally, not the actual child!
512       * @param opt The new node to be used as the optional node for the Finally child.
513       * @apilevel low-level
514       */
515      public void setFinallyOpt(Opt<Block> opt) {
516        setChild(opt, 3);
517      }
518      /**
519       * Replaces the (optional) Finally child.
520       * @param node The new node to be used as the Finally child.
521       * @apilevel high-level
522       */
523      public void setFinally(Block node) {
524        getFinallyOpt().setChild(node, 0);
525      }
526      /**
527       * Check whether the optional Finally child exists.
528       * @return {@code true} if the optional Finally child exists, {@code false} if it does not.
529       * @apilevel high-level
530       */
531      public boolean hasFinally() {
532        return getFinallyOpt().getNumChild() != 0;
533      }
534      /**
535       * Retrieves the (optional) Finally child.
536       * @return The Finally child, if it exists. Returns {@code null} otherwise.
537       * @apilevel low-level
538       */
539      public Block getFinally() {
540        return (Block) getFinallyOpt().getChild(0);
541      }
542      /**
543       * Retrieves the optional node for the Finally child. This is the <code>Opt</code> node containing the child Finally, not the actual child!
544       * @return The optional node for child the Finally child.
545       * @apilevel low-level
546       */
547      @ASTNodeAnnotation.OptChild(name="Finally")
548      public Opt<Block> getFinallyOpt() {
549        return (Opt<Block>) getChild(3);
550      }
551      /**
552       * Retrieves the optional node for child Finally. This is the <code>Opt</code> node containing the child Finally, not the actual child!
553       * <p><em>This method does not invoke AST transformations.</em></p>
554       * @return The optional node for child Finally.
555       * @apilevel low-level
556       */
557      public Opt<Block> getFinallyOptNoTransform() {
558        return (Opt<Block>) getChildNoTransform(3);
559      }
560      /**
561       * Retrieves the ExceptionHandler child.
562       * <p><em>This method does not invoke AST transformations.</em></p>
563       * @return The current node used as the ExceptionHandler child.
564       * @apilevel low-level
565       */
566      public Block getExceptionHandlerNoTransform() {
567        return (Block) getChildNoTransform(4);
568      }
569      /**
570       * Retrieves the child position of the optional child ExceptionHandler.
571       * @return The the child position of the optional child ExceptionHandler.
572       * @apilevel low-level
573       */
574      protected int getExceptionHandlerChildPosition() {
575        return 4;
576      }
577      /**
578       * This attribute computes whether or not the TWR statement
579       * has a catch clause which handles the exception.
580       * @attribute syn
581       * @aspect TryWithResources
582       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:86
583       */
584      @ASTNodeAnnotation.Attribute
585      public boolean catchHandlesException(TypeDecl exceptionType) {
586        {
587            for (int i = 0; i < getNumCatchClause(); i++) {
588              if (getCatchClause(i).handles(exceptionType)) {
589                return true;
590              }
591            }
592            return false;
593          }
594      }
595      /**
596       * Returns true if exceptions of type exceptionType are handled
597       * in the try-with-resources statement or any containing statement
598       * within the directly enclosing method or initializer block.
599       * @attribute syn
600       * @aspect TryWithResources
601       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:100
602       */
603      @ASTNodeAnnotation.Attribute
604      public boolean twrHandlesException(TypeDecl exceptionType) {
605        {
606            if (catchHandlesException(exceptionType)) {
607              return true;
608            }
609            if (hasNonEmptyFinally() && !getFinally().canCompleteNormally()) {
610              return true;
611            }
612            return handlesException(exceptionType);
613          }
614      }
615      /**
616       * Lookup the close method declaration for the resource which is being used.
617       * @attribute syn
618       * @aspect TryWithResources
619       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:125
620       */
621      @ASTNodeAnnotation.Attribute
622      public MethodDecl lookupClose(ResourceDeclaration resource) {
623        {
624            TypeDecl resourceType = resource.getTypeAccess().type();
625            for (MethodDecl method : (Collection<MethodDecl>) resourceType.memberMethods("close")) {
626              if (method.getNumParameter() == 0) {
627                return method;
628              }
629            }
630            return null;
631            /* We can't throw a runtime exception here. If there is no close method it
632             * likely means that the resource type is not a subtype of java.lang.AutoCloseable
633             * and type checking will report this error.
634             */
635            //throw new RuntimeException("close() not found for resource type "+resourceType.fullName());
636          }
637      }
638      /**
639       * @apilevel internal
640       */
641      protected java.util.Map localLookup_String_values;
642      /**
643       * @apilevel internal
644       */
645      private void localLookup_String_reset() {
646        localLookup_String_values = null;
647      }
648      /**
649       * @attribute syn
650       * @aspect TryWithResources
651       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:162
652       */
653      @ASTNodeAnnotation.Attribute
654      public SimpleSet localLookup(String name) {
655        Object _parameters = name;
656        if (localLookup_String_values == null) localLookup_String_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
657        ASTNode$State state = state();
658        if (localLookup_String_values.containsKey(_parameters)) {
659          return (SimpleSet) localLookup_String_values.get(_parameters);
660        }
661        boolean intermediate = state.INTERMEDIATE_VALUE;
662        state.INTERMEDIATE_VALUE = false;
663        int num = state.boundariesCrossed;
664        boolean isFinal = this.is$Final();
665        SimpleSet localLookup_String_value = localLookup_compute(name);
666        if (isFinal && num == state().boundariesCrossed) {
667          localLookup_String_values.put(_parameters, localLookup_String_value);
668        } else {
669        }
670        state.INTERMEDIATE_VALUE |= intermediate;
671    
672        return localLookup_String_value;
673      }
674      /**
675       * @apilevel internal
676       */
677      private SimpleSet localLookup_compute(String name) {
678          VariableDeclaration v = localVariableDeclaration(name);
679          if (v != null) {
680            return v;
681          }
682          return lookupVariable(name);
683        }
684      /**
685       * @apilevel internal
686       */
687      protected java.util.Map localVariableDeclaration_String_values;
688      /**
689       * @apilevel internal
690       */
691      private void localVariableDeclaration_String_reset() {
692        localVariableDeclaration_String_values = null;
693      }
694      /**
695       * @attribute syn
696       * @aspect TryWithResources
697       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:169
698       */
699      @ASTNodeAnnotation.Attribute
700      public VariableDeclaration localVariableDeclaration(String name) {
701        Object _parameters = name;
702        if (localVariableDeclaration_String_values == null) localVariableDeclaration_String_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
703        ASTNode$State state = state();
704        if (localVariableDeclaration_String_values.containsKey(_parameters)) {
705          return (VariableDeclaration) localVariableDeclaration_String_values.get(_parameters);
706        }
707        boolean intermediate = state.INTERMEDIATE_VALUE;
708        state.INTERMEDIATE_VALUE = false;
709        int num = state.boundariesCrossed;
710        boolean isFinal = this.is$Final();
711        VariableDeclaration localVariableDeclaration_String_value = localVariableDeclaration_compute(name);
712        if (isFinal && num == state().boundariesCrossed) {
713          localVariableDeclaration_String_values.put(_parameters, localVariableDeclaration_String_value);
714        } else {
715        }
716        state.INTERMEDIATE_VALUE |= intermediate;
717    
718        return localVariableDeclaration_String_value;
719      }
720      /**
721       * @apilevel internal
722       */
723      private VariableDeclaration localVariableDeclaration_compute(String name) {
724          for (ResourceDeclaration resource : getResourceList()) {
725            if (resource.declaresVariable(name)) {
726              return resource;
727            }
728          }
729          return null;
730        }
731      /**
732       * @apilevel internal
733       */
734      protected java.util.Map isDAafter_Variable_values;
735      /**
736       * @apilevel internal
737       */
738      private void isDAafter_Variable_reset() {
739        isDAafter_Variable_values = null;
740      }
741      /**
742       * @attribute syn
743       * @aspect DA
744       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:257
745       */
746      @ASTNodeAnnotation.Attribute
747      public boolean isDAafter(Variable v) {
748        Object _parameters = v;
749        if (isDAafter_Variable_values == null) isDAafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
750        ASTNode$State state = state();
751        if (isDAafter_Variable_values.containsKey(_parameters)) {
752          return (Boolean) isDAafter_Variable_values.get(_parameters);
753        }
754        boolean intermediate = state.INTERMEDIATE_VALUE;
755        state.INTERMEDIATE_VALUE = false;
756        int num = state.boundariesCrossed;
757        boolean isFinal = this.is$Final();
758        boolean isDAafter_Variable_value = getBlock().isDAafter(v);
759        if (isFinal && num == state().boundariesCrossed) {
760          isDAafter_Variable_values.put(_parameters, isDAafter_Variable_value);
761        } else {
762        }
763        state.INTERMEDIATE_VALUE |= intermediate;
764    
765        return isDAafter_Variable_value;
766      }
767      /**
768       * True if the automatic closing of resources in this try-with-resources statement
769       * may throw an exception of type catchType.
770       * @attribute syn
771       * @aspect TryWithResources
772       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:251
773       */
774      @ASTNodeAnnotation.Attribute
775      public boolean resourceClosingException(TypeDecl catchType) {
776        {
777            for (ResourceDeclaration resource : getResourceList()) {
778              MethodDecl close = lookupClose(resource);
779              if (close == null) {
780                continue;
781              }
782              for (Access exception : close.getExceptionList()) {
783                TypeDecl exceptionType = exception.type();
784                if (catchType.mayCatch(exception.type())) {
785                  return true;
786                }
787              }
788            }
789            return false;
790          }
791      }
792      /**
793       * True if the resource initialization of this try-with-resources statement
794       * may throw an exception of type catchType.
795       * @attribute syn
796       * @aspect TryWithResources
797       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:271
798       */
799      @ASTNodeAnnotation.Attribute
800      public boolean resourceInitializationException(TypeDecl catchType) {
801        {
802            for (ResourceDeclaration resource : getResourceList()) {
803              if (resource.reachedException(catchType)) {
804                return true;
805              }
806            }
807            return false;
808          }
809      }
810      /**
811       * @apilevel internal
812       */
813      protected java.util.Map catchableException_TypeDecl_values;
814      /**
815       * @apilevel internal
816       */
817      private void catchableException_TypeDecl_reset() {
818        catchableException_TypeDecl_values = null;
819      }
820      /**
821       * The block of the try statement can throw an exception of
822       * a type assignable to the given type.
823       * @attribute syn
824       * @aspect ExceptionHandling
825       * @declaredat /home/jesper/git/extendj/java4/frontend/ExceptionHandling.jrag:268
826       */
827      @ASTNodeAnnotation.Attribute
828      public boolean catchableException(TypeDecl type) {
829        Object _parameters = type;
830        if (catchableException_TypeDecl_values == null) catchableException_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
831        ASTNode$State state = state();
832        if (catchableException_TypeDecl_values.containsKey(_parameters)) {
833          return (Boolean) catchableException_TypeDecl_values.get(_parameters);
834        }
835        boolean intermediate = state.INTERMEDIATE_VALUE;
836        state.INTERMEDIATE_VALUE = false;
837        int num = state.boundariesCrossed;
838        boolean isFinal = this.is$Final();
839        boolean catchableException_TypeDecl_value = getBlock().reachedException(type)
840              || resourceClosingException(type)
841              || resourceInitializationException(type);
842        if (isFinal && num == state().boundariesCrossed) {
843          catchableException_TypeDecl_values.put(_parameters, catchableException_TypeDecl_value);
844        } else {
845        }
846        state.INTERMEDIATE_VALUE |= intermediate;
847    
848        return catchableException_TypeDecl_value;
849      }
850      /**
851       * @apilevel internal
852       */
853      protected boolean getTransformed_computed = false;
854      /**
855       * @apilevel internal
856       */
857      protected Stmt getTransformed_value;
858      /**
859       * @apilevel internal
860       */
861      private void getTransformed_reset() {
862        getTransformed_computed = false;
863        getTransformed_value = null;
864      }
865      /**
866       * An NTA which is used for code generation.
867       * 
868       * This NTA will handle the recursive nature of code
869       * generation for try-with-resources statements.
870       * @attribute syn
871       * @aspect TryWithResources
872       * @declaredat /home/jesper/git/extendj/java7/backend/TryWithResources.jrag:39
873       */
874      @ASTNodeAnnotation.Attribute
875      public Stmt getTransformed() {
876        ASTNode$State state = state();
877        if (getTransformed_computed) {
878          return getTransformed_value;
879        }
880        boolean intermediate = state.INTERMEDIATE_VALUE;
881        state.INTERMEDIATE_VALUE = false;
882        int num = state.boundariesCrossed;
883        boolean isFinal = this.is$Final();
884        getTransformed_value = getTransformed_compute();
885        getTransformed_value.setParent(this);
886        getTransformed_value.is$Final = true;
887        if (true) {
888          getTransformed_computed = true;
889        } else {
890        }
891        state.INTERMEDIATE_VALUE |= intermediate;
892    
893        return getTransformed_value;
894      }
895      /**
896       * @apilevel internal
897       */
898      private Stmt getTransformed_compute() {
899          if (getNumCatchClause() == 0 && !hasNonEmptyFinally()) {
900            // transform to BasicTWR
901            Block block;
902            if (getNumResource() == 1) {
903              block = (Block) getBlock().treeCopyNoTransform();
904            } else {
905              block = new Block();
906              List<ResourceDeclaration> resourceListTail = new List<ResourceDeclaration>();
907              for (int i = 1; i < getNumResource(); ++i) {
908                resourceListTail.add((ResourceDeclaration)
909                    getResource(i).treeCopyNoTransform());
910              }
911              block.addStmt(new TryWithResources(
912                    resourceListTail,
913                    (Block) getBlock().treeCopyNoTransform(),
914                    new List<CatchClause>(),
915                    new Opt<Block>()));
916            }
917            return new BasicTWR(
918                (ResourceDeclaration)
919                getResource(0).treeCopyNoTransform(),
920                block);
921          } else {
922            // transform to surrounding try stmt
923            Block block = new Block();
924            block.addStmt(new TryWithResources(
925                  (List<ResourceDeclaration>)
926                  getResourceList().treeCopyNoTransform(),
927                  (Block) getBlock().treeCopyNoTransform(),
928                  new List<CatchClause>(),
929                  new Opt<Block>()));
930      
931            return new TryStmt(block,
932                (List<CatchClause>) getCatchClauseList().treeCopyNoTransform(),
933                (Opt<Block>) getFinallyOpt().treeCopyNoTransform());
934          }
935        }
936      /**
937       * Inherit the handlesException attribute from methoddecl.
938       * @attribute inh
939       * @aspect TryWithResources
940       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:113
941       */
942      /**
943       * Inherit the handlesException attribute from methoddecl.
944       * @attribute inh
945       * @aspect TryWithResources
946       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:113
947       */
948      @ASTNodeAnnotation.Attribute
949      public boolean handlesException(TypeDecl exceptionType) {
950        Object _parameters = exceptionType;
951        if (handlesException_TypeDecl_values == null) handlesException_TypeDecl_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
952        ASTNode$State state = state();
953        if (handlesException_TypeDecl_values.containsKey(_parameters)) {
954          return (Boolean) handlesException_TypeDecl_values.get(_parameters);
955        }
956        boolean intermediate = state.INTERMEDIATE_VALUE;
957        state.INTERMEDIATE_VALUE = false;
958        int num = state.boundariesCrossed;
959        boolean isFinal = this.is$Final();
960        boolean handlesException_TypeDecl_value = getParent().Define_handlesException(this, null, exceptionType);
961        if (isFinal && num == state().boundariesCrossed) {
962          handlesException_TypeDecl_values.put(_parameters, handlesException_TypeDecl_value);
963        } else {
964        }
965        state.INTERMEDIATE_VALUE |= intermediate;
966    
967        return handlesException_TypeDecl_value;
968      }
969      /**
970       * @apilevel internal
971       */
972      protected java.util.Map handlesException_TypeDecl_values;
973      /**
974       * @apilevel internal
975       */
976      private void handlesException_TypeDecl_reset() {
977        handlesException_TypeDecl_values = null;
978      }
979      /**
980       * @attribute inh
981       * @aspect TryWithResources
982       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:140
983       */
984      /**
985       * @attribute inh
986       * @aspect TryWithResources
987       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:140
988       */
989      @ASTNodeAnnotation.Attribute
990      public TypeDecl typeError() {
991        ASTNode$State state = state();
992        if (typeError_computed) {
993          return typeError_value;
994        }
995        boolean intermediate = state.INTERMEDIATE_VALUE;
996        state.INTERMEDIATE_VALUE = false;
997        int num = state.boundariesCrossed;
998        boolean isFinal = this.is$Final();
999        typeError_value = getParent().Define_typeError(this, null);
1000        if (isFinal && num == state().boundariesCrossed) {
1001          typeError_computed = true;
1002        } else {
1003        }
1004        state.INTERMEDIATE_VALUE |= intermediate;
1005    
1006        return typeError_value;
1007      }
1008      /**
1009       * @apilevel internal
1010       */
1011      protected boolean typeError_computed = false;
1012      /**
1013       * @apilevel internal
1014       */
1015      protected TypeDecl typeError_value;
1016      /**
1017       * @apilevel internal
1018       */
1019      private void typeError_reset() {
1020        typeError_computed = false;
1021        typeError_value = null;
1022      }
1023      /**
1024       * @attribute inh
1025       * @aspect TryWithResources
1026       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:141
1027       */
1028      /**
1029       * @attribute inh
1030       * @aspect TryWithResources
1031       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:141
1032       */
1033      @ASTNodeAnnotation.Attribute
1034      public TypeDecl typeRuntimeException() {
1035        ASTNode$State state = state();
1036        if (typeRuntimeException_computed) {
1037          return typeRuntimeException_value;
1038        }
1039        boolean intermediate = state.INTERMEDIATE_VALUE;
1040        state.INTERMEDIATE_VALUE = false;
1041        int num = state.boundariesCrossed;
1042        boolean isFinal = this.is$Final();
1043        typeRuntimeException_value = getParent().Define_typeRuntimeException(this, null);
1044        if (isFinal && num == state().boundariesCrossed) {
1045          typeRuntimeException_computed = true;
1046        } else {
1047        }
1048        state.INTERMEDIATE_VALUE |= intermediate;
1049    
1050        return typeRuntimeException_value;
1051      }
1052      /**
1053       * @apilevel internal
1054       */
1055      protected boolean typeRuntimeException_computed = false;
1056      /**
1057       * @apilevel internal
1058       */
1059      protected TypeDecl typeRuntimeException_value;
1060      /**
1061       * @apilevel internal
1062       */
1063      private void typeRuntimeException_reset() {
1064        typeRuntimeException_computed = false;
1065        typeRuntimeException_value = null;
1066      }
1067      /**
1068       * @attribute inh
1069       * @aspect TryWithResources
1070       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:179
1071       */
1072      /**
1073       * @attribute inh
1074       * @aspect TryWithResources
1075       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:179
1076       */
1077      @ASTNodeAnnotation.Attribute
1078      public SimpleSet lookupVariable(String name) {
1079        Object _parameters = name;
1080        if (lookupVariable_String_values == null) lookupVariable_String_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
1081        ASTNode$State state = state();
1082        if (lookupVariable_String_values.containsKey(_parameters)) {
1083          return (SimpleSet) lookupVariable_String_values.get(_parameters);
1084        }
1085        boolean intermediate = state.INTERMEDIATE_VALUE;
1086        state.INTERMEDIATE_VALUE = false;
1087        int num = state.boundariesCrossed;
1088        boolean isFinal = this.is$Final();
1089        SimpleSet lookupVariable_String_value = getParent().Define_lookupVariable(this, null, name);
1090        if (isFinal && num == state().boundariesCrossed) {
1091          lookupVariable_String_values.put(_parameters, lookupVariable_String_value);
1092        } else {
1093        }
1094        state.INTERMEDIATE_VALUE |= intermediate;
1095    
1096        return lookupVariable_String_value;
1097      }
1098      /**
1099       * @apilevel internal
1100       */
1101      protected java.util.Map lookupVariable_String_values;
1102      /**
1103       * @apilevel internal
1104       */
1105      private void lookupVariable_String_reset() {
1106        lookupVariable_String_values = null;
1107      }
1108      /**
1109       * @attribute inh
1110       * @aspect TryWithResources
1111       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:183
1112       */
1113      /**
1114       * @attribute inh
1115       * @aspect TryWithResources
1116       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:183
1117       */
1118      @ASTNodeAnnotation.Attribute
1119      public boolean resourcePreviouslyDeclared(String name) {
1120        boolean resourcePreviouslyDeclared_String_value = getParent().Define_resourcePreviouslyDeclared(this, null, name);
1121    
1122        return resourcePreviouslyDeclared_String_value;
1123      }
1124      /**
1125       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:113
1126       * @apilevel internal
1127       */
1128      public boolean Define_handlesException(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1129        if (caller == getBlockNoTransform()) {
1130          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:118
1131          return twrHandlesException(exceptionType);
1132        }
1133        else if (caller == getResourceListNoTransform()) {
1134          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:115
1135          int i = caller.getIndexOfChild(child);
1136          return twrHandlesException(exceptionType);
1137        }
1138        else {
1139          return super.Define_handlesException(caller, child, exceptionType);
1140        }
1141      }
1142      protected boolean canDefine_handlesException(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1143        return true;
1144      }
1145      /**
1146       * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:185
1147       * @apilevel internal
1148       */
1149      public boolean Define_reachableCatchClause(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1150        if (caller == getCatchClauseListNoTransform()) {
1151          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:143
1152          int childIndex = caller.getIndexOfChild(child);
1153          {
1154              for (int i = 0; i < childIndex; i++) {
1155                if (getCatchClause(i).handles(exceptionType)) {
1156                  return false;
1157                }
1158              }
1159              if (catchableException(exceptionType)) {
1160                return true;
1161              }
1162              if (exceptionType.mayCatch(typeError()) || exceptionType.mayCatch(typeRuntimeException())) {
1163                return true;
1164              }
1165              return false;
1166            }
1167        }
1168        else {
1169          return super.Define_reachableCatchClause(caller, child, exceptionType);
1170        }
1171      }
1172      protected boolean canDefine_reachableCatchClause(ASTNode caller, ASTNode child, TypeDecl exceptionType) {
1173        return true;
1174      }
1175      /**
1176       * @declaredat /home/jesper/git/extendj/java8/frontend/LookupVariable.jrag:30
1177       * @apilevel internal
1178       */
1179      public SimpleSet Define_lookupVariable(ASTNode caller, ASTNode child, String name) {
1180        if (caller == getBlockNoTransform()) {
1181          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:161
1182          return localLookup(name);
1183        }
1184        else {
1185          return getParent().Define_lookupVariable(this, caller, name);
1186        }
1187      }
1188      protected boolean canDefine_lookupVariable(ASTNode caller, ASTNode child, String name) {
1189        return true;
1190      }
1191      /**
1192       * @declaredat /home/jesper/git/extendj/java8/frontend/NameCheck.jrag:30
1193       * @apilevel internal
1194       */
1195      public VariableScope Define_outerScope(ASTNode caller, ASTNode child) {
1196        if (caller == getResourceListNoTransform()) {
1197          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:180
1198          int i = caller.getIndexOfChild(child);
1199          return this;
1200        }
1201        else {
1202          return getParent().Define_outerScope(this, caller);
1203        }
1204      }
1205      protected boolean canDefine_outerScope(ASTNode caller, ASTNode child) {
1206        return true;
1207      }
1208      /**
1209       * @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:183
1210       * @apilevel internal
1211       */
1212      public boolean Define_resourcePreviouslyDeclared(ASTNode caller, ASTNode child, String name) {
1213        if (caller == getResourceListNoTransform()) {
1214          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:184
1215          int index = caller.getIndexOfChild(child);
1216          {
1217              for (int i = 0; i < index; ++i) {
1218                if (getResource(i).name().equals(name)) {
1219                  return true;
1220                }
1221              }
1222              return false;
1223            }
1224        }
1225        else {
1226          return getParent().Define_resourcePreviouslyDeclared(this, caller, name);
1227        }
1228      }
1229      protected boolean canDefine_resourcePreviouslyDeclared(ASTNode caller, ASTNode child, String name) {
1230        return true;
1231      }
1232      /**
1233       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:255
1234       * @apilevel internal
1235       */
1236      public boolean Define_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
1237        if (caller == getBlockNoTransform()) {
1238          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:213
1239          return getNumResource() == 0
1240                ? isDAbefore(v)
1241                : getResource(getNumResource() - 1).isDAafter(v);
1242        }
1243        else if (caller == getResourceListNoTransform()) {
1244          // @declaredat /home/jesper/git/extendj/java7/frontend/TryWithResources.jrag:210
1245          int index = caller.getIndexOfChild(child);
1246          return index == 0 ? isDAbefore(v) : getResource(index - 1).isDAafter(v);
1247        }
1248        else {
1249          return super.Define_isDAbefore(caller, child, v);
1250        }
1251      }
1252      protected boolean canDefine_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
1253        return true;
1254      }
1255      /**
1256       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:64
1257       * @apilevel internal
1258       */
1259      public int Define_localNum(ASTNode caller, ASTNode child) {
1260        if (caller == getBlockNoTransform()) {
1261          // @declaredat /home/jesper/git/extendj/java7/backend/TryWithResources.jrag:309
1262          return 100;
1263        }
1264        else if (caller == getResourceListNoTransform()) {
1265          // @declaredat /home/jesper/git/extendj/java7/backend/TryWithResources.jrag:308
1266          int index = caller.getIndexOfChild(child);
1267          return 50;
1268        }
1269        else {
1270          return super.Define_localNum(caller, child);
1271        }
1272      }
1273      protected boolean canDefine_localNum(ASTNode caller, ASTNode child) {
1274        return true;
1275      }
1276      /**
1277       * @apilevel internal
1278       */
1279      public ASTNode rewriteTo() {
1280        return super.rewriteTo();
1281      }
1282    }