Home | History | Annotate | Download | only in find
      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 
     12   public ReceiverCriterion(String methodName) {
     13     this.methodName = methodName;
     14     isSigMethodCriterion = Criteria.isSigMethod(methodName);
     15   }
     16 
     17   /** {@inheritDoc} */
     18   @Override
     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
     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
     72   public Kind getKind() {
     73     return Kind.RECEIVER;
     74   }
     75 
     76   @Override
     77   public String toString() {
     78     return "ReceiverCriterion for method: " + methodName;
     79   }
     80 }
     81