1 /* 2 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package com.sun.tools.javac.tree; 27 28 import com.sun.tools.javac.util.*; 29 import com.sun.tools.javac.tree.JCTree.*; 30 31 /** A subclass of Tree.Visitor, this class defines 32 * a general tree translator pattern. Translation proceeds recursively in 33 * left-to-right order down a tree, constructing translated nodes by 34 * overwriting existing ones. There is one visitor method in this class 35 * for every possible kind of tree node. To obtain a specific 36 * translator, it suffices to override those visitor methods which 37 * do some interesting work. The translator class itself takes care of all 38 * navigational aspects. 39 * 40 * <p><b>This is NOT part of any API supported by Sun Microsystems. If 41 * you write code that depends on this, you do so at your own risk. 42 * This code and its internal interfaces are subject to change or 43 * deletion without notice.</b> 44 */ 45 public class TreeTranslator extends JCTree.Visitor { 46 47 /** Visitor result field: a tree 48 */ 49 protected JCTree result; 50 51 /** Visitor method: Translate a single node. 52 */ 53 @SuppressWarnings("unchecked") 54 public <T extends JCTree> T translate(T tree) { 55 if (tree == null) { 56 return null; 57 } else { 58 tree.accept(this); 59 JCTree result = this.result; 60 this.result = null; 61 return (T)result; // XXX cast 62 } 63 } 64 65 /** Visitor method: translate a list of nodes. 66 */ 67 public <T extends JCTree> List<T> translate(List<T> trees) { 68 if (trees == null) return null; 69 for (List<T> l = trees; l.nonEmpty(); l = l.tail) 70 l.head = translate(l.head); 71 return trees; 72 } 73 74 /** Visitor method: translate a list of variable definitions. 75 */ 76 public List<JCVariableDecl> translateVarDefs(List<JCVariableDecl> trees) { 77 for (List<JCVariableDecl> l = trees; l.nonEmpty(); l = l.tail) 78 l.head = translate(l.head); 79 return trees; 80 } 81 82 /** Visitor method: translate a list of type parameters. 83 */ 84 public List<JCTypeParameter> translateTypeParams(List<JCTypeParameter> trees) { 85 for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail) 86 l.head = translate(l.head); 87 return trees; 88 } 89 90 /** Visitor method: translate a list of case parts of switch statements. 91 */ 92 public List<JCCase> translateCases(List<JCCase> trees) { 93 for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail) 94 l.head = translate(l.head); 95 return trees; 96 } 97 98 /** Visitor method: translate a list of catch clauses in try statements. 99 */ 100 public List<JCCatch> translateCatchers(List<JCCatch> trees) { 101 for (List<JCCatch> l = trees; l.nonEmpty(); l = l.tail) 102 l.head = translate(l.head); 103 return trees; 104 } 105 106 /** Visitor method: translate a list of catch clauses in try statements. 107 */ 108 public List<JCAnnotation> translateAnnotations(List<JCAnnotation> trees) { 109 for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) 110 l.head = translate(l.head); 111 return trees; 112 } 113 114 /* *************************************************************************** 115 * Visitor methods 116 ****************************************************************************/ 117 118 public void visitTopLevel(JCCompilationUnit tree) { 119 tree.pid = translate(tree.pid); 120 tree.defs = translate(tree.defs); 121 result = tree; 122 } 123 124 public void visitImport(JCImport tree) { 125 tree.qualid = translate(tree.qualid); 126 result = tree; 127 } 128 129 public void visitClassDef(JCClassDecl tree) { 130 tree.mods = translate(tree.mods); 131 tree.typarams = translateTypeParams(tree.typarams); 132 tree.extending = translate(tree.extending); 133 tree.implementing = translate(tree.implementing); 134 tree.defs = translate(tree.defs); 135 result = tree; 136 } 137 138 public void visitMethodDef(JCMethodDecl tree) { 139 tree.mods = translate(tree.mods); 140 tree.restype = translate(tree.restype); 141 tree.typarams = translateTypeParams(tree.typarams); 142 tree.params = translateVarDefs(tree.params); 143 tree.thrown = translate(tree.thrown); 144 tree.body = translate(tree.body); 145 result = tree; 146 } 147 148 public void visitVarDef(JCVariableDecl tree) { 149 tree.mods = translate(tree.mods); 150 tree.vartype = translate(tree.vartype); 151 tree.init = translate(tree.init); 152 result = tree; 153 } 154 155 public void visitSkip(JCSkip tree) { 156 result = tree; 157 } 158 159 public void visitBlock(JCBlock tree) { 160 tree.stats = translate(tree.stats); 161 result = tree; 162 } 163 164 public void visitDoLoop(JCDoWhileLoop tree) { 165 tree.body = translate(tree.body); 166 tree.cond = translate(tree.cond); 167 result = tree; 168 } 169 170 public void visitWhileLoop(JCWhileLoop tree) { 171 tree.cond = translate(tree.cond); 172 tree.body = translate(tree.body); 173 result = tree; 174 } 175 176 public void visitForLoop(JCForLoop tree) { 177 tree.init = translate(tree.init); 178 tree.cond = translate(tree.cond); 179 tree.step = translate(tree.step); 180 tree.body = translate(tree.body); 181 result = tree; 182 } 183 184 public void visitForeachLoop(JCEnhancedForLoop tree) { 185 tree.var = translate(tree.var); 186 tree.expr = translate(tree.expr); 187 tree.body = translate(tree.body); 188 result = tree; 189 } 190 191 public void visitLabelled(JCLabeledStatement tree) { 192 tree.body = translate(tree.body); 193 result = tree; 194 } 195 196 public void visitSwitch(JCSwitch tree) { 197 tree.selector = translate(tree.selector); 198 tree.cases = translateCases(tree.cases); 199 result = tree; 200 } 201 202 public void visitCase(JCCase tree) { 203 tree.pat = translate(tree.pat); 204 tree.stats = translate(tree.stats); 205 result = tree; 206 } 207 208 public void visitSynchronized(JCSynchronized tree) { 209 tree.lock = translate(tree.lock); 210 tree.body = translate(tree.body); 211 result = tree; 212 } 213 214 public void visitTry(JCTry tree) { 215 tree.body = translate(tree.body); 216 tree.catchers = translateCatchers(tree.catchers); 217 tree.finalizer = translate(tree.finalizer); 218 result = tree; 219 } 220 221 public void visitCatch(JCCatch tree) { 222 tree.param = translate(tree.param); 223 tree.body = translate(tree.body); 224 result = tree; 225 } 226 227 public void visitConditional(JCConditional tree) { 228 tree.cond = translate(tree.cond); 229 tree.truepart = translate(tree.truepart); 230 tree.falsepart = translate(tree.falsepart); 231 result = tree; 232 } 233 234 public void visitIf(JCIf tree) { 235 tree.cond = translate(tree.cond); 236 tree.thenpart = translate(tree.thenpart); 237 tree.elsepart = translate(tree.elsepart); 238 result = tree; 239 } 240 241 public void visitExec(JCExpressionStatement tree) { 242 tree.expr = translate(tree.expr); 243 result = tree; 244 } 245 246 public void visitBreak(JCBreak tree) { 247 result = tree; 248 } 249 250 public void visitContinue(JCContinue tree) { 251 result = tree; 252 } 253 254 public void visitReturn(JCReturn tree) { 255 tree.expr = translate(tree.expr); 256 result = tree; 257 } 258 259 public void visitThrow(JCThrow tree) { 260 tree.expr = translate(tree.expr); 261 result = tree; 262 } 263 264 public void visitAssert(JCAssert tree) { 265 tree.cond = translate(tree.cond); 266 tree.detail = translate(tree.detail); 267 result = tree; 268 } 269 270 public void visitApply(JCMethodInvocation tree) { 271 tree.meth = translate(tree.meth); 272 tree.args = translate(tree.args); 273 result = tree; 274 } 275 276 public void visitNewClass(JCNewClass tree) { 277 tree.encl = translate(tree.encl); 278 tree.clazz = translate(tree.clazz); 279 tree.args = translate(tree.args); 280 tree.def = translate(tree.def); 281 result = tree; 282 } 283 284 public void visitNewArray(JCNewArray tree) { 285 tree.annotations = translate(tree.annotations); 286 List<List<JCTypeAnnotation>> dimAnnos = List.nil(); 287 for (List<JCTypeAnnotation> origDimAnnos : tree.dimAnnotations) 288 dimAnnos = dimAnnos.append(translate(origDimAnnos)); 289 tree.dimAnnotations = dimAnnos; 290 tree.elemtype = translate(tree.elemtype); 291 tree.dims = translate(tree.dims); 292 tree.elems = translate(tree.elems); 293 result = tree; 294 } 295 296 public void visitParens(JCParens tree) { 297 tree.expr = translate(tree.expr); 298 result = tree; 299 } 300 301 public void visitAssign(JCAssign tree) { 302 tree.lhs = translate(tree.lhs); 303 tree.rhs = translate(tree.rhs); 304 result = tree; 305 } 306 307 public void visitAssignop(JCAssignOp tree) { 308 tree.lhs = translate(tree.lhs); 309 tree.rhs = translate(tree.rhs); 310 result = tree; 311 } 312 313 public void visitUnary(JCUnary tree) { 314 tree.arg = translate(tree.arg); 315 result = tree; 316 } 317 318 public void visitBinary(JCBinary tree) { 319 tree.lhs = translate(tree.lhs); 320 tree.rhs = translate(tree.rhs); 321 result = tree; 322 } 323 324 public void visitTypeCast(JCTypeCast tree) { 325 tree.clazz = translate(tree.clazz); 326 tree.expr = translate(tree.expr); 327 result = tree; 328 } 329 330 public void visitTypeTest(JCInstanceOf tree) { 331 tree.expr = translate(tree.expr); 332 tree.clazz = translate(tree.clazz); 333 result = tree; 334 } 335 336 public void visitIndexed(JCArrayAccess tree) { 337 tree.indexed = translate(tree.indexed); 338 tree.index = translate(tree.index); 339 result = tree; 340 } 341 342 public void visitSelect(JCFieldAccess tree) { 343 tree.selected = translate(tree.selected); 344 result = tree; 345 } 346 347 public void visitIdent(JCIdent tree) { 348 result = tree; 349 } 350 351 public void visitLiteral(JCLiteral tree) { 352 result = tree; 353 } 354 355 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 356 result = tree; 357 } 358 359 public void visitTypeArray(JCArrayTypeTree tree) { 360 tree.elemtype = translate(tree.elemtype); 361 result = tree; 362 } 363 364 public void visitTypeApply(JCTypeApply tree) { 365 tree.clazz = translate(tree.clazz); 366 tree.arguments = translate(tree.arguments); 367 result = tree; 368 } 369 370 public void visitTypeParameter(JCTypeParameter tree) { 371 tree.annotations = translate(tree.annotations); 372 tree.bounds = translate(tree.bounds); 373 result = tree; 374 } 375 376 @Override 377 public void visitWildcard(JCWildcard tree) { 378 tree.kind = translate(tree.kind); 379 tree.inner = translate(tree.inner); 380 result = tree; 381 } 382 383 @Override 384 public void visitTypeBoundKind(TypeBoundKind tree) { 385 result = tree; 386 } 387 388 public void visitFunctionType(JCFunctionType tree) { 389 tree.returnType = translate(tree.returnType); 390 tree.parameterTypes = translate(tree.parameterTypes); 391 result = tree; 392 } 393 394 public void visitLambda(JCLambda tree) { 395 tree.parameters = translate(tree.parameters); 396 tree.bodyOrExpr = translate(tree.bodyOrExpr); 397 result = tree; 398 } 399 400 public void visitErroneous(JCErroneous tree) { 401 result = tree; 402 } 403 404 public void visitLetExpr(LetExpr tree) { 405 tree.defs = translateVarDefs(tree.defs); 406 tree.expr = translate(tree.expr); 407 result = tree; 408 } 409 410 public void visitModifiers(JCModifiers tree) { 411 tree.annotations = translateAnnotations(tree.annotations); 412 result = tree; 413 } 414 415 public void visitAnnotation(JCAnnotation tree) { 416 tree.annotationType = translate(tree.annotationType); 417 tree.args = translate(tree.args); 418 result = tree; 419 } 420 421 public void visitAnnotatedType(JCAnnotatedType tree) { 422 tree.annotations = translate(tree.annotations); 423 tree.underlyingType = translate(tree.underlyingType); 424 result = tree; 425 } 426 427 public void visitTree(JCTree tree) { 428 throw new AssertionError(tree); 429 } 430 }