blob: c0d740515334693a5e21b02a6a6d9e9d9873dad7 [file] [log] [blame]
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.syntax;
import java.util.List;
/** A visitor for visiting the nodes of a syntax tree in lexical order. */
public class NodeVisitor {
public void visit(Node node) {
// dispatch to the node specific method
node.accept(this);
}
// methods dealing with sequences of nodes
public void visitAll(List<? extends Node> nodes) {
for (Node node : nodes) {
visit(node);
}
}
/**
* Visit a sequence ("block") of statements (e.g. an if branch, for block, function block etc.)
*
* This method allows subclasses to handle statement blocks more easily, like doing an action
* after every statement in a block without having to override visit(...) for all statements.
*
* @param statements list of statements in the block
*/
public void visitBlock(List<Statement> statements) {
visitAll(statements);
}
// node-specific visit methods
// All four subclasses of Argument are handled together.
public void visit(Argument node) {
visit(node.getValue());
}
// All four subclasses of Parameter are handled together.
public void visit(Parameter node) {
visit(node.getIdentifier());
if (node.getDefaultValue() != null) {
visit(node.getDefaultValue());
}
}
public void visit(StarlarkFile node) {
visitBlock(node.getStatements());
visitAll(node.getComments());
}
public void visit(BinaryOperatorExpression node) {
visit(node.getX());
visit(node.getY());
}
public void visit(CallExpression node) {
visit(node.getFunction());
visitAll(node.getArguments());
}
public void visit(@SuppressWarnings("unused") Identifier node) {}
public void visit(Comprehension node) {
for (Comprehension.Clause clause : node.getClauses()) {
if (clause instanceof Comprehension.For) {
Comprehension.For forClause = (Comprehension.For) clause;
visit(forClause.getVars());
visit(forClause.getIterable());
} else {
Comprehension.If ifClause = (Comprehension.If) clause;
visit(ifClause.getCondition());
}
}
visit(node.getBody());
}
public void visit(ForStatement node) {
visit(node.getCollection());
visit(node.getLHS());
visitBlock(node.getBlock());
}
public void visit(LoadStatement node) {
for (LoadStatement.Binding binding : node.getBindings()) {
visit(binding.getLocalName());
}
}
public void visit(ListExpression node) {
visitAll(node.getElements());
}
public void visit(@SuppressWarnings("unused") IntegerLiteral node) {}
public void visit(@SuppressWarnings("unused") StringLiteral node) {}
public void visit(AssignmentStatement node) {
visit(node.getRHS());
visit(node.getLHS());
}
public void visit(ExpressionStatement node) {
visit(node.getExpression());
}
public void visit(IfStatement node) {
visit(node.getCondition());
visitBlock(node.getThenBlock());
if (node.getElseBlock() != null) {
visitBlock(node.getElseBlock());
}
}
public void visit(DefStatement node) {
visit(node.getIdentifier());
visitAll(node.getParameters());
visitBlock(node.getStatements());
}
public void visit(ReturnStatement node) {
if (node.getReturnExpression() != null) {
visit(node.getReturnExpression());
}
}
public void visit(FlowStatement node) {}
public void visit(DictExpression node) {
visitAll(node.getEntries());
}
public void visit(DictExpression.Entry node) {
visit(node.getKey());
visit(node.getValue());
}
public void visit(UnaryOperatorExpression node) {
visit(node.getX());
}
public void visit(DotExpression node) {
visit(node.getObject());
visit(node.getField());
}
public void visit(IndexExpression node) {
visit(node.getObject());
visit(node.getKey());
}
public void visit(SliceExpression node) {
visit(node.getObject());
if (node.getStart() != null) {
visit(node.getStart());
}
if (node.getStop() != null) {
visit(node.getStop());
}
if (node.getStep() != null) {
visit(node.getStep());
}
}
public void visit(@SuppressWarnings("unused") Comment node) {}
public void visit(ConditionalExpression node) {
visit(node.getCondition());
visit(node.getThenCase());
if (node.getElseCase() != null) {
visit(node.getElseCase());
}
}
}