1 package annotator.find; 2 3 import com.sun.source.tree.MethodTree; 4 import com.sun.source.tree.Tree; 5 import com.sun.source.util.TreePath; 6 7 public class ReceiverCriterion implements Criterion { 8 9 private final String methodName; // no return type 10 private final Criterion isSigMethodCriterion; 11 ReceiverCriterion(String methodName)12 public ReceiverCriterion(String methodName) { 13 this.methodName = methodName; 14 isSigMethodCriterion = Criteria.isSigMethod(methodName); 15 } 16 17 /** {@inheritDoc} */ 18 @Override isSatisfiedBy(TreePath path, Tree leaf)19 public boolean isSatisfiedBy(TreePath path, Tree leaf) { 20 assert path == null || path.getLeaf() == leaf; 21 return isSatisfiedBy(path); 22 } 23 24 /** {@inheritDoc} */ 25 @Override isSatisfiedBy(TreePath path)26 public boolean isSatisfiedBy(TreePath path) { 27 // want to annotate BlockTree returned by MethodTree.getBody(); 28 if (path == null) { 29 return false; 30 } 31 32 if (path.getLeaf().getKind() == Tree.Kind.METHOD) { 33 if (isSigMethodCriterion.isSatisfiedBy(path)) { 34 MethodTree leaf = (MethodTree) path.getLeaf(); 35 // If the method already has a receiver, then insert directly on the 36 // receiver, not on the method. 37 return leaf.getReceiverParameter() == null; 38 } 39 return false; 40 } else { 41 // We may be attempting to insert an annotation on a type parameter of an 42 // existing receiver, so make sure this is the right receiver parameter: 43 // work up the tree to find the method declaration. Store the parameter we 44 // pass through up to the method declaration so we can make sure we came up 45 // through the receiver. Then check to make sure this is the correct method 46 // declaration. 47 Tree param = null; 48 TreePath parent = path; 49 while (parent != null && parent.getLeaf().getKind() != Tree.Kind.METHOD) { 50 if (parent.getLeaf().getKind() == Tree.Kind.VARIABLE) { 51 if (param == null) { 52 param = parent.getLeaf(); 53 } else { 54 // The only variable we should pass through is the receiver parameter. 55 // If we pass through more than one then this isn't the right place. 56 return false; 57 } 58 } 59 parent = parent.getParentPath(); 60 } 61 if (parent != null && param != null) { 62 MethodTree method = (MethodTree) parent.getLeaf(); 63 if (param == method.getReceiverParameter()) { 64 return isSigMethodCriterion.isSatisfiedBy(parent); 65 } 66 } 67 return false; 68 } 69 } 70 71 @Override getKind()72 public Kind getKind() { 73 return Kind.RECEIVER; 74 } 75 76 @Override toString()77 public String toString() { 78 return "ReceiverCriterion for method: " + methodName; 79 } 80 } 81