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/java8/grammar/Lambda.ast:12 027 * @production BlockLambdaBody : {@link LambdaBody} ::= <span class="component">{@link Block}</span>; 028 029 */ 030 public class BlockLambdaBody extends LambdaBody implements Cloneable { 031 /** 032 * @aspect ReturnCompatible 033 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:57 034 */ 035 public boolean noReturnsHasResult() { 036 ArrayList<ReturnStmt> returnList = lambdaReturns(); 037 for (int i = 0; i < returnList.size(); i++) { 038 if (returnList.get(i).hasResult()) { 039 return false; 040 } 041 } 042 return true; 043 } 044 /** 045 * @aspect ReturnCompatible 046 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:67 047 */ 048 public boolean allReturnsHasResult() { 049 ArrayList<ReturnStmt> returnList = lambdaReturns(); 050 for (int i = 0; i < returnList.size(); i++) { 051 if (!returnList.get(i).hasResult()) { 052 return false; 053 } 054 } 055 return true; 056 } 057 /** 058 * @aspect Java8PrettyPrint 059 * @declaredat /home/jesper/git/extendj/java8/frontend/PrettyPrint.jadd:51 060 */ 061 public void prettyPrint(PrettyPrinter out) { 062 out.print(getBlock()); 063 } 064 /** 065 * @aspect TypeCheck 066 * @declaredat /home/jesper/git/extendj/java8/frontend/TypeCheck.jrag:189 067 */ 068 public void typeCheck() { 069 // 15.27.2 070 if (!voidCompatible() && !valueCompatible()) { 071 error("Block lambda bodies must be either void or value compatible"); 072 } 073 } 074 /** 075 * @declaredat ASTNode:1 076 */ 077 public BlockLambdaBody() { 078 super(); 079 } 080 /** 081 * Initializes the child array to the correct size. 082 * Initializes List and Opt nta children. 083 * @apilevel internal 084 * @ast method 085 * @declaredat ASTNode:10 086 */ 087 public void init$Children() { 088 children = new ASTNode[1]; 089 } 090 /** 091 * @declaredat ASTNode:13 092 */ 093 public BlockLambdaBody(Block p0) { 094 setChild(p0, 0); 095 } 096 /** 097 * @apilevel low-level 098 * @declaredat ASTNode:19 099 */ 100 protected int numChildren() { 101 return 1; 102 } 103 /** 104 * @apilevel internal 105 * @declaredat ASTNode:25 106 */ 107 public boolean mayHaveRewrite() { 108 return false; 109 } 110 /** 111 * @apilevel internal 112 * @declaredat ASTNode:31 113 */ 114 public void flushAttrCache() { 115 super.flushAttrCache(); 116 isBlockBody_reset(); 117 isExprBody_reset(); 118 voidCompatible_reset(); 119 valueCompatible_reset(); 120 congruentTo_FunctionDescriptor_reset(); 121 toBlock_reset(); 122 } 123 /** 124 * @apilevel internal 125 * @declaredat ASTNode:43 126 */ 127 public void flushCollectionCache() { 128 super.flushCollectionCache(); 129 BlockLambdaBody_lambdaReturns_computed = false; 130 BlockLambdaBody_lambdaReturns_value = null; 131 BlockLambdaBody_lambdaReturns_contributors = null; 132 } 133 /** 134 * @apilevel internal 135 * @declaredat ASTNode:52 136 */ 137 public void flushRewriteCache() { 138 super.flushRewriteCache(); 139 } 140 /** 141 * @apilevel internal 142 * @declaredat ASTNode:58 143 */ 144 public BlockLambdaBody clone() throws CloneNotSupportedException { 145 BlockLambdaBody node = (BlockLambdaBody) super.clone(); 146 return node; 147 } 148 /** 149 * @apilevel internal 150 * @declaredat ASTNode:65 151 */ 152 public BlockLambdaBody copy() { 153 try { 154 BlockLambdaBody node = (BlockLambdaBody) clone(); 155 node.parent = null; 156 if (children != null) { 157 node.children = (ASTNode[]) children.clone(); 158 } 159 return node; 160 } catch (CloneNotSupportedException e) { 161 throw new Error("Error: clone not supported for " + getClass().getName()); 162 } 163 } 164 /** 165 * Create a deep copy of the AST subtree at this node. 166 * The copy is dangling, i.e. has no parent. 167 * @return dangling copy of the subtree at this node 168 * @apilevel low-level 169 * @deprecated Please use treeCopy or treeCopyNoTransform instead 170 * @declaredat ASTNode:84 171 */ 172 @Deprecated 173 public BlockLambdaBody fullCopy() { 174 return treeCopyNoTransform(); 175 } 176 /** 177 * Create a deep copy of the AST subtree at this node. 178 * The copy is dangling, i.e. has no parent. 179 * @return dangling copy of the subtree at this node 180 * @apilevel low-level 181 * @declaredat ASTNode:94 182 */ 183 public BlockLambdaBody treeCopyNoTransform() { 184 BlockLambdaBody tree = (BlockLambdaBody) copy(); 185 if (children != null) { 186 for (int i = 0; i < children.length; ++i) { 187 ASTNode child = (ASTNode) children[i]; 188 if (child != null) { 189 child = child.treeCopyNoTransform(); 190 tree.setChild(child, i); 191 } 192 } 193 } 194 return tree; 195 } 196 /** 197 * Create a deep copy of the AST subtree at this node. 198 * The subtree of this node is traversed to trigger rewrites before copy. 199 * The copy is dangling, i.e. has no parent. 200 * @return dangling copy of the subtree at this node 201 * @apilevel low-level 202 * @declaredat ASTNode:114 203 */ 204 public BlockLambdaBody treeCopy() { 205 doFullTraversal(); 206 return treeCopyNoTransform(); 207 } 208 /** 209 * @apilevel internal 210 * @declaredat ASTNode:121 211 */ 212 protected boolean is$Equal(ASTNode node) { 213 return super.is$Equal(node); 214 } 215 /** 216 * Replaces the Block child. 217 * @param node The new node to replace the Block child. 218 * @apilevel high-level 219 */ 220 public void setBlock(Block node) { 221 setChild(node, 0); 222 } 223 /** 224 * Retrieves the Block child. 225 * @return The current node used as the Block child. 226 * @apilevel high-level 227 */ 228 @ASTNodeAnnotation.Child(name="Block") 229 public Block getBlock() { 230 return (Block) getChild(0); 231 } 232 /** 233 * Retrieves the Block child. 234 * <p><em>This method does not invoke AST transformations.</em></p> 235 * @return The current node used as the Block child. 236 * @apilevel low-level 237 */ 238 public Block getBlockNoTransform() { 239 return (Block) getChildNoTransform(0); 240 } 241 /** 242 * @attribute syn 243 * @aspect PreciseRethrow 244 * @declaredat /home/jesper/git/extendj/java8/frontend/EffectivelyFinal.jrag:43 245 */ 246 @ASTNodeAnnotation.Attribute 247 public boolean modifiedInScope(Variable var) { 248 boolean modifiedInScope_Variable_value = getBlock().modifiedInScope(var); 249 250 return modifiedInScope_Variable_value; 251 } 252 /** 253 * @apilevel internal 254 */ 255 protected boolean isBlockBody_computed = false; 256 /** 257 * @apilevel internal 258 */ 259 protected boolean isBlockBody_value; 260 /** 261 * @apilevel internal 262 */ 263 private void isBlockBody_reset() { 264 isBlockBody_computed = false; 265 } 266 /** 267 * @attribute syn 268 * @aspect LambdaBody 269 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:29 270 */ 271 @ASTNodeAnnotation.Attribute 272 public boolean isBlockBody() { 273 ASTNode$State state = state(); 274 if (isBlockBody_computed) { 275 return isBlockBody_value; 276 } 277 boolean intermediate = state.INTERMEDIATE_VALUE; 278 state.INTERMEDIATE_VALUE = false; 279 int num = state.boundariesCrossed; 280 boolean isFinal = this.is$Final(); 281 isBlockBody_value = true; 282 if (isFinal && num == state().boundariesCrossed) { 283 isBlockBody_computed = true; 284 } else { 285 } 286 state.INTERMEDIATE_VALUE |= intermediate; 287 288 return isBlockBody_value; 289 } 290 /** 291 * @apilevel internal 292 */ 293 protected boolean isExprBody_computed = false; 294 /** 295 * @apilevel internal 296 */ 297 protected boolean isExprBody_value; 298 /** 299 * @apilevel internal 300 */ 301 private void isExprBody_reset() { 302 isExprBody_computed = false; 303 } 304 /** 305 * @attribute syn 306 * @aspect LambdaBody 307 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:30 308 */ 309 @ASTNodeAnnotation.Attribute 310 public boolean isExprBody() { 311 ASTNode$State state = state(); 312 if (isExprBody_computed) { 313 return isExprBody_value; 314 } 315 boolean intermediate = state.INTERMEDIATE_VALUE; 316 state.INTERMEDIATE_VALUE = false; 317 int num = state.boundariesCrossed; 318 boolean isFinal = this.is$Final(); 319 isExprBody_value = false; 320 if (isFinal && num == state().boundariesCrossed) { 321 isExprBody_computed = true; 322 } else { 323 } 324 state.INTERMEDIATE_VALUE |= intermediate; 325 326 return isExprBody_value; 327 } 328 /** 329 * @apilevel internal 330 */ 331 protected boolean voidCompatible_computed = false; 332 /** 333 * @apilevel internal 334 */ 335 protected boolean voidCompatible_value; 336 /** 337 * @apilevel internal 338 */ 339 private void voidCompatible_reset() { 340 voidCompatible_computed = false; 341 } 342 /** 343 * @attribute syn 344 * @aspect ReturnCompatible 345 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:40 346 */ 347 @ASTNodeAnnotation.Attribute 348 public boolean voidCompatible() { 349 ASTNode$State state = state(); 350 if (voidCompatible_computed) { 351 return voidCompatible_value; 352 } 353 boolean intermediate = state.INTERMEDIATE_VALUE; 354 state.INTERMEDIATE_VALUE = false; 355 int num = state.boundariesCrossed; 356 boolean isFinal = this.is$Final(); 357 voidCompatible_value = noReturnsHasResult(); 358 if (isFinal && num == state().boundariesCrossed) { 359 voidCompatible_computed = true; 360 } else { 361 } 362 state.INTERMEDIATE_VALUE |= intermediate; 363 364 return voidCompatible_value; 365 } 366 /** 367 * @apilevel internal 368 */ 369 protected boolean valueCompatible_computed = false; 370 /** 371 * @apilevel internal 372 */ 373 protected boolean valueCompatible_value; 374 /** 375 * @apilevel internal 376 */ 377 private void valueCompatible_reset() { 378 valueCompatible_computed = false; 379 } 380 /** 381 * @attribute syn 382 * @aspect ReturnCompatible 383 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:41 384 */ 385 @ASTNodeAnnotation.Attribute 386 public boolean valueCompatible() { 387 ASTNode$State state = state(); 388 if (valueCompatible_computed) { 389 return valueCompatible_value; 390 } 391 boolean intermediate = state.INTERMEDIATE_VALUE; 392 state.INTERMEDIATE_VALUE = false; 393 int num = state.boundariesCrossed; 394 boolean isFinal = this.is$Final(); 395 valueCompatible_value = allReturnsHasResult() && !getBlock().canCompleteNormally(); 396 if (isFinal && num == state().boundariesCrossed) { 397 valueCompatible_computed = true; 398 } else { 399 } 400 state.INTERMEDIATE_VALUE |= intermediate; 401 402 return valueCompatible_value; 403 } 404 /** 405 * @apilevel internal 406 */ 407 protected java.util.Map congruentTo_FunctionDescriptor_values; 408 /** 409 * @apilevel internal 410 */ 411 private void congruentTo_FunctionDescriptor_reset() { 412 congruentTo_FunctionDescriptor_values = null; 413 } 414 /** 415 * @attribute syn 416 * @aspect LambdaExpr 417 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaExpr.jrag:71 418 */ 419 @ASTNodeAnnotation.Attribute 420 public boolean congruentTo(FunctionDescriptor f) { 421 Object _parameters = f; 422 if (congruentTo_FunctionDescriptor_values == null) congruentTo_FunctionDescriptor_values = new org.jastadd.util.RobustMap(new java.util.HashMap()); 423 ASTNode$State state = state(); 424 if (congruentTo_FunctionDescriptor_values.containsKey(_parameters)) { 425 return (Boolean) congruentTo_FunctionDescriptor_values.get(_parameters); 426 } 427 boolean intermediate = state.INTERMEDIATE_VALUE; 428 state.INTERMEDIATE_VALUE = false; 429 int num = state.boundariesCrossed; 430 boolean isFinal = this.is$Final(); 431 boolean congruentTo_FunctionDescriptor_value = congruentTo_compute(f); 432 if (isFinal && num == state().boundariesCrossed) { 433 congruentTo_FunctionDescriptor_values.put(_parameters, congruentTo_FunctionDescriptor_value); 434 } else { 435 } 436 state.INTERMEDIATE_VALUE |= intermediate; 437 438 return congruentTo_FunctionDescriptor_value; 439 } 440 /** 441 * @apilevel internal 442 */ 443 private boolean congruentTo_compute(FunctionDescriptor f) { 444 if (f.method.type().isVoid()) { 445 return voidCompatible(); 446 } else { 447 if (!valueCompatible()) { 448 return false; 449 } 450 for (ReturnStmt returnStmt : lambdaReturns()) { 451 if (!returnStmt.getResult().assignConversionTo(f.method.type())) { 452 return false; 453 } 454 } 455 return true; 456 } 457 } 458 /** 459 * @apilevel internal 460 */ 461 protected boolean toBlock_computed = false; 462 /** 463 * @apilevel internal 464 */ 465 protected Block toBlock_value; 466 /** 467 * @apilevel internal 468 */ 469 private void toBlock_reset() { 470 toBlock_computed = false; 471 toBlock_value = null; 472 } 473 /** 474 * @attribute syn 475 * @aspect LambdaToClass 476 * @declaredat /home/jesper/git/extendj/java8/backend/LambdaToClass.jrag:68 477 */ 478 @ASTNodeAnnotation.Attribute 479 public Block toBlock() { 480 ASTNode$State state = state(); 481 if (toBlock_computed) { 482 return toBlock_value; 483 } 484 boolean intermediate = state.INTERMEDIATE_VALUE; 485 state.INTERMEDIATE_VALUE = false; 486 int num = state.boundariesCrossed; 487 boolean isFinal = this.is$Final(); 488 toBlock_value = toBlock_compute(); 489 if (isFinal && num == state().boundariesCrossed) { 490 toBlock_computed = true; 491 } else { 492 } 493 state.INTERMEDIATE_VALUE |= intermediate; 494 495 return toBlock_value; 496 } 497 /** 498 * @apilevel internal 499 */ 500 private Block toBlock_compute() { 501 Block b = getBlock(); 502 setChild(new Block(), 0); 503 b.flushCaches(); 504 return b; 505 } 506 /** 507 * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:196 508 * @apilevel internal 509 */ 510 public boolean Define_assignmentContext(ASTNode caller, ASTNode child) { 511 if (caller == getBlockNoTransform()) { 512 // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:214 513 return false; 514 } 515 else { 516 return getParent().Define_assignmentContext(this, caller); 517 } 518 } 519 protected boolean canDefine_assignmentContext(ASTNode caller, ASTNode child) { 520 return true; 521 } 522 /** 523 * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:197 524 * @apilevel internal 525 */ 526 public boolean Define_invocationContext(ASTNode caller, ASTNode child) { 527 if (caller == getBlockNoTransform()) { 528 // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:215 529 return false; 530 } 531 else { 532 return getParent().Define_invocationContext(this, caller); 533 } 534 } 535 protected boolean canDefine_invocationContext(ASTNode caller, ASTNode child) { 536 return true; 537 } 538 /** 539 * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:198 540 * @apilevel internal 541 */ 542 public boolean Define_castContext(ASTNode caller, ASTNode child) { 543 if (caller == getBlockNoTransform()) { 544 // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:216 545 return false; 546 } 547 else { 548 return getParent().Define_castContext(this, caller); 549 } 550 } 551 protected boolean canDefine_castContext(ASTNode caller, ASTNode child) { 552 return true; 553 } 554 /** 555 * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:199 556 * @apilevel internal 557 */ 558 public boolean Define_stringContext(ASTNode caller, ASTNode child) { 559 if (caller == getBlockNoTransform()) { 560 // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:217 561 return false; 562 } 563 else { 564 return getParent().Define_stringContext(this, caller); 565 } 566 } 567 protected boolean canDefine_stringContext(ASTNode caller, ASTNode child) { 568 return true; 569 } 570 /** 571 * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:200 572 * @apilevel internal 573 */ 574 public boolean Define_numericContext(ASTNode caller, ASTNode child) { 575 if (caller == getBlockNoTransform()) { 576 // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:218 577 return false; 578 } 579 else { 580 return getParent().Define_numericContext(this, caller); 581 } 582 } 583 protected boolean canDefine_numericContext(ASTNode caller, ASTNode child) { 584 return true; 585 } 586 /** 587 * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:472 588 * @apilevel internal 589 */ 590 public TypeDecl Define_returnType(ASTNode caller, ASTNode child) { 591 if (caller == getBlockNoTransform()) { 592 // @declaredat /home/jesper/git/extendj/java8/frontend/TypeCheck.jrag:38 593 { 594 TypeDecl decl = enclosingLambda().targetType(); 595 if (decl == null) { 596 return unknownType(); 597 } else if (!(decl instanceof InterfaceDecl)) { 598 return unknownType(); 599 } else { 600 InterfaceDecl iDecl = (InterfaceDecl)decl; 601 if (!iDecl.isFunctional()) { 602 return unknownType(); 603 } else { 604 return iDecl.functionDescriptor().method.type(); 605 } 606 } 607 } 608 } 609 else { 610 return getParent().Define_returnType(this, caller); 611 } 612 } 613 protected boolean canDefine_returnType(ASTNode caller, ASTNode child) { 614 return true; 615 } 616 /** 617 * @declaredat /home/jesper/git/extendj/java4/frontend/UnreachableStatements.jrag:52 618 * @apilevel internal 619 */ 620 public boolean Define_reachable(ASTNode caller, ASTNode child) { 621 if (caller == getBlockNoTransform()) { 622 // @declaredat /home/jesper/git/extendj/java8/frontend/UnreachableStatements.jrag:29 623 return true; 624 } 625 else { 626 return getParent().Define_reachable(this, caller); 627 } 628 } 629 protected boolean canDefine_reachable(ASTNode caller, ASTNode child) { 630 return true; 631 } 632 /** 633 * @apilevel internal 634 */ 635 public ASTNode rewriteTo() { 636 return super.rewriteTo(); 637 } 638 /** 639 * @attribute coll 640 * @aspect ReturnCompatible 641 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:47 642 */ 643 /** 644 * @attribute coll 645 * @aspect ReturnCompatible 646 * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaBody.jrag:47 647 */ 648 @ASTNodeAnnotation.Attribute 649 public ArrayList<ReturnStmt> lambdaReturns() { 650 ASTNode$State state = state(); 651 if (BlockLambdaBody_lambdaReturns_computed) { 652 return BlockLambdaBody_lambdaReturns_value; 653 } 654 boolean intermediate = state.INTERMEDIATE_VALUE; 655 state.INTERMEDIATE_VALUE = false; 656 int num = state.boundariesCrossed; 657 boolean isFinal = this.is$Final(); 658 BlockLambdaBody_lambdaReturns_value = lambdaReturns_compute(); 659 if (isFinal && num == state().boundariesCrossed) { 660 BlockLambdaBody_lambdaReturns_computed = true; 661 } else { 662 } 663 state.INTERMEDIATE_VALUE |= intermediate; 664 665 return BlockLambdaBody_lambdaReturns_value; 666 } 667 java.util.Collection BlockLambdaBody_lambdaReturns_contributors; 668 669 /** 670 * @apilevel internal 671 * @return the contributor set for lambdaReturns 672 */ 673 public java.util.Collection BlockLambdaBody_lambdaReturns_contributors() { 674 if (BlockLambdaBody_lambdaReturns_contributors == null) 675 BlockLambdaBody_lambdaReturns_contributors = new java.util.LinkedList(); 676 return BlockLambdaBody_lambdaReturns_contributors; 677 } 678 679 /** 680 * @apilevel internal 681 */ 682 private ArrayList<ReturnStmt> lambdaReturns_compute() { 683 ASTNode node = this; 684 while(node.getParent() != null && !(node instanceof Program)) { 685 node = node.getParent(); 686 } 687 Program root = (Program) node; 688 root.collect_contributors_BlockLambdaBody_lambdaReturns(); 689 BlockLambdaBody_lambdaReturns_value = new ArrayList<ReturnStmt>(); 690 if (BlockLambdaBody_lambdaReturns_contributors != null) { 691 for (java.util.Iterator iter = BlockLambdaBody_lambdaReturns_contributors.iterator(); iter.hasNext(); ) { 692 ASTNode contributor = (ASTNode) iter.next(); 693 contributor.contributeTo_BlockLambdaBody_BlockLambdaBody_lambdaReturns(BlockLambdaBody_lambdaReturns_value); 694 } 695 } 696 // TODO: disabled temporarily since collections may not be cached 697 //BlockLambdaBody_lambdaReturns_contributors = null; 698 return BlockLambdaBody_lambdaReturns_value; 699 } 700 /** 701 * @apilevel internal 702 */ 703 protected boolean BlockLambdaBody_lambdaReturns_computed = false; 704 /** 705 * @apilevel internal 706 */ 707 protected ArrayList<ReturnStmt> BlockLambdaBody_lambdaReturns_value; 708 /** 709 * @apilevel internal 710 */ 711 private void BlockLambdaBody_lambdaReturns_reset() { 712 BlockLambdaBody_lambdaReturns_computed = false; 713 BlockLambdaBody_lambdaReturns_value = null; 714 } 715 }