1 /* 2 * Copyright 2006-2008 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.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 API supported by Sun Microsystems. If 38 * 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 visitAnnotatedType(AnnotatedTypeTree node, P p) { 75 JCAnnotatedType t = (JCAnnotatedType) node; 76 List<JCTypeAnnotation> annotations = copy(t.annotations, p); 77 JCExpression underlyingType = copy(t.underlyingType, p); 78 return M.at(t.pos).AnnotatedType(annotations, underlyingType); 79 } 80 81 public JCTree visitAnnotation(AnnotationTree node, P p) { 82 JCAnnotation t = (JCAnnotation) node; 83 JCTree annotationType = copy(t.annotationType, p); 84 List<JCExpression> args = copy(t.args, p); 85 return M.at(t.pos).Annotation(annotationType, args); 86 } 87 88 public JCTree visitAssert(AssertTree node, P p) { 89 JCAssert t = (JCAssert) node; 90 JCExpression cond = copy(t.cond, p); 91 JCExpression detail = copy(t.detail, p); 92 return M.at(t.pos).Assert(cond, detail); 93 } 94 95 public JCTree visitAssignment(AssignmentTree node, P p) { 96 JCAssign t = (JCAssign) node; 97 JCExpression lhs = copy(t.lhs, p); 98 JCExpression rhs = copy(t.rhs, p); 99 return M.at(t.pos).Assign(lhs, rhs); 100 } 101 102 public JCTree visitCompoundAssignment(CompoundAssignmentTree node, P p) { 103 JCAssignOp t = (JCAssignOp) node; 104 JCTree lhs = copy(t.lhs, p); 105 JCTree rhs = copy(t.rhs, p); 106 return M.at(t.pos).Assignop(t.getTag(), lhs, rhs); 107 } 108 109 public JCTree visitBinary(BinaryTree node, P p) { 110 JCBinary t = (JCBinary) node; 111 JCExpression lhs = copy(t.lhs, p); 112 JCExpression rhs = copy(t.rhs, p); 113 return M.at(t.pos).Binary(t.getTag(), lhs, rhs); 114 } 115 116 public JCTree visitBlock(BlockTree node, P p) { 117 JCBlock t = (JCBlock) node; 118 List<JCStatement> stats = copy(t.stats, p); 119 return M.at(t.pos).Block(t.flags, stats); 120 } 121 122 public JCTree visitBreak(BreakTree node, P p) { 123 JCBreak t = (JCBreak) node; 124 return M.at(t.pos).Break(t.label); 125 } 126 127 public JCTree visitCase(CaseTree node, P p) { 128 JCCase t = (JCCase) node; 129 JCExpression pat = copy(t.pat, p); 130 List<JCStatement> stats = copy(t.stats, p); 131 return M.at(t.pos).Case(pat, stats); 132 } 133 134 public JCTree visitCatch(CatchTree node, P p) { 135 JCCatch t = (JCCatch) node; 136 JCVariableDecl param = copy(t.param, p); 137 JCBlock body = copy(t.body, p); 138 return M.at(t.pos).Catch(param, body); 139 } 140 141 public JCTree visitClass(ClassTree node, P p) { 142 JCClassDecl t = (JCClassDecl) node; 143 JCModifiers mods = copy(t.mods, p); 144 List<JCTypeParameter> typarams = copy(t.typarams, p); 145 JCTree extending = copy(t.extending, p); 146 List<JCExpression> implementing = copy(t.implementing, p); 147 List<JCTree> defs = copy(t.defs, p); 148 return M.at(t.pos).ClassDef(mods, t.name, typarams, extending, implementing, defs); 149 } 150 151 public JCTree visitConditionalExpression(ConditionalExpressionTree node, P p) { 152 JCConditional t = (JCConditional) node; 153 JCExpression cond = copy(t.cond, p); 154 JCExpression truepart = copy(t.truepart, p); 155 JCExpression falsepart = copy(t.falsepart, p); 156 return M.at(t.pos).Conditional(cond, truepart, falsepart); 157 } 158 159 public JCTree visitContinue(ContinueTree node, P p) { 160 JCContinue t = (JCContinue) node; 161 return M.at(t.pos).Continue(t.label); 162 } 163 164 public JCTree visitDoWhileLoop(DoWhileLoopTree node, P p) { 165 JCDoWhileLoop t = (JCDoWhileLoop) node; 166 JCStatement body = copy(t.body, p); 167 JCExpression cond = copy(t.cond, p); 168 return M.at(t.pos).DoLoop(body, cond); 169 } 170 171 public JCTree visitErroneous(ErroneousTree node, P p) { 172 JCErroneous t = (JCErroneous) node; 173 List<? extends JCTree> errs = copy(t.errs, p); 174 return M.at(t.pos).Erroneous(errs); 175 } 176 177 public JCTree visitExpressionStatement(ExpressionStatementTree node, P p) { 178 JCExpressionStatement t = (JCExpressionStatement) node; 179 JCExpression expr = copy(t.expr, p); 180 return M.at(t.pos).Exec(expr); 181 } 182 183 public JCTree visitEnhancedForLoop(EnhancedForLoopTree node, P p) { 184 JCEnhancedForLoop t = (JCEnhancedForLoop) node; 185 JCVariableDecl var = copy(t.var, p); 186 JCExpression expr = copy(t.expr, p); 187 JCStatement body = copy(t.body, p); 188 return M.at(t.pos).ForeachLoop(var, expr, body); 189 } 190 191 public JCTree visitForLoop(ForLoopTree node, P p) { 192 JCForLoop t = (JCForLoop) node; 193 List<JCStatement> init = copy(t.init, p); 194 JCExpression cond = copy(t.cond, p); 195 List<JCExpressionStatement> step = copy(t.step, p); 196 JCStatement body = copy(t.body, p); 197 return M.at(t.pos).ForLoop(init, cond, step, body); 198 } 199 200 public JCTree visitFunctionType(FunctionTypeTree node, P p) { 201 JCFunctionType t = (JCFunctionType) node; 202 List<JCExpression> parameterTypes = copy(t.parameterTypes, p); 203 JCExpression returnType = copy(t.returnType, p); 204 return M.at(t.pos).FunctionType(parameterTypes, returnType); 205 } 206 207 public JCTree visitIdentifier(IdentifierTree node, P p) { 208 JCIdent t = (JCIdent) node; 209 return M.at(t.pos).Ident(t.name); 210 } 211 212 public JCTree visitIf(IfTree node, P p) { 213 JCIf t = (JCIf) node; 214 JCExpression cond = copy(t.cond, p); 215 JCStatement thenpart = copy(t.thenpart, p); 216 JCStatement elsepart = copy(t.elsepart, p); 217 return M.at(t.pos).If(cond, thenpart, elsepart); 218 } 219 220 public JCTree visitImport(ImportTree node, P p) { 221 JCImport t = (JCImport) node; 222 JCTree qualid = copy(t.qualid, p); 223 return M.at(t.pos).Import(qualid, t.staticImport); 224 } 225 226 public JCTree visitArrayAccess(ArrayAccessTree node, P p) { 227 JCArrayAccess t = (JCArrayAccess) node; 228 JCExpression indexed = copy(t.indexed, p); 229 JCExpression index = copy(t.index, p); 230 return M.at(t.pos).Indexed(indexed, index); 231 } 232 233 public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { 234 JCLabeledStatement t = (JCLabeledStatement) node; 235 JCStatement body = copy(t.body, p); 236 return M.at(t.pos).Labelled(t.label, t.body); 237 } 238 239 public JCTree visitLambda(LambdaTree node, P p) { 240 JCLambda t = (JCLambda) node; 241 List<JCVariableDecl> parameters = copy(t.parameters, p); 242 JCTree bodyOrExpr = copy(t.bodyOrExpr, p); 243 return M.at(t.pos).Lambda(parameters, bodyOrExpr); 244 } 245 246 public JCTree visitLiteral(LiteralTree node, P p) { 247 JCLiteral t = (JCLiteral) node; 248 return M.at(t.pos).Literal(t.typetag, t.value); 249 } 250 251 public JCTree visitMethod(MethodTree node, P p) { 252 JCMethodDecl t = (JCMethodDecl) node; 253 JCModifiers mods = copy(t.mods, p); 254 JCExpression restype = copy(t.restype, p); 255 List<JCTypeParameter> typarams = copy(t.typarams, p); 256 List<JCVariableDecl> params = copy(t.params, p); 257 List<JCTypeAnnotation> receiver = copy(t.receiverAnnotations, p); 258 List<JCExpression> thrown = copy(t.thrown, p); 259 JCBlock body = copy(t.body, p); 260 JCExpression defaultValue = copy(t.defaultValue, p); 261 return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, receiver, thrown, body, defaultValue); 262 } 263 264 public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { 265 JCMethodInvocation t = (JCMethodInvocation) node; 266 List<JCExpression> typeargs = copy(t.typeargs, p); 267 JCExpression meth = copy(t.meth, p); 268 List<JCExpression> args = copy(t.args, p); 269 return M.at(t.pos).Apply(typeargs, meth, args); 270 } 271 272 public JCTree visitModifiers(ModifiersTree node, P p) { 273 JCModifiers t = (JCModifiers) node; 274 List<JCAnnotation> annotations = copy(t.annotations, p); 275 return M.at(t.pos).Modifiers(t.flags, annotations); 276 } 277 278 public JCTree visitNewArray(NewArrayTree node, P p) { 279 JCNewArray t = (JCNewArray) node; 280 JCExpression elemtype = copy(t.elemtype, p); 281 List<JCExpression> dims = copy(t.dims, p); 282 List<JCExpression> elems = copy(t.elems, p); 283 return M.at(t.pos).NewArray(elemtype, dims, elems); 284 } 285 286 public JCTree visitNewClass(NewClassTree node, P p) { 287 JCNewClass t = (JCNewClass) node; 288 JCExpression encl = copy(t.encl, p); 289 List<JCExpression> typeargs = copy(t.typeargs, p); 290 JCExpression clazz = copy(t.clazz, p); 291 List<JCExpression> args = copy(t.args, p); 292 JCClassDecl def = copy(t.def, p); 293 return M.at(t.pos).NewClass(encl, typeargs, clazz, args, def); 294 } 295 296 public JCTree visitParenthesized(ParenthesizedTree node, P p) { 297 JCParens t = (JCParens) node; 298 JCExpression expr = copy(t.expr, p); 299 return M.at(t.pos).Parens(expr); 300 } 301 302 public JCTree visitReturn(ReturnTree node, P p) { 303 JCReturn t = (JCReturn) node; 304 JCExpression expr = copy(t.expr, p); 305 return M.at(t.pos).Return(expr); 306 } 307 308 public JCTree visitMemberSelect(MemberSelectTree node, P p) { 309 JCFieldAccess t = (JCFieldAccess) node; 310 JCExpression selected = copy(t.selected, p); 311 return M.at(t.pos).Select(selected, t.name); 312 } 313 314 public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { 315 JCSkip t = (JCSkip) node; 316 return M.at(t.pos).Skip(); 317 } 318 319 public JCTree visitSwitch(SwitchTree node, P p) { 320 JCSwitch t = (JCSwitch) node; 321 JCExpression selector = copy(t.selector, p); 322 List<JCCase> cases = copy(t.cases, p); 323 return M.at(t.pos).Switch(selector, cases); 324 } 325 326 public JCTree visitSynchronized(SynchronizedTree node, P p) { 327 JCSynchronized t = (JCSynchronized) node; 328 JCExpression lock = copy(t.lock, p); 329 JCBlock body = copy(t.body, p); 330 return M.at(t.pos).Synchronized(lock, body); 331 } 332 333 public JCTree visitThrow(ThrowTree node, P p) { 334 JCThrow t = (JCThrow) node; 335 JCTree expr = copy(t.expr, p); 336 return M.at(t.pos).Throw(expr); 337 } 338 339 public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { 340 JCCompilationUnit t = (JCCompilationUnit) node; 341 List<JCAnnotation> packageAnnotations = copy(t.packageAnnotations, p); 342 JCExpression pid = copy(t.pid, p); 343 List<JCTree> defs = copy(t.defs, p); 344 return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); 345 } 346 347 public JCTree visitTry(TryTree node, P p) { 348 JCTry t = (JCTry) node; 349 JCBlock body = copy(t.body, p); 350 List<JCCatch> catchers = copy(t.catchers, p); 351 JCBlock finalizer = copy(t.finalizer, p); 352 return M.at(t.pos).Try(body, catchers, finalizer); 353 } 354 355 public JCTree visitParameterizedType(ParameterizedTypeTree node, P p) { 356 JCTypeApply t = (JCTypeApply) node; 357 JCExpression clazz = copy(t.clazz, p); 358 List<JCExpression> arguments = copy(t.arguments, p); 359 return M.at(t.pos).TypeApply(clazz, arguments); 360 } 361 362 public JCTree visitArrayType(ArrayTypeTree node, P p) { 363 JCArrayTypeTree t = (JCArrayTypeTree) node; 364 JCExpression elemtype = copy(t.elemtype, p); 365 return M.at(t.pos).TypeArray(elemtype); 366 } 367 368 public JCTree visitTypeCast(TypeCastTree node, P p) { 369 JCTypeCast t = (JCTypeCast) node; 370 JCTree clazz = copy(t.clazz, p); 371 JCExpression expr = copy(t.expr, p); 372 return M.at(t.pos).TypeCast(clazz, expr); 373 } 374 375 public JCTree visitPrimitiveType(PrimitiveTypeTree node, P p) { 376 JCPrimitiveTypeTree t = (JCPrimitiveTypeTree) node; 377 return M.at(t.pos).TypeIdent(t.typetag); 378 } 379 380 public JCTree visitTypeParameter(TypeParameterTree node, P p) { 381 JCTypeParameter t = (JCTypeParameter) node; 382 List<JCTypeAnnotation> annos = copy(t.annotations, p); 383 List<JCExpression> bounds = copy(t.bounds, p); 384 return M.at(t.pos).TypeParameter(t.name, bounds, annos); 385 } 386 387 public JCTree visitInstanceOf(InstanceOfTree node, P p) { 388 JCInstanceOf t = (JCInstanceOf) node; 389 JCExpression expr = copy(t.expr, p); 390 JCTree clazz = copy(t.clazz, p); 391 return M.at(t.pos).TypeTest(expr, clazz); 392 } 393 394 public JCTree visitUnary(UnaryTree node, P p) { 395 JCUnary t = (JCUnary) node; 396 JCExpression arg = copy(t.arg, p); 397 return M.at(t.pos).Unary(t.getTag(), arg); 398 } 399 400 public JCTree visitVariable(VariableTree node, P p) { 401 JCVariableDecl t = (JCVariableDecl) node; 402 JCModifiers mods = copy(t.mods, p); 403 JCExpression vartype = copy(t.vartype, p); 404 JCExpression init = copy(t.init, p); 405 return M.at(t.pos).VarDef(mods, t.name, vartype, init); 406 } 407 408 public JCTree visitWhileLoop(WhileLoopTree node, P p) { 409 JCWhileLoop t = (JCWhileLoop) node; 410 JCStatement body = copy(t.body, p); 411 JCExpression cond = copy(t.cond, p); 412 return M.at(t.pos).WhileLoop(cond, body); 413 } 414 415 public JCTree visitWildcard(WildcardTree node, P p) { 416 JCWildcard t = (JCWildcard) node; 417 TypeBoundKind kind = M.at(t.kind.pos).TypeBoundKind(t.kind.kind); 418 JCTree inner = copy(t.inner, p); 419 return M.at(t.pos).Wildcard(kind, inner); 420 } 421 422 public JCTree visitOther(Tree node, P p) { 423 JCTree tree = (JCTree) node; 424 switch (tree.getTag()) { 425 case JCTree.LETEXPR: { 426 LetExpr t = (LetExpr) node; 427 List<JCVariableDecl> defs = copy(t.defs, p); 428 JCTree expr = copy(t.expr, p); 429 return M.at(t.pos).LetExpr(defs, expr); 430 } 431 default: 432 throw new AssertionError("unknown tree tag: " + tree.getTag()); 433 } 434 } 435 436 }