| package annotator.find; |
| |
| import com.sun.source.tree.MethodTree; |
| import com.sun.source.tree.Tree; |
| import com.sun.source.util.TreePath; |
| |
| public class ReceiverCriterion implements Criterion { |
| |
| private final String methodName; // no return type |
| private final Criterion isSigMethodCriterion; |
| |
| public ReceiverCriterion(String methodName) { |
| this.methodName = methodName; |
| isSigMethodCriterion = Criteria.isSigMethod(methodName); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| public boolean isSatisfiedBy(TreePath path, Tree leaf) { |
| assert path == null || path.getLeaf() == leaf; |
| return isSatisfiedBy(path); |
| } |
| |
| /** {@inheritDoc} */ |
| @Override |
| public boolean isSatisfiedBy(TreePath path) { |
| // want to annotate BlockTree returned by MethodTree.getBody(); |
| if (path == null) { |
| return false; |
| } |
| |
| if (path.getLeaf().getKind() == Tree.Kind.METHOD) { |
| if (isSigMethodCriterion.isSatisfiedBy(path)) { |
| MethodTree leaf = (MethodTree) path.getLeaf(); |
| // If the method already has a receiver, then insert directly on the |
| // receiver, not on the method. |
| return leaf.getReceiverParameter() == null; |
| } |
| return false; |
| } else { |
| // We may be attempting to insert an annotation on a type parameter of an |
| // existing receiver, so make sure this is the right receiver parameter: |
| // work up the tree to find the method declaration. Store the parameter we |
| // pass through up to the method declaration so we can make sure we came up |
| // through the receiver. Then check to make sure this is the correct method |
| // declaration. |
| Tree param = null; |
| TreePath parent = path; |
| while (parent != null && parent.getLeaf().getKind() != Tree.Kind.METHOD) { |
| if (parent.getLeaf().getKind() == Tree.Kind.VARIABLE) { |
| if (param == null) { |
| param = parent.getLeaf(); |
| } else { |
| // The only variable we should pass through is the receiver parameter. |
| // If we pass through more than one then this isn't the right place. |
| return false; |
| } |
| } |
| parent = parent.getParentPath(); |
| } |
| if (parent != null && param != null) { |
| MethodTree method = (MethodTree) parent.getLeaf(); |
| if (param == method.getReceiverParameter()) { |
| return isSigMethodCriterion.isSatisfiedBy(parent); |
| } |
| } |
| return false; |
| } |
| } |
| |
| @Override |
| public Kind getKind() { |
| return Kind.RECEIVER; |
| } |
| |
| @Override |
| public String toString() { |
| return "ReceiverCriterion for method: " + methodName; |
| } |
| } |