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 SwitchStmt : {@link BranchTargetStmt} ::= <span class="component">{@link Expr}</span> <span class="component">{@link Block}</span>;
015     * @ast node
016     * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/java.ast:202
017     */
018    public class SwitchStmt extends BranchTargetStmt implements Cloneable {
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 SwitchStmt clone() throws CloneNotSupportedException {
034        SwitchStmt node = (SwitchStmt)super.clone();
035        node.targetOf_ContinueStmt_values = null;
036        node.targetOf_BreakStmt_values = null;
037        node.isDAafter_Variable_values = null;
038        node.isDUafter_Variable_values = null;
039        node.canCompleteNormally_computed = false;
040        node.defaultCase_computed = false;
041        node.defaultCase_value = null;
042        node.end_label_computed = false;
043        node.typeInt_computed = false;
044        node.typeInt_value = null;
045        node.typeLong_computed = false;
046        node.typeLong_value = null;
047        node.in$Circle(false);
048        node.is$Final(false);
049        return node;
050      }
051    /**
052     * @apilevel internal
053     */
054      @SuppressWarnings({"unchecked", "cast"})
055    public SwitchStmt copy() {
056      
057      try {
058        SwitchStmt node = (SwitchStmt) clone();
059        node.parent = null;
060        if(children != null)
061          node.children = (ASTNode[]) children.clone();
062        
063        return node;
064      } catch (CloneNotSupportedException e) {
065        throw new Error("Error: clone not supported for " + getClass().getName());
066      }
067      
068    }/**
069     * Create a deep copy of the AST subtree at this node.
070     * The copy is dangling, i.e. has no parent.
071     * @return dangling copy of the subtree at this node
072     * @apilevel low-level
073     */
074      @SuppressWarnings({"unchecked", "cast"})
075    public SwitchStmt fullCopy() {
076      
077      SwitchStmt tree = (SwitchStmt) copy();
078      if (children != null) {
079        for (int i = 0; i < children.length; ++i) {
080          
081          ASTNode child = (ASTNode) children[i];
082          if(child != null) {
083            child = child.fullCopy();
084            tree.setChild(child, i);
085          }
086        }
087      }
088      return tree;
089      
090    }  /**
091       * @ast method 
092       * @aspect PrettyPrint
093       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/PrettyPrint.jadd:554
094       */
095      public void toString(StringBuffer s) {
096        s.append(indent());
097        s.append("switch (");
098        getExpr().toString(s);
099        s.append(")");
100        getBlock().toString(s);
101      }
102      /**
103       * @ast method 
104       * @aspect CreateBCode
105       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1298
106       */
107      private int emitPad(CodeGeneration gen) {
108        int pad = (4 - (gen.pos() % 4)) % 4;
109        for(int i = 0; i < pad; i++)
110          gen.emit(Bytecode.NOP);
111        if(gen.pos() % 4 != 0)
112          throw new Error("Switch not at 4-byte boundary:" + gen.pos());
113        return pad;
114      }
115      /**
116       * @ast method 
117       * @aspect CreateBCode
118       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1306
119       */
120      private int defaultOffset(CodeGeneration gen, int switch_label) {
121        boolean hasDefault = defaultCase() != null;
122        if(hasDefault) {
123          int offset = gen.addressOf(defaultCase().label(gen))
124            - gen.addressOf(switch_label);
125          return offset;
126        }
127        return 0;
128      }
129      /**
130       * @ast method 
131       * @aspect EnumsCodegen
132       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Backend/EnumsCodegen.jrag:17
133       */
134      public void transformation() {
135        if(getExpr().type().isEnumDecl()) {
136          TypeDecl type = getExpr().type();
137          hostType().createEnumArray(type);
138          hostType().createEnumMethod(type);
139          setExpr(
140            hostType().createEnumMethod(type).createBoundAccess(new List()).qualifiesAccess(
141            new ArrayAccess(
142              ((Expr)getExpr().fullCopy()).qualifiesAccess(new MethodAccess("ordinal", new List()))
143            ))
144          );
145        }
146        super.transformation();
147      }
148      /**
149       * @ast method 
150       * @aspect StringsInSwitch
151       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:156
152       */
153      private void genFirstSwitch(
154                       CodeGeneration gen,
155                       TreeMap<Integer, CaseGroup> groups,
156                       int index_a) {
157               int cond_label = hostType().constantPool().newLabel();
158               int switch_label = hostType().constantPool().newLabel();
159               int end_label1 = hostType().constantPool().newLabel();
160               int index_b = localNumB();
161    
162               gen.emitGoto(cond_label);
163    
164               // Code generation for switch body
165               for (CaseGroup group : groups.values()) {
166                       gen.addLabel(group.lbl);
167    
168                       // Possible hash miss. Check for equality.
169                       Iterator<CaseLbl> iter = group.lbls.iterator();
170                       while (iter.hasNext()) {
171                               CaseLbl lbl = iter.next();
172                               int thenLbl;
173                               if (iter.hasNext())
174                                       thenLbl = hostType().constantPool().newLabel();
175                               else
176                                       // last conditional branches to end label
177                                       thenLbl = end_label1;
178    
179                               typeString().emitLoadLocal(gen, index_b);
180                               StringLiteral.push(gen, lbl.value);
181                               equalsMethod().emitInvokeMethod(gen,
182                                               lookupType("java.lang", "Object"));
183                               gen.emitCompare(Bytecode.IFEQ, thenLbl);
184                               IntegerLiteral.push(gen, lbl.serial);
185                               typeInt().emitStoreLocal(gen, index_a);
186                               gen.emitGoto(end_label1);
187    
188                               if (iter.hasNext())
189                                       gen.addLabel(thenLbl);
190                       }
191               }
192    
193               gen.addLabel(cond_label);
194    
195               // Initialize switch variable for second switch
196               IntegerLiteral.push(gen, 0);
197               typeInt().emitStoreLocal(gen, index_a);
198    
199               // Store the value of the switch expr so that it is only evaluated once!
200               getExpr().createBCode(gen);
201    
202               // Push the hash code for the switch instruction
203               if (getExpr().isConstant()) {
204                       typeString().emitStoreLocal(gen, index_b);
205    
206                       int hashCode = getExpr().constant().stringValue().hashCode();
207                       IntegerLiteral.push(gen, hashCode);
208               } else {
209                       typeString().emitDup(gen);
210                       typeString().emitStoreLocal(gen, index_b);
211                       hashCodeMethod().emitInvokeMethod(gen,
212                                       lookupType("java.lang", "Object"));
213               }
214    
215               // Emit switch instruction
216               gen.addLabel(switch_label);
217               long low = groups.isEmpty() ? 0 : groups.firstKey();
218               long high = groups.isEmpty() ? 0 : groups.lastKey();
219    
220               long tableSwitchSize = 8L + (high - low + 1L) * 4L;
221               long lookupSwitchSize = 4L + groups.size() * 8L;
222    
223               // Select the switch type which produces the smallest switch instr.
224               if (tableSwitchSize < lookupSwitchSize) {
225                       gen.emit(Bytecode.TABLESWITCH);
226                       int pad = emitPad(gen);
227                       int defaultOffset = 1 + pad + 4 + 4 + 4 +
228                               4 * (int)(high - low + 1);
229                       gen.add4(defaultOffset);
230                       gen.add4((int)low);
231                       gen.add4((int)high);
232                       for(long i = low; i <= high; i++) {
233                               if (groups.containsKey((int)i)) {
234                                       CaseGroup group = groups.get((int)i);
235                                       int offset = labelOffset(gen, group.lbl, switch_label);
236                                       gen.add4(offset);
237                               } else {
238                                       gen.add4(defaultOffset);
239                               }
240                       }
241               } else {
242                       gen.emit(Bytecode.LOOKUPSWITCH);
243                       int pad = emitPad(gen);
244                       int defaultOffset = 1 + pad + 4 + 4 + 8 * groups.size();
245                       gen.add4(defaultOffset);
246                       gen.add4(groups.size());
247                       for (CaseGroup group : groups.values()) {
248                               gen.add4(group.hashCode);
249                               int offset = labelOffset(gen, group.lbl, switch_label);
250                               gen.add4(offset);
251                       }
252               }
253               gen.addLabel(end_label1);
254       }
255      /**
256       * @ast method 
257       * @aspect StringsInSwitch
258       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:259
259       */
260      private void genSecondSwitch(
261                       CodeGeneration gen,
262                       java.util.List<CaseLbl> labels,
263                       int index_a,
264                       CaseLbl defaultLbl) {
265               int cond_label = hostType().constantPool().newLabel();
266               int switch_label = hostType().constantPool().newLabel();
267               int default_label = hostType().constantPool().newLabel();
268    
269               gen.emitGoto(cond_label);
270    
271               // Code generation for case labels
272    
273               for (CaseLbl lbl : labels) {
274                       gen.addLabel(lbl.lbl);
275                       lbl.createBCode(gen);
276               }
277    
278               gen.addLabel(default_label);
279               if (defaultLbl != null) {
280                       defaultLbl.createBCode(gen);
281    
282               }
283               if (canCompleteNormally())
284                       gen.emitGoto(end_label());
285    
286               gen.addLabel(cond_label);
287    
288               // push the switch variable
289               typeInt().emitLoadLocal(gen, index_a);
290    
291               // Emit switch instruction
292               gen.addLabel(switch_label);
293               gen.emit(Bytecode.TABLESWITCH);
294               long high = labels.size();
295               long tableSwitchSize = 8L + (high + 1L) * 4L;
296               int pad = emitPad(gen);
297               int defaultOffset = 1 + pad + 4 + 4 + 4 +
298                               4 * (int)(high + 1);
299               gen.add4(defaultOffset);
300               gen.add4(0);
301               gen.add4((int)high);
302    
303               int offset = labelOffset(gen, default_label, switch_label);
304               gen.add4(offset);
305               for (CaseLbl lbl : labels) {
306                       offset = labelOffset(gen, lbl.lbl, switch_label);
307                       gen.add4(offset);
308               }
309    
310               if (canCompleteNormally())
311                       gen.addLabel(end_label());
312       }
313      /**
314        * Generate invocation of method
315        * {@code java.lang.Object.hashCode()}.
316        * @ast method 
317       * @aspect StringsInSwitch
318       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:317
319       */
320      private MethodDecl hashCodeMethod() {
321               TypeDecl objectType = lookupType("java.lang", "Object");
322               if (objectType == null)
323                       throw new Error("Could not find java.lang.Object");
324               for (MethodDecl method :
325                               (Collection<MethodDecl>) objectType.memberMethods("hashCode")) {
326                       if (method.getNumParameter() == 0)
327                               return method;
328               }
329               throw new Error("Could not find java.lang.Object.hashCode()");
330       }
331      /**
332        * Generate invocation of method
333        * {@code java.lang.Object.equals(java.lang.Object)}.
334        * @ast method 
335       * @aspect StringsInSwitch
336       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:333
337       */
338      private MethodDecl equalsMethod() {
339               TypeDecl objectType = lookupType("java.lang", "Object");
340               if (objectType == null)
341                       throw new Error("Could not find java.lang.Object");
342               for (MethodDecl method :
343                               (Collection<MethodDecl>) objectType.memberMethods("equals")) {
344                       if (method.getNumParameter() == 1 &&
345                                       method.getParameter(0).getTypeAccess().type() == objectType)
346                               return method;
347               }
348               throw new Error("Could not find java.lang.Object.equals()");
349       }
350      /**
351       * @ast method 
352       * 
353       */
354      public SwitchStmt() {
355        super();
356    
357    
358      }
359      /**
360       * Initializes the child array to the correct size.
361       * Initializes List and Opt nta children.
362       * @apilevel internal
363       * @ast method
364       * @ast method 
365       * 
366       */
367      public void init$Children() {
368        children = new ASTNode[2];
369      }
370      /**
371       * @ast method 
372       * 
373       */
374      public SwitchStmt(Expr p0, Block p1) {
375        setChild(p0, 0);
376        setChild(p1, 1);
377      }
378      /**
379       * @apilevel low-level
380       * @ast method 
381       * 
382       */
383      protected int numChildren() {
384        return 2;
385      }
386      /**
387       * @apilevel internal
388       * @ast method 
389       * 
390       */
391      public boolean mayHaveRewrite() {
392        return false;
393      }
394      /**
395       * Replaces the Expr child.
396       * @param node The new node to replace the Expr child.
397       * @apilevel high-level
398       * @ast method 
399       * 
400       */
401      public void setExpr(Expr node) {
402        setChild(node, 0);
403      }
404      /**
405       * Retrieves the Expr child.
406       * @return The current node used as the Expr child.
407       * @apilevel high-level
408       * @ast method 
409       * 
410       */
411      public Expr getExpr() {
412        return (Expr)getChild(0);
413      }
414      /**
415       * Retrieves the Expr child.
416       * <p><em>This method does not invoke AST transformations.</em></p>
417       * @return The current node used as the Expr child.
418       * @apilevel low-level
419       * @ast method 
420       * 
421       */
422      public Expr getExprNoTransform() {
423        return (Expr)getChildNoTransform(0);
424      }
425      /**
426       * Replaces the Block child.
427       * @param node The new node to replace the Block child.
428       * @apilevel high-level
429       * @ast method 
430       * 
431       */
432      public void setBlock(Block node) {
433        setChild(node, 1);
434      }
435      /**
436       * Retrieves the Block child.
437       * @return The current node used as the Block child.
438       * @apilevel high-level
439       * @ast method 
440       * 
441       */
442      public Block getBlock() {
443        return (Block)getChild(1);
444      }
445      /**
446       * Retrieves the Block child.
447       * <p><em>This method does not invoke AST transformations.</em></p>
448       * @return The current node used as the Block child.
449       * @apilevel low-level
450       * @ast method 
451       * 
452       */
453      public Block getBlockNoTransform() {
454        return (Block)getChildNoTransform(1);
455      }
456      /**
457       * @ast method 
458       * @aspect AutoBoxingCodegen
459       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Backend/AutoBoxingCodegen.jrag:125
460       */
461        public void refined_AutoBoxingCodegen_SwitchStmt_createBCode(CodeGeneration gen) {
462        super.createBCode(gen);
463        int cond_label = hostType().constantPool().newLabel();
464        int switch_label = hostType().constantPool().newLabel();
465    
466        gen.emitGoto(cond_label);
467        getBlock().createBCode(gen);
468        if(canCompleteNormally())
469          gen.emitGoto(end_label());
470        gen.addLabel(cond_label);
471        getExpr().createBCode(gen);
472        if(getExpr().type().isReferenceType())
473          getExpr().type().emitUnboxingOperation(gen);
474    
475        TreeMap map = new TreeMap();
476        for(int i = 0; i < getBlock().getNumStmt(); i++) {
477          if(getBlock().getStmt(i) instanceof ConstCase) {
478            ConstCase ca = (ConstCase)getBlock().getStmt(i);
479            map.put(new Integer(ca.getValue().constant().intValue()), ca);
480          }        
481        }
482    
483        long low = map.isEmpty() ? 0 : ((Integer)map.firstKey()).intValue();
484        long high = map.isEmpty() ? 0 : ((Integer)map.lastKey()).intValue();
485    
486        long tableSwitchSize = 8L + (high - low + 1L) * 4L;
487        long lookupSwitchSize = 4L + map.size() * 8L;
488    
489        gen.addLabel(switch_label);
490        if(tableSwitchSize < lookupSwitchSize) {
491          gen.emit(Bytecode.TABLESWITCH);
492          int pad = emitPad(gen);
493          int defaultOffset = defaultOffset(gen, switch_label);
494          if(defaultOffset == 0) {
495            defaultOffset = 1 + pad + 4 + 4 + 4 + 4 * (int)(high - low + 1);
496          }
497          gen.add4(defaultOffset);
498          gen.add4((int)low);
499          gen.add4((int)high);
500          for(long i = low; i <= high; i++) {
501            ConstCase ca = (ConstCase)map.get(new Integer((int)i));
502            if(ca != null) {
503              int offset = gen.addressOf(ca.label(gen))
504                - gen.addressOf(switch_label);
505              gen.add4(offset);
506            }
507            else {
508              gen.add4(defaultOffset);
509            }
510          }
511        }
512        else {
513          gen.emit(Bytecode.LOOKUPSWITCH);
514          int pad = emitPad(gen);
515          int defaultOffset = defaultOffset(gen, switch_label);
516          if(defaultOffset == 0) {
517            defaultOffset = 1 + pad + 4 + 4 + 8 * numCase();
518          }
519          gen.add4(defaultOffset);
520          gen.add4(map.size());
521          for(Iterator iter = map.values().iterator(); iter.hasNext(); ) {
522            ConstCase ca = (ConstCase)iter.next();
523            gen.add4(ca.getValue().constant().intValue());
524            int offset = gen.addressOf(ca.label(gen))
525              - gen.addressOf(switch_label);
526            gen.add4(offset);
527          }
528        }
529        gen.addLabel(end_label());
530      }
531      /**
532       * @ast method 
533       * @aspect Enums
534       * @declaredat /home/jesper/svn/JastAddJ/Java1.5Frontend/Enums.jrag:491
535       */
536        public void refined_Enums_SwitchStmt_typeCheck() {
537         TypeDecl type = getExpr().type();
538        if((!type.isIntegralType() || type.isLong()) && !type.isEnumDecl())
539          error("Switch expression must be of char, byte, short, int, or enum type");
540      }
541      /**
542        * <p>Overrides the type checking of the switch statement's expression.
543        *
544        * <p>In JSR 334 a switch statement may use an expression of type String.
545        * @ast method 
546       * @aspect StringsInSwitch
547       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/StringsInSwitch.jrag:25
548       */
549        public void typeCheck() {
550               TypeDecl type = getExpr().type();
551               if ((!type.isIntegralType() || type.isLong()) && !type.isEnumDecl()
552                               && !type.isString())
553                       error("Switch expression must be of type " +
554                                       "char, byte, short, int, enum, or string");
555       }
556      /**
557        * Two switch statements are generated.
558        * The first switch will switch on the hash code of the switch expression.
559        * The first switch statement computes a value for a variable that selects
560        * a case in the second switch statement.
561        *
562        * @ast method 
563       * @aspect StringsInSwitch
564       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:110
565       */
566       
567               public void createBCode(CodeGeneration gen) {
568               if (getExpr().type().isString()) {
569                       // add line number for start of statement
570                       super.createBCode(gen);
571    
572                       // Enumerate case labels with same hash value
573                       TreeMap< Integer, CaseGroup > groups =
574                               new TreeMap< Integer, CaseGroup >();
575                       java.util.List<CaseLbl> labels = new LinkedList<CaseLbl>();
576    
577                       CaseLbl defaultLbl = null;
578                       CaseLbl caseLbl = null;
579                       int serial = 1;
580                       for (Stmt stmt : getBlock().getStmts()) {
581                               if (stmt instanceof ConstCase) {
582                                       ConstCase cc = (ConstCase) stmt;
583                                       caseLbl = new CaseLbl(cc, gen);
584                                       caseLbl.serial = serial++;
585                                       labels.add(caseLbl);
586                                       int key = caseLbl.value.hashCode();
587                                       if (groups.containsKey(key)) {
588                                               groups.get(key).addCase(caseLbl);
589                                       } else {
590                                               CaseGroup group = new CaseGroup(this, key);
591                                               group.addCase(caseLbl);
592                                               groups.put(key, group);
593                                       }
594                               } else if (stmt instanceof DefaultCase) {
595                                       defaultLbl =
596                                               new CaseLbl(hostType().constantPool().newLabel());
597                                       caseLbl = defaultLbl;
598                               } else if (caseLbl != null) {
599                                       caseLbl.addStmt(stmt);
600                               }
601                       }
602    
603                       int index_a = localNumA();
604                       genFirstSwitch(gen, groups, index_a);
605                       genSecondSwitch(gen, labels, index_a, defaultLbl);
606    
607               } else {
608                       refined_AutoBoxingCodegen_SwitchStmt_createBCode(gen);
609               }
610       }
611      protected java.util.Map targetOf_ContinueStmt_values;
612      /**
613       * @attribute syn
614       * @aspect BranchTarget
615       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/BranchTarget.jrag:72
616       */
617      @SuppressWarnings({"unchecked", "cast"})
618      public boolean targetOf(ContinueStmt stmt) {
619        Object _parameters = stmt;
620        if(targetOf_ContinueStmt_values == null) targetOf_ContinueStmt_values = new java.util.HashMap(4);
621        if(targetOf_ContinueStmt_values.containsKey(_parameters)) {
622          return ((Boolean)targetOf_ContinueStmt_values.get(_parameters)).booleanValue();
623        }
624          ASTNode$State state = state();
625      int num = state.boundariesCrossed;
626      boolean isFinal = this.is$Final();
627        boolean targetOf_ContinueStmt_value = targetOf_compute(stmt);
628      if(isFinal && num == state().boundariesCrossed){ targetOf_ContinueStmt_values.put(_parameters, Boolean.valueOf(targetOf_ContinueStmt_value)); }
629            return targetOf_ContinueStmt_value;
630      }
631      /**
632       * @apilevel internal
633       */
634      private boolean targetOf_compute(ContinueStmt stmt) {  return false;  }
635      protected java.util.Map targetOf_BreakStmt_values;
636      /**
637       * @attribute syn
638       * @aspect BranchTarget
639       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/BranchTarget.jrag:76
640       */
641      @SuppressWarnings({"unchecked", "cast"})
642      public boolean targetOf(BreakStmt stmt) {
643        Object _parameters = stmt;
644        if(targetOf_BreakStmt_values == null) targetOf_BreakStmt_values = new java.util.HashMap(4);
645        if(targetOf_BreakStmt_values.containsKey(_parameters)) {
646          return ((Boolean)targetOf_BreakStmt_values.get(_parameters)).booleanValue();
647        }
648          ASTNode$State state = state();
649      int num = state.boundariesCrossed;
650      boolean isFinal = this.is$Final();
651        boolean targetOf_BreakStmt_value = targetOf_compute(stmt);
652      if(isFinal && num == state().boundariesCrossed){ targetOf_BreakStmt_values.put(_parameters, Boolean.valueOf(targetOf_BreakStmt_value)); }
653            return targetOf_BreakStmt_value;
654      }
655      /**
656       * @apilevel internal
657       */
658      private boolean targetOf_compute(BreakStmt stmt) {  return !stmt.hasLabel();  }
659      protected java.util.Map isDAafter_Variable_values;
660      /**
661       * @attribute syn
662       * @aspect DA
663       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:531
664       */
665      @SuppressWarnings({"unchecked", "cast"})
666      public boolean isDAafter(Variable v) {
667        Object _parameters = v;
668        if(isDAafter_Variable_values == null) isDAafter_Variable_values = new java.util.HashMap(4);
669        if(isDAafter_Variable_values.containsKey(_parameters)) {
670          return ((Boolean)isDAafter_Variable_values.get(_parameters)).booleanValue();
671        }
672          ASTNode$State state = state();
673      int num = state.boundariesCrossed;
674      boolean isFinal = this.is$Final();
675        boolean isDAafter_Variable_value = isDAafter_compute(v);
676      if(isFinal && num == state().boundariesCrossed){ isDAafter_Variable_values.put(_parameters, Boolean.valueOf(isDAafter_Variable_value)); }
677            return isDAafter_Variable_value;
678      }
679      /**
680       * @apilevel internal
681       */
682      private boolean isDAafter_compute(Variable v) {
683        if(!(!noDefaultLabel() || getExpr().isDAafter(v))) {
684          return false;
685        }
686        if(!(!switchLabelEndsBlock() || getExpr().isDAafter(v))) {
687          return false;
688        }
689        if(!assignedAfterLastStmt(v)) {
690          return false;
691        }
692        for(Iterator iter = targetBreaks().iterator(); iter.hasNext(); ) {
693          BreakStmt stmt = (BreakStmt)iter.next();
694          if(!stmt.isDAafterReachedFinallyBlocks(v))
695            return false;
696        }
697        return true;
698      }
699      /**
700       * @attribute syn
701       * @aspect DA
702       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:549
703       */
704      public boolean assignedAfterLastStmt(Variable v) {
705        ASTNode$State state = state();
706        try {  return getBlock().isDAafter(v);  }
707        finally {
708        }
709      }
710      protected java.util.Map isDUafter_Variable_values;
711      /**
712       * @attribute syn
713       * @aspect DU
714       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:1000
715       */
716      @SuppressWarnings({"unchecked", "cast"})
717      public boolean isDUafter(Variable v) {
718        Object _parameters = v;
719        if(isDUafter_Variable_values == null) isDUafter_Variable_values = new java.util.HashMap(4);
720        if(isDUafter_Variable_values.containsKey(_parameters)) {
721          return ((Boolean)isDUafter_Variable_values.get(_parameters)).booleanValue();
722        }
723          ASTNode$State state = state();
724      int num = state.boundariesCrossed;
725      boolean isFinal = this.is$Final();
726        boolean isDUafter_Variable_value = isDUafter_compute(v);
727      if(isFinal && num == state().boundariesCrossed){ isDUafter_Variable_values.put(_parameters, Boolean.valueOf(isDUafter_Variable_value)); }
728            return isDUafter_Variable_value;
729      }
730      /**
731       * @apilevel internal
732       */
733      private boolean isDUafter_compute(Variable v) {
734        if(!(!noDefaultLabel() || getExpr().isDUafter(v)))
735          return false;
736        if(!(!switchLabelEndsBlock() || getExpr().isDUafter(v)))
737          return false;
738        if(!unassignedAfterLastStmt(v))
739          return false;
740        for(Iterator iter = targetBreaks().iterator(); iter.hasNext(); ) {
741          BreakStmt stmt = (BreakStmt)iter.next();
742          if(!stmt.isDUafterReachedFinallyBlocks(v))
743            return false;
744        }
745        return true;
746      }
747      /**
748       * @attribute syn
749       * @aspect DU
750       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:1015
751       */
752      public boolean unassignedAfterLastStmt(Variable v) {
753        ASTNode$State state = state();
754        try {  return getBlock().isDUafter(v);  }
755        finally {
756        }
757      }
758      /**
759       * @attribute syn
760       * @aspect DU
761       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:1018
762       */
763      public boolean switchLabelEndsBlock() {
764        ASTNode$State state = state();
765        try {  return getBlock().getNumStmt() > 0 && getBlock().getStmt(getBlock().getNumStmt()-1) instanceof ConstCase;  }
766        finally {
767        }
768      }
769      /**
770       * @attribute syn
771       * @aspect UnreachableStatements
772       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:60
773       */
774      public boolean lastStmtCanCompleteNormally() {
775        ASTNode$State state = state();
776        try {  return getBlock().canCompleteNormally();  }
777        finally {
778        }
779      }
780      /**
781       * @attribute syn
782       * @aspect UnreachableStatements
783       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:62
784       */
785      public boolean noStmts() {
786        ASTNode$State state = state();
787        try {
788        for(int i = 0; i < getBlock().getNumStmt(); i++)
789          if(!(getBlock().getStmt(i) instanceof Case))
790            return false;
791        return true;
792      }
793        finally {
794        }
795      }
796      /**
797       * @attribute syn
798       * @aspect UnreachableStatements
799       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:69
800       */
801      public boolean noStmtsAfterLastLabel() {
802        ASTNode$State state = state();
803        try {  return getBlock().getNumStmt() > 0 && getBlock().getStmt(getBlock().getNumStmt()-1) instanceof Case;  }
804        finally {
805        }
806      }
807      /**
808       * @attribute syn
809       * @aspect UnreachableStatements
810       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:72
811       */
812      public boolean noDefaultLabel() {
813        ASTNode$State state = state();
814        try {
815        for(int i = 0; i < getBlock().getNumStmt(); i++)
816          if(getBlock().getStmt(i) instanceof DefaultCase)
817            return false;
818        return true;
819      }
820        finally {
821        }
822      }
823      /**
824       * @apilevel internal
825       */
826      protected boolean canCompleteNormally_computed = false;
827      /**
828       * @apilevel internal
829       */
830      protected boolean canCompleteNormally_value;
831      /**
832       * @attribute syn
833       * @aspect UnreachableStatements
834       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:79
835       */
836      @SuppressWarnings({"unchecked", "cast"})
837      public boolean canCompleteNormally() {
838        if(canCompleteNormally_computed) {
839          return canCompleteNormally_value;
840        }
841          ASTNode$State state = state();
842      int num = state.boundariesCrossed;
843      boolean isFinal = this.is$Final();
844        canCompleteNormally_value = canCompleteNormally_compute();
845      if(isFinal && num == state().boundariesCrossed){ canCompleteNormally_computed = true; }
846            return canCompleteNormally_value;
847      }
848      /**
849       * @apilevel internal
850       */
851      private boolean canCompleteNormally_compute() {  return lastStmtCanCompleteNormally() || noStmts() || noStmtsAfterLastLabel() || noDefaultLabel() || reachableBreak();  }
852      /**
853       * @apilevel internal
854       */
855      protected boolean defaultCase_computed = false;
856      /**
857       * @apilevel internal
858       */
859      protected DefaultCase defaultCase_value;
860      /**
861       * @attribute syn
862       * @aspect CreateBCode
863       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1211
864       */
865      @SuppressWarnings({"unchecked", "cast"})
866      public DefaultCase defaultCase() {
867        if(defaultCase_computed) {
868          return defaultCase_value;
869        }
870          ASTNode$State state = state();
871      int num = state.boundariesCrossed;
872      boolean isFinal = this.is$Final();
873        defaultCase_value = defaultCase_compute();
874      if(isFinal && num == state().boundariesCrossed){ defaultCase_computed = true; }
875            return defaultCase_value;
876      }
877      /**
878       * @apilevel internal
879       */
880      private DefaultCase defaultCase_compute() {
881        for(int i= 0; i < getBlock().getNumStmt(); i++) {
882          if(getBlock().getStmt(i) instanceof DefaultCase)
883            return (DefaultCase)getBlock().getStmt(i);
884        }
885        return null;
886      }
887      /**
888       * @apilevel internal
889       */
890      protected boolean end_label_computed = false;
891      /**
892       * @apilevel internal
893       */
894      protected int end_label_value;
895      /**
896       * @attribute syn
897       * @aspect CreateBCode
898       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1219
899       */
900      @SuppressWarnings({"unchecked", "cast"})
901      public int end_label() {
902        if(end_label_computed) {
903          return end_label_value;
904        }
905          ASTNode$State state = state();
906      int num = state.boundariesCrossed;
907      boolean isFinal = this.is$Final();
908        end_label_value = end_label_compute();
909      if(isFinal && num == state().boundariesCrossed){ end_label_computed = true; }
910            return end_label_value;
911      }
912      /**
913       * @apilevel internal
914       */
915      private int end_label_compute() {  return hostType().constantPool().newLabel();  }
916      /**
917       * @attribute syn
918       * @aspect CreateBCode
919       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1290
920       */
921      public int numCase() {
922        ASTNode$State state = state();
923        try {
924        int result = 0;
925        for(int i = 0; i < getBlock().getNumStmt(); i++)
926          if(getBlock().getStmt(i) instanceof Case)
927            result++;
928        return result;
929      }
930        finally {
931        }
932      }
933      /**
934       * @attribute syn
935       * @aspect CreateBCode
936       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:1398
937       */
938      public int break_label() {
939        ASTNode$State state = state();
940        try {  return end_label();  }
941        finally {
942        }
943      }
944      /**
945       * @attribute syn
946       * @aspect PreciseRethrow
947       * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/PreciseRethrow.jrag:55
948       */
949      public boolean modifiedInScope(Variable var) {
950        ASTNode$State state = state();
951        try {  return getBlock().modifiedInScope(var);  }
952        finally {
953        }
954      }
955      /**
956       * @attribute syn
957       * @aspect StringsInSwitch
958       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:21
959       */
960      public boolean isSwitchWithString() {
961        ASTNode$State state = state();
962        try {  return getExpr().type().isString();  }
963        finally {
964        }
965      }
966      /**
967       * @attribute syn
968       * @aspect StringsInSwitch
969       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:38
970       */
971      public int localNumA() {
972        ASTNode$State state = state();
973        try {  return localNum();  }
974        finally {
975        }
976      }
977      /**
978        * Local index for the second switch variable.
979        * @attribute syn
980       * @aspect StringsInSwitch
981       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:44
982       */
983      public int localNumB() {
984        ASTNode$State state = state();
985        try {  return localNum() + typeInt().variableSize();  }
986        finally {
987        }
988      }
989      /**
990        * Utility method to compute offsets between labels.
991        * @attribute syn
992       * @aspect StringsInSwitch
993       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:100
994       */
995      public int labelOffset(CodeGeneration gen, int lbl1, int lbl2) {
996        ASTNode$State state = state();
997        try {  return gen.addressOf(lbl1) - gen.addressOf(lbl2);  }
998        finally {
999        }
1000      }
1001      /**
1002       * @apilevel internal
1003       */
1004      protected boolean typeInt_computed = false;
1005      /**
1006       * @apilevel internal
1007       */
1008      protected TypeDecl typeInt_value;
1009      /**
1010       * @attribute inh
1011       * @aspect SpecialClasses
1012       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/LookupType.jrag:61
1013       */
1014      @SuppressWarnings({"unchecked", "cast"})
1015      public TypeDecl typeInt() {
1016        if(typeInt_computed) {
1017          return typeInt_value;
1018        }
1019          ASTNode$State state = state();
1020      int num = state.boundariesCrossed;
1021      boolean isFinal = this.is$Final();
1022        typeInt_value = getParent().Define_TypeDecl_typeInt(this, null);
1023      if(isFinal && num == state().boundariesCrossed){ typeInt_computed = true; }
1024            return typeInt_value;
1025      }
1026      /**
1027       * @apilevel internal
1028       */
1029      protected boolean typeLong_computed = false;
1030      /**
1031       * @apilevel internal
1032       */
1033      protected TypeDecl typeLong_value;
1034      /**
1035       * @attribute inh
1036       * @aspect SpecialClasses
1037       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/LookupType.jrag:63
1038       */
1039      @SuppressWarnings({"unchecked", "cast"})
1040      public TypeDecl typeLong() {
1041        if(typeLong_computed) {
1042          return typeLong_value;
1043        }
1044          ASTNode$State state = state();
1045      int num = state.boundariesCrossed;
1046      boolean isFinal = this.is$Final();
1047        typeLong_value = getParent().Define_TypeDecl_typeLong(this, null);
1048      if(isFinal && num == state().boundariesCrossed){ typeLong_computed = true; }
1049            return typeLong_value;
1050      }
1051      /**
1052       * @attribute inh
1053       * @aspect StringsInSwitch
1054       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:25
1055       */
1056      @SuppressWarnings({"unchecked", "cast"})
1057      public TypeDecl typeString() {
1058          ASTNode$State state = state();
1059        TypeDecl typeString_value = getParent().Define_TypeDecl_typeString(this, null);
1060            return typeString_value;
1061      }
1062      /**
1063       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:568
1064       * @apilevel internal
1065       */
1066      public boolean Define_boolean_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
1067        if(caller == getBlockNoTransform()) {
1068          return getExpr().isDAafter(v);
1069        }
1070        else if(caller == getExprNoTransform()){
1071        if(((ASTNode)v).isDescendantTo(this))
1072          return false;
1073        boolean result = isDAbefore(v);
1074        return result;
1075      }
1076        else {      return getParent().Define_boolean_isDAbefore(this, caller, v);
1077        }
1078      }
1079      /**
1080       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/DefiniteAssignment.jrag:1023
1081       * @apilevel internal
1082       */
1083      public boolean Define_boolean_isDUbefore(ASTNode caller, ASTNode child, Variable v) {
1084        if(caller == getBlockNoTransform()) {
1085          return getExpr().isDUafter(v);
1086        }
1087        else if(caller == getExprNoTransform()) {
1088          return isDUbefore(v);
1089        }
1090        else {      return getParent().Define_boolean_isDUbefore(this, caller, v);
1091        }
1092      }
1093      /**
1094       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/NameCheck.jrag:377
1095       * @apilevel internal
1096       */
1097      public boolean Define_boolean_insideSwitch(ASTNode caller, ASTNode child) {
1098        if(caller == getBlockNoTransform()) {
1099          return true;
1100        }
1101        else {      return getParent().Define_boolean_insideSwitch(this, caller);
1102        }
1103      }
1104      /**
1105       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/NameCheck.jrag:418
1106       * @apilevel internal
1107       */
1108      public Case Define_Case_bind(ASTNode caller, ASTNode child, Case c) {
1109        if(caller == getBlockNoTransform()){
1110        Block b = getBlock();
1111        for(int i = 0; i < b.getNumStmt(); i++)
1112          if(b.getStmt(i) instanceof Case && ((Case)b.getStmt(i)).constValue(c))
1113            return (Case)b.getStmt(i);
1114        return null;
1115      }
1116        else {      return getParent().Define_Case_bind(this, caller, c);
1117        }
1118      }
1119      /**
1120       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/TypeCheck.jrag:359
1121       * @apilevel internal
1122       */
1123      public TypeDecl Define_TypeDecl_switchType(ASTNode caller, ASTNode child) {
1124        if(caller == getBlockNoTransform()) {
1125          return getExpr().type();
1126        }
1127        else {      return getParent().Define_TypeDecl_switchType(this, caller);
1128        }
1129      }
1130      /**
1131       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:82
1132       * @apilevel internal
1133       */
1134      public boolean Define_boolean_reachable(ASTNode caller, ASTNode child) {
1135        if(caller == getBlockNoTransform()) {
1136          return reachable();
1137        }
1138        else {      return getParent().Define_boolean_reachable(this, caller);
1139        }
1140      }
1141      /**
1142       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/UnreachableStatements.jrag:158
1143       * @apilevel internal
1144       */
1145      public boolean Define_boolean_reportUnreachable(ASTNode caller, ASTNode child) {
1146        if(caller == getBlockNoTransform()) {
1147          return reachable();
1148        }
1149        else {      return getParent().Define_boolean_reportUnreachable(this, caller);
1150        }
1151      }
1152      /**
1153       * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/StringsInSwitch.jrag:30
1154       * @apilevel internal
1155       */
1156      public int Define_int_localNum(ASTNode caller, ASTNode child) {
1157         {
1158          int childIndex = this.getIndexOfChild(caller);
1159          return //isSwitchWithString()
1160             localNum() + typeInt().variableSize() + typeString().variableSize();
1161        }
1162      }
1163      /**
1164       * @apilevel internal
1165       */
1166      public ASTNode rewriteTo() {
1167        return super.rewriteTo();
1168      }
1169    }