TreeCopier.java revision 3088:424fba7cabb0
1/* 2 * Copyright (c) 2006, 2013, 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 26package com.sun.tools.javac.tree; 27 28import com.sun.source.tree.*; 29import com.sun.tools.javac.tree.JCTree.*; 30import com.sun.tools.javac.util.DefinedBy; 31import com.sun.tools.javac.util.DefinedBy.Api; 32import com.sun.tools.javac.util.List; 33import com.sun.tools.javac.util.ListBuffer; 34 35/** 36 * Creates a copy of a tree, using a given TreeMaker. 37 * Names, literal values, etc are shared with the original. 38 * 39 * <p><b>This is NOT part of any supported API. 40 * If you write code that depends on this, you do so at your own risk. 41 * This code and its internal interfaces are subject to change or 42 * deletion without notice.</b> 43 */ 44public class TreeCopier<P> implements TreeVisitor<JCTree,P> { 45 private TreeMaker M; 46 47 /** Creates a new instance of TreeCopier */ 48 public TreeCopier(TreeMaker M) { 49 this.M = M; 50 } 51 52 public <T extends JCTree> T copy(T tree) { 53 return copy(tree, null); 54 } 55 56 @SuppressWarnings("unchecked") 57 public <T extends JCTree> T copy(T tree, P p) { 58 if (tree == null) 59 return null; 60 return (T) (tree.accept(this, p)); 61 } 62 63 public <T extends JCTree> List<T> copy(List<T> trees) { 64 return copy(trees, null); 65 } 66 67 public <T extends JCTree> List<T> copy(List<T> trees, P p) { 68 if (trees == null) 69 return null; 70 ListBuffer<T> lb = new ListBuffer<>(); 71 for (T tree: trees) 72 lb.append(copy(tree, p)); 73 return lb.toList(); 74 } 75 76 @DefinedBy(Api.COMPILER_TREE) 77 public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) { 78 JCAnnotatedType t = (JCAnnotatedType) node; 79 List<JCAnnotation> annotations = copy(t.annotations, p); 80 JCExpression underlyingType = copy(t.underlyingType, p); 81 return M.at(t.pos).AnnotatedType(annotations, underlyingType); 82 } 83 84 @DefinedBy(Api.COMPILER_TREE) 85 public JCTree visitAnnotation(AnnotationTree node, P p) { 86 JCAnnotation t = (JCAnnotation) node; 87 JCTree annotationType = copy(t.annotationType, p); 88 List<JCExpression> args = copy(t.args, p); 89 if (t.getKind() == Tree.Kind.TYPE_ANNOTATION) { 90 JCAnnotation newTA = M.at(t.pos).TypeAnnotation(annotationType, args); 91 newTA.attribute = t.attribute; 92 return newTA; 93 } else { 94 JCAnnotation newT = M.at(t.pos).Annotation(annotationType, args); 95 newT.attribute = t.attribute; 96 return newT; 97 } 98 } 99 100 @DefinedBy(Api.COMPILER_TREE) 101 public JCTree visitAssert(AssertTree node, P p) { 102 JCAssert t = (JCAssert) node; 103 JCExpression cond = copy(t.cond, p); 104 JCExpression detail = copy(t.detail, p); 105 return M.at(t.pos).Assert(cond, detail); 106 } 107 108 @DefinedBy(Api.COMPILER_TREE) 109 public JCTree visitAssignment(AssignmentTree node, P p) { 110 JCAssign t = (JCAssign) node; 111 JCExpression lhs = copy(t.lhs, p); 112 JCExpression rhs = copy(t.rhs, p); 113 return M.at(t.pos).Assign(lhs, rhs); 114 } 115 116 @DefinedBy(Api.COMPILER_TREE) 117 public JCTree visitCompoundAssignment(CompoundAssignmentTree node, P p) { 118 JCAssignOp t = (JCAssignOp) node; 119 JCTree lhs = copy(t.lhs, p); 120 JCTree rhs = copy(t.rhs, p); 121 return M.at(t.pos).Assignop(t.getTag(), lhs, rhs); 122 } 123 124 @DefinedBy(Api.COMPILER_TREE) 125 public JCTree visitBinary(BinaryTree node, P p) { 126 JCBinary t = (JCBinary) node; 127 JCExpression lhs = copy(t.lhs, p); 128 JCExpression rhs = copy(t.rhs, p); 129 return M.at(t.pos).Binary(t.getTag(), lhs, rhs); 130 } 131 132 @DefinedBy(Api.COMPILER_TREE) 133 public JCTree visitBlock(BlockTree node, P p) { 134 JCBlock t = (JCBlock) node; 135 List<JCStatement> stats = copy(t.stats, p); 136 return M.at(t.pos).Block(t.flags, stats); 137 } 138 139 @DefinedBy(Api.COMPILER_TREE) 140 public JCTree visitBreak(BreakTree node, P p) { 141 JCBreak t = (JCBreak) node; 142 return M.at(t.pos).Break(t.label); 143 } 144 145 @DefinedBy(Api.COMPILER_TREE) 146 public JCTree visitCase(CaseTree node, P p) { 147 JCCase t = (JCCase) node; 148 JCExpression pat = copy(t.pat, p); 149 List<JCStatement> stats = copy(t.stats, p); 150 return M.at(t.pos).Case(pat, stats); 151 } 152 153 @DefinedBy(Api.COMPILER_TREE) 154 public JCTree visitCatch(CatchTree node, P p) { 155 JCCatch t = (JCCatch) node; 156 JCVariableDecl param = copy(t.param, p); 157 JCBlock body = copy(t.body, p); 158 return M.at(t.pos).Catch(param, body); 159 } 160 161 @DefinedBy(Api.COMPILER_TREE) 162 public JCTree visitClass(ClassTree node, P p) { 163 JCClassDecl t = (JCClassDecl) node; 164 JCModifiers mods = copy(t.mods, p); 165 List<JCTypeParameter> typarams = copy(t.typarams, p); 166 JCExpression extending = copy(t.extending, p); 167 List<JCExpression> implementing = copy(t.implementing, p); 168 List<JCTree> defs = copy(t.defs, p); 169 return M.at(t.pos).ClassDef(mods, t.name, typarams, extending, implementing, defs); 170 } 171 172 @DefinedBy(Api.COMPILER_TREE) 173 public JCTree visitConditionalExpression(ConditionalExpressionTree node, P p) { 174 JCConditional t = (JCConditional) node; 175 JCExpression cond = copy(t.cond, p); 176 JCExpression truepart = copy(t.truepart, p); 177 JCExpression falsepart = copy(t.falsepart, p); 178 return M.at(t.pos).Conditional(cond, truepart, falsepart); 179 } 180 181 @DefinedBy(Api.COMPILER_TREE) 182 public JCTree visitContinue(ContinueTree node, P p) { 183 JCContinue t = (JCContinue) node; 184 return M.at(t.pos).Continue(t.label); 185 } 186 187 @DefinedBy(Api.COMPILER_TREE) 188 public JCTree visitDoWhileLoop(DoWhileLoopTree node, P p) { 189 JCDoWhileLoop t = (JCDoWhileLoop) node; 190 JCStatement body = copy(t.body, p); 191 JCExpression cond = copy(t.cond, p); 192 return M.at(t.pos).DoLoop(body, cond); 193 } 194 195 @DefinedBy(Api.COMPILER_TREE) 196 public JCTree visitErroneous(ErroneousTree node, P p) { 197 JCErroneous t = (JCErroneous) node; 198 List<? extends JCTree> errs = copy(t.errs, p); 199 return M.at(t.pos).Erroneous(errs); 200 } 201 202 @DefinedBy(Api.COMPILER_TREE) 203 public JCTree visitExpressionStatement(ExpressionStatementTree node, P p) { 204 JCExpressionStatement t = (JCExpressionStatement) node; 205 JCExpression expr = copy(t.expr, p); 206 return M.at(t.pos).Exec(expr); 207 } 208 209 @DefinedBy(Api.COMPILER_TREE) 210 public JCTree visitEnhancedForLoop(EnhancedForLoopTree node, P p) { 211 JCEnhancedForLoop t = (JCEnhancedForLoop) node; 212 JCVariableDecl var = copy(t.var, p); 213 JCExpression expr = copy(t.expr, p); 214 JCStatement body = copy(t.body, p); 215 return M.at(t.pos).ForeachLoop(var, expr, body); 216 } 217 218 @DefinedBy(Api.COMPILER_TREE) 219 public JCTree visitForLoop(ForLoopTree node, P p) { 220 JCForLoop t = (JCForLoop) node; 221 List<JCStatement> init = copy(t.init, p); 222 JCExpression cond = copy(t.cond, p); 223 List<JCExpressionStatement> step = copy(t.step, p); 224 JCStatement body = copy(t.body, p); 225 return M.at(t.pos).ForLoop(init, cond, step, body); 226 } 227 228 @DefinedBy(Api.COMPILER_TREE) 229 public JCTree visitIdentifier(IdentifierTree node, P p) { 230 JCIdent t = (JCIdent) node; 231 return M.at(t.pos).Ident(t.name); 232 } 233 234 @DefinedBy(Api.COMPILER_TREE) 235 public JCTree visitIf(IfTree node, P p) { 236 JCIf t = (JCIf) node; 237 JCExpression cond = copy(t.cond, p); 238 JCStatement thenpart = copy(t.thenpart, p); 239 JCStatement elsepart = copy(t.elsepart, p); 240 return M.at(t.pos).If(cond, thenpart, elsepart); 241 } 242 243 @DefinedBy(Api.COMPILER_TREE) 244 public JCTree visitImport(ImportTree node, P p) { 245 JCImport t = (JCImport) node; 246 JCTree qualid = copy(t.qualid, p); 247 return M.at(t.pos).Import(qualid, t.staticImport); 248 } 249 250 @DefinedBy(Api.COMPILER_TREE) 251 public JCTree visitArrayAccess(ArrayAccessTree node, P p) { 252 JCArrayAccess t = (JCArrayAccess) node; 253 JCExpression indexed = copy(t.indexed, p); 254 JCExpression index = copy(t.index, p); 255 return M.at(t.pos).Indexed(indexed, index); 256 } 257 258 @DefinedBy(Api.COMPILER_TREE) 259 public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { 260 JCLabeledStatement t = (JCLabeledStatement) node; 261 JCStatement body = copy(t.body, p); 262 return M.at(t.pos).Labelled(t.label, body); 263 } 264 265 @DefinedBy(Api.COMPILER_TREE) 266 public JCTree visitLiteral(LiteralTree node, P p) { 267 JCLiteral t = (JCLiteral) node; 268 return M.at(t.pos).Literal(t.typetag, t.value); 269 } 270 271 @DefinedBy(Api.COMPILER_TREE) 272 public JCTree visitMethod(MethodTree node, P p) { 273 JCMethodDecl t = (JCMethodDecl) node; 274 JCModifiers mods = copy(t.mods, p); 275 JCExpression restype = copy(t.restype, p); 276 List<JCTypeParameter> typarams = copy(t.typarams, p); 277 List<JCVariableDecl> params = copy(t.params, p); 278 JCVariableDecl recvparam = copy(t.recvparam, p); 279 List<JCExpression> thrown = copy(t.thrown, p); 280 JCBlock body = copy(t.body, p); 281 JCExpression defaultValue = copy(t.defaultValue, p); 282 return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, recvparam, params, thrown, body, defaultValue); 283 } 284 285 @DefinedBy(Api.COMPILER_TREE) 286 public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { 287 JCMethodInvocation t = (JCMethodInvocation) node; 288 List<JCExpression> typeargs = copy(t.typeargs, p); 289 JCExpression meth = copy(t.meth, p); 290 List<JCExpression> args = copy(t.args, p); 291 return M.at(t.pos).Apply(typeargs, meth, args); 292 } 293 294 @DefinedBy(Api.COMPILER_TREE) 295 public JCTree visitModifiers(ModifiersTree node, P p) { 296 JCModifiers t = (JCModifiers) node; 297 List<JCAnnotation> annotations = copy(t.annotations, p); 298 return M.at(t.pos).Modifiers(t.flags, annotations); 299 } 300 301 @DefinedBy(Api.COMPILER_TREE) 302 public JCTree visitNewArray(NewArrayTree node, P p) { 303 JCNewArray t = (JCNewArray) node; 304 JCExpression elemtype = copy(t.elemtype, p); 305 List<JCExpression> dims = copy(t.dims, p); 306 List<JCExpression> elems = copy(t.elems, p); 307 return M.at(t.pos).NewArray(elemtype, dims, elems); 308 } 309 310 @DefinedBy(Api.COMPILER_TREE) 311 public JCTree visitNewClass(NewClassTree node, P p) { 312 JCNewClass t = (JCNewClass) node; 313 JCExpression encl = copy(t.encl, p); 314 List<JCExpression> typeargs = copy(t.typeargs, p); 315 JCExpression clazz = copy(t.clazz, p); 316 List<JCExpression> args = copy(t.args, p); 317 JCClassDecl def = copy(t.def, p); 318 return M.at(t.pos).NewClass(encl, typeargs, clazz, args, def); 319 } 320 321 @DefinedBy(Api.COMPILER_TREE) 322 public JCTree visitLambdaExpression(LambdaExpressionTree node, P p) { 323 JCLambda t = (JCLambda) node; 324 List<JCVariableDecl> params = copy(t.params, p); 325 JCTree body = copy(t.body, p); 326 return M.at(t.pos).Lambda(params, body); 327 } 328 329 @DefinedBy(Api.COMPILER_TREE) 330 public JCTree visitParenthesized(ParenthesizedTree node, P p) { 331 JCParens t = (JCParens) node; 332 JCExpression expr = copy(t.expr, p); 333 return M.at(t.pos).Parens(expr); 334 } 335 336 @DefinedBy(Api.COMPILER_TREE) 337 public JCTree visitReturn(ReturnTree node, P p) { 338 JCReturn t = (JCReturn) node; 339 JCExpression expr = copy(t.expr, p); 340 return M.at(t.pos).Return(expr); 341 } 342 343 @DefinedBy(Api.COMPILER_TREE) 344 public JCTree visitMemberSelect(MemberSelectTree node, P p) { 345 JCFieldAccess t = (JCFieldAccess) node; 346 JCExpression selected = copy(t.selected, p); 347 return M.at(t.pos).Select(selected, t.name); 348 } 349 350 @DefinedBy(Api.COMPILER_TREE) 351 public JCTree visitMemberReference(MemberReferenceTree node, P p) { 352 JCMemberReference t = (JCMemberReference) node; 353 JCExpression expr = copy(t.expr, p); 354 List<JCExpression> typeargs = copy(t.typeargs, p); 355 return M.at(t.pos).Reference(t.mode, t.name, expr, typeargs); 356 } 357 358 @DefinedBy(Api.COMPILER_TREE) 359 public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { 360 JCSkip t = (JCSkip) node; 361 return M.at(t.pos).Skip(); 362 } 363 364 @DefinedBy(Api.COMPILER_TREE) 365 public JCTree visitSwitch(SwitchTree node, P p) { 366 JCSwitch t = (JCSwitch) node; 367 JCExpression selector = copy(t.selector, p); 368 List<JCCase> cases = copy(t.cases, p); 369 return M.at(t.pos).Switch(selector, cases); 370 } 371 372 @DefinedBy(Api.COMPILER_TREE) 373 public JCTree visitSynchronized(SynchronizedTree node, P p) { 374 JCSynchronized t = (JCSynchronized) node; 375 JCExpression lock = copy(t.lock, p); 376 JCBlock body = copy(t.body, p); 377 return M.at(t.pos).Synchronized(lock, body); 378 } 379 380 @DefinedBy(Api.COMPILER_TREE) 381 public JCTree visitThrow(ThrowTree node, P p) { 382 JCThrow t = (JCThrow) node; 383 JCExpression expr = copy(t.expr, p); 384 return M.at(t.pos).Throw(expr); 385 } 386 387 @DefinedBy(Api.COMPILER_TREE) 388 public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { 389 JCCompilationUnit t = (JCCompilationUnit) node; 390 List<JCTree> defs = copy(t.defs, p); 391 return M.at(t.pos).TopLevel(defs); 392 } 393 394 @DefinedBy(Api.COMPILER_TREE) 395 public JCTree visitPackage(PackageTree node, P p) { 396 JCPackageDecl t = (JCPackageDecl) node; 397 List<JCAnnotation> annotations = copy(t.annotations, p); 398 JCExpression pid = copy(t.pid, p); 399 return M.at(t.pos).PackageDecl(annotations, pid); 400 } 401 402 @DefinedBy(Api.COMPILER_TREE) 403 public JCTree visitTry(TryTree node, P p) { 404 JCTry t = (JCTry) node; 405 List<JCTree> resources = copy(t.resources, p); 406 JCBlock body = copy(t.body, p); 407 List<JCCatch> catchers = copy(t.catchers, p); 408 JCBlock finalizer = copy(t.finalizer, p); 409 return M.at(t.pos).Try(resources, body, catchers, finalizer); 410 } 411 412 @DefinedBy(Api.COMPILER_TREE) 413 public JCTree visitParameterizedType(ParameterizedTypeTree node, P p) { 414 JCTypeApply t = (JCTypeApply) node; 415 JCExpression clazz = copy(t.clazz, p); 416 List<JCExpression> arguments = copy(t.arguments, p); 417 return M.at(t.pos).TypeApply(clazz, arguments); 418 } 419 420 @DefinedBy(Api.COMPILER_TREE) 421 public JCTree visitUnionType(UnionTypeTree node, P p) { 422 JCTypeUnion t = (JCTypeUnion) node; 423 List<JCExpression> components = copy(t.alternatives, p); 424 return M.at(t.pos).TypeUnion(components); 425 } 426 427 @DefinedBy(Api.COMPILER_TREE) 428 public JCTree visitIntersectionType(IntersectionTypeTree node, P p) { 429 JCTypeIntersection t = (JCTypeIntersection) node; 430 List<JCExpression> bounds = copy(t.bounds, p); 431 return M.at(t.pos).TypeIntersection(bounds); 432 } 433 434 @DefinedBy(Api.COMPILER_TREE) 435 public JCTree visitArrayType(ArrayTypeTree node, P p) { 436 JCArrayTypeTree t = (JCArrayTypeTree) node; 437 JCExpression elemtype = copy(t.elemtype, p); 438 return M.at(t.pos).TypeArray(elemtype); 439 } 440 441 @DefinedBy(Api.COMPILER_TREE) 442 public JCTree visitTypeCast(TypeCastTree node, P p) { 443 JCTypeCast t = (JCTypeCast) node; 444 JCTree clazz = copy(t.clazz, p); 445 JCExpression expr = copy(t.expr, p); 446 return M.at(t.pos).TypeCast(clazz, expr); 447 } 448 449 @DefinedBy(Api.COMPILER_TREE) 450 public JCTree visitPrimitiveType(PrimitiveTypeTree node, P p) { 451 JCPrimitiveTypeTree t = (JCPrimitiveTypeTree) node; 452 return M.at(t.pos).TypeIdent(t.typetag); 453 } 454 455 @DefinedBy(Api.COMPILER_TREE) 456 public JCTree visitTypeParameter(TypeParameterTree node, P p) { 457 JCTypeParameter t = (JCTypeParameter) node; 458 List<JCAnnotation> annos = copy(t.annotations, p); 459 List<JCExpression> bounds = copy(t.bounds, p); 460 return M.at(t.pos).TypeParameter(t.name, bounds, annos); 461 } 462 463 @DefinedBy(Api.COMPILER_TREE) 464 public JCTree visitInstanceOf(InstanceOfTree node, P p) { 465 JCInstanceOf t = (JCInstanceOf) node; 466 JCExpression expr = copy(t.expr, p); 467 JCTree clazz = copy(t.clazz, p); 468 return M.at(t.pos).TypeTest(expr, clazz); 469 } 470 471 @DefinedBy(Api.COMPILER_TREE) 472 public JCTree visitUnary(UnaryTree node, P p) { 473 JCUnary t = (JCUnary) node; 474 JCExpression arg = copy(t.arg, p); 475 return M.at(t.pos).Unary(t.getTag(), arg); 476 } 477 478 @DefinedBy(Api.COMPILER_TREE) 479 public JCTree visitVariable(VariableTree node, P p) { 480 JCVariableDecl t = (JCVariableDecl) node; 481 JCModifiers mods = copy(t.mods, p); 482 JCExpression vartype = copy(t.vartype, p); 483 if (t.nameexpr == null) { 484 JCExpression init = copy(t.init, p); 485 return M.at(t.pos).VarDef(mods, t.name, vartype, init); 486 } else { 487 JCExpression nameexpr = copy(t.nameexpr, p); 488 return M.at(t.pos).ReceiverVarDef(mods, nameexpr, vartype); 489 } 490 } 491 492 @DefinedBy(Api.COMPILER_TREE) 493 public JCTree visitWhileLoop(WhileLoopTree node, P p) { 494 JCWhileLoop t = (JCWhileLoop) node; 495 JCStatement body = copy(t.body, p); 496 JCExpression cond = copy(t.cond, p); 497 return M.at(t.pos).WhileLoop(cond, body); 498 } 499 500 @DefinedBy(Api.COMPILER_TREE) 501 public JCTree visitWildcard(WildcardTree node, P p) { 502 JCWildcard t = (JCWildcard) node; 503 TypeBoundKind kind = M.at(t.kind.pos).TypeBoundKind(t.kind.kind); 504 JCTree inner = copy(t.inner, p); 505 return M.at(t.pos).Wildcard(kind, inner); 506 } 507 508 @DefinedBy(Api.COMPILER_TREE) 509 public JCTree visitOther(Tree node, P p) { 510 JCTree tree = (JCTree) node; 511 switch (tree.getTag()) { 512 case LETEXPR: { 513 LetExpr t = (LetExpr) node; 514 List<JCVariableDecl> defs = copy(t.defs, p); 515 JCExpression expr = copy(t.expr, p); 516 return M.at(t.pos).LetExpr(defs, expr); 517 } 518 default: 519 throw new AssertionError("unknown tree tag: " + tree.getTag()); 520 } 521 } 522 523} 524