blob: 4bb768285da2cc78aef2e4a092ffe1792e057d38 [file] [log] [blame]
package org.checkerframework.framework.type.treeannotator;
import com.sun.source.tree.BinaryTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.SimpleTreeVisitor;
import org.checkerframework.framework.type.AnnotatedTypeFactory;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
/**
* {@link TreeAnnotator} is an abstract SimpleTreeVisitor to be used with {@link ListTreeAnnotator}.
*
* <p>This class does not visit component parts of the tree. By default, the visit methods all call
* {@link #defaultAction(Tree, Object)}, which does nothing unless overriden. Therefore, subclass do
* not need to call super unless they override {@link #defaultAction(Tree, Object)}.
*
* @see ListTreeAnnotator
* @see PropagationTreeAnnotator
* @see LiteralTreeAnnotator
*/
public abstract class TreeAnnotator extends SimpleTreeVisitor<Void, AnnotatedTypeMirror> {
protected final AnnotatedTypeFactory atypeFactory;
protected TreeAnnotator(AnnotatedTypeFactory atypeFactory) {
this.atypeFactory = atypeFactory;
}
/**
* This method is not called when checking a method invocation against its declaration. So,
* instead of overriding this method, override TypeAnnotator.visitExecutable.
* TypeAnnotator.visitExecutable is called both when checking method declarations and method
* invocations.
*
* @see org.checkerframework.framework.type.typeannotator.TypeAnnotator
*/
@Override
public Void visitMethod(MethodTree node, AnnotatedTypeMirror p) {
return super.visitMethod(node, p);
}
/**
* When overriding this method, getAnnotatedType on the left and right operands should only be
* called when absolutely necessary. Otherwise, the checker will be very slow on heavily nested
* binary trees. (For example, a + b + c + d + e + f + g + h.)
*
* <p>If a checker's performance is still too slow, the types of binary trees could be computed in
* a subclass of {@link org.checkerframework.framework.flow.CFTransfer}. When computing the types
* in a transfer, look up the value in the store rather than the AnnotatedTypeFactory. Then this
* method should annotate binary trees with top so that the type applied in the transfer is always
* a subtype of the type the AnnotatedTypeFactory computes.
*/
@Override
public Void visitBinary(BinaryTree node, AnnotatedTypeMirror mirror) {
return super.visitBinary(node, mirror);
}
}