1 /* 2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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 supported API. 41 * If 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") translate(T tree)54 public <T extends JCTree> T translate(T tree) { 55 if (tree == null) { 56 return null; 57 } else { 58 tree.accept(this); 59 JCTree tmpResult = this.result; 60 this.result = null; 61 return (T)tmpResult; // XXX cast 62 } 63 } 64 65 /** Visitor method: translate a list of nodes. 66 */ translate(List<T> trees)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 */ translateVarDefs(List<JCVariableDecl> trees)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 */ translateTypeParams(List<JCTypeParameter> trees)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 */ translateCases(List<JCCase> trees)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 */ translateCatchers(List<JCCatch> trees)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 */ translateAnnotations(List<JCAnnotation> trees)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 visitTopLevel(JCCompilationUnit tree)118 public void visitTopLevel(JCCompilationUnit tree) { 119 tree.defs = translate(tree.defs); 120 result = tree; 121 } 122 visitPackageDef(JCPackageDecl tree)123 public void visitPackageDef(JCPackageDecl tree) { 124 tree.annotations = translate(tree.annotations); 125 tree.pid = translate(tree.pid); 126 result = tree; 127 } 128 visitImport(JCImport tree)129 public void visitImport(JCImport tree) { 130 tree.qualid = translate(tree.qualid); 131 result = tree; 132 } 133 visitClassDef(JCClassDecl tree)134 public void visitClassDef(JCClassDecl tree) { 135 tree.mods = translate(tree.mods); 136 tree.typarams = translateTypeParams(tree.typarams); 137 tree.extending = translate(tree.extending); 138 tree.implementing = translate(tree.implementing); 139 tree.defs = translate(tree.defs); 140 result = tree; 141 } 142 visitMethodDef(JCMethodDecl tree)143 public void visitMethodDef(JCMethodDecl tree) { 144 tree.mods = translate(tree.mods); 145 tree.restype = translate(tree.restype); 146 tree.typarams = translateTypeParams(tree.typarams); 147 tree.recvparam = translate(tree.recvparam); 148 tree.params = translateVarDefs(tree.params); 149 tree.thrown = translate(tree.thrown); 150 tree.body = translate(tree.body); 151 result = tree; 152 } 153 visitVarDef(JCVariableDecl tree)154 public void visitVarDef(JCVariableDecl tree) { 155 tree.mods = translate(tree.mods); 156 tree.nameexpr = translate(tree.nameexpr); 157 tree.vartype = translate(tree.vartype); 158 tree.init = translate(tree.init); 159 result = tree; 160 } 161 visitSkip(JCSkip tree)162 public void visitSkip(JCSkip tree) { 163 result = tree; 164 } 165 visitBlock(JCBlock tree)166 public void visitBlock(JCBlock tree) { 167 tree.stats = translate(tree.stats); 168 result = tree; 169 } 170 visitDoLoop(JCDoWhileLoop tree)171 public void visitDoLoop(JCDoWhileLoop tree) { 172 tree.body = translate(tree.body); 173 tree.cond = translate(tree.cond); 174 result = tree; 175 } 176 visitWhileLoop(JCWhileLoop tree)177 public void visitWhileLoop(JCWhileLoop tree) { 178 tree.cond = translate(tree.cond); 179 tree.body = translate(tree.body); 180 result = tree; 181 } 182 visitForLoop(JCForLoop tree)183 public void visitForLoop(JCForLoop tree) { 184 tree.init = translate(tree.init); 185 tree.cond = translate(tree.cond); 186 tree.step = translate(tree.step); 187 tree.body = translate(tree.body); 188 result = tree; 189 } 190 visitForeachLoop(JCEnhancedForLoop tree)191 public void visitForeachLoop(JCEnhancedForLoop tree) { 192 tree.var = translate(tree.var); 193 tree.expr = translate(tree.expr); 194 tree.body = translate(tree.body); 195 result = tree; 196 } 197 visitLabelled(JCLabeledStatement tree)198 public void visitLabelled(JCLabeledStatement tree) { 199 tree.body = translate(tree.body); 200 result = tree; 201 } 202 visitSwitch(JCSwitch tree)203 public void visitSwitch(JCSwitch tree) { 204 tree.selector = translate(tree.selector); 205 tree.cases = translateCases(tree.cases); 206 result = tree; 207 } 208 visitCase(JCCase tree)209 public void visitCase(JCCase tree) { 210 tree.labels = translate(tree.labels); 211 tree.stats = translate(tree.stats); 212 result = tree; 213 } 214 visitSwitchExpression(JCSwitchExpression tree)215 public void visitSwitchExpression(JCSwitchExpression tree) { 216 tree.selector = translate(tree.selector); 217 tree.cases = translateCases(tree.cases); 218 result = tree; 219 } 220 visitSynchronized(JCSynchronized tree)221 public void visitSynchronized(JCSynchronized tree) { 222 tree.lock = translate(tree.lock); 223 tree.body = translate(tree.body); 224 result = tree; 225 } 226 visitTry(JCTry tree)227 public void visitTry(JCTry tree) { 228 tree.resources = translate(tree.resources); 229 tree.body = translate(tree.body); 230 tree.catchers = translateCatchers(tree.catchers); 231 tree.finalizer = translate(tree.finalizer); 232 result = tree; 233 } 234 visitCatch(JCCatch tree)235 public void visitCatch(JCCatch tree) { 236 tree.param = translate(tree.param); 237 tree.body = translate(tree.body); 238 result = tree; 239 } 240 visitConditional(JCConditional tree)241 public void visitConditional(JCConditional tree) { 242 tree.cond = translate(tree.cond); 243 tree.truepart = translate(tree.truepart); 244 tree.falsepart = translate(tree.falsepart); 245 result = tree; 246 } 247 visitIf(JCIf tree)248 public void visitIf(JCIf tree) { 249 tree.cond = translate(tree.cond); 250 tree.thenpart = translate(tree.thenpart); 251 tree.elsepart = translate(tree.elsepart); 252 result = tree; 253 } 254 visitExec(JCExpressionStatement tree)255 public void visitExec(JCExpressionStatement tree) { 256 tree.expr = translate(tree.expr); 257 result = tree; 258 } 259 visitBreak(JCBreak tree)260 public void visitBreak(JCBreak tree) { 261 result = tree; 262 } 263 visitYield(JCYield tree)264 public void visitYield(JCYield tree) { 265 tree.value = translate(tree.value); 266 result = tree; 267 } 268 visitContinue(JCContinue tree)269 public void visitContinue(JCContinue tree) { 270 result = tree; 271 } 272 visitReturn(JCReturn tree)273 public void visitReturn(JCReturn tree) { 274 tree.expr = translate(tree.expr); 275 result = tree; 276 } 277 visitThrow(JCThrow tree)278 public void visitThrow(JCThrow tree) { 279 tree.expr = translate(tree.expr); 280 result = tree; 281 } 282 visitAssert(JCAssert tree)283 public void visitAssert(JCAssert tree) { 284 tree.cond = translate(tree.cond); 285 tree.detail = translate(tree.detail); 286 result = tree; 287 } 288 visitApply(JCMethodInvocation tree)289 public void visitApply(JCMethodInvocation tree) { 290 tree.meth = translate(tree.meth); 291 tree.args = translate(tree.args); 292 result = tree; 293 } 294 visitNewClass(JCNewClass tree)295 public void visitNewClass(JCNewClass tree) { 296 tree.encl = translate(tree.encl); 297 tree.clazz = translate(tree.clazz); 298 tree.args = translate(tree.args); 299 tree.def = translate(tree.def); 300 result = tree; 301 } 302 visitLambda(JCLambda tree)303 public void visitLambda(JCLambda tree) { 304 tree.params = translate(tree.params); 305 tree.body = translate(tree.body); 306 result = tree; 307 } 308 visitNewArray(JCNewArray tree)309 public void visitNewArray(JCNewArray tree) { 310 tree.annotations = translate(tree.annotations); 311 List<List<JCAnnotation>> dimAnnos = List.nil(); 312 for (List<JCAnnotation> origDimAnnos : tree.dimAnnotations) 313 dimAnnos = dimAnnos.append(translate(origDimAnnos)); 314 tree.dimAnnotations = dimAnnos; 315 tree.elemtype = translate(tree.elemtype); 316 tree.dims = translate(tree.dims); 317 tree.elems = translate(tree.elems); 318 result = tree; 319 } 320 visitParens(JCParens tree)321 public void visitParens(JCParens tree) { 322 tree.expr = translate(tree.expr); 323 result = tree; 324 } 325 visitAssign(JCAssign tree)326 public void visitAssign(JCAssign tree) { 327 tree.lhs = translate(tree.lhs); 328 tree.rhs = translate(tree.rhs); 329 result = tree; 330 } 331 visitAssignop(JCAssignOp tree)332 public void visitAssignop(JCAssignOp tree) { 333 tree.lhs = translate(tree.lhs); 334 tree.rhs = translate(tree.rhs); 335 result = tree; 336 } 337 visitUnary(JCUnary tree)338 public void visitUnary(JCUnary tree) { 339 tree.arg = translate(tree.arg); 340 result = tree; 341 } 342 visitBinary(JCBinary tree)343 public void visitBinary(JCBinary tree) { 344 tree.lhs = translate(tree.lhs); 345 tree.rhs = translate(tree.rhs); 346 result = tree; 347 } 348 visitTypeCast(JCTypeCast tree)349 public void visitTypeCast(JCTypeCast tree) { 350 tree.clazz = translate(tree.clazz); 351 tree.expr = translate(tree.expr); 352 result = tree; 353 } 354 visitTypeTest(JCInstanceOf tree)355 public void visitTypeTest(JCInstanceOf tree) { 356 tree.expr = translate(tree.expr); 357 tree.pattern = translate(tree.pattern); 358 result = tree; 359 } 360 visitBindingPattern(JCBindingPattern tree)361 public void visitBindingPattern(JCBindingPattern tree) { 362 tree.var = translate(tree.var); 363 result = tree; 364 } 365 366 @Override visitDefaultCaseLabel(JCDefaultCaseLabel tree)367 public void visitDefaultCaseLabel(JCDefaultCaseLabel tree) { 368 result = tree; 369 } 370 371 @Override visitParenthesizedPattern(JCParenthesizedPattern tree)372 public void visitParenthesizedPattern(JCParenthesizedPattern tree) { 373 tree.pattern = translate(tree.pattern); 374 result = tree; 375 } 376 377 @Override visitGuardPattern(JCGuardPattern tree)378 public void visitGuardPattern(JCGuardPattern tree) { 379 tree.patt = translate(tree.patt); 380 tree.expr = translate(tree.expr); 381 result = tree; 382 } 383 visitIndexed(JCArrayAccess tree)384 public void visitIndexed(JCArrayAccess tree) { 385 tree.indexed = translate(tree.indexed); 386 tree.index = translate(tree.index); 387 result = tree; 388 } 389 visitSelect(JCFieldAccess tree)390 public void visitSelect(JCFieldAccess tree) { 391 tree.selected = translate(tree.selected); 392 result = tree; 393 } 394 visitReference(JCMemberReference tree)395 public void visitReference(JCMemberReference tree) { 396 tree.expr = translate(tree.expr); 397 result = tree; 398 } 399 visitIdent(JCIdent tree)400 public void visitIdent(JCIdent tree) { 401 result = tree; 402 } 403 visitLiteral(JCLiteral tree)404 public void visitLiteral(JCLiteral tree) { 405 result = tree; 406 } 407 visitTypeIdent(JCPrimitiveTypeTree tree)408 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 409 result = tree; 410 } 411 visitTypeArray(JCArrayTypeTree tree)412 public void visitTypeArray(JCArrayTypeTree tree) { 413 tree.elemtype = translate(tree.elemtype); 414 result = tree; 415 } 416 visitTypeApply(JCTypeApply tree)417 public void visitTypeApply(JCTypeApply tree) { 418 tree.clazz = translate(tree.clazz); 419 tree.arguments = translate(tree.arguments); 420 result = tree; 421 } 422 visitTypeUnion(JCTypeUnion tree)423 public void visitTypeUnion(JCTypeUnion tree) { 424 tree.alternatives = translate(tree.alternatives); 425 result = tree; 426 } 427 visitTypeIntersection(JCTypeIntersection tree)428 public void visitTypeIntersection(JCTypeIntersection tree) { 429 tree.bounds = translate(tree.bounds); 430 result = tree; 431 } 432 visitTypeParameter(JCTypeParameter tree)433 public void visitTypeParameter(JCTypeParameter tree) { 434 tree.annotations = translate(tree.annotations); 435 tree.bounds = translate(tree.bounds); 436 result = tree; 437 } 438 439 @Override visitWildcard(JCWildcard tree)440 public void visitWildcard(JCWildcard tree) { 441 tree.kind = translate(tree.kind); 442 tree.inner = translate(tree.inner); 443 result = tree; 444 } 445 446 @Override visitTypeBoundKind(TypeBoundKind tree)447 public void visitTypeBoundKind(TypeBoundKind tree) { 448 result = tree; 449 } 450 visitErroneous(JCErroneous tree)451 public void visitErroneous(JCErroneous tree) { 452 result = tree; 453 } 454 visitLetExpr(LetExpr tree)455 public void visitLetExpr(LetExpr tree) { 456 tree.defs = translate(tree.defs); 457 tree.expr = translate(tree.expr); 458 result = tree; 459 } 460 visitModifiers(JCModifiers tree)461 public void visitModifiers(JCModifiers tree) { 462 tree.annotations = translateAnnotations(tree.annotations); 463 result = tree; 464 } 465 visitAnnotation(JCAnnotation tree)466 public void visitAnnotation(JCAnnotation tree) { 467 tree.annotationType = translate(tree.annotationType); 468 tree.args = translate(tree.args); 469 result = tree; 470 } 471 visitAnnotatedType(JCAnnotatedType tree)472 public void visitAnnotatedType(JCAnnotatedType tree) { 473 tree.annotations = translate(tree.annotations); 474 tree.underlyingType = translate(tree.underlyingType); 475 result = tree; 476 } 477 visitTree(JCTree tree)478 public void visitTree(JCTree tree) { 479 throw new AssertionError(tree); 480 } 481 } 482