package org.checkerframework.framework.source;
/*>>>
import org.checkerframework.checker.nullness.qual.*;
*/
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreePathScanner;
import com.sun.source.util.Trees;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import org.checkerframework.javacutil.ErrorReporter;
/**
* An AST visitor that provides a variety of compiler utilities and interfaces to facilitate
* type-checking.
*/
public abstract class SourceVisitor<R, P> extends TreePathScanner<R, P> {
/** The {@link Trees} instance to use for scanning. */
protected final Trees trees;
/** The {@link Elements} helper to use when scanning. */
protected final Elements elements;
/** The {@link Types} helper to use when scanning. */
protected final Types types;
/** The root of the AST that this {@link SourceVisitor} will scan. */
protected CompilationUnitTree root;
/**
* Creates a {@link SourceVisitor} to use for scanning a source tree.
*
* @param checker the checker to invoke on the input source tree
*/
public SourceVisitor(SourceChecker checker) {
// Use the checker's processing environment to get the helpers we need.
ProcessingEnvironment env = checker.getProcessingEnvironment();
this.trees = Trees.instance(env);
this.elements = env.getElementUtils();
this.types = env.getTypeUtils();
// Install the SourceChecker as the error handler
// TODO: having this static state is ugly. Use the context to instantiate.
ErrorReporter.setHandler(checker);
}
/*
* Set the CompilationUnitTree to be used during any visits.
* For any later calls of {@see com.sun.source.util.TreePathScanner.scan(TreePath, P)},
* the CompilationUnitTree of the TreePath has to be equal to {@code root}.
*/
public void setRoot(CompilationUnitTree root) {
this.root = root;
}
/*
* Entry point for a type processor: the TreePath leaf is
* a top-level type tree within root.
*/
public void visit(TreePath path) {
this.scan(path, null);
}
}