Home | History | Annotate | Download | only in find
      1 package annotator.find;
      2 
      3 import annotations.el.RelativeLocation;
      4 import annotator.scanner.NewScanner;
      5 
      6 import com.sun.source.tree.Tree;
      7 import com.sun.source.util.TreePath;
      8 
      9 /**
     10  * Criterion for being a specific object creation expression.
     11  */
     12 public class NewCriterion implements Criterion {
     13 
     14   private final String methodName;
     15   private final Criterion inMethodCriterion;
     16 
     17   private final RelativeLocation loc;
     18 
     19   public NewCriterion(String methodName, RelativeLocation loc) {
     20     this.methodName = methodName.substring(0, methodName.lastIndexOf(")") + 1);
     21 
     22     if (!(methodName.startsWith("init for field") ||
     23             methodName.startsWith("static init number")
     24             || methodName.startsWith("instance init number"))) {
     25       // keep strings consistent with text used in IndexFileSpecification
     26       this.inMethodCriterion = Criteria.inMethod(methodName);
     27     } else {
     28       this.inMethodCriterion = null;
     29     }
     30 
     31     this.loc = loc;
     32   }
     33 
     34   /** {@inheritDoc} */
     35   @Override
     36   public boolean isSatisfiedBy(TreePath path, Tree leaf) {
     37     assert path == null || path.getLeaf() == leaf;
     38     return isSatisfiedBy(path);
     39   }
     40 
     41   /** {@inheritDoc} */
     42   @Override
     43   public boolean isSatisfiedBy(TreePath path) {
     44     if (path == null) {
     45       return false;
     46     }
     47 
     48     Tree leaf = path.getLeaf();
     49 
     50     if (inMethodCriterion!=null && !inMethodCriterion.isSatisfiedBy(path)) {
     51       // If we're not in the method now, the parent path may still be in the method.
     52       // For example, the current leaf could be inside a method inside of an
     53       // anonymous inner class defined in another method.
     54       return this.isSatisfiedBy(path.getParentPath());
     55     }
     56     if (leaf.getKind() == Tree.Kind.NEW_CLASS
     57             || leaf.getKind() == Tree.Kind.NEW_ARRAY) {
     58       int indexInSource = NewScanner.indexOfNewTree(path, leaf);
     59       // System.out.printf("indexInSource=%d%n", indexInSource);
     60       boolean b;
     61       if (loc.isBytecodeOffset()) {
     62         int indexInClass = NewScanner.getMethodNewIndex(methodName, loc.offset);
     63         b = (indexInSource == indexInClass);
     64       } else {
     65         b = (indexInSource == loc.index);
     66       }
     67       return b;
     68     } else {
     69       return this.isSatisfiedBy(path.getParentPath());
     70     }
     71   }
     72 
     73   @Override
     74   public Kind getKind() {
     75     return Kind.NEW;
     76   }
     77 
     78   @Override
     79   public String toString() {
     80     return "NewCriterion in method: " + methodName + " at location " + loc;
     81   }
     82 
     83 }
     84