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 }