package de.skuzzle.polly.core.parser.ast.visitor; import de.skuzzle.polly.core.parser.ast.Identifier; 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.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.Problem; import de.skuzzle.polly.core.parser.ast.expressions.VarAccess; import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.ListLiteral; import de.skuzzle.polly.core.parser.ast.expressions.literals.Literal; import de.skuzzle.polly.core.parser.ast.expressions.literals.ProductLiteral; /** * {@link ASTVisitor} implementation that traverses the AST in depth-first order. * Implementation of <code>beforeXY</code> and <code>afterXY</code> methods is empty and * may be overridden by sub classes. * * @author Simon Taddiken */ public class DepthFirstVisitor extends VisitorAdapter { @Override public boolean visit(Root node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } for (final Expression exp : node.getExpressions()) { if (!exp.visit(this)) { return false; } } for (final Directive dir : node.getDirectives().values()) { if (!dir.visit(this)) { return false; } } return this.after(node) == CONTINUE; } @Override public boolean visit(Literal node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Identifier node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(ResolvableIdentifier node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Assignment node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getExpression().visit(this)) { return false; } if (!node.getName().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Declaration node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Call node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getLhs().visit(this)) { return false; } if (!node.getRhs().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Native node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Problem problem) throws ASTTraversalException { return this.before(problem) == CONTINUE && this.after(problem) == CONTINUE; } @Override public boolean visit(NamespaceAccess node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getLhs().visit(this)) { return false; } if (!node.getRhs().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(VarAccess node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getIdentifier().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(FunctionLiteral node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } for (final Declaration d : node.getFormal()) { if (!d.visit(this)) { return false; } } if (!node.getBody().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(ListLiteral node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } for (final Expression exp : node.getContent()) { if (!exp.visit(this)) { return false; } } return this.after(node) == CONTINUE; } @Override public boolean visit(ProductLiteral node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } for (final Expression exp : node.getContent()) { if (!exp.visit(this)) { return false; } } return this.after(node) == CONTINUE; } @Override public boolean visit(OperatorCall node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getLhs().visit(this)) { return false; } if (!node.getRhs().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Braced node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getExpression().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(Delete node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } for (final Identifier id : node.getIdentifiers()) { if (!id.visit(this)) { return false; } } return this.after(node) == CONTINUE; } @Override public boolean visit(Inspect node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getAccess().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(DelayDirective node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } if (!node.getTargetTime().visit(this)) { return false; } return this.after(node) == CONTINUE; } @Override public boolean visit(ProblemDirective node) throws ASTTraversalException { switch (this.before(node)) { case SKIP: return true; case ABORT: return false; } return this.after(node) == CONTINUE; } }