duke@1: /* jjg@815: * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package com.sun.tools.javac.tree; duke@1: duke@1: import com.sun.source.tree.*; duke@1: import com.sun.tools.javac.tree.JCTree.*; duke@1: import com.sun.tools.javac.util.List; duke@1: import com.sun.tools.javac.util.ListBuffer; duke@1: duke@1: /** duke@1: * Creates a copy of a tree, using a given TreeMaker. duke@1: * Names, literal values, etc are shared with the original. duke@1: * jjg@581: *

This is NOT part of any supported API. jjg@581: * If you write code that depends on this, you do so at your own risk. duke@1: * This code and its internal interfaces are subject to change or duke@1: * deletion without notice. duke@1: */ duke@1: public class TreeCopier

implements TreeVisitor { duke@1: private TreeMaker M; duke@1: duke@1: /** Creates a new instance of TreeCopier */ duke@1: public TreeCopier(TreeMaker M) { duke@1: this.M = M; duke@1: } duke@1: duke@1: public T copy(T tree) { duke@1: return copy(tree, null); duke@1: } duke@1: duke@1: @SuppressWarnings("unchecked") duke@1: public T copy(T tree, P p) { duke@1: if (tree == null) duke@1: return null; duke@1: return (T) (tree.accept(this, p)); duke@1: } duke@1: duke@1: public List copy(List trees) { duke@1: return copy(trees, null); duke@1: } duke@1: duke@1: public List copy(List trees, P p) { duke@1: if (trees == null) duke@1: return null; duke@1: ListBuffer lb = new ListBuffer(); duke@1: for (T tree: trees) duke@1: lb.append(copy(tree, p)); duke@1: return lb.toList(); duke@1: } duke@1: duke@1: public JCTree visitAnnotation(AnnotationTree node, P p) { duke@1: JCAnnotation t = (JCAnnotation) node; duke@1: JCTree annotationType = copy(t.annotationType, p); duke@1: List args = copy(t.args, p); duke@1: return M.at(t.pos).Annotation(annotationType, args); duke@1: } duke@1: duke@1: public JCTree visitAssert(AssertTree node, P p) { duke@1: JCAssert t = (JCAssert) node; duke@1: JCExpression cond = copy(t.cond, p); duke@1: JCExpression detail = copy(t.detail, p); duke@1: return M.at(t.pos).Assert(cond, detail); duke@1: } duke@1: duke@1: public JCTree visitAssignment(AssignmentTree node, P p) { duke@1: JCAssign t = (JCAssign) node; duke@1: JCExpression lhs = copy(t.lhs, p); duke@1: JCExpression rhs = copy(t.rhs, p); duke@1: return M.at(t.pos).Assign(lhs, rhs); duke@1: } duke@1: duke@1: public JCTree visitCompoundAssignment(CompoundAssignmentTree node, P p) { duke@1: JCAssignOp t = (JCAssignOp) node; duke@1: JCTree lhs = copy(t.lhs, p); duke@1: JCTree rhs = copy(t.rhs, p); duke@1: return M.at(t.pos).Assignop(t.getTag(), lhs, rhs); duke@1: } duke@1: duke@1: public JCTree visitBinary(BinaryTree node, P p) { duke@1: JCBinary t = (JCBinary) node; duke@1: JCExpression lhs = copy(t.lhs, p); duke@1: JCExpression rhs = copy(t.rhs, p); duke@1: return M.at(t.pos).Binary(t.getTag(), lhs, rhs); duke@1: } duke@1: duke@1: public JCTree visitBlock(BlockTree node, P p) { duke@1: JCBlock t = (JCBlock) node; duke@1: List stats = copy(t.stats, p); duke@1: return M.at(t.pos).Block(t.flags, stats); duke@1: } duke@1: duke@1: public JCTree visitBreak(BreakTree node, P p) { duke@1: JCBreak t = (JCBreak) node; duke@1: return M.at(t.pos).Break(t.label); duke@1: } duke@1: duke@1: public JCTree visitCase(CaseTree node, P p) { duke@1: JCCase t = (JCCase) node; duke@1: JCExpression pat = copy(t.pat, p); duke@1: List stats = copy(t.stats, p); duke@1: return M.at(t.pos).Case(pat, stats); duke@1: } duke@1: duke@1: public JCTree visitCatch(CatchTree node, P p) { duke@1: JCCatch t = (JCCatch) node; duke@1: JCVariableDecl param = copy(t.param, p); duke@1: JCBlock body = copy(t.body, p); duke@1: return M.at(t.pos).Catch(param, body); duke@1: } duke@1: duke@1: public JCTree visitClass(ClassTree node, P p) { duke@1: JCClassDecl t = (JCClassDecl) node; duke@1: JCModifiers mods = copy(t.mods, p); duke@1: List typarams = copy(t.typarams, p); jjg@904: JCExpression extending = copy(t.extending, p); duke@1: List implementing = copy(t.implementing, p); duke@1: List defs = copy(t.defs, p); duke@1: return M.at(t.pos).ClassDef(mods, t.name, typarams, extending, implementing, defs); duke@1: } duke@1: duke@1: public JCTree visitConditionalExpression(ConditionalExpressionTree node, P p) { duke@1: JCConditional t = (JCConditional) node; duke@1: JCExpression cond = copy(t.cond, p); duke@1: JCExpression truepart = copy(t.truepart, p); duke@1: JCExpression falsepart = copy(t.falsepart, p); duke@1: return M.at(t.pos).Conditional(cond, truepart, falsepart); duke@1: } duke@1: duke@1: public JCTree visitContinue(ContinueTree node, P p) { duke@1: JCContinue t = (JCContinue) node; duke@1: return M.at(t.pos).Continue(t.label); duke@1: } duke@1: duke@1: public JCTree visitDoWhileLoop(DoWhileLoopTree node, P p) { duke@1: JCDoWhileLoop t = (JCDoWhileLoop) node; duke@1: JCStatement body = copy(t.body, p); duke@1: JCExpression cond = copy(t.cond, p); duke@1: return M.at(t.pos).DoLoop(body, cond); duke@1: } duke@1: duke@1: public JCTree visitErroneous(ErroneousTree node, P p) { duke@1: JCErroneous t = (JCErroneous) node; duke@1: List errs = copy(t.errs, p); duke@1: return M.at(t.pos).Erroneous(errs); duke@1: } duke@1: duke@1: public JCTree visitExpressionStatement(ExpressionStatementTree node, P p) { duke@1: JCExpressionStatement t = (JCExpressionStatement) node; duke@1: JCExpression expr = copy(t.expr, p); duke@1: return M.at(t.pos).Exec(expr); duke@1: } duke@1: duke@1: public JCTree visitEnhancedForLoop(EnhancedForLoopTree node, P p) { duke@1: JCEnhancedForLoop t = (JCEnhancedForLoop) node; duke@1: JCVariableDecl var = copy(t.var, p); duke@1: JCExpression expr = copy(t.expr, p); duke@1: JCStatement body = copy(t.body, p); duke@1: return M.at(t.pos).ForeachLoop(var, expr, body); duke@1: } duke@1: duke@1: public JCTree visitForLoop(ForLoopTree node, P p) { duke@1: JCForLoop t = (JCForLoop) node; duke@1: List init = copy(t.init, p); duke@1: JCExpression cond = copy(t.cond, p); duke@1: List step = copy(t.step, p); duke@1: JCStatement body = copy(t.body, p); duke@1: return M.at(t.pos).ForLoop(init, cond, step, body); duke@1: } duke@1: duke@1: public JCTree visitIdentifier(IdentifierTree node, P p) { duke@1: JCIdent t = (JCIdent) node; duke@1: return M.at(t.pos).Ident(t.name); duke@1: } duke@1: duke@1: public JCTree visitIf(IfTree node, P p) { duke@1: JCIf t = (JCIf) node; duke@1: JCExpression cond = copy(t.cond, p); duke@1: JCStatement thenpart = copy(t.thenpart, p); duke@1: JCStatement elsepart = copy(t.elsepart, p); duke@1: return M.at(t.pos).If(cond, thenpart, elsepart); duke@1: } duke@1: duke@1: public JCTree visitImport(ImportTree node, P p) { duke@1: JCImport t = (JCImport) node; duke@1: JCTree qualid = copy(t.qualid, p); duke@1: return M.at(t.pos).Import(qualid, t.staticImport); duke@1: } duke@1: duke@1: public JCTree visitArrayAccess(ArrayAccessTree node, P p) { duke@1: JCArrayAccess t = (JCArrayAccess) node; duke@1: JCExpression indexed = copy(t.indexed, p); duke@1: JCExpression index = copy(t.index, p); duke@1: return M.at(t.pos).Indexed(indexed, index); duke@1: } duke@1: duke@1: public JCTree visitLabeledStatement(LabeledStatementTree node, P p) { duke@1: JCLabeledStatement t = (JCLabeledStatement) node; duke@1: JCStatement body = copy(t.body, p); duke@1: return M.at(t.pos).Labelled(t.label, t.body); duke@1: } duke@1: duke@1: public JCTree visitLiteral(LiteralTree node, P p) { duke@1: JCLiteral t = (JCLiteral) node; duke@1: return M.at(t.pos).Literal(t.typetag, t.value); duke@1: } duke@1: duke@1: public JCTree visitMethod(MethodTree node, P p) { duke@1: JCMethodDecl t = (JCMethodDecl) node; duke@1: JCModifiers mods = copy(t.mods, p); duke@1: JCExpression restype = copy(t.restype, p); duke@1: List typarams = copy(t.typarams, p); duke@1: List params = copy(t.params, p); duke@1: List thrown = copy(t.thrown, p); duke@1: JCBlock body = copy(t.body, p); duke@1: JCExpression defaultValue = copy(t.defaultValue, p); jjg@815: return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, thrown, body, defaultValue); duke@1: } duke@1: duke@1: public JCTree visitMethodInvocation(MethodInvocationTree node, P p) { duke@1: JCMethodInvocation t = (JCMethodInvocation) node; duke@1: List typeargs = copy(t.typeargs, p); duke@1: JCExpression meth = copy(t.meth, p); duke@1: List args = copy(t.args, p); duke@1: return M.at(t.pos).Apply(typeargs, meth, args); duke@1: } duke@1: duke@1: public JCTree visitModifiers(ModifiersTree node, P p) { duke@1: JCModifiers t = (JCModifiers) node; duke@1: List annotations = copy(t.annotations, p); duke@1: return M.at(t.pos).Modifiers(t.flags, annotations); duke@1: } duke@1: duke@1: public JCTree visitNewArray(NewArrayTree node, P p) { duke@1: JCNewArray t = (JCNewArray) node; duke@1: JCExpression elemtype = copy(t.elemtype, p); duke@1: List dims = copy(t.dims, p); duke@1: List elems = copy(t.elems, p); duke@1: return M.at(t.pos).NewArray(elemtype, dims, elems); duke@1: } duke@1: duke@1: public JCTree visitNewClass(NewClassTree node, P p) { duke@1: JCNewClass t = (JCNewClass) node; duke@1: JCExpression encl = copy(t.encl, p); duke@1: List typeargs = copy(t.typeargs, p); duke@1: JCExpression clazz = copy(t.clazz, p); duke@1: List args = copy(t.args, p); duke@1: JCClassDecl def = copy(t.def, p); duke@1: return M.at(t.pos).NewClass(encl, typeargs, clazz, args, def); duke@1: } duke@1: duke@1: public JCTree visitParenthesized(ParenthesizedTree node, P p) { duke@1: JCParens t = (JCParens) node; duke@1: JCExpression expr = copy(t.expr, p); duke@1: return M.at(t.pos).Parens(expr); duke@1: } duke@1: duke@1: public JCTree visitReturn(ReturnTree node, P p) { duke@1: JCReturn t = (JCReturn) node; duke@1: JCExpression expr = copy(t.expr, p); duke@1: return M.at(t.pos).Return(expr); duke@1: } duke@1: duke@1: public JCTree visitMemberSelect(MemberSelectTree node, P p) { duke@1: JCFieldAccess t = (JCFieldAccess) node; duke@1: JCExpression selected = copy(t.selected, p); duke@1: return M.at(t.pos).Select(selected, t.name); duke@1: } duke@1: duke@1: public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { duke@1: JCSkip t = (JCSkip) node; duke@1: return M.at(t.pos).Skip(); duke@1: } duke@1: duke@1: public JCTree visitSwitch(SwitchTree node, P p) { duke@1: JCSwitch t = (JCSwitch) node; duke@1: JCExpression selector = copy(t.selector, p); duke@1: List cases = copy(t.cases, p); duke@1: return M.at(t.pos).Switch(selector, cases); duke@1: } duke@1: duke@1: public JCTree visitSynchronized(SynchronizedTree node, P p) { duke@1: JCSynchronized t = (JCSynchronized) node; duke@1: JCExpression lock = copy(t.lock, p); duke@1: JCBlock body = copy(t.body, p); duke@1: return M.at(t.pos).Synchronized(lock, body); duke@1: } duke@1: duke@1: public JCTree visitThrow(ThrowTree node, P p) { duke@1: JCThrow t = (JCThrow) node; duke@1: JCTree expr = copy(t.expr, p); duke@1: return M.at(t.pos).Throw(expr); duke@1: } duke@1: duke@1: public JCTree visitCompilationUnit(CompilationUnitTree node, P p) { duke@1: JCCompilationUnit t = (JCCompilationUnit) node; duke@1: List packageAnnotations = copy(t.packageAnnotations, p); duke@1: JCExpression pid = copy(t.pid, p); duke@1: List defs = copy(t.defs, p); duke@1: return M.at(t.pos).TopLevel(packageAnnotations, pid, defs); duke@1: } duke@1: duke@1: public JCTree visitTry(TryTree node, P p) { duke@1: JCTry t = (JCTry) node; darcy@609: List resources = copy(t.resources, p); duke@1: JCBlock body = copy(t.body, p); duke@1: List catchers = copy(t.catchers, p); duke@1: JCBlock finalizer = copy(t.finalizer, p); darcy@609: return M.at(t.pos).Try(resources, body, catchers, finalizer); duke@1: } duke@1: duke@1: public JCTree visitParameterizedType(ParameterizedTypeTree node, P p) { duke@1: JCTypeApply t = (JCTypeApply) node; duke@1: JCExpression clazz = copy(t.clazz, p); duke@1: List arguments = copy(t.arguments, p); duke@1: return M.at(t.pos).TypeApply(clazz, arguments); duke@1: } duke@1: darcy@969: public JCTree visitUnionType(UnionTypeTree node, P p) { darcy@969: JCTypeUnion t = (JCTypeUnion) node; jjg@724: List components = copy(t.alternatives, p); darcy@969: return M.at(t.pos).TypeUnion(components); mcimadamore@550: } mcimadamore@550: duke@1: public JCTree visitArrayType(ArrayTypeTree node, P p) { duke@1: JCArrayTypeTree t = (JCArrayTypeTree) node; duke@1: JCExpression elemtype = copy(t.elemtype, p); duke@1: return M.at(t.pos).TypeArray(elemtype); duke@1: } duke@1: duke@1: public JCTree visitTypeCast(TypeCastTree node, P p) { duke@1: JCTypeCast t = (JCTypeCast) node; duke@1: JCTree clazz = copy(t.clazz, p); duke@1: JCExpression expr = copy(t.expr, p); duke@1: return M.at(t.pos).TypeCast(clazz, expr); duke@1: } duke@1: duke@1: public JCTree visitPrimitiveType(PrimitiveTypeTree node, P p) { duke@1: JCPrimitiveTypeTree t = (JCPrimitiveTypeTree) node; duke@1: return M.at(t.pos).TypeIdent(t.typetag); duke@1: } duke@1: duke@1: public JCTree visitTypeParameter(TypeParameterTree node, P p) { duke@1: JCTypeParameter t = (JCTypeParameter) node; duke@1: List bounds = copy(t.bounds, p); jjg@815: return M.at(t.pos).TypeParameter(t.name, bounds); duke@1: } duke@1: duke@1: public JCTree visitInstanceOf(InstanceOfTree node, P p) { duke@1: JCInstanceOf t = (JCInstanceOf) node; duke@1: JCExpression expr = copy(t.expr, p); duke@1: JCTree clazz = copy(t.clazz, p); duke@1: return M.at(t.pos).TypeTest(expr, clazz); duke@1: } duke@1: duke@1: public JCTree visitUnary(UnaryTree node, P p) { duke@1: JCUnary t = (JCUnary) node; duke@1: JCExpression arg = copy(t.arg, p); duke@1: return M.at(t.pos).Unary(t.getTag(), arg); duke@1: } duke@1: duke@1: public JCTree visitVariable(VariableTree node, P p) { duke@1: JCVariableDecl t = (JCVariableDecl) node; duke@1: JCModifiers mods = copy(t.mods, p); duke@1: JCExpression vartype = copy(t.vartype, p); duke@1: JCExpression init = copy(t.init, p); duke@1: return M.at(t.pos).VarDef(mods, t.name, vartype, init); duke@1: } duke@1: duke@1: public JCTree visitWhileLoop(WhileLoopTree node, P p) { duke@1: JCWhileLoop t = (JCWhileLoop) node; duke@1: JCStatement body = copy(t.body, p); duke@1: JCExpression cond = copy(t.cond, p); duke@1: return M.at(t.pos).WhileLoop(cond, body); duke@1: } duke@1: duke@1: public JCTree visitWildcard(WildcardTree node, P p) { duke@1: JCWildcard t = (JCWildcard) node; duke@1: TypeBoundKind kind = M.at(t.kind.pos).TypeBoundKind(t.kind.kind); duke@1: JCTree inner = copy(t.inner, p); duke@1: return M.at(t.pos).Wildcard(kind, inner); duke@1: } duke@1: duke@1: public JCTree visitOther(Tree node, P p) { duke@1: JCTree tree = (JCTree) node; duke@1: switch (tree.getTag()) { duke@1: case JCTree.LETEXPR: { duke@1: LetExpr t = (LetExpr) node; duke@1: List defs = copy(t.defs, p); duke@1: JCTree expr = copy(t.expr, p); duke@1: return M.at(t.pos).LetExpr(defs, expr); duke@1: } duke@1: default: duke@1: throw new AssertionError("unknown tree tag: " + tree.getTag()); duke@1: } duke@1: } duke@1: duke@1: }