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