001    /* This file was generated with JastAdd2 (http://jastadd.org) version R20130213 */
002    package AST;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.*;
007    import beaver.*;
008    import java.util.ArrayList;
009    import java.util.zip.*;
010    import java.io.*;
011    import java.io.FileNotFoundException;
012    import java.util.Collection;
013    /**
014     * @production BasicTWR : {@link Stmt} ::= <span class="component">Resource:{@link ResourceDeclaration}</span> <span class="component">{@link Block}</span>;
015     * @ast node
016     * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/BasicTWR.ast:1
017     */
018    public class BasicTWR extends Stmt implements Cloneable, VariableScope {
019      /**
020       * @apilevel low-level
021       */
022      public void flushCache() {
023      }
024      /**
025       * @apilevel internal
026       */
027      public void flushCollectionCache() {
028      }
029      /**
030       * @apilevel internal
031       */
032      @SuppressWarnings({"unchecked", "cast"})
033      public BasicTWR clone() throws CloneNotSupportedException {
034        BasicTWR node = (BasicTWR)super.clone();
035        node.localLookup_String_values = null;
036        node.localVariableDeclaration_String_values = null;
037        node.lookupVariable_String_values = null;
038        node.in$Circle(false);
039        node.is$Final(false);
040        return node;
041      }
042    /**
043     * @apilevel internal
044     */
045      @SuppressWarnings({"unchecked", "cast"})
046    public BasicTWR copy() {
047      
048      try {
049        BasicTWR node = (BasicTWR) clone();
050        node.parent = null;
051        if(children != null)
052          node.children = (ASTNode[]) children.clone();
053        
054        return node;
055      } catch (CloneNotSupportedException e) {
056        throw new Error("Error: clone not supported for " + getClass().getName());
057      }
058      
059    }/**
060     * Create a deep copy of the AST subtree at this node.
061     * The copy is dangling, i.e. has no parent.
062     * @return dangling copy of the subtree at this node
063     * @apilevel low-level
064     */
065      @SuppressWarnings({"unchecked", "cast"})
066    public BasicTWR fullCopy() {
067      
068      BasicTWR tree = (BasicTWR) copy();
069      if (children != null) {
070        for (int i = 0; i < children.length; ++i) {
071          
072          ASTNode child = (ASTNode) children[i];
073          if(child != null) {
074            child = child.fullCopy();
075            tree.setChild(child, i);
076          }
077        }
078      }
079      return tree;
080      
081    }  /**
082         * The general structure of the basic try-with-resources:
083         *
084         * <pre><code>
085         * RESOURCE
086         * BLOCK
087         *
088         * Primary Exception Handler
089         *   Automatic Closing of Resource
090         *     Suppressed Exception Handler
091         *   re-throw primary exception
092         * Automatic Closing of Resource
093         * </pre></code>
094         *
095         * Pseudocode for basic try-with-resources:
096         *
097         * <pre><code>
098         * 0  .resourceBegin
099         * 1  emit RESOURCE
100        * 0  store resource
101        * 0  .resourceEnd
102        *
103        * 0  .blockBegin
104        * 0  emit BLOCK
105        * 0  .blockEnd
106        * 0  goto outerFinally
107        *
108        * 1  .resourceException
109        * 1  throw
110        *
111        * #if BLOCK is not empty:
112        *
113        * 1  .catchPrimary
114        * 0  store primary
115        *
116        * 0  .tryCloseBegin
117        * 1  load resource
118        * 0  ifnull innerFinally
119        * 1  load resource
120        * 0  invoke java.lang.AutoCloseable.close()
121        * 0  .tryCloseEnd
122        *
123        * 0  goto innerFinally
124        *
125        * 1  .catchSuppressed
126        * 0  store suppressed
127        * 1  load primary
128        * 2  load suppressed
129        * 0  invoke java.lang.Throwable.addSuppressed(Throwable)
130        *
131        * 0  .innerFinally
132        * 1  load primary
133        * 1  throw
134        *
135        * #endif BLOCK is not empty
136        *
137        * 0  .outerFinally
138        * 1  load resource
139        * 0  ifnull tryEnd
140        * 1  load resource
141        * 0  invoke java.lang.AutoCloseable.close()
142        *
143        * 0  .tryEnd
144        *
145        * Exception Table:
146        * resourceBegin .. resourceEnd : resourceException
147        * blockBegin .. blockEnd : catchPrimary
148        * tryCloseBegin .. tryCloseEnd : catchSuppressed
149        * </pre></code>
150        *
151        * @ast method 
152       * @aspect TryWithResources
153       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:136
154       */
155      public void createBCode(CodeGeneration gen) {
156               ResourceDeclaration resource = getResource();
157    
158               int resourceBeginLbl = hostType().constantPool().newLabel();
159               int resourceEndLbl = hostType().constantPool().newLabel();
160               int blockBeginLbl = hostType().constantPool().newLabel();
161               int blockEndLbl = hostType().constantPool().newLabel();
162               int tryCloseBeginLbl = hostType().constantPool().newLabel();
163               int tryCloseEndLbl = hostType().constantPool().newLabel();
164    
165               int resourceExceptionLbl = hostType().constantPool().newLabel();
166               int catchPrimaryLbl = hostType().constantPool().newLabel();
167               int catchSuppressedLbl = hostType().constantPool().newLabel();
168               int innerFinallyLbl = hostType().constantPool().newLabel();
169               int outerFinallyLbl = hostType().constantPool().newLabel();
170               int tryEndLbl = hostType().constantPool().newLabel();
171    
172               TypeDecl throwableType = lookupType("java.lang", "Throwable");
173               TypeDecl resourceType = resource.type();
174               TypeDecl autoCloseableType = lookupType("java.lang", "AutoCloseable");
175    
176               gen.changeStackDepth(3);
177               int resourceIndex = resource.localNum();
178               int primaryIndex = resourceIndex+resourceType.variableSize();
179               int suppressedIndex = primaryIndex+throwableType.variableSize();
180    
181               // store the resource in local
182               gen.addLabel(resourceBeginLbl);
183               resource.createBCode(gen);
184               gen.addLabel(resourceEndLbl);
185               gen.emit(Bytecode.NOP);
186    
187               gen.addLabel(blockBeginLbl);
188               getBlock().createBCode(gen);
189               gen.addLabel(blockEndLbl);
190               gen.emitGoto(outerFinallyLbl);
191    
192               // If there was an exception when initializing the resource
193               // we need to directly rethrow the exception
194               gen.addLabel(resourceExceptionLbl);
195               gen.emitThrow();
196               gen.addException(
197                       gen.addressOf(resourceBeginLbl),
198                       gen.addressOf(resourceEndLbl),
199                       gen.addressOf(resourceExceptionLbl),
200                       0);
201    
202               if (gen.addressOf(blockBeginLbl) != gen.addressOf(blockEndLbl)) {
203    
204                       // catch primary exception
205                       // operand stack: .., #primary
206                       gen.addLabel(catchPrimaryLbl);
207                       throwableType.emitStoreLocal(gen, primaryIndex);
208    
209                       // try-close resource
210                       gen.addLabel(tryCloseBeginLbl);
211                       {
212                               // if resource != null
213                               resourceType.emitLoadLocal(gen, resourceIndex);
214                               gen.emitCompare(Bytecode.IFNULL, innerFinallyLbl);
215                               resourceType.emitLoadLocal(gen, resourceIndex);
216                               closeMethod().emitInvokeMethod(gen, autoCloseableType);
217                       }
218                       gen.addLabel(tryCloseEndLbl);
219                       gen.emitGoto(innerFinallyLbl);
220                       
221                       // catch suppressed exception
222                       // operand stack: .., #primary, #suppressed
223                       gen.addLabel(catchSuppressedLbl);
224                       throwableType.emitStoreLocal(gen, suppressedIndex);
225                       throwableType.emitLoadLocal(gen, primaryIndex);
226                       throwableType.emitLoadLocal(gen, suppressedIndex);
227                       addSuppressedMethod().emitInvokeMethod(gen, throwableType);
228    
229                       // inner finally
230                       // operand stack: .., #primary
231                       gen.addLabel(innerFinallyLbl);
232                       throwableType.emitLoadLocal(gen, primaryIndex);
233                       gen.emitThrow();
234    
235                       // If there was an exception during the block of the try
236                       // statement, then we should try to close the resource
237                       gen.addException(
238                               gen.addressOf(blockBeginLbl),
239                               gen.addressOf(blockEndLbl),
240                               gen.addressOf(catchPrimaryLbl),
241                               0);
242    
243                       // If an exception occurrs during the automatic closing
244                       // of a resource after an exception in the try block...
245                       gen.addException(
246                               gen.addressOf(tryCloseBeginLbl),
247                               gen.addressOf(tryCloseEndLbl),
248                               gen.addressOf(catchSuppressedLbl),
249                               0);
250               }
251    
252               // outer finally
253               gen.addLabel(outerFinallyLbl);
254               {
255                       // if resource != null
256                       resourceType.emitLoadLocal(gen, resourceIndex);
257                       gen.emitCompare(Bytecode.IFNULL, tryEndLbl);
258                       resourceType.emitLoadLocal(gen, resourceIndex);
259                       closeMethod().emitInvokeMethod(gen, autoCloseableType);
260               }
261    
262               gen.addLabel(tryEndLbl);
263               gen.emit(Bytecode.NOP);
264       }
265      /**
266        * Lookup the java.lang.Throwable.close() method.
267        * @ast method 
268       * @aspect TryWithResources
269       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:250
270       */
271      private MethodDecl closeMethod() {
272               TypeDecl autoCloseableType = lookupType("java.lang", "AutoCloseable");
273               if (autoCloseableType == null)
274                       throw new Error("Could not find java.lang.AutoCloseable");
275               for (MethodDecl method : (Collection<MethodDecl>)
276                               autoCloseableType.memberMethods("close")) {
277                       if (method.getNumParameter() == 0)
278                               return method;
279               }
280               throw new Error("Could not find java.lang.AutoCloseable.close()");
281       }
282      /**
283        * Lookup the java.lang.Throwable.addSuppressed(Throwable) method.
284        * @ast method 
285       * @aspect TryWithResources
286       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:265
287       */
288      private MethodDecl addSuppressedMethod() {
289               TypeDecl throwableType = lookupType("java.lang", "Throwable");
290               if (throwableType == null)
291                       throw new Error("Could not find java.lang.Throwable");
292               for (MethodDecl method : (Collection<MethodDecl>)
293                               throwableType.memberMethods("addSuppressed")) {
294                       if (method.getNumParameter() == 1 &&
295                                       method.getParameter(0).getTypeAccess().type() ==
296                                       throwableType) {
297                               return method;
298                       }
299               }
300               throw new Error("Could not find java.lang.Throwable.addSuppressed()");
301       }
302      /**
303       * @ast method 
304       * 
305       */
306      public BasicTWR() {
307        super();
308    
309    
310      }
311      /**
312       * Initializes the child array to the correct size.
313       * Initializes List and Opt nta children.
314       * @apilevel internal
315       * @ast method
316       * @ast method 
317       * 
318       */
319      public void init$Children() {
320        children = new ASTNode[2];
321      }
322      /**
323       * @ast method 
324       * 
325       */
326      public BasicTWR(ResourceDeclaration p0, Block p1) {
327        setChild(p0, 0);
328        setChild(p1, 1);
329      }
330      /**
331       * @apilevel low-level
332       * @ast method 
333       * 
334       */
335      protected int numChildren() {
336        return 2;
337      }
338      /**
339       * @apilevel internal
340       * @ast method 
341       * 
342       */
343      public boolean mayHaveRewrite() {
344        return false;
345      }
346      /**
347       * Replaces the Resource child.
348       * @param node The new node to replace the Resource child.
349       * @apilevel high-level
350       * @ast method 
351       * 
352       */
353      public void setResource(ResourceDeclaration node) {
354        setChild(node, 0);
355      }
356      /**
357       * Retrieves the Resource child.
358       * @return The current node used as the Resource child.
359       * @apilevel high-level
360       * @ast method 
361       * 
362       */
363      public ResourceDeclaration getResource() {
364        return (ResourceDeclaration)getChild(0);
365      }
366      /**
367       * Retrieves the Resource child.
368       * <p><em>This method does not invoke AST transformations.</em></p>
369       * @return The current node used as the Resource child.
370       * @apilevel low-level
371       * @ast method 
372       * 
373       */
374      public ResourceDeclaration getResourceNoTransform() {
375        return (ResourceDeclaration)getChildNoTransform(0);
376      }
377      /**
378       * Replaces the Block child.
379       * @param node The new node to replace the Block child.
380       * @apilevel high-level
381       * @ast method 
382       * 
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       * @ast method 
392       * 
393       */
394      public Block getBlock() {
395        return (Block)getChild(1);
396      }
397      /**
398       * Retrieves the Block child.
399       * <p><em>This method does not invoke AST transformations.</em></p>
400       * @return The current node used as the Block child.
401       * @apilevel low-level
402       * @ast method 
403       * 
404       */
405      public Block getBlockNoTransform() {
406        return (Block)getChildNoTransform(1);
407      }
408      protected java.util.Map localLookup_String_values;
409      /**
410       * @attribute syn
411       * @aspect MultiCatch
412       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:78
413       */
414      @SuppressWarnings({"unchecked", "cast"})
415      public SimpleSet localLookup(String name) {
416        Object _parameters = name;
417        if(localLookup_String_values == null) localLookup_String_values = new java.util.HashMap(4);
418        if(localLookup_String_values.containsKey(_parameters)) {
419          return (SimpleSet)localLookup_String_values.get(_parameters);
420        }
421          ASTNode$State state = state();
422      int num = state.boundariesCrossed;
423      boolean isFinal = this.is$Final();
424        SimpleSet localLookup_String_value = localLookup_compute(name);
425      if(isFinal && num == state().boundariesCrossed){ localLookup_String_values.put(_parameters, localLookup_String_value); }
426            return localLookup_String_value;
427      }
428      /**
429       * @apilevel internal
430       */
431      private SimpleSet localLookup_compute(String name) {
432               VariableDeclaration v = localVariableDeclaration(name);
433               if (v != null) return v;
434               return lookupVariable(name);
435       }
436      protected java.util.Map localVariableDeclaration_String_values;
437      /**
438       * @attribute syn
439       * @aspect MultiCatch
440       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:83
441       */
442      @SuppressWarnings({"unchecked", "cast"})
443      public VariableDeclaration localVariableDeclaration(String name) {
444        Object _parameters = name;
445        if(localVariableDeclaration_String_values == null) localVariableDeclaration_String_values = new java.util.HashMap(4);
446        if(localVariableDeclaration_String_values.containsKey(_parameters)) {
447          return (VariableDeclaration)localVariableDeclaration_String_values.get(_parameters);
448        }
449          ASTNode$State state = state();
450      int num = state.boundariesCrossed;
451      boolean isFinal = this.is$Final();
452        VariableDeclaration localVariableDeclaration_String_value = localVariableDeclaration_compute(name);
453      if(isFinal && num == state().boundariesCrossed){ localVariableDeclaration_String_values.put(_parameters, localVariableDeclaration_String_value); }
454            return localVariableDeclaration_String_value;
455      }
456      /**
457       * @apilevel internal
458       */
459      private VariableDeclaration localVariableDeclaration_compute(String name) {  return getResource().declaresVariable(name) ? getResource() : null;  }
460      /**
461       * @attribute syn
462       * @aspect PreciseRethrow
463       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/PreciseRethrow.jrag:55
464       */
465      public boolean modifiedInScope(Variable var) {
466        ASTNode$State state = state();
467        try {  return getBlock().modifiedInScope(var);  }
468        finally {
469        }
470      }
471      protected java.util.Map lookupVariable_String_values;
472      /**
473       * @attribute inh
474       * @aspect MultiCatch
475       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:87
476       */
477      @SuppressWarnings({"unchecked", "cast"})
478      public SimpleSet lookupVariable(String name) {
479        Object _parameters = name;
480        if(lookupVariable_String_values == null) lookupVariable_String_values = new java.util.HashMap(4);
481        if(lookupVariable_String_values.containsKey(_parameters)) {
482          return (SimpleSet)lookupVariable_String_values.get(_parameters);
483        }
484          ASTNode$State state = state();
485      int num = state.boundariesCrossed;
486      boolean isFinal = this.is$Final();
487        SimpleSet lookupVariable_String_value = getParent().Define_SimpleSet_lookupVariable(this, null, name);
488      if(isFinal && num == state().boundariesCrossed){ lookupVariable_String_values.put(_parameters, lookupVariable_String_value); }
489            return lookupVariable_String_value;
490      }
491      /**
492       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:76
493       * @apilevel internal
494       */
495      public SimpleSet Define_SimpleSet_lookupVariable(ASTNode caller, ASTNode child, String name) {
496        if(caller == getBlockNoTransform()) {
497          return localLookup(name);
498        }
499        else {      return getParent().Define_SimpleSet_lookupVariable(this, caller, name);
500        }
501      }
502      /**
503       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:292
504       * @apilevel internal
505       */
506      public int Define_int_localNum(ASTNode caller, ASTNode child) {
507        if(caller == getBlockNoTransform()) {
508          return getResource().localNum() +
509               getResource().type().variableSize() +
510               2 * lookupType("java.lang", "Throwable").variableSize();
511        }
512        else if(caller == getResourceNoTransform()) {
513          return localNum();
514        }
515        else {      return getParent().Define_int_localNum(this, caller);
516        }
517      }
518      /**
519       * @apilevel internal
520       */
521      public ASTNode rewriteTo() {
522        return super.rewriteTo();
523      }
524    }