package annotator.find;
import annotations.el.RelativeLocation;
import annotator.scanner.NewScanner;
import com.sun.source.tree.Tree;
import com.sun.source.util.TreePath;
/**
* Criterion for being a specific object creation expression.
*/
public class NewCriterion implements Criterion {
private final String methodName;
private final Criterion inMethodCriterion;
private final RelativeLocation loc;
public NewCriterion(String methodName, RelativeLocation loc) {
this.methodName = methodName.substring(0, methodName.lastIndexOf(")") + 1);
if (!(methodName.startsWith("init for field") ||
methodName.startsWith("static init number")
|| methodName.startsWith("instance init number"))) {
// keep strings consistent with text used in IndexFileSpecification
this.inMethodCriterion = Criteria.inMethod(methodName);
} else {
this.inMethodCriterion = null;
}
this.loc = loc;
}
/** {@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) {
if (path == null) {
return false;
}
Tree leaf = path.getLeaf();
if (inMethodCriterion!=null && !inMethodCriterion.isSatisfiedBy(path)) {
// If we're not in the method now, the parent path may still be in the method.
// For example, the current leaf could be inside a method inside of an
// anonymous inner class defined in another method.
return this.isSatisfiedBy(path.getParentPath());
}
if (leaf.getKind() == Tree.Kind.NEW_CLASS
|| leaf.getKind() == Tree.Kind.NEW_ARRAY) {
int indexInSource = NewScanner.indexOfNewTree(path, leaf);
// System.out.printf("indexInSource=%d%n", indexInSource);
boolean b;
if (loc.isBytecodeOffset()) {
int indexInClass = NewScanner.getMethodNewIndex(methodName, loc.offset);
b = (indexInSource == indexInClass);
} else {
b = (indexInSource == loc.index);
}
return b;
} else {
return this.isSatisfiedBy(path.getParentPath());
}
}
@Override
public Kind getKind() {
return Kind.NEW;
}
@Override
public String toString() {
return "NewCriterion in method: " + methodName + " at location " + loc;
}
}