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.ASTFactory; 21 import antlr.ASTPair; 22 import antlr.Token; 23 import antlr.collections.AST; 24 import antlr.collections.impl.ASTArray; 25 /*** 26 */ 27 public abstract class DynASTFactory extends ASTFactory 28 { 29 protected DynTypeFactory typeFactory_=null; 30 protected ASTPair lastASTPair_=null; 31 /*** 32 * Constructor creates a new DynASTFactory object. 33 */ 34 protectedDynASTFactory(Class types,String[] packages)/package-summary.html"> DynASTFactory(Class types,String[] packages) 35 { 36 typeFactory_=new DynTypeFactory("AST_", types, packages, 37 getDefaultASTType()); 38 } 39 /*** 40 * Constructor creates a new DynASTFactory object. 41 * <p> 42 * This method uses the type factory from the template to speed up 43 * construction. 44 * </p> 45 */ 46 protected DynASTFactory(DynASTFactory template) 47 { 48 typeFactory_=template.typeFactory_; 49 } 50 /*** 51 * DOCUMENT ME! 52 * 53 * @param type DOCUMENT ME! 54 * @return DOCUMENT ME! 55 * @throws RuntimeException DOCUMENT ME! 56 */ 57 public Class getASTNodeType(int type) 58 { 59 Class astClass=typeFactory_.getClass4Type(type); 60 return astClass; 61 } 62 /*** 63 * DOCUMENT ME! 64 * 65 * @param currentAST DOCUMENT ME! 66 * @param child DOCUMENT ME! 67 */ 68 public void addASTChild(ASTPair currentAST,AST child) 69 { 70 // 71 // make sure that the instances are of correct type 72 // 73 lastASTPair_=currentAST; 74 super.addASTChild(currentAST, child); 75 } 76 /*** 77 * DOCUMENT ME! 78 * 79 * @param currentAST DOCUMENT ME! 80 * @param root DOCUMENT ME! 81 */ 82 public void makeASTRoot(ASTPair currentAST,AST root) 83 { 84 // 85 // make sure that the child instances are of correct type 86 // 87 lastASTPair_=currentAST; 88 super.makeASTRoot(currentAST, root); 89 } 90 /*** 91 * Must override this method to make user that all the asts in an 92 * array are of the correct type. 93 * 94 * @param arr the array to check 95 * @return The new root 96 */ 97 public AST make(ASTArray arr) 98 { 99 for(int i=arr.size-1; i>=0; i--){ 100 arr.array[i]=checkAST(arr.array[i]); 101 } 102 return super.make(arr); 103 } 104 /*** 105 * DOCUMENT ME! 106 * 107 * @param ast DOCUMENT ME! 108 * @return DOCUMENT ME! 109 * @throws RuntimeException DOCUMENT ME! 110 */ 111 private AST checkAST(AST ast) 112 { 113 if(ast==null) { 114 return null; 115 } 116 try{ 117 Class factoryClass=getASTNodeType(ast.getType()); 118 Class childClass=ast.getClass(); 119 if(factoryClass!=childClass) { 120 AST newAST=(AST)factoryClass.newInstance(); 121 newAST.initialize(ast); 122 AST firstChild=ast.getFirstChild(); 123 AST nextSibling=ast.getNextSibling(); 124 ast.setFirstChild(null); 125 ast.setNextSibling(null); 126 newAST.setFirstChild(firstChild); 127 newAST.setNextSibling(nextSibling); 128 // make it official 129 ast=newAST; 130 } 131 return ast; 132 }catch (InstantiationException e) { 133 e.printStackTrace(); 134 throw new RuntimeException("Failed to instantiate AST node:InstantiationException:"+e.getMessage()); 135 }catch (IllegalAccessException e) { 136 throw new RuntimeException("Failed to instantiate AST node:IllegalAccessException:"+e.getMessage()); 137 } 138 } 139 /*** 140 * As ASTs are created from tokens we need to signal that an ast 141 * actually has been created for that token. 142 * 143 * @param token 144 * @return 145 */ 146 public AST create(Token token) 147 { 148 BaseAST ast=(BaseAST)super.create(token); 149 ast.setASTFactory(this); 150 ((BaseToken)token).setCreatedAst(ast); 151 return ast; 152 } 153 /*** 154 * @return 155 */ 156 protected abstract Class getDefaultASTType(); 157 158 /*** 159 * Signals that an AST has altered its type. 160 * <p> 161 * This metod is invoked from the <code>BaseAST</code> 162 * </p> 163 * 164 * @param oldAST the altered ast. 165 */ 166 public void typeAltered(BaseAST oldAST) 167 { 168 // the last ast pair should contain the altered ast! 169 // 170 // check root! 171 // 172 if(lastASTPair_.root==oldAST) { 173 lastASTPair_.root=checkAST(lastASTPair_.root); 174 return; 175 } 176 // 177 // check first child 178 // 179 if(lastASTPair_.root.getFirstChild()==oldAST) { 180 lastASTPair_.root.setFirstChild(checkAST(lastASTPair_.root.getFirstChild())); 181 return; 182 } 183 // 184 // check all the siblings 185 // 186 AST node=lastASTPair_.root.getFirstChild(); 187 while(node.getNextSibling()!=null){ 188 if(node.getNextSibling()==oldAST) { 189 node.setNextSibling(checkAST(node.getNextSibling())); 190 return; 191 } 192 node=node.getNextSibling(); 193 } 194 throw new IllegalStateException("Failed to update altered ast"); 195 } 196 }

This page was automatically generated by Maven