• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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