001 /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.3 */ 002 package AST; 003 004 import java.util.Collection; 005 import java.util.ArrayList; 006 import java.util.HashSet; 007 /** 008 * @ast node 009 * @production ASTNode; 010 011 */ 012 public class ASTNode<T extends ASTNode> implements Cloneable, Iterable<T> { 013 /** 014 * @apilevel internal 015 */ 016 public ASTNode<T> clone() throws CloneNotSupportedException { 017 ASTNode node = (ASTNode) super.clone(); 018 node.in$Circle(false); 019 node.is$Final(false); 020 return node; 021 } 022 /** 023 * @apilevel internal 024 */ 025 public ASTNode<T> copy() { 026 try { 027 ASTNode node = (ASTNode) clone(); 028 node.parent = null; 029 if(children != null) { 030 node.children = (ASTNode[]) children.clone(); 031 } 032 return node; 033 } catch (CloneNotSupportedException e) { 034 throw new Error("Error: clone not supported for " + getClass().getName()); 035 } 036 } 037 /** 038 * Create a deep copy of the AST subtree at this node. 039 * The copy is dangling, i.e. has no parent. 040 * @return dangling copy of the subtree at this node 041 * @apilevel low-level 042 */ 043 public ASTNode<T> fullCopy() { 044 ASTNode tree = (ASTNode) copy(); 045 if (children != null) { 046 for (int i = 0; i < children.length; ++i) { 047 ASTNode child = (ASTNode) children[i]; 048 if(child != null) { 049 child = child.fullCopy(); 050 tree.setChild(child, i); 051 } 052 } 053 } 054 return tree; 055 } 056 /** 057 * @aspect ErrorCheck 058 * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:12 059 */ 060 public void collectErrors(Collection c) { 061 for(int i = 0; i < getNumChild(); i++) 062 getChild(i).collectErrors(c); 063 } 064 /** 065 * @aspect ErrorCheck 066 * @declaredat /home/csz-naf/examples/PicoJava/spec/ErrorCheck.jadd:18 067 */ 068 protected void error(Collection c, String s) { 069 //c.add(getLine(getStart()) + ": " + s); 070 c.add(s); 071 } 072 /** 073 * Print AST 074 * @aspect PrettyPrint 075 * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:5 076 */ 077 public String printAST() { 078 StringBuilder sb = new StringBuilder(); 079 printAST(sb); 080 return sb.toString(); 081 } 082 /** 083 * @aspect PrettyPrint 084 * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:10 085 */ 086 public void printAST(StringBuilder sb) { 087 printAST(sb, 0); 088 } 089 /** 090 * @aspect PrettyPrint 091 * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:13 092 */ 093 public void printAST(StringBuilder sb, int t) { 094 for (int j = 0; j < t; j++) { 095 sb.append((j%2==0) ? " |" : " !"); 096 } 097 sb.append(getClass().getName() + "\n"); 098 for (int i = 0; i < getNumChild(); i++) { 099 getChild(i).printAST(sb, t+1); 100 } 101 } 102 /** 103 * @aspect PrettyPrint 104 * @declaredat /home/csz-naf/examples/PicoJava/spec/PrettyPrint.jadd:78 105 */ 106 public String getIndent(int t) { 107 String s = ""; 108 for (int i = 0; i < t; i++) { 109 s += "\t"; 110 } 111 return s; 112 } 113 /** 114 */ 115 public ASTNode() { 116 super(); 117 init$Children(); 118 } 119 /** 120 * Initializes the child array to the correct size. 121 * Initializes List and Opt nta children. 122 * @apilevel internal 123 * @ast method 124 */ 125 public void init$Children() { 126 } 127 /** 128 * @apilevel internal 129 */ 130 private int childIndex; 131 /** 132 * @apilevel low-level 133 */ 134 public int getIndexOfChild(ASTNode node) { 135 if (node == null) { 136 return -1; 137 } 138 if (node.childIndex < numChildren && node == children[node.childIndex]) { 139 return node.childIndex; 140 } 141 for(int i = 0; children != null && i < children.length; i++) { 142 if(children[i] == node) { 143 node.childIndex = i; 144 return i; 145 } 146 } 147 return -1; 148 } 149 /** 150 * @apilevel internal 151 */ 152 public static final boolean generatedWithCircularEnabled = true; 153 /** 154 * @apilevel internal 155 */ 156 public static final boolean generatedWithCacheCycle = true; 157 /** 158 * @apilevel internal 159 */ 160 public static final boolean generatedWithComponentCheck = false; 161 /** 162 * Parent pointer 163 * @apilevel low-level 164 */ 165 protected ASTNode parent; 166 /** 167 * Child array 168 * @apilevel low-level 169 */ 170 protected ASTNode[] children; 171 /** 172 * @apilevel internal 173 */ 174 protected static ASTNode$State state = new ASTNode$State(); 175 /** 176 * @apilevel internal 177 */ 178 public final ASTNode$State state() { 179 return state; 180 } 181 /** 182 * @apilevel internal 183 */ 184 public boolean in$Circle = false; 185 /** 186 * @apilevel internal 187 */ 188 public boolean in$Circle() { 189 return in$Circle; 190 } 191 /** 192 * @apilevel internal 193 */ 194 public void in$Circle(boolean b) { 195 in$Circle = b; 196 } 197 /** 198 * @apilevel internal 199 */ 200 public boolean is$Final = false; 201 /** 202 * @apilevel internal 203 */ 204 public boolean is$Final() { return is$Final; } 205 /** 206 * @apilevel internal 207 */ 208 public void is$Final(boolean b) { is$Final = b; } 209 /** 210 * @apilevel low-level 211 */ 212 public T getChild(int i) { 213 214 ASTNode node = this.getChildNoTransform(i); 215 if(node == null) { 216 return null; 217 } 218 if(node.is$Final()) { 219 return (T) node; 220 } 221 if(!node.mayHaveRewrite()) { 222 node.is$Final(this.is$Final()); 223 return (T) node; 224 } 225 if(!node.in$Circle()) { 226 int rewriteState; 227 int num = this.state().boundariesCrossed; 228 do { 229 this.state().push(ASTNode$State.REWRITE_CHANGE); 230 ASTNode oldNode = node; 231 oldNode.in$Circle(true); 232 node = node.rewriteTo(); 233 if(node != oldNode) { 234 this.setChild(node, i); 235 } 236 oldNode.in$Circle(false); 237 rewriteState = this.state().pop(); 238 } while(rewriteState == ASTNode$State.REWRITE_CHANGE); 239 if(rewriteState == ASTNode$State.REWRITE_NOCHANGE && this.is$Final()) { 240 node.is$Final(true); 241 this.state().boundariesCrossed = num; 242 } else { 243 } 244 } else if(this.is$Final() != node.is$Final()) { 245 this.state().boundariesCrossed++; 246 } else { 247 } 248 return (T) node; 249 250 251 } 252 /** 253 * @apilevel low-level 254 */ 255 public void addChild(T node) { 256 setChild(node, getNumChildNoTransform()); 257 } 258 /** 259 * <p><em>This method does not invoke AST transformations.</em></p> 260 * @apilevel low-level 261 */ 262 public final T getChildNoTransform(int i) { 263 if (children == null) { 264 return null; 265 } 266 T child = (T)children[i]; 267 return child; 268 } 269 /** 270 * @apilevel low-level 271 */ 272 protected int numChildren; 273 /** 274 * @apilevel low-level 275 */ 276 protected int numChildren() { 277 return numChildren; 278 } 279 /** 280 * @apilevel low-level 281 */ 282 public int getNumChild() { 283 return numChildren(); 284 } 285 /** 286 * <p><em>This method does not invoke AST transformations.</em></p> 287 * @apilevel low-level 288 */ 289 public final int getNumChildNoTransform() { 290 return numChildren(); 291 } 292 /** 293 * @apilevel low-level 294 */ 295 public void setChild(ASTNode node, int i) { 296 if(children == null) { 297 children = new ASTNode[(i+1>4 || !(this instanceof List))?i+1:4]; 298 } else if (i >= children.length) { 299 ASTNode c[] = new ASTNode[i << 1]; 300 System.arraycopy(children, 0, c, 0, children.length); 301 children = c; 302 } 303 children[i] = node; 304 if(i >= numChildren) { 305 numChildren = i+1; 306 } 307 if(node != null) { 308 node.setParent(this); 309 node.childIndex = i; 310 } 311 } 312 /** 313 * @apilevel low-level 314 */ 315 public void insertChild(ASTNode node, int i) { 316 if(children == null) { 317 children = new ASTNode[(i+1>4 || !(this instanceof List))?i+1:4]; 318 children[i] = node; 319 } else { 320 ASTNode c[] = new ASTNode[children.length + 1]; 321 System.arraycopy(children, 0, c, 0, i); 322 c[i] = node; 323 if(i < children.length) { 324 System.arraycopy(children, i, c, i+1, children.length-i); 325 for(int j = i+1; j < c.length; ++j) { 326 if(c[j] != null) { 327 c[j].childIndex = j; 328 } 329 } 330 } 331 children = c; 332 } 333 numChildren++; 334 if(node != null) { 335 node.setParent(this); 336 node.childIndex = i; 337 } 338 } 339 /** 340 * @apilevel low-level 341 */ 342 public void removeChild(int i) { 343 if(children != null) { 344 ASTNode child = (ASTNode) children[i]; 345 if(child != null) { 346 child.parent = null; 347 child.childIndex = -1; 348 } 349 // Adding a check of this instance to make sure its a List, a move of children doesn't make 350 // any sense for a node unless its a list. Also, there is a problem if a child of a non-List node is removed 351 // and siblings are moved one step to the right, with null at the end. 352 if (this instanceof List || this instanceof Opt) { 353 System.arraycopy(children, i+1, children, i, children.length-i-1); 354 children[children.length-1] = null; 355 numChildren--; 356 // fix child indices 357 for(int j = i; j < numChildren; ++j) { 358 if(children[j] != null) { 359 child = (ASTNode) children[j]; 360 child.childIndex = j; 361 } 362 } 363 } else { 364 children[i] = null; 365 } 366 } 367 } 368 /** 369 * @apilevel low-level 370 */ 371 public ASTNode getParent() { 372 if(parent != null && ((ASTNode) parent).is$Final() != is$Final()) { 373 state().boundariesCrossed++; 374 } 375 ; 376 return (ASTNode) parent; 377 } 378 /** 379 * @apilevel low-level 380 */ 381 public void setParent(ASTNode node) { 382 parent = node; 383 } 384 /** 385 * Line and column information. 386 */ 387 protected int startLine; 388 /** 389 */ 390 protected short startColumn; 391 /** 392 */ 393 protected int endLine; 394 /** 395 */ 396 protected short endColumn; 397 /** 398 */ 399 public int getStartLine() { 400 return startLine; 401 } 402 /** 403 */ 404 public short getStartColumn() { 405 return startColumn; 406 } 407 /** 408 */ 409 public int getEndLine() { 410 return endLine; 411 } 412 /** 413 */ 414 public short getEndColumn() { 415 return endColumn; 416 } 417 /** 418 */ 419 public void setStart(int startLine, short startColumn) { 420 this.startLine = startLine; 421 this.startColumn = startColumn; 422 } 423 /** 424 */ 425 public void setEnd(int endLine, short endColumn) { 426 this.endLine = endLine; 427 this.endColumn = endColumn; 428 } 429 /** 430 */ 431 protected boolean duringTypeAnalysis() { 432 if(state().duringTypeAnalysis == 0) { 433 return false; 434 } else { 435 state().pop(); 436 state().push(ASTNode$State.REWRITE_INTERRUPT); 437 return true; 438 } 439 } 440 /** 441 * @apilevel low-level 442 */ 443 public java.util.Iterator<T> iterator() { 444 return new java.util.Iterator<T>() { 445 private int counter = 0; 446 public boolean hasNext() { 447 return counter < getNumChild(); 448 } 449 public T next() { 450 if(hasNext()) 451 return (T)getChild(counter++); 452 else 453 return null; 454 } 455 public void remove() { 456 throw new UnsupportedOperationException(); 457 } 458 }; 459 } 460 /** 461 * @apilevel internal 462 */ 463 public boolean mayHaveRewrite() { 464 return false; 465 } 466 /** 467 * @apilevel low-level 468 */ 469 public void flushCache() { 470 } 471 /** 472 * @apilevel internal 473 */ 474 public void flushCollectionCache() { 475 } 476 /** 477 * @apilevel internal 478 */ 479 public ASTNode rewriteTo() { if(state().peek() == ASTNode$State.REWRITE_CHANGE) { 480 state().pop(); 481 state().push(ASTNode$State.REWRITE_NOCHANGE); 482 } 483 return this; 484 } /** 485 * @apilevel internal 486 */ 487 public boolean Define_boolean_isQualified(ASTNode caller, ASTNode child) { 488 return getParent().Define_boolean_isQualified(this, caller); 489 } 490 /** 491 * @apilevel internal 492 */ 493 public Access Define_Access_qualifier(ASTNode caller, ASTNode child) { 494 return getParent().Define_Access_qualifier(this, caller); 495 } 496 /** 497 * @apilevel internal 498 */ 499 public Decl Define_Decl_lookup(ASTNode caller, ASTNode child, String name) { 500 return getParent().Define_Decl_lookup(this, caller, name); 501 } 502 /** 503 * @apilevel internal 504 */ 505 public Decl Define_Decl_unknownDecl(ASTNode caller, ASTNode child) { 506 return getParent().Define_Decl_unknownDecl(this, caller); 507 } 508 /** 509 * @apilevel internal 510 */ 511 public PrimitiveDecl Define_PrimitiveDecl_booleanType(ASTNode caller, ASTNode child) { 512 return getParent().Define_PrimitiveDecl_booleanType(this, caller); 513 } 514 }