/*
* Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package org.visage.tools.tree;
import com.sun.tools.mjavac.tree.JCTree;
import com.sun.tools.mjavac.util.List;
import com.sun.tools.mjavac.util.ListBuffer;
import com.sun.tools.mjavac.util.Name;
import java.util.Map;
/**
* Creates a copy of a tree, using a given TreeMaker.
* Names, literal values, etc are shared with the original.
*
* @author tball
*/
public class VisageTreeCopier implements VisageVisitor {
protected VisageTreeMaker maker;
protected VisageTree result;
public Map<JCTree, Integer> endPositions;
/** Creates a new instance of TreeCopier */
public VisageTreeCopier(VisageTreeMaker maker) {
this.maker = maker;
}
@SuppressWarnings("unchecked")
public <T extends VisageTree> T copy(T tree) {
if (tree == null)
return null;
tree.accept(this);
// Update the end positions map, we keep the prior object
// in there in case others have references to them.
//
Integer endpos = endPositions.get(tree);
endPositions.put(result, endpos);
return (T)result;
}
public <T extends VisageTree> List<T> copy(List<T> trees) {
if (trees == null)
return null;
ListBuffer<T> lb = new ListBuffer<T>();
for (T tree: trees)
lb.append(copy(tree));
return lb.toList();
}
public void visitScript(VisageScript tree) {
VisageExpression pid = copy(tree.pid);
List<VisageTree> defs = copy(tree.defs);
result = maker.at(tree.pos).Script(pid, defs);
}
public void visitImport(VisageImport tree) {
VisageExpression qualid = copy(tree.qualid);
result = maker.at(tree.pos).Import(qualid);
}
public void visitSkip(VisageSkip tree) {
result = maker.at(tree.pos).Skip();
}
public void visitWhileLoop(VisageWhileLoop tree) {
VisageExpression cond = copy(tree.cond);
VisageExpression body = copy(tree.body);
result = maker.at(tree.pos).WhileLoop(cond, body);
}
public void visitTry(VisageTry tree) {
VisageBlock body = copy(tree.body);
List<VisageCatch> catchers = copy(tree.catchers);
VisageBlock finalizer = copy(tree.finalizer);
result = maker.at(tree.pos).Try(body, catchers, finalizer);
}
public void visitCatch(VisageCatch tree) {
VisageVar param = copy(tree.param);
VisageBlock body = copy(tree.body);
result = maker.at(tree.pos).Catch(param, body);
}
public void visitIfExpression(VisageIfExpression tree) {
VisageExpression cond = copy(tree.cond);
VisageExpression truepart = copy(tree.truepart);
VisageExpression falsepart = copy(tree.falsepart);
result = maker.at(tree.pos).Conditional(cond, truepart, falsepart);
}
public void visitBreak(VisageBreak tree) {
result = maker.at(tree.pos).Break(tree.label);
}
public void visitContinue(VisageContinue tree) {
result = maker.at(tree.pos).Continue(tree.label);
}
public void visitReturn(VisageReturn tree) {
VisageExpression expr = copy(tree.expr);
result = maker.at(tree.pos).Return(expr);
}
public void visitThrow(VisageThrow tree) {
VisageExpression expr = copy(tree.expr);
result = maker.at(tree.pos).Throw(expr);
}
public void visitFunctionInvocation(VisageFunctionInvocation tree) {
List<VisageExpression> typeargs = copy(tree.typeargs);
VisageExpression fn = copy(tree.meth);
List<VisageExpression> args = copy(tree.args);
result = maker.at(tree.pos).Apply(typeargs, fn, args);
}
public void visitParens(VisageParens tree) {
VisageExpression expr = copy(tree.expr);
result = maker.at(tree.pos).Parens(expr);
}
public void visitAssign(VisageAssign tree) {
VisageExpression lhs = copy(tree.lhs);
VisageExpression rhs = copy(tree.rhs);
result = maker.at(tree.pos).Assign(lhs, rhs);
}
public void visitAssignop(VisageAssignOp tree) {
VisageExpression lhs = copy(tree.lhs);
VisageExpression rhs = copy(tree.rhs);
VisageTag tag = tree.getVisageTag();
result = maker.at(tree.pos).Assignop(tag, lhs, rhs);
}
public void visitUnary(VisageUnary tree) {
VisageExpression arg = copy(tree.arg);
VisageTag tag = tree.getVisageTag();
result = maker.at(tree.pos).Unary(tag, arg);
}
public void visitBinary(VisageBinary tree) {
VisageExpression lhs = copy(tree.lhs);
VisageExpression rhs = copy(tree.rhs);
VisageTag tag = tree.getVisageTag();
result = maker.at(tree.pos).Binary(tag, lhs, rhs);
}
public void visitTypeCast(VisageTypeCast tree) {
VisageTree clazz = copy(tree.clazz);
VisageExpression expr = copy(tree.expr);
result = maker.at(tree.pos).TypeCast(clazz, expr);
}
public void visitInstanceOf(VisageInstanceOf tree) {
VisageExpression expr = copy(tree.expr);
VisageTree clazz = copy(tree.clazz);
result = maker.at(tree.pos).TypeTest(expr, clazz);
}
public void visitSelect(VisageSelect tree) {
VisageExpression selected = copy(tree.selected);
result = maker.at(tree.pos).Select(selected, tree.name, tree.nullCheck);
}
public void visitIdent(VisageIdent tree) {
result = maker.at(tree.pos).Ident(tree.getName());
}
public void visitLiteral(VisageLiteral tree) {
result = maker.at(tree.pos).Literal(tree.typetag, tree.value);
}
public void visitModifiers(VisageModifiers tree) {
result = maker.at(tree.pos).Modifiers(tree.flags);
}
public void visitErroneous(VisageErroneous tree) {
List<? extends VisageTree> errs = copy(tree.getErrorTrees());
result = maker.at(tree.pos).Erroneous(errs);
}
public void visitClassDeclaration(VisageClassDeclaration tree) {
VisageModifiers mods = copy(tree.mods);
Name name = tree.getName();
List<VisageExpression> supertypes = copy(tree.getSupertypes());
List<VisageTree> defs = copy(tree.getMembers());
result = maker.at(tree.pos).ClassDeclaration(mods, name, supertypes, defs);
}
public void visitFunctionDefinition(VisageFunctionDefinition tree) {
VisageModifiers mods = copy(tree.mods);
Name name = tree.getName();
VisageType restype = copy(tree.getVisageReturnType());
List<VisageVar> params = copy(tree.getParams());
VisageBlock bodyExpression = copy(tree.getBodyExpression());
result = maker.at(tree.pos).FunctionDefinition(mods, name, restype, params, bodyExpression);
}
public void visitInitDefinition(VisageInitDefinition tree) {
VisageBlock body = tree.body;
result = maker.at(tree.pos).InitDefinition(body);
}
public void visitPostInitDefinition(VisagePostInitDefinition tree) {
VisageBlock body = tree.body;
result = maker.at(tree.pos).PostInitDefinition(body);
}
public void visitStringExpression(VisageStringExpression tree) {
List<VisageExpression> parts = copy(tree.parts);
result = maker.at(tree.pos).StringExpression(parts, tree.translationKey);
}
public void visitInstanciate(VisageInstanciate tree) {
VisageExpression clazz = copy(tree.getIdentifier());
VisageClassDeclaration def = copy(tree.getClassBody());
List<VisageExpression> args = copy(tree.getArgs());
List<VisageObjectLiteralPart> parts = copy(tree.getParts());
List<VisageVar> localVars = copy(tree.getLocalvars());
result = maker.at(tree.pos).Instanciate(tree.getVisageKind(), clazz, def, args, parts, localVars);
}
public void visitObjectLiteralPart(VisageObjectLiteralPart tree) {
VisageExpression expr = copy(tree.getExpression());
VisageObjectLiteralPart res = maker.at(tree.pos).ObjectLiteralPart(tree.name, expr, tree.getExplicitBindStatus());
res.markBound(tree.getBindStatus());
result = res;
}
public void visitTypeAny(VisageTypeAny tree) {
result = maker.at(tree.pos).TypeAny(tree.getCardinality());
}
public void visitTypeClass(VisageTypeClass tree) {
VisageExpression clazz = copy(tree.getClassName());
result = maker.at(tree.pos).TypeClass(clazz, tree.getCardinality());
}
public void visitTypeFunctional(VisageTypeFunctional tree) {
List<VisageType> params = copy(tree.getParams());
VisageType restype = copy(tree.restype);
result = maker.at(tree.pos).TypeFunctional(params, restype, tree.getCardinality());
}
//@Override
public void visitTypeArray(VisageTypeArray tree) {
VisageType elementType = copy(tree.getElementType());
result = maker.at(tree.pos).TypeArray(elementType);
}
public void visitTypeUnknown(VisageTypeUnknown tree) {
result = maker.at(tree.pos).TypeUnknown();
}
//@Override
public void visitVarInit(VisageVarInit tree) {
}
//@Override
public void visitVarRef(VisageVarRef tree) {
result = maker.at(tree.pos).VarRef(tree.getExpression(), tree.getVarRefKind());
}
public void visitVar(VisageVar tree) {
Name name = tree.name;
VisageType type = copy(tree.getVisageType());
VisageModifiers mods = copy(tree.getModifiers());
VisageExpression init = copy(tree.getInitializer());
VisageOnReplace onReplace = copy(tree.getOnReplace());
VisageOnReplace onInvalidate = copy(tree.getOnInvalidate());
result = maker.at(tree.pos).Var(name, type, mods,
init, tree.getBindStatus(), onReplace, onInvalidate);
}
public void visitOnReplace(VisageOnReplace tree) {
VisageVar oldValue = copy(tree.getOldValue());
VisageVar firstIndex = copy(tree.getFirstIndex());
VisageVar lastIndex = copy(tree.getLastIndex());
VisageVar newElements = copy(tree.getNewElements());
VisageBlock body = copy(tree.getBody());
result = maker.at(tree.pos).OnReplace(oldValue, firstIndex, lastIndex, tree.getEndKind(), newElements, body);
}
public void visitBlockExpression(VisageBlock tree) {
List<VisageExpression> stats = copy(tree.stats);
VisageExpression value = copy(tree.value);
result = maker.at(tree.pos).Block(tree.flags, stats, value);
}
public void visitFunctionValue(VisageFunctionValue tree) {
VisageType restype = copy(tree.rettype);
List<VisageVar> params = copy(tree.getParams());
VisageBlock bodyExpression = copy(tree.bodyExpression);
result = maker.at(tree.pos).FunctionValue(restype, params, bodyExpression);
}
public void visitSequenceEmpty(VisageSequenceEmpty tree) {
result = maker.at(tree.pos).EmptySequence();
}
public void visitSequenceRange(VisageSequenceRange tree) {
VisageExpression lower = copy(tree.getLower());
VisageExpression upper = copy(tree.getUpper());
VisageExpression stepOrNull = copy(tree.getStepOrNull());
result = maker.at(tree.pos).RangeSequence(lower, upper, stepOrNull, tree.isExclusive());
}
public void visitSequenceExplicit(VisageSequenceExplicit tree) {
List<VisageExpression> items = copy(tree.getItems());
result = maker.at(tree.pos).ExplicitSequence(items);
}
public void visitSequenceIndexed(VisageSequenceIndexed tree) {
VisageExpression sequence = copy(tree.getSequence());
VisageExpression index = copy(tree.getIndex());
result = maker.at(tree.pos).SequenceIndexed(sequence, index);
}
public void visitSequenceSlice(VisageSequenceSlice tree) {
VisageExpression sequence = copy(tree.getSequence());
VisageExpression firstIndex = copy(tree.getFirstIndex());
VisageExpression lastIndex = copy(tree.getLastIndex());
result = maker.at(tree.pos).SequenceSlice(sequence, firstIndex, lastIndex, tree.getEndKind());
}
public void visitSequenceInsert(VisageSequenceInsert tree) {
VisageExpression sequence = copy(tree.getSequence());
VisageExpression element = copy(tree.getElement());
VisageExpression position = copy(tree.getPosition());
result = maker.at(tree.pos).SequenceInsert(sequence, element, position, tree.shouldInsertAfter());
}
public void visitSequenceDelete(VisageSequenceDelete tree) {
VisageExpression sequence = copy(tree.getSequence());
VisageExpression element = copy(tree.getElement());
result = maker.at(tree.pos).SequenceDelete(sequence, element);
}
public void visitInvalidate(VisageInvalidate tree) {
VisageExpression variable = copy(tree.getVariable());
result = maker.at(tree.pos).Invalidate(variable);
}
public void visitForExpression(VisageForExpression tree) {
List<VisageForExpressionInClause> inClauses = copy(tree.inClauses);
VisageExpression bodyExpr = copy(tree.bodyExpr);
result = maker.at(tree.pos).ForExpression(inClauses, bodyExpr);
}
public void visitForExpressionInClause(VisageForExpressionInClause tree) {
tree.seqExpr = copy(tree.seqExpr);
tree.setWhereExpr(copy(tree.getWhereExpression()));
result = tree;
}
public void visitIndexof(VisageIndexof tree) {
result = maker.at(tree.pos).Indexof(tree.fname);
}
public void visitTimeLiteral(VisageTimeLiteral tree) {
VisageLiteral literal = copy(tree.value);
result = maker.at(tree.pos).TimeLiteral(literal, tree.duration);
}
public void visitLengthLiteral(VisageLengthLiteral tree) {
VisageLiteral literal = copy(tree.value);
result = maker.at(tree.pos).LengthLiteral(literal, tree.units);
}
public void visitAngleLiteral(VisageAngleLiteral tree) {
VisageLiteral literal = copy(tree.value);
result = maker.at(tree.pos).AngleLiteral(literal, tree.units);
}
public void visitColorLiteral(VisageColorLiteral tree) {
VisageLiteral literal = copy(tree.value);
result = maker.at(tree.pos).ColorLiteral(literal);
}
public void visitOverrideClassVar(VisageOverrideClassVar tree) {
Name name = tree.getName();
VisageModifiers mods = copy(tree.getModifiers());
VisageIdent expr = copy(tree.getId());
VisageType visagetype = copy(tree.getVisageType());
VisageExpression initializer = copy(tree.getInitializer());
VisageOnReplace onReplace = copy(tree.getOnReplace());
VisageOnReplace onInvalidate = copy(tree.getOnInvalidate());
result = maker.at(tree.pos).OverrideClassVar(name, visagetype, mods, expr, initializer, tree.getBindStatus(), onReplace, onInvalidate);
}
public void visitInterpolateValue(VisageInterpolateValue tree) {
VisageExpression attr = copy(tree.attribute);
VisageExpression value = copy(tree.value);
VisageExpression interpolation = copy(tree.interpolation);
result = maker.at(tree.pos).InterpolateValue(attr, value, interpolation);
}
public void visitKeyFrameLiteral(VisageKeyFrameLiteral tree) {
VisageExpression start = copy(tree.start);
List<VisageExpression> values = copy(tree.values);
VisageExpression trigger = copy(tree.trigger);
result = maker.at(tree.pos).KeyFrameLiteral(start, values, trigger);
}
}