1 /* 2 * Copyright (c) 2006, 2008, 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 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 visitIdentifier(IdentifierTree node, P p) { 201 JCIdent t = (JCIdent) node; 202 return M.at(t.pos).Ident(t.name); 203 } 204 205 public JCTree visitIf(IfTree node, P p) { 206 JCIf t = (JCIf) node; 207 JCExpression cond = copy(t.cond, p); 208 JCStatement thenpart = copy(t.thenpart, p); 209 JCStatement elsepart = copy(t.elsepart, p); 210 return M.at(t.pos).If(cond, thenpart, elsepart); 211 } 212 213 public JCTree visitImport(ImportTree node, P p) { 214 JCImport t = (JCImport) node; 215 JCTree qualid = copy(t.qualid, p); 216 return M.at(t.pos).Import(qualid, t.staticImport); 217 } 218 219 public JCTree visitArrayAccess(ArrayAccessTree node, P p) { 220 JCArrayAccess t = (JCArrayAccess) node; 221 JCExpression indexed = copy(t.indexed, p); 222 JCExpression index = copy(t.index, p); 223 return M.at(t.pos).Indexed(indexed, index); 224 } 225 226 public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { 227 JCLabeledStatement t = (JCLabeledStatement) node; 228 JCStatement body = copy(t.body, p); 229 return M.at(t.pos).Labelled(t.label, t.body); 230 } 231 232 public JCTree visitLiteral(LiteralTree node, P p) { 233 JCLiteral t = (JCLiteral) node; 234 return M.at(t.pos).Literal(t.typetag, t.value); 235 } 236 237 public JCTree visitMethod(MethodTree node, P p) { 238 JCMethodDecl t = (JCMethodDecl) node; 239 JCModifiers mods = copy(t.mods, p); 240 JCExpression restype = copy(t.restype, p); 241 List<JCTypeParameter> typarams = copy(t.typarams, p); 242 List<JCVariableDecl> params = copy(t.params, p); 243 List<JCTypeAnnotation> receiver = copy(t.receiverAnnotations, p); 244 List<JCExpression> thrown = copy(t.thrown, p); 245 JCBlock body = copy(t.body, p); 246 JCExpression defaultValue = copy(t.defaultValue, p); 247 return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, receiver, thrown, body, defaultValue); 248 } 249 250 public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { 251 JCMethodInvocation t = (JCMethodInvocation) node; 252 List<JCExpression> typeargs = copy(t.typeargs, p); 253 JCExpression meth = copy(t.meth, p); 254 List<JCExpression> args = copy(t.args, p); 255 return M.at(t.pos).Apply(typeargs, meth, args); 256 } 257 258 public JCTree visitModifiers(ModifiersTree node, P p) { 259 JCModifiers t = (JCModifiers) node; 260 List<JCAnnotation> annotations = copy(t.annotations, p); 261 return M.at(t.pos).Modifiers(t.flags, annotations); 262 } 263 264 public JCTree visitNewArray(NewArrayTree node, P p) { 265 JCNewArray t = (JCNewArray) node; 266 JCExpression elemtype = copy(t.elemtype, p); 267 List<JCExpression> dims = copy(t.dims, p); 268 List<JCExpression> elems = copy(t.elems, p); 269 return M.at(t.pos).NewArray(elemtype, dims, elems); 270 } 271 272 public JCTree visitNewClass(NewClassTree node, P p) { 273 JCNewClass t = (JCNewClass) node; 274 JCExpression encl = copy(t.encl, p); 275 List<JCExpression> typeargs = copy(t.typeargs, p); 276 JCExpression clazz = copy(t.clazz, p); 277 List<JCExpression> args = copy(t.args, p); 278 JCClassDecl def = copy(t.def, p); 279 return M.at(t.pos).NewClass(encl, typeargs, clazz, args, def); 280 } 281 282 public JCTree visitParenthesized(ParenthesizedTree node, P p) { 283 JCParens t = (JCParens) node; 284 JCExpression expr = copy(t.expr, p); 285 return M.at(t.pos).Parens(expr); 286 } 287 288 public JCTree visitReturn(ReturnTree node, P p) { 289 JCReturn t = (JCReturn) node; 290 JCExpression expr = copy(t.expr, p); 291 return M.at(t.pos).Return(expr); 292 } 293 294 public JCTree visitMemberSelect(MemberSelectTree node, P p) { 295 JCFieldAccess t = (JCFieldAccess) node; 296 JCExpression selected = copy(t.selected, p); 297 return M.at(t.pos).Select(selected, t.name); 298 } 299 300 public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { 301 JCSkip t = (JCSkip) node; 302 return M.at(t.pos).Skip(); 303 } 304 305 public JCTree visitSwitch(SwitchTree node, P p) { 306 JCSwitch t = (JCSwitch) node; 307 JCExpression selector = copy(t.selector, p); 308 List<JCCase> cases = copy(t.cases, p); 309 return M.at(t.pos).Switch(selector, cases); 310 } 311 312 public JCTree visitSynchronized(SynchronizedTree node, P p) { 313 JCSynchronized t = (JCSynchronized) node; 314 JCExpression lock = copy(t.lock, p); 315 JCBlock body = copy(t.body, p); 316 return M.at(t.pos).Synchronized(lock, body); 317 } 318 319 public JCTree visitThrow(ThrowTree node, P p) { 320 JCThrow t = (JCThrow) node; 321 JCTree expr = copy(t.expr, p); 322 return M.at(t.pos).Throw(expr); 323 } 324 325 public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { 326 JCCompilationUnit t = (JCCompilationUnit) node; 327 List<JCAnnotation> packageAnnotations = copy(t.packageAnnotations, p); 328 JCExpression pid = copy(t.pid, p); 329 List<JCTree> defs = copy(t.defs, p); 330 return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); 331 } 332 333 public JCTree visitTry(TryTree node, P p) { 334 JCTry t = (JCTry) node; 335 JCBlock body = copy(t.body, p); 336 List<JCCatch> catchers = copy(t.catchers, p); 337 JCBlock finalizer = copy(t.finalizer, p); 338 List<JCTree> resources = copy(t.resources, p); 339 return M.at(t.pos).Try(body, catchers, finalizer, resources); 340 } 341 342 public JCTree visitParameterizedType(ParameterizedTypeTree node, P p) { 343 JCTypeApply t = (JCTypeApply) node; 344 JCExpression clazz = copy(t.clazz, p); 345 List<JCExpression> arguments = copy(t.arguments, p); 346 return M.at(t.pos).TypeApply(clazz, arguments); 347 } 348 349 public JCTree visitDisjointType(DisjointTypeTree node, P p) { 350 JCTypeDisjoint t = (JCTypeDisjoint) node; 351 List<JCExpression> components = copy(t.components, p); 352 return M.at(t.pos).TypeDisjoint(components); 353 } 354 355 public JCTree visitArrayType(ArrayTypeTree node, P p) { 356 JCArrayTypeTree t = (JCArrayTypeTree) node; 357 JCExpression elemtype = copy(t.elemtype, p); 358 return M.at(t.pos).TypeArray(elemtype); 359 } 360 361 public JCTree visitTypeCast(TypeCastTree node, P p) { 362 JCTypeCast t = (JCTypeCast) node; 363 JCTree clazz = copy(t.clazz, p); 364 JCExpression expr = copy(t.expr, p); 365 return M.at(t.pos).TypeCast(clazz, expr); 366 } 367 368 public JCTree visitPrimitiveType(PrimitiveTypeTree node, P p) { 369 JCPrimitiveTypeTree t = (JCPrimitiveTypeTree) node; 370 return M.at(t.pos).TypeIdent(t.typetag); 371 } 372 373 public JCTree visitTypeParameter(TypeParameterTree node, P p) { 374 JCTypeParameter t = (JCTypeParameter) node; 375 List<JCTypeAnnotation> annos = copy(t.annotations, p); 376 List<JCExpression> bounds = copy(t.bounds, p); 377 return M.at(t.pos).TypeParameter(t.name, bounds, annos); 378 } 379 380 public JCTree visitInstanceOf(InstanceOfTree node, P p) { 381 JCInstanceOf t = (JCInstanceOf) node; 382 JCExpression expr = copy(t.expr, p); 383 JCTree clazz = copy(t.clazz, p); 384 return M.at(t.pos).TypeTest(expr, clazz); 385 } 386 387 public JCTree visitUnary(UnaryTree node, P p) { 388 JCUnary t = (JCUnary) node; 389 JCExpression arg = copy(t.arg, p); 390 return M.at(t.pos).Unary(t.getTag(), arg); 391 } 392 393 public JCTree visitVariable(VariableTree node, P p) { 394 JCVariableDecl t = (JCVariableDecl) node; 395 JCModifiers mods = copy(t.mods, p); 396 JCExpression vartype = copy(t.vartype, p); 397 JCExpression init = copy(t.init, p); 398 return M.at(t.pos).VarDef(mods, t.name, vartype, init); 399 } 400 401 public JCTree visitWhileLoop(WhileLoopTree node, P p) { 402 JCWhileLoop t = (JCWhileLoop) node; 403 JCStatement body = copy(t.body, p); 404 JCExpression cond = copy(t.cond, p); 405 return M.at(t.pos).WhileLoop(cond, body); 406 } 407 408 public JCTree visitWildcard(WildcardTree node, P p) { 409 JCWildcard t = (JCWildcard) node; 410 TypeBoundKind kind = M.at(t.kind.pos).TypeBoundKind(t.kind.kind); 411 JCTree inner = copy(t.inner, p); 412 return M.at(t.pos).Wildcard(kind, inner); 413 } 414 415 public JCTree visitOther(Tree node, P p) { 416 JCTree tree = (JCTree) node; 417 switch (tree.getTag()) { 418 case JCTree.LETEXPR: { 419 LetExpr t = (LetExpr) node; 420 List<JCVariableDecl> defs = copy(t.defs, p); 421 JCTree expr = copy(t.expr, p); 422 return M.at(t.pos).LetExpr(defs, expr); 423 } 424 default: 425 throw new AssertionError("unknown tree tag: " + tree.getTag()); 426 } 427 } 428 429 }