1package annotator.find;
2
3import java.util.List;
4
5import annotations.el.TypeIndexLocation;
6import annotator.scanner.CommonScanner;
7
8import com.sun.source.tree.ClassTree;
9import com.sun.source.tree.Tree;
10import com.sun.source.util.TreePath;
11import com.sun.tools.javac.tree.JCTree;
12
13/**
14 * A criterion to find a given extends or implements clause.
15 */
16public class ExtImplsLocationCriterion implements Criterion {
17
18  private final String classname;
19  private final Integer index;
20
21  /**
22   * @param classname the class name; for debugging purposes only, not used to constrain
23   * @param tyLoc -1 for an extends clause, $ge; 0 for the zero-based implements clause
24   */
25  public ExtImplsLocationCriterion(String classname, TypeIndexLocation tyLoc) {
26    this.classname = classname;
27    this.index = tyLoc.typeIndex;
28  }
29
30  /** {@inheritDoc} */
31  @Override
32  public boolean isSatisfiedBy(TreePath path, Tree leaf) {
33    assert path == null || path.getLeaf() == leaf;
34    return isSatisfiedBy(path);
35  }
36
37  /** {@inheritDoc} */
38  @Override
39  public boolean isSatisfiedBy(TreePath path) {
40    if (path == null) {
41      return false;
42    }
43
44    Tree leaf = path.getLeaf();
45
46    // System.out.printf("ExtImplsLocationCriterion.isSatisfiedBy(%s):%n  leaf=%s (%s)%n", path, leaf, leaf.getClass());
47
48    TreePath parentPath = path.getParentPath();
49    if (parentPath == null) {
50      return false;
51    }
52
53    Tree parent = parentPath.getLeaf();
54    if (parent == null) {
55      return false;
56    }
57
58    // System.out.printf("ExtImplsLocationCriterion.isSatisfiedBy(%s):%n  leaf=%s (%s)%n  parent=%s (%s)%n", path, leaf, leaf.getClass(), parent, parent.getClass());
59
60    boolean returnValue = false;
61
62    if (index == -1 && leaf.getKind() == Tree.Kind.CLASS) {
63        return ((JCTree.JCClassDecl) leaf).getExtendsClause() == null;
64    }
65    if (CommonScanner.hasClassKind(parent)) {
66        ClassTree ct = (ClassTree) parent;
67
68        if (index==-1) {
69            Tree ext = ct.getExtendsClause();
70            if (ext == leaf) {
71                returnValue = true;
72            }
73        } else {
74            List<? extends Tree> impls = ct.getImplementsClause();
75            if (index < impls.size() && impls.get(index) == leaf) {
76                returnValue = true;
77            }
78        }
79    }
80
81    if (!returnValue) {
82        return this.isSatisfiedBy(parentPath);
83    } else {
84        return true;
85    }
86  }
87
88  public Integer getIndex() {
89    return index;
90  }
91
92  /** {@inheritDoc} */
93  @Override
94  public Kind getKind() {
95    return Kind.EXTIMPLS_LOCATION;
96  }
97
98  /** {@inheritDoc} */
99  @Override
100  public String toString() {
101    return "ExtImplsLocationCriterion: class " + classname + " at type index: " + index;
102  }
103}
104