001 /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */ 002 package org.extendj.ast; 003 004 import java.util.HashSet; 005 import java.io.File; 006 import java.util.Set; 007 import java.util.Collections; 008 import java.util.Collection; 009 import java.util.ArrayList; 010 import beaver.*; 011 import java.util.*; 012 import java.io.ByteArrayOutputStream; 013 import java.io.PrintStream; 014 import java.lang.reflect.InvocationTargetException; 015 import java.lang.reflect.Method; 016 import org.jastadd.util.*; 017 import java.util.zip.*; 018 import java.io.*; 019 import org.jastadd.util.PrettyPrintable; 020 import org.jastadd.util.PrettyPrinter; 021 import java.io.FileNotFoundException; 022 import java.io.BufferedInputStream; 023 import java.io.DataInputStream; 024 /** 025 * @ast node 026 * @declaredat /home/jesper/git/extendj/java4/grammar/Java.ast:213 027 * @production SynchronizedStmt : {@link Stmt} ::= <span class="component">{@link Expr}</span> <span class="component">{@link Block}</span> <span class="component">{@link MonitorExit}</span>; 028 029 */ 030 public class SynchronizedStmt extends Stmt implements Cloneable, FinallyHost { 031 /** 032 * @aspect DU 033 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1046 034 */ 035 public Block getFinallyBlock() { 036 return getMonitorExit(); 037 } 038 /** 039 * @aspect Java4PrettyPrint 040 * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:202 041 */ 042 public void prettyPrint(PrettyPrinter out) { 043 out.print("synchronized "); 044 out.print(getExpr()); 045 out.print(" "); 046 out.print(getBlock()); 047 if (!out.isNewLine()) { 048 out.println(); 049 } 050 } 051 /** 052 * @aspect TypeCheck 053 * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:424 054 */ 055 public void typeCheck() { 056 TypeDecl type = getExpr().type(); 057 if (!type.isReferenceType() || type.isNull()) { 058 error("*** The type of the expression must be a reference"); 059 } 060 } 061 /** 062 * @aspect CreateBCode 063 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1793 064 */ 065 public void emitMonitorEnter(CodeGeneration gen) { 066 gen.emitDup(); 067 int num = localNum(); 068 gen.emitStoreReference(num); 069 gen.emit(Bytecode.MONITORENTER); 070 } 071 /** 072 * @aspect CreateBCode 073 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1809 074 */ 075 protected int monitorId = -1; 076 /** 077 * @aspect CreateBCode 078 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1811 079 */ 080 public void createBCode(CodeGeneration gen) { 081 int lbl_start = gen.constantPool().newLabel(); 082 super.createBCode(gen); 083 getExpr().createBCode(gen); 084 085 monitorId = gen.monitorEnter(this); 086 gen.addLabel(lbl_start); 087 gen.monitorRangeStart(monitorId, lbl_start); 088 089 getBlock().createBCode(gen); 090 091 if (getBlock().canCompleteNormally()) { 092 getMonitorExit().createBCode(gen); 093 gen.emitGoto(label_end()); 094 } 095 096 gen.monitorExit(); 097 098 gen.addLabel(label_end()); 099 } 100 /** 101 * @declaredat ASTNode:1 102 */ 103 public SynchronizedStmt() { 104 super(); 105 } 106 /** 107 * Initializes the child array to the correct size. 108 * Initializes List and Opt nta children. 109 * @apilevel internal 110 * @ast method 111 * @declaredat ASTNode:10 112 */ 113 public void init$Children() { 114 children = new ASTNode[3]; 115 } 116 /** 117 * @declaredat ASTNode:13 118 */ 119 public SynchronizedStmt(Expr p0, Block p1) { 120 setChild(p0, 0); 121 setChild(p1, 1); 122 } 123 /** 124 * @apilevel low-level 125 * @declaredat ASTNode:20 126 */ 127 protected int numChildren() { 128 return 2; 129 } 130 /** 131 * @apilevel internal 132 * @declaredat ASTNode:26 133 */ 134 public boolean mayHaveRewrite() { 135 return false; 136 } 137 /** 138 * @apilevel internal 139 * @declaredat ASTNode:32 140 */ 141 public void flushAttrCache() { 142 super.flushAttrCache(); 143 isDAafter_Variable_reset(); 144 isDUafter_Variable_reset(); 145 getMonitorExit_reset(); 146 canCompleteNormally_reset(); 147 start_label_reset(); 148 label_end_reset(); 149 } 150 /** 151 * @apilevel internal 152 * @declaredat ASTNode:44 153 */ 154 public void flushCollectionCache() { 155 super.flushCollectionCache(); 156 } 157 /** 158 * @apilevel internal 159 * @declaredat ASTNode:50 160 */ 161 public void flushRewriteCache() { 162 super.flushRewriteCache(); 163 } 164 /** 165 * @apilevel internal 166 * @declaredat ASTNode:56 167 */ 168 public SynchronizedStmt clone() throws CloneNotSupportedException { 169 SynchronizedStmt node = (SynchronizedStmt) super.clone(); 170 return node; 171 } 172 /** 173 * @apilevel internal 174 * @declaredat ASTNode:63 175 */ 176 public SynchronizedStmt copy() { 177 try { 178 SynchronizedStmt node = (SynchronizedStmt) clone(); 179 node.parent = null; 180 if (children != null) { 181 node.children = (ASTNode[]) children.clone(); 182 } 183 return node; 184 } catch (CloneNotSupportedException e) { 185 throw new Error("Error: clone not supported for " + getClass().getName()); 186 } 187 } 188 /** 189 * Create a deep copy of the AST subtree at this node. 190 * The copy is dangling, i.e. has no parent. 191 * @return dangling copy of the subtree at this node 192 * @apilevel low-level 193 * @deprecated Please use treeCopy or treeCopyNoTransform instead 194 * @declaredat ASTNode:82 195 */ 196 @Deprecated 197 public SynchronizedStmt fullCopy() { 198 return treeCopyNoTransform(); 199 } 200 /** 201 * Create a deep copy of the AST subtree at this node. 202 * The copy is dangling, i.e. has no parent. 203 * @return dangling copy of the subtree at this node 204 * @apilevel low-level 205 * @declaredat ASTNode:92 206 */ 207 public SynchronizedStmt treeCopyNoTransform() { 208 SynchronizedStmt tree = (SynchronizedStmt) copy(); 209 if (children != null) { 210 for (int i = 0; i < children.length; ++i) { 211 switch (i) { 212 case 2: 213 tree.children[i] = null; 214 continue; 215 } 216 ASTNode child = (ASTNode) children[i]; 217 if (child != null) { 218 child = child.treeCopyNoTransform(); 219 tree.setChild(child, i); 220 } 221 } 222 } 223 return tree; 224 } 225 /** 226 * Create a deep copy of the AST subtree at this node. 227 * The subtree of this node is traversed to trigger rewrites before copy. 228 * The copy is dangling, i.e. has no parent. 229 * @return dangling copy of the subtree at this node 230 * @apilevel low-level 231 * @declaredat ASTNode:117 232 */ 233 public SynchronizedStmt treeCopy() { 234 doFullTraversal(); 235 return treeCopyNoTransform(); 236 } 237 /** 238 * @apilevel internal 239 * @declaredat ASTNode:124 240 */ 241 protected boolean is$Equal(ASTNode node) { 242 return super.is$Equal(node); 243 } 244 /** 245 * Replaces the Expr child. 246 * @param node The new node to replace the Expr child. 247 * @apilevel high-level 248 */ 249 public void setExpr(Expr node) { 250 setChild(node, 0); 251 } 252 /** 253 * Retrieves the Expr child. 254 * @return The current node used as the Expr child. 255 * @apilevel high-level 256 */ 257 @ASTNodeAnnotation.Child(name="Expr") 258 public Expr getExpr() { 259 return (Expr) getChild(0); 260 } 261 /** 262 * Retrieves the Expr child. 263 * <p><em>This method does not invoke AST transformations.</em></p> 264 * @return The current node used as the Expr child. 265 * @apilevel low-level 266 */ 267 public Expr getExprNoTransform() { 268 return (Expr) getChildNoTransform(0); 269 } 270 /** 271 * Replaces the Block child. 272 * @param node The new node to replace the Block child. 273 * @apilevel high-level 274 */ 275 public void setBlock(Block node) { 276 setChild(node, 1); 277 } 278 /** 279 * Retrieves the Block child. 280 * @return The current node used as the Block child. 281 * @apilevel high-level 282 */ 283 @ASTNodeAnnotation.Child(name="Block") 284 public Block getBlock() { 285 return (Block) getChild(1); 286 } 287 /** 288 * Retrieves the Block child. 289 * <p><em>This method does not invoke AST transformations.</em></p> 290 * @return The current node used as the Block child. 291 * @apilevel low-level 292 */ 293 public Block getBlockNoTransform() { 294 return (Block) getChildNoTransform(1); 295 } 296 /** 297 * Retrieves the MonitorExit child. 298 * <p><em>This method does not invoke AST transformations.</em></p> 299 * @return The current node used as the MonitorExit child. 300 * @apilevel low-level 301 */ 302 public MonitorExit getMonitorExitNoTransform() { 303 return (MonitorExit) getChildNoTransform(2); 304 } 305 /** 306 * Retrieves the child position of the optional child MonitorExit. 307 * @return The the child position of the optional child MonitorExit. 308 * @apilevel low-level 309 */ 310 protected int getMonitorExitChildPosition() { 311 return 2; 312 } 313 /** 314 * @apilevel internal 315 */ 316 protected java.util.Map isDAafter_Variable_values; 317 /** 318 * @apilevel internal 319 */ 320 private void isDAafter_Variable_reset() { 321 isDAafter_Variable_values = null; 322 } 323 /** 324 * @attribute syn 325 * @aspect DA 326 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:257 327 */ 328 @ASTNodeAnnotation.Attribute 329 public boolean isDAafter(Variable v) { 330 Object _parameters = v; 331 if (isDAafter_Variable_values == null) isDAafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap()); 332 ASTNode$State state = state(); 333 if (isDAafter_Variable_values.containsKey(_parameters)) { 334 return (Boolean) isDAafter_Variable_values.get(_parameters); 335 } 336 boolean intermediate = state.INTERMEDIATE_VALUE; 337 state.INTERMEDIATE_VALUE = false; 338 int num = state.boundariesCrossed; 339 boolean isFinal = this.is$Final(); 340 boolean isDAafter_Variable_value = getBlock().isDAafter(v); 341 if (isFinal && num == state().boundariesCrossed) { 342 isDAafter_Variable_values.put(_parameters, isDAafter_Variable_value); 343 } else { 344 } 345 state.INTERMEDIATE_VALUE |= intermediate; 346 347 return isDAafter_Variable_value; 348 } 349 /** 350 * @attribute syn 351 * @aspect DU 352 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1051 353 */ 354 @ASTNodeAnnotation.Attribute 355 public boolean isDUafterFinally(Variable v) { 356 boolean isDUafterFinally_Variable_value = true; 357 358 return isDUafterFinally_Variable_value; 359 } 360 /** 361 * @attribute syn 362 * @aspect DU 363 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1054 364 */ 365 @ASTNodeAnnotation.Attribute 366 public boolean isDAafterFinally(Variable v) { 367 boolean isDAafterFinally_Variable_value = false; 368 369 return isDAafterFinally_Variable_value; 370 } 371 /** 372 * @apilevel internal 373 */ 374 protected java.util.Map isDUafter_Variable_values; 375 /** 376 * @apilevel internal 377 */ 378 private void isDUafter_Variable_reset() { 379 isDUafter_Variable_values = null; 380 } 381 /** 382 * @attribute syn 383 * @aspect DU 384 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:781 385 */ 386 @ASTNodeAnnotation.Attribute 387 public boolean isDUafter(Variable v) { 388 Object _parameters = v; 389 if (isDUafter_Variable_values == null) isDUafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap()); 390 ASTNode$State state = state(); 391 if (isDUafter_Variable_values.containsKey(_parameters)) { 392 return (Boolean) isDUafter_Variable_values.get(_parameters); 393 } 394 boolean intermediate = state.INTERMEDIATE_VALUE; 395 state.INTERMEDIATE_VALUE = false; 396 int num = state.boundariesCrossed; 397 boolean isFinal = this.is$Final(); 398 boolean isDUafter_Variable_value = getBlock().isDUafter(v); 399 if (isFinal && num == state().boundariesCrossed) { 400 isDUafter_Variable_values.put(_parameters, isDUafter_Variable_value); 401 } else { 402 } 403 state.INTERMEDIATE_VALUE |= intermediate; 404 405 return isDUafter_Variable_value; 406 } 407 /** 408 * @apilevel internal 409 */ 410 protected boolean getMonitorExit_computed = false; 411 /** 412 * @apilevel internal 413 */ 414 protected MonitorExit getMonitorExit_value; 415 /** 416 * @apilevel internal 417 */ 418 private void getMonitorExit_reset() { 419 getMonitorExit_computed = false; 420 getMonitorExit_value = null; 421 } 422 /** 423 * @attribute syn nta 424 * @aspect MonitorExit 425 * @declaredat /home/jesper/git/extendj/java4/frontend/MonitorExit.jrag:32 426 */ 427 @ASTNodeAnnotation.Attribute 428 public MonitorExit getMonitorExit() { 429 ASTNode$State state = state(); 430 if (getMonitorExit_computed) { 431 return (MonitorExit) getChild(getMonitorExitChildPosition()); 432 } 433 boolean intermediate = state.INTERMEDIATE_VALUE; 434 state.INTERMEDIATE_VALUE = false; 435 int num = state.boundariesCrossed; 436 boolean isFinal = this.is$Final(); 437 getMonitorExit_value = new MonitorExit(this); 438 setChild(getMonitorExit_value, getMonitorExitChildPosition()); 439 if (isFinal && num == state().boundariesCrossed) { 440 getMonitorExit_computed = true; 441 } else { 442 } 443 state.INTERMEDIATE_VALUE |= intermediate; 444 445 MonitorExit node = (MonitorExit) this.getChild(getMonitorExitChildPosition()); 446 return node; 447 } 448 /** 449 * @apilevel internal 450 */ 451 protected boolean canCompleteNormally_computed = false; 452 /** 453 * @apilevel internal 454 */ 455 protected boolean canCompleteNormally_value; 456 /** 457 * @apilevel internal 458 */ 459 private void canCompleteNormally_reset() { 460 canCompleteNormally_computed = false; 461 } 462 /** 463 * @attribute syn 464 * @aspect UnreachableStatements 465 * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:53 466 */ 467 @ASTNodeAnnotation.Attribute 468 public boolean canCompleteNormally() { 469 ASTNode$State state = state(); 470 if (canCompleteNormally_computed) { 471 return canCompleteNormally_value; 472 } 473 boolean intermediate = state.INTERMEDIATE_VALUE; 474 state.INTERMEDIATE_VALUE = false; 475 int num = state.boundariesCrossed; 476 boolean isFinal = this.is$Final(); 477 canCompleteNormally_value = getBlock().canCompleteNormally(); 478 if (isFinal && num == state().boundariesCrossed) { 479 canCompleteNormally_computed = true; 480 } else { 481 } 482 state.INTERMEDIATE_VALUE |= intermediate; 483 484 return canCompleteNormally_value; 485 } 486 /** 487 * @apilevel internal 488 */ 489 protected boolean start_label_computed = false; 490 /** 491 * @apilevel internal 492 */ 493 protected int start_label_value; 494 /** 495 * @apilevel internal 496 */ 497 private void start_label_reset() { 498 start_label_computed = false; 499 } 500 /** 501 * @attribute syn 502 * @aspect CreateBCode 503 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1630 504 */ 505 @ASTNodeAnnotation.Attribute 506 public int start_label() { 507 ASTNode$State state = state(); 508 if (start_label_computed) { 509 return start_label_value; 510 } 511 boolean intermediate = state.INTERMEDIATE_VALUE; 512 state.INTERMEDIATE_VALUE = false; 513 int num = state.boundariesCrossed; 514 boolean isFinal = this.is$Final(); 515 start_label_value = hostType().constantPool().newLabel(); 516 if (isFinal && num == state().boundariesCrossed) { 517 start_label_computed = true; 518 } else { 519 } 520 state.INTERMEDIATE_VALUE |= intermediate; 521 522 return start_label_value; 523 } 524 /** 525 * @attribute syn 526 * @aspect PreciseRethrow 527 * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:84 528 */ 529 @ASTNodeAnnotation.Attribute 530 public boolean modifiedInScope(Variable var) { 531 boolean modifiedInScope_Variable_value = getBlock().modifiedInScope(var); 532 533 return modifiedInScope_Variable_value; 534 } 535 /** 536 * @apilevel internal 537 */ 538 protected boolean label_end_computed = false; 539 /** 540 * @apilevel internal 541 */ 542 protected int label_end_value; 543 /** 544 * @apilevel internal 545 */ 546 private void label_end_reset() { 547 label_end_computed = false; 548 } 549 /** 550 * @attribute syn 551 * @aspect NTAFinally 552 * @declaredat /home/jesper/git/extendj/java4/backend/NTAFinally.jrag:32 553 */ 554 @ASTNodeAnnotation.Attribute 555 public int label_end() { 556 ASTNode$State state = state(); 557 if (label_end_computed) { 558 return label_end_value; 559 } 560 boolean intermediate = state.INTERMEDIATE_VALUE; 561 state.INTERMEDIATE_VALUE = false; 562 int num = state.boundariesCrossed; 563 boolean isFinal = this.is$Final(); 564 label_end_value = hostType().constantPool().newLabel(); 565 if (isFinal && num == state().boundariesCrossed) { 566 label_end_computed = true; 567 } else { 568 } 569 state.INTERMEDIATE_VALUE |= intermediate; 570 571 return label_end_value; 572 } 573 /** 574 * @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:262 575 * @apilevel internal 576 */ 577 public FinallyHost Define_enclosingFinally(ASTNode caller, ASTNode child, Stmt branch) { 578 if (caller == getMonitorExitNoTransform()) { 579 // @declaredat /home/jesper/git/extendj/java4/frontend/BranchTarget.jrag:273 580 return enclosingFinally(branch); 581 } 582 else { 583 int childIndex = this.getIndexOfChild(caller); 584 return this; 585 } 586 } 587 protected boolean canDefine_enclosingFinally(ASTNode caller, ASTNode child, Stmt branch) { 588 return true; 589 } 590 /** 591 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:255 592 * @apilevel internal 593 */ 594 public boolean Define_isDAbefore(ASTNode caller, ASTNode child, Variable v) { 595 if (caller == getBlockNoTransform()) { 596 // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:739 597 return getExpr().isDAafter(v); 598 } 599 else if (caller == getExprNoTransform()) { 600 // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:738 601 return isDAbefore(v); 602 } 603 else { 604 return getParent().Define_isDAbefore(this, caller, v); 605 } 606 } 607 protected boolean canDefine_isDAbefore(ASTNode caller, ASTNode child, Variable v) { 608 return true; 609 } 610 /** 611 * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:779 612 * @apilevel internal 613 */ 614 public boolean Define_isDUbefore(ASTNode caller, ASTNode child, Variable v) { 615 if (caller == getBlockNoTransform()) { 616 // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1358 617 return getExpr().isDUafter(v); 618 } 619 else if (caller == getExprNoTransform()) { 620 // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:1357 621 return isDUbefore(v); 622 } 623 else { 624 return getParent().Define_isDUbefore(this, caller, v); 625 } 626 } 627 protected boolean canDefine_isDUbefore(ASTNode caller, ASTNode child, Variable v) { 628 return true; 629 } 630 /** 631 * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:52 632 * @apilevel internal 633 */ 634 public boolean Define_reachable(ASTNode caller, ASTNode child) { 635 if (caller == getBlockNoTransform()) { 636 // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:168 637 return reachable(); 638 } 639 else { 640 return getParent().Define_reachable(this, caller); 641 } 642 } 643 protected boolean canDefine_reachable(ASTNode caller, ASTNode child) { 644 return true; 645 } 646 /** 647 * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:283 648 * @apilevel internal 649 */ 650 public boolean Define_reportUnreachable(ASTNode caller, ASTNode child) { 651 if (caller == getBlockNoTransform()) { 652 // @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:219 653 return reachable(); 654 } 655 else { 656 return getParent().Define_reportUnreachable(this, caller); 657 } 658 } 659 protected boolean canDefine_reportUnreachable(ASTNode caller, ASTNode child) { 660 return true; 661 } 662 /** 663 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1836 664 * @apilevel internal 665 */ 666 public boolean Define_leavesMonitor(ASTNode caller, ASTNode child, Stmt branch, SynchronizedStmt monitor) { 667 int childIndex = this.getIndexOfChild(caller); 668 { 669 if (monitor == this) { 670 return true; 671 } else { 672 return leavesMonitor(branch, monitor); 673 } 674 } 675 } 676 protected boolean canDefine_leavesMonitor(ASTNode caller, ASTNode child, Stmt branch, SynchronizedStmt monitor) { 677 return true; 678 } 679 /** 680 * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:64 681 * @apilevel internal 682 */ 683 public int Define_localNum(ASTNode caller, ASTNode child) { 684 if (caller == getBlockNoTransform()) { 685 // @declaredat /home/jesper/git/extendj/java4/backend/LocalNum.jrag:197 686 return localNum() + 3; 687 } 688 else { 689 return getParent().Define_localNum(this, caller); 690 } 691 } 692 protected boolean canDefine_localNum(ASTNode caller, ASTNode child) { 693 return true; 694 } 695 /** 696 * @apilevel internal 697 */ 698 public ASTNode rewriteTo() { 699 return super.rewriteTo(); 700 } 701 }