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