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 BasicTWR : {@link Stmt} ::= <span class="component">Resource:{@link ResourceDeclaration}</span> <span class="component">{@link Block}</span>; 015 * @ast node 016 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/BasicTWR.ast:1 017 */ 018 public class BasicTWR extends Stmt implements Cloneable, VariableScope { 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 BasicTWR clone() throws CloneNotSupportedException { 034 BasicTWR node = (BasicTWR)super.clone(); 035 node.localLookup_String_values = null; 036 node.localVariableDeclaration_String_values = null; 037 node.lookupVariable_String_values = null; 038 node.in$Circle(false); 039 node.is$Final(false); 040 return node; 041 } 042 /** 043 * @apilevel internal 044 */ 045 @SuppressWarnings({"unchecked", "cast"}) 046 public BasicTWR copy() { 047 048 try { 049 BasicTWR node = (BasicTWR) clone(); 050 node.parent = null; 051 if(children != null) 052 node.children = (ASTNode[]) children.clone(); 053 054 return node; 055 } catch (CloneNotSupportedException e) { 056 throw new Error("Error: clone not supported for " + getClass().getName()); 057 } 058 059 }/** 060 * Create a deep copy of the AST subtree at this node. 061 * The copy is dangling, i.e. has no parent. 062 * @return dangling copy of the subtree at this node 063 * @apilevel low-level 064 */ 065 @SuppressWarnings({"unchecked", "cast"}) 066 public BasicTWR fullCopy() { 067 068 BasicTWR tree = (BasicTWR) copy(); 069 if (children != null) { 070 for (int i = 0; i < children.length; ++i) { 071 072 ASTNode child = (ASTNode) children[i]; 073 if(child != null) { 074 child = child.fullCopy(); 075 tree.setChild(child, i); 076 } 077 } 078 } 079 return tree; 080 081 } /** 082 * The general structure of the basic try-with-resources: 083 * 084 * <pre><code> 085 * RESOURCE 086 * BLOCK 087 * 088 * Primary Exception Handler 089 * Automatic Closing of Resource 090 * Suppressed Exception Handler 091 * re-throw primary exception 092 * Automatic Closing of Resource 093 * </pre></code> 094 * 095 * Pseudocode for basic try-with-resources: 096 * 097 * <pre><code> 098 * 0 .resourceBegin 099 * 1 emit RESOURCE 100 * 0 store resource 101 * 0 .resourceEnd 102 * 103 * 0 .blockBegin 104 * 0 emit BLOCK 105 * 0 .blockEnd 106 * 0 goto outerFinally 107 * 108 * 1 .resourceException 109 * 1 throw 110 * 111 * #if BLOCK is not empty: 112 * 113 * 1 .catchPrimary 114 * 0 store primary 115 * 116 * 0 .tryCloseBegin 117 * 1 load resource 118 * 0 ifnull innerFinally 119 * 1 load resource 120 * 0 invoke java.lang.AutoCloseable.close() 121 * 0 .tryCloseEnd 122 * 123 * 0 goto innerFinally 124 * 125 * 1 .catchSuppressed 126 * 0 store suppressed 127 * 1 load primary 128 * 2 load suppressed 129 * 0 invoke java.lang.Throwable.addSuppressed(Throwable) 130 * 131 * 0 .innerFinally 132 * 1 load primary 133 * 1 throw 134 * 135 * #endif BLOCK is not empty 136 * 137 * 0 .outerFinally 138 * 1 load resource 139 * 0 ifnull tryEnd 140 * 1 load resource 141 * 0 invoke java.lang.AutoCloseable.close() 142 * 143 * 0 .tryEnd 144 * 145 * Exception Table: 146 * resourceBegin .. resourceEnd : resourceException 147 * blockBegin .. blockEnd : catchPrimary 148 * tryCloseBegin .. tryCloseEnd : catchSuppressed 149 * </pre></code> 150 * 151 * @ast method 152 * @aspect TryWithResources 153 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:136 154 */ 155 public void createBCode(CodeGeneration gen) { 156 ResourceDeclaration resource = getResource(); 157 158 int resourceBeginLbl = hostType().constantPool().newLabel(); 159 int resourceEndLbl = hostType().constantPool().newLabel(); 160 int blockBeginLbl = hostType().constantPool().newLabel(); 161 int blockEndLbl = hostType().constantPool().newLabel(); 162 int tryCloseBeginLbl = hostType().constantPool().newLabel(); 163 int tryCloseEndLbl = hostType().constantPool().newLabel(); 164 165 int resourceExceptionLbl = hostType().constantPool().newLabel(); 166 int catchPrimaryLbl = hostType().constantPool().newLabel(); 167 int catchSuppressedLbl = hostType().constantPool().newLabel(); 168 int innerFinallyLbl = hostType().constantPool().newLabel(); 169 int outerFinallyLbl = hostType().constantPool().newLabel(); 170 int tryEndLbl = hostType().constantPool().newLabel(); 171 172 TypeDecl throwableType = lookupType("java.lang", "Throwable"); 173 TypeDecl resourceType = resource.type(); 174 TypeDecl autoCloseableType = lookupType("java.lang", "AutoCloseable"); 175 176 gen.changeStackDepth(3); 177 int resourceIndex = resource.localNum(); 178 int primaryIndex = resourceIndex+resourceType.variableSize(); 179 int suppressedIndex = primaryIndex+throwableType.variableSize(); 180 181 // store the resource in local 182 gen.addLabel(resourceBeginLbl); 183 resource.createBCode(gen); 184 gen.addLabel(resourceEndLbl); 185 gen.emit(Bytecode.NOP); 186 187 gen.addLabel(blockBeginLbl); 188 getBlock().createBCode(gen); 189 gen.addLabel(blockEndLbl); 190 gen.emitGoto(outerFinallyLbl); 191 192 // If there was an exception when initializing the resource 193 // we need to directly rethrow the exception 194 gen.addLabel(resourceExceptionLbl); 195 gen.emitThrow(); 196 gen.addException( 197 gen.addressOf(resourceBeginLbl), 198 gen.addressOf(resourceEndLbl), 199 gen.addressOf(resourceExceptionLbl), 200 0); 201 202 if (gen.addressOf(blockBeginLbl) != gen.addressOf(blockEndLbl)) { 203 204 // catch primary exception 205 // operand stack: .., #primary 206 gen.addLabel(catchPrimaryLbl); 207 throwableType.emitStoreLocal(gen, primaryIndex); 208 209 // try-close resource 210 gen.addLabel(tryCloseBeginLbl); 211 { 212 // if resource != null 213 resourceType.emitLoadLocal(gen, resourceIndex); 214 gen.emitCompare(Bytecode.IFNULL, innerFinallyLbl); 215 resourceType.emitLoadLocal(gen, resourceIndex); 216 closeMethod().emitInvokeMethod(gen, autoCloseableType); 217 } 218 gen.addLabel(tryCloseEndLbl); 219 gen.emitGoto(innerFinallyLbl); 220 221 // catch suppressed exception 222 // operand stack: .., #primary, #suppressed 223 gen.addLabel(catchSuppressedLbl); 224 throwableType.emitStoreLocal(gen, suppressedIndex); 225 throwableType.emitLoadLocal(gen, primaryIndex); 226 throwableType.emitLoadLocal(gen, suppressedIndex); 227 addSuppressedMethod().emitInvokeMethod(gen, throwableType); 228 229 // inner finally 230 // operand stack: .., #primary 231 gen.addLabel(innerFinallyLbl); 232 throwableType.emitLoadLocal(gen, primaryIndex); 233 gen.emitThrow(); 234 235 // If there was an exception during the block of the try 236 // statement, then we should try to close the resource 237 gen.addException( 238 gen.addressOf(blockBeginLbl), 239 gen.addressOf(blockEndLbl), 240 gen.addressOf(catchPrimaryLbl), 241 0); 242 243 // If an exception occurrs during the automatic closing 244 // of a resource after an exception in the try block... 245 gen.addException( 246 gen.addressOf(tryCloseBeginLbl), 247 gen.addressOf(tryCloseEndLbl), 248 gen.addressOf(catchSuppressedLbl), 249 0); 250 } 251 252 // outer finally 253 gen.addLabel(outerFinallyLbl); 254 { 255 // if resource != null 256 resourceType.emitLoadLocal(gen, resourceIndex); 257 gen.emitCompare(Bytecode.IFNULL, tryEndLbl); 258 resourceType.emitLoadLocal(gen, resourceIndex); 259 closeMethod().emitInvokeMethod(gen, autoCloseableType); 260 } 261 262 gen.addLabel(tryEndLbl); 263 gen.emit(Bytecode.NOP); 264 } 265 /** 266 * Lookup the java.lang.Throwable.close() method. 267 * @ast method 268 * @aspect TryWithResources 269 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:250 270 */ 271 private MethodDecl closeMethod() { 272 TypeDecl autoCloseableType = lookupType("java.lang", "AutoCloseable"); 273 if (autoCloseableType == null) 274 throw new Error("Could not find java.lang.AutoCloseable"); 275 for (MethodDecl method : (Collection<MethodDecl>) 276 autoCloseableType.memberMethods("close")) { 277 if (method.getNumParameter() == 0) 278 return method; 279 } 280 throw new Error("Could not find java.lang.AutoCloseable.close()"); 281 } 282 /** 283 * Lookup the java.lang.Throwable.addSuppressed(Throwable) method. 284 * @ast method 285 * @aspect TryWithResources 286 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:265 287 */ 288 private MethodDecl addSuppressedMethod() { 289 TypeDecl throwableType = lookupType("java.lang", "Throwable"); 290 if (throwableType == null) 291 throw new Error("Could not find java.lang.Throwable"); 292 for (MethodDecl method : (Collection<MethodDecl>) 293 throwableType.memberMethods("addSuppressed")) { 294 if (method.getNumParameter() == 1 && 295 method.getParameter(0).getTypeAccess().type() == 296 throwableType) { 297 return method; 298 } 299 } 300 throw new Error("Could not find java.lang.Throwable.addSuppressed()"); 301 } 302 /** 303 * @ast method 304 * 305 */ 306 public BasicTWR() { 307 super(); 308 309 310 } 311 /** 312 * Initializes the child array to the correct size. 313 * Initializes List and Opt nta children. 314 * @apilevel internal 315 * @ast method 316 * @ast method 317 * 318 */ 319 public void init$Children() { 320 children = new ASTNode[2]; 321 } 322 /** 323 * @ast method 324 * 325 */ 326 public BasicTWR(ResourceDeclaration p0, Block p1) { 327 setChild(p0, 0); 328 setChild(p1, 1); 329 } 330 /** 331 * @apilevel low-level 332 * @ast method 333 * 334 */ 335 protected int numChildren() { 336 return 2; 337 } 338 /** 339 * @apilevel internal 340 * @ast method 341 * 342 */ 343 public boolean mayHaveRewrite() { 344 return false; 345 } 346 /** 347 * Replaces the Resource child. 348 * @param node The new node to replace the Resource child. 349 * @apilevel high-level 350 * @ast method 351 * 352 */ 353 public void setResource(ResourceDeclaration node) { 354 setChild(node, 0); 355 } 356 /** 357 * Retrieves the Resource child. 358 * @return The current node used as the Resource child. 359 * @apilevel high-level 360 * @ast method 361 * 362 */ 363 public ResourceDeclaration getResource() { 364 return (ResourceDeclaration)getChild(0); 365 } 366 /** 367 * Retrieves the Resource child. 368 * <p><em>This method does not invoke AST transformations.</em></p> 369 * @return The current node used as the Resource child. 370 * @apilevel low-level 371 * @ast method 372 * 373 */ 374 public ResourceDeclaration getResourceNoTransform() { 375 return (ResourceDeclaration)getChildNoTransform(0); 376 } 377 /** 378 * Replaces the Block child. 379 * @param node The new node to replace the Block child. 380 * @apilevel high-level 381 * @ast method 382 * 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 * @ast method 392 * 393 */ 394 public Block getBlock() { 395 return (Block)getChild(1); 396 } 397 /** 398 * Retrieves the Block child. 399 * <p><em>This method does not invoke AST transformations.</em></p> 400 * @return The current node used as the Block child. 401 * @apilevel low-level 402 * @ast method 403 * 404 */ 405 public Block getBlockNoTransform() { 406 return (Block)getChildNoTransform(1); 407 } 408 protected java.util.Map localLookup_String_values; 409 /** 410 * @attribute syn 411 * @aspect MultiCatch 412 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:78 413 */ 414 @SuppressWarnings({"unchecked", "cast"}) 415 public SimpleSet localLookup(String name) { 416 Object _parameters = name; 417 if(localLookup_String_values == null) localLookup_String_values = new java.util.HashMap(4); 418 if(localLookup_String_values.containsKey(_parameters)) { 419 return (SimpleSet)localLookup_String_values.get(_parameters); 420 } 421 ASTNode$State state = state(); 422 int num = state.boundariesCrossed; 423 boolean isFinal = this.is$Final(); 424 SimpleSet localLookup_String_value = localLookup_compute(name); 425 if(isFinal && num == state().boundariesCrossed){ localLookup_String_values.put(_parameters, localLookup_String_value); } 426 return localLookup_String_value; 427 } 428 /** 429 * @apilevel internal 430 */ 431 private SimpleSet localLookup_compute(String name) { 432 VariableDeclaration v = localVariableDeclaration(name); 433 if (v != null) return v; 434 return lookupVariable(name); 435 } 436 protected java.util.Map localVariableDeclaration_String_values; 437 /** 438 * @attribute syn 439 * @aspect MultiCatch 440 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:83 441 */ 442 @SuppressWarnings({"unchecked", "cast"}) 443 public VariableDeclaration localVariableDeclaration(String name) { 444 Object _parameters = name; 445 if(localVariableDeclaration_String_values == null) localVariableDeclaration_String_values = new java.util.HashMap(4); 446 if(localVariableDeclaration_String_values.containsKey(_parameters)) { 447 return (VariableDeclaration)localVariableDeclaration_String_values.get(_parameters); 448 } 449 ASTNode$State state = state(); 450 int num = state.boundariesCrossed; 451 boolean isFinal = this.is$Final(); 452 VariableDeclaration localVariableDeclaration_String_value = localVariableDeclaration_compute(name); 453 if(isFinal && num == state().boundariesCrossed){ localVariableDeclaration_String_values.put(_parameters, localVariableDeclaration_String_value); } 454 return localVariableDeclaration_String_value; 455 } 456 /** 457 * @apilevel internal 458 */ 459 private VariableDeclaration localVariableDeclaration_compute(String name) { return getResource().declaresVariable(name) ? getResource() : null; } 460 /** 461 * @attribute syn 462 * @aspect PreciseRethrow 463 * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/PreciseRethrow.jrag:55 464 */ 465 public boolean modifiedInScope(Variable var) { 466 ASTNode$State state = state(); 467 try { return getBlock().modifiedInScope(var); } 468 finally { 469 } 470 } 471 protected java.util.Map lookupVariable_String_values; 472 /** 473 * @attribute inh 474 * @aspect MultiCatch 475 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:87 476 */ 477 @SuppressWarnings({"unchecked", "cast"}) 478 public SimpleSet lookupVariable(String name) { 479 Object _parameters = name; 480 if(lookupVariable_String_values == null) lookupVariable_String_values = new java.util.HashMap(4); 481 if(lookupVariable_String_values.containsKey(_parameters)) { 482 return (SimpleSet)lookupVariable_String_values.get(_parameters); 483 } 484 ASTNode$State state = state(); 485 int num = state.boundariesCrossed; 486 boolean isFinal = this.is$Final(); 487 SimpleSet lookupVariable_String_value = getParent().Define_SimpleSet_lookupVariable(this, null, name); 488 if(isFinal && num == state().boundariesCrossed){ lookupVariable_String_values.put(_parameters, lookupVariable_String_value); } 489 return lookupVariable_String_value; 490 } 491 /** 492 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/MultiCatch.jrag:76 493 * @apilevel internal 494 */ 495 public SimpleSet Define_SimpleSet_lookupVariable(ASTNode caller, ASTNode child, String name) { 496 if(caller == getBlockNoTransform()) { 497 return localLookup(name); 498 } 499 else { return getParent().Define_SimpleSet_lookupVariable(this, caller, name); 500 } 501 } 502 /** 503 * @declaredat /home/jesper/svn/JastAddJ/Java7Backend/TryWithResources.jrag:292 504 * @apilevel internal 505 */ 506 public int Define_int_localNum(ASTNode caller, ASTNode child) { 507 if(caller == getBlockNoTransform()) { 508 return getResource().localNum() + 509 getResource().type().variableSize() + 510 2 * lookupType("java.lang", "Throwable").variableSize(); 511 } 512 else if(caller == getResourceNoTransform()) { 513 return localNum(); 514 } 515 else { return getParent().Define_int_localNum(this, caller); 516 } 517 } 518 /** 519 * @apilevel internal 520 */ 521 public ASTNode rewriteTo() { 522 return super.rewriteTo(); 523 } 524 }