package de.skuzzle.polly.core.parser.ast.visitor; import java.util.ArrayList; import java.util.Collection; import java.util.List; import de.skuzzle.polly.core.parser.ast.Identifier; import de.skuzzle.polly.core.parser.ast.Node; import de.skuzzle.polly.core.parser.ast.ResolvableIdentifier; import de.skuzzle.polly.core.parser.ast.Root; import de.skuzzle.polly.core.parser.ast.declarations.Declaration; import de.skuzzle.polly.core.parser.ast.directives.DelayDirective; import de.skuzzle.polly.core.parser.ast.directives.Directive; import de.skuzzle.polly.core.parser.ast.directives.ProblemDirective; import de.skuzzle.polly.core.parser.ast.expressions.Assignment; import de.skuzzle.polly.core.parser.ast.expressions.Braced; import de.skuzzle.polly.core.parser.ast.expressions.Call; import de.skuzzle.polly.core.parser.ast.expressions.Delete; import de.skuzzle.polly.core.parser.ast.expressions.Delete.DeleteableIdentifier; import de.skuzzle.polly.core.parser.ast.expressions.Expression; import de.skuzzle.polly.core.parser.ast.expressions.Inspect; import de.skuzzle.polly.core.parser.ast.expressions.NamespaceAccess; import de.skuzzle.polly.core.parser.ast.expressions.Native; import de.skuzzle.polly.core.parser.ast.expressions.OperatorCall; import de.skuzzle.polly.core.parser.ast.expressions.VarAccess; import de.skuzzle.polly.core.parser.ast.expressions.literals.BooleanLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ChannelLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.DateLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.HelpLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ListLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.NumberLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ProductLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.StringLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.TimespanLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.UserLiteral; public class CopyTransformation implements Transformation { @SuppressWarnings("unchecked") private final <T extends Node> List<T> transformList(Collection<T> nodes) throws ASTTraversalException { final List<T> result = new ArrayList<T>(nodes.size()); for (final T node : nodes) { result.add((T) node.transform(this)); } return result; } private <T extends Expression> T applyTypes(Expression source, T copy) { copy.setUnique(source.getUnique()); copy.setTypes(source.getTypes()); return copy; } @Override public Identifier transformIdentifier(Identifier node) throws ASTTraversalException { return new Identifier(node.getPosition(), node.getId()); } @Override public Root transformRoot(Root node) throws ASTTraversalException { return new Root(node.getPosition(), node.getCommand().transform(this), this.transformList(node.getExpressions()), node.hasProblems(), node.getDirectives()); // HACK: directives not copied! } @Override public Declaration transformDeclaration(Declaration node) throws ASTTraversalException { final Declaration result = new Declaration(node.getPosition(), node.getName() .transform(this), node.getExpression().transform(this)); result.setNative(node.isNative()); result.setPublic(result.isPublic()); return result; } @Override public Expression transformAssignment(Assignment node) throws ASTTraversalException { return this.applyTypes(node, new Assignment( node.getPosition(), node.getExpression().transform(this), node.getName().transform(this), node.isPublic(), node.isTemp())); } @Override public Expression transformBraced(Braced node) throws ASTTraversalException { return this.applyTypes(node, new Braced(node.getPosition(), node.getExpression().transform(this))); } @Override public Expression transformCall(Call node) throws ASTTraversalException { return this.applyTypes(node, new Call( node.getPosition(), node.getLhs().transform(this), node.getRhs().transform(this))); } @Override public Expression transformDelete(Delete node) throws ASTTraversalException { return this.applyTypes(node, new Delete(node.getPosition(), this.transformList(node.getIdentifiers()))); } @Override public Expression transformAccess(NamespaceAccess node) throws ASTTraversalException { return this.applyTypes(node, new NamespaceAccess( node.getPosition(), node.getLhs().transform(this), node.getRhs().transform(this))); } @Override public Expression transformNative(Native node) throws ASTTraversalException { // XXX: native nodes are not copied return node; } @Override public Expression transformOperatorCall(OperatorCall node) throws ASTTraversalException { return this.applyTypes(node, new OperatorCall( node.getPosition(), node.getOperator(), node.getRhs().transform(this).getContent(), node.isPostfix())); } @Override public Expression transformVarAccess(VarAccess node) throws ASTTraversalException { return this.applyTypes(node, new VarAccess( node.getPosition(), node.getIdentifier().transform(this))); } @Override public Expression transformBoolean(BooleanLiteral node) { return new BooleanLiteral(node.getPosition(), node.getValue()); } @Override public Expression transformString(ChannelLiteral node) throws ASTTraversalException { return new ChannelLiteral(node.getPosition(), node.getValue()); } @Override public Expression transformDate(DateLiteral node) throws ASTTraversalException { return new DateLiteral(node.getPosition(), node.getValue()); } @Override public Expression transformFunction(FunctionLiteral node) throws ASTTraversalException { return this.applyTypes(node, new FunctionLiteral( node.getPosition(), this.transformList(node.getFormal()), node.getBody().transform(this))); } @Override public Expression transformList(ListLiteral node) throws ASTTraversalException { return this.applyTypes(node, new ListLiteral( node.getPosition(), this.transformList(node.getContent()), node.getUnique())); } @Override public Expression transformNumber(NumberLiteral node) throws ASTTraversalException { return new NumberLiteral(node.getPosition(), node.getValue()); } @Override public ProductLiteral transformProduct(ProductLiteral node) throws ASTTraversalException { return this.applyTypes(node, new ProductLiteral( node.getPosition(), this.transformList(node.getContent()))); } @Override public Expression transformString(StringLiteral node) throws ASTTraversalException { return new StringLiteral(node.getPosition(), node.getValue()); } @Override public Expression transformTimeSpan(TimespanLiteral node) throws ASTTraversalException { return new TimespanLiteral(node.getPosition(), node.getSeconds()); } @Override public Expression transformUser(UserLiteral node) throws ASTTraversalException { return new UserLiteral(node.getPosition(), node.getValue()); } @Override public HelpLiteral transformHelp(HelpLiteral node) { return new HelpLiteral(node.getPosition()); } @Override public Inspect transformInspect(Inspect node) throws ASTTraversalException { return new Inspect(node.getPosition(), node.getAccess().transform(this), node.isGlobal()); } @Override public ResolvableIdentifier transformIdentifier(ResolvableIdentifier node) throws ASTTraversalException { return new ResolvableIdentifier(node.getPosition(), node.getId(), node.wasEscaped()); } @Override public DeleteableIdentifier transformIdentifier(DeleteableIdentifier node) { return new DeleteableIdentifier(node, node.isGlobal()); } @Override public Directive transform(DelayDirective node) throws ASTTraversalException { return new DelayDirective(node.getPosition(), node.getTargetTime().transform(this)); } @Override public Directive transform(ProblemDirective node) throws ASTTraversalException { return new ProblemDirective(node.getPosition()); } }