View Javadoc
1 /* FOREGEJ - FOrmatting REfactoring GEnerating Java 2 * 3 * Copyright (C) 2003 Andreas Arrgard 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 package com.octagroup.foregej.antlr; 20 import antlr.CommonASTWithHiddenTokens; 21 import antlr.collections.AST; 22 import java.util.List; 23 /*** 24 * The base representation of an AST in the FOREGEJ system. 25 */ 26 public class BaseAST extends CommonASTWithHiddenTokens 27 { 28 public static int WRAP_PREF_NONE=0; 29 public static int WRAP_PREF_NO=1; 30 public static int WRAP_PREF_OK=2; 31 /*** 32 * This is the parent AST. 33 */ 34 private AST _parent; 35 /*** 36 * the AST factory that created this token 37 */ 38 protected DynASTFactory astFactory_; 39 /*** 40 * Constructor creates a new BaseAST object. 41 */ 42 public BaseAST() 43 { 44 } 45 /*** 46 * Constructor creates a new BaseAST object. 47 * 48 * @param ast DOCUMENT ME! 49 */ 50 public BaseAST(AST ast) 51 { 52 this.setType(ast.getType()); 53 this.setText(ast.getText()); 54 this.setFirstChild(ast.getFirstChild()); 55 this.setNextSibling(ast.getNextSibling()); 56 } 57 /*** 58 * As we invoke the <code>NodeWriter.write</code>we store how the node 59 * prefers to handle wrapping. 60 * 61 * @return the wrapping preference. 62 */ 63 public int getWrappingPreference() 64 { 65 return WRAP_PREF_NONE; 66 } 67 /*** 68 * DOCUMENT ME! 69 * 70 * @param type DOCUMENT ME! 71 * @return DOCUMENT ME! 72 */ 73 public AST getChildAST(Class type) 74 { 75 List asts=getChildASTs(type); 76 if(asts==null) { 77 return null; 78 } 79 if(asts.size()==0) { 80 return null; 81 } 82 return (AST)asts.get(0); 83 } 84 /*** 85 * Returns all the child asts that match the supplied type. 86 * 87 * @param type the type to look for. 88 * @return 89 */ 90 public List getChildASTs(Class type) 91 { 92 return new AST_List(this, type); 93 } 94 /*** 95 * Returns all the child asts that do not match the supplied classes. 96 * 97 * @param excluding the classes to exclude. 98 * @return all the child asts that do not match the supplied classes. 99 */ 100 public List getChildASTsExcluding(Class[] excluding) 101 { 102 return new AST_List(this, null, excluding); 103 } 104 /*** 105 * Helper method that inserts an ast after the last occurence of the 106 * supplied type. 107 * 108 * @param afterType DOCUMENT ME! 109 * @param newAst the new ast 110 * @throws RuntimeException DOCUMENT ME! 111 */ 112 public void insertAfter(Class afterType,AST newAst) 113 { 114 AST_ListIterator iter=new AST_ListIterator(this, afterType); 115 AST node=null; 116 while(iter.hasNext()){ 117 node=(AST)iter.next(); 118 } 119 if(node==null) { 120 throw new RuntimeException("Failed to insert AST after node of type("+afterType.getName()+"):"+this); 121 } 122 newAst.setNextSibling(node.getNextSibling()); 123 node.setNextSibling(newAst); 124 } 125 /*** 126 * Helper method that replaces a child or ast with a new ast. 127 * 128 * @param newAst the new ast 129 */ 130 public void insertFirst(AST newAst) 131 { 132 AST nextSibling=getFirstChild(); 133 setFirstChild(null); 134 newAst.setNextSibling(nextSibling); 135 setFirstChild(newAst); 136 } 137 /*** 138 * Helper method that replaces a child or ast with a new ast. 139 * 140 * @param oldAst the ast to replace 141 * @param newAst the new ast 142 * @return 143 */ 144 public boolean replaceAST(AST oldAst,AST newAst) 145 { 146 // we cannot replace a null node 147 if(oldAst==null) { 148 return false; 149 } 150 // start with the first child and compare 151 AST node=getFirstChild(); 152 if(node==oldAst) { 153 AST nextSibling=node.getNextSibling(); 154 node.setNextSibling(null); 155 newAst.setNextSibling(nextSibling); 156 setFirstChild(newAst); 157 } 158 while(node!=null){ 159 if(node.getNextSibling()==oldAst) { 160 AST nextSibling=node.getNextSibling().getNextSibling(); 161 node.getNextSibling().setNextSibling(null); 162 newAst.setNextSibling(nextSibling); 163 node.setNextSibling(newAst); 164 return true; 165 } 166 node=node.getNextSibling(); 167 } 168 throw new RuntimeException("Failed to replace AST!"); 169 } 170 /*** 171 * DOCUMENT ME! 172 * 173 * @param nw DOCUMENT ME! 174 * @throws RuntimeException DOCUMENT ME! 175 */ 176 public void write(NodeWriter nw) 177 { 178 throw new RuntimeException("Cannot write a:"+getType()+"["+getClass().getName()+"]"); 179 } 180 /*** 181 * Compares two objects 182 * 183 * @param o1 184 * @param o2 185 * @return 186 */ 187 public boolean equals(Object o1,Object o2) 188 { 189 if(o1==o2) return true; 190 if(o1==null) return false; 191 return o1.equals(o2); 192 } 193 /*** 194 * Performs a deep copy of the node. 195 * 196 * @return 197 */ 198 public BaseAST deepCopy() 199 { 200 return (BaseAST)deepCopy(this); 201 } 202 /*** 203 * @param ast 204 * @return 205 */ 206 public static AST deepCopy(AST ast) 207 { 208 try{ 209 AST copy=(AST)ast.getClass().newInstance(); 210 copy.initialize(ast); 211 if(ast instanceof BaseAST) { 212 ((BaseAST)copy).hiddenBefore=((BaseAST)ast).hiddenBefore; 213 ((BaseAST)copy).hiddenAfter=((BaseAST)ast).hiddenAfter; 214 } 215 AST node=ast.getFirstChild(); 216 if(node!=null) { 217 copy.setFirstChild(deepCopy(node)); 218 node=node.getNextSibling(); 219 } 220 AST siblingOwner=copy.getFirstChild(); 221 while(node!=null){ 222 siblingOwner.setNextSibling(deepCopy(node)); 223 siblingOwner=siblingOwner.getNextSibling(); 224 node=node.getNextSibling(); 225 } 226 return copy; 227 }catch (InstantiationException e) { 228 throw new IllegalStateException("Failed to copy node:InstantiationException:"+e.getMessage()); 229 }catch (IllegalAccessException e) { 230 throw new IllegalStateException("Failed to copy node:InstantiationException:"+e.getMessage()); 231 } 232 } 233 /*** 234 * @param includeComments 235 * @return 236 */ 237 public String toString(boolean includeComments) 238 { 239 NodeWriter nw=new NodeWriter(); 240 nw.write(this); 241 return nw.toString(); 242 } 243 /*** 244 * @return 245 */ 246 public String toString() 247 { 248 return toString(true); 249 } 250 /*** 251 * @param o 252 * @return 253 */ 254 public boolean equals(Object o) 255 { 256 if(o==null) return false; 257 if(o.getClass()!=getClass()) return false; 258 BaseAST a=(BaseAST)o; 259 if(false==equals(getText(), a.getText())) return false; 260 AST thisNode=getFirstChild(); 261 AST aNode=a.getFirstChild(); 262 while(thisNode!=null&&aNode!=null){ 263 if(false==equals(thisNode, aNode)) return false; 264 thisNode=thisNode.getNextSibling(); 265 aNode=aNode.getNextSibling(); 266 } 267 return thisNode==null&&aNode==null; 268 } 269 /*** 270 * Sets the token hidden before this ast. 271 * 272 * @param hiddenBefore 273 */ 274 public void setHiddenBefore(BaseToken hiddenBefore) 275 { 276 this.hiddenBefore=hiddenBefore; 277 if(hiddenBefore!=null) { 278 ((BaseToken)hiddenBefore).setHiddenAfter(null); 279 } 280 } 281 /*** 282 * Sets the token hidden after this ast. 283 * 284 * @param hiddenAfter 285 */ 286 public void setHiddenAfter(BaseToken hiddenAfter) 287 { 288 this.hiddenAfter=hiddenAfter; 289 if(hiddenAfter!=null) { 290 ((BaseToken)hiddenAfter).setHiddenBefore(null); 291 } 292 } 293 /*** 294 * Sets the factory used to create this AST. 295 * <p> 296 * This method is invoked from the AST factory when the token is 297 * created. 298 * </p> 299 * 300 * <p> 301 * The factory is used to signal that types have been changed. 302 * </p> 303 * 304 * @param factory the factory that created the AST 305 */ 306 public void setASTFactory(DynASTFactory factory) 307 { 308 astFactory_=factory; 309 } 310 /*** 311 * Sets the type of this ast. 312 * <p> 313 * It also signals to the AST factory that we have modified the type 314 * so that the next call to the DynASTFactory scans the tree to 315 * replace the created AST with the new type. 316 * </p> 317 * 318 * @param type 319 */ 320 public void setType(int type) 321 { 322 int oldType=getType(); 323 super.setType(type); 324 // 325 // If the AST is uninitialized we do not signal the change. 326 // The token types spec. starts at 1. 327 // 328 if(oldType!=0&&oldType!=type) astFactory_.typeAltered(this); 329 } 330 /*** 331 * Sets the parent AST. 332 * 333 * @param parent the parent AST 334 */ 335 public void setParentAst(AST parent) 336 { 337 _parent=parent; 338 } 339 /*** 340 * Returns the parent AST. 341 * 342 * @return the parent AST. 343 */ 344 public AST getParentAst() 345 { 346 return _parent; 347 } 348 /*** 349 * As we set the first child we update the parent of the child ast to 350 * this ast. 351 * <p> 352 * We need to update all the siblings of the first child as well. 353 * </p> 354 * 355 * @param child 356 */ 357 public void setFirstChild(AST child) 358 { 359 // 360 // TODO: Rewrite the AST_List so that we do not need to check if the parents are same. 361 // 362 if(child!=null&&((BaseAST)child).getParentAst()!=null&& 363 ((BaseAST)child).getParentAst()!=this) { 364 throw new IllegalArgumentException("Cannot add a child that has a parent reference other than this one."); 365 } 366 setFirstChildForced(child); 367 } 368 /*** 369 * As we set the first child we update the parent of the child ast to 370 * this ast. 371 * <p> 372 * We need to update all the siblings of the first child as well. 373 * </p> 374 * 375 * <p> 376 * This method does not check that the new child has a parent 377 * specified. 378 * </p> 379 * 380 * @param child 381 */ 382 public void setFirstChildForced(AST child) 383 { 384 //System.out.println(">setFirstChildForced"); 385 // 386 // none of the current childs reference this parent 387 // anymore 388 // 389 updateParentOfChilds(null); 390 super.setFirstChild(child); 391 // 392 // update parents of all the new childs 393 // 394 updateParentOfChilds(this); 395 //System.out.println("<setFirstChildForced"); 396 } 397 /*** 398 * Helper method that updates the parent of all the children to the 399 * supplied parent. 400 * <p> 401 * This method is invoked from the setFirstChild method to update the 402 * parent references of all the children 403 * </p> 404 * 405 * @param parent 406 */ 407 private void updateParentOfChilds(AST parent) 408 { 409 BaseAST node=(BaseAST)getFirstChild(); 410 while(node!=null&&node.getParentAst()!=parent){ 411 node.setParentAst(parent); 412 node=(BaseAST)node.getNextSibling(); 413 } 414 } 415 /*** 416 * As we set the next sibling we update the parent ast to the same ast 417 * as this node. 418 * 419 * @param sib 420 */ 421 public void setNextSibling(AST sib) 422 { 423 // 424 // TODO: Rewrite the AST_List so that we do not need to check if the parents are same. 425 // 426 if(sib!=null&&((BaseAST)sib).getParentAst()!=null&& 427 ((BaseAST)sib).getParentAst()!=getParentAst()) { 428 throw new IllegalArgumentException("Cannot add a child that has a parent reference other than the parent of this AST."); 429 } 430 setNextSiblingForced(sib); 431 } 432 /*** 433 * As we set the next sibling we update the parent ast to the same ast 434 * as this node. 435 * <p> 436 * This method does not check that the supplied sibling has a parent 437 * AST specified. 438 * </p> 439 * 440 * @param sib 441 */ 442 public void setNextSiblingForced(AST sib) 443 { 444 //System.out.println(">setNextSiblingForced"); 445 // 446 // if this ast already have a sibling - remove it and all of its successors 447 // 448 BaseAST previousSib=(BaseAST)getNextSibling(); 449 while(previousSib!=null&&previousSib.getParentAst()!=null){ 450 previousSib.setParentAst(null); 451 previousSib=(BaseAST)previousSib.getNextSibling(); 452 } 453 super.setNextSibling(sib); 454 // 455 // set the parent of the added sibling 456 // 457 while(sib!=null&&((BaseAST)sib).getParentAst()!=getParentAst()){ 458 ((BaseAST)sib).setParentAst(getParentAst()); 459 sib=sib.getNextSibling(); 460 } 461 } 462 }

This page was automatically generated by Maven