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

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

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