110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Alipackage annotator.find; 210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport java.util.List; 410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport annotations.el.BoundLocation; 610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport com.sun.source.tree.ClassTree; 810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport com.sun.source.tree.MethodTree; 910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport com.sun.source.tree.Tree; 1010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport com.sun.source.tree.TypeParameterTree; 1110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Aliimport com.sun.source.util.TreePath; 12dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brownimport com.sun.tools.javac.code.Type; 13dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brownimport com.sun.tools.javac.tree.JCTree.JCExpression; 1410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 1510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Alipublic class BoundLocationCriterion implements Criterion { 1610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 1710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali private Criterion parentCriterion; 18315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak private final int boundIndex; 19315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak private final int paramIndex; 2010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 2110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 2210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali public BoundLocationCriterion(BoundLocation boundLoc) { 2310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali this(boundLoc.boundIndex, boundLoc.paramIndex); 2410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 2510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 26315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak private BoundLocationCriterion(int boundIndex, int paramIndex) { 2710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali this.boundIndex = boundIndex; 2810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali this.paramIndex = paramIndex; 2910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 30315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak if (boundIndex != -1) { 31315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak this.parentCriterion = new BoundLocationCriterion(-1, paramIndex); 32315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak } else if (paramIndex != -1) { 3310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali this.parentCriterion = null; 3410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 3510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 3610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 374735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst /** {@inheritDoc} */ 384735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst @Override 394735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst public boolean isSatisfiedBy(TreePath path, Tree leaf) { 404735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst assert path == null || path.getLeaf() == leaf; 414735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst return isSatisfiedBy(path); 424735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst } 434735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst 444735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst /** {@inheritDoc} */ 454735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst @Override 4610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali public boolean isSatisfiedBy(TreePath path) { 474735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst if (path == null) { 4810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return false; 4910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 5010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 5110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali Tree leaf = path.getLeaf(); 5210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 530f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst // System.out.printf("BoundLocationCriterion.isSatisfiedBy(%s):%n leaf=%s (%s)%n", path, leaf, leaf.getClass()); 540f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst 5510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali TreePath parentPath = path.getParentPath(); 5610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (parentPath == null) { 5710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return false; 5810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 5910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 6010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali Tree parent = parentPath.getLeaf(); 6110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (parent == null) { 6210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return false; 6310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 6410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 6510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali boolean returnValue = false; 6610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 670f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst // System.out.printf("BoundLocationCriterion.isSatisfiedBy(%s):%n leaf=%s (%s)%n parent=%s (%s)%n", path, leaf, leaf.getClass(), parent, parent.getClass()); 680f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst 6910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali // if boundIndex is not null, need to check that this is right bound 7010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali // in parent 71315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak if (boundIndex != -1) { 7210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (parent instanceof TypeParameterTree) { 73dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown List<? extends Tree> bounds = ((TypeParameterTree) parent).getBounds(); 74dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown int ix = boundIndex; 75dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown if (!bounds.isEmpty() && isInterface((JCExpression) bounds.get(0))) { 76dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown --ix; 7710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 78dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown if (ix < 0 || ix < bounds.size() && bounds.get(ix) == leaf) { 79dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown returnValue = parentCriterion.isSatisfiedBy(parentPath); 80dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } 81dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } else if (boundIndex == 0 && leaf instanceof TypeParameterTree) { 82dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown List<? extends Tree> bounds = ((TypeParameterTree) leaf).getBounds(); 83dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown if (bounds.isEmpty() || isInterface((JCExpression) bounds.get(0))) { 840f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst // If the bound is implicit (i.e., a missing "extends Object"), 850f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst // then permit the match here. 860f7ed8e9f456276945e3cc04203c31dbce61a0b5Michael Ernst returnValue = parentCriterion.isSatisfiedBy(path); 87dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } else { 88dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown Type type = ((JCExpression) bounds.get(0)).type; 89dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown if (type != null && type.tsym != null && type.tsym.isInterface()) { 90dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown returnValue = parentCriterion.isSatisfiedBy(parentPath); 91dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } 92dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } 9310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 94315403cf0cb532b4bce3c6da753046b993eac572Eric Spishak } else if (paramIndex != -1) { 9510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali // if paramIndex is not null, need to ensure this present 9610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali // typeparameter tree represents the correct parameter 9710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (parent instanceof MethodTree || parent instanceof ClassTree) { 9810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali List<? extends TypeParameterTree> params = null; 9910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 10010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (parent instanceof MethodTree) { 10110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali params = ((MethodTree) parent).getTypeParameters(); 10210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } else if (parent instanceof ClassTree) { 10310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali params = ((ClassTree) parent).getTypeParameters(); 10410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 10510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 10610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (paramIndex < params.size()) { 10710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (params.get(paramIndex) == leaf) { 10810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali returnValue = true; 10910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 11010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 11110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 11210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 11310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 11410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali if (!returnValue) { 11510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return this.isSatisfiedBy(parentPath); 11610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } else { 11710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return true; 11810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 11910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 12010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 121dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown private boolean isInterface(JCExpression bound) { 122dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown Type type = bound.type; 123dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown return type != null && type.tsym != null && type.tsym.isInterface(); 124dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown } 125dd5ddd43212d92e5d5051c2f070fb299a1e1e43bDan Brown 1264735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst /** {@inheritDoc} */ 1270c0bd9d1e50a213629b2031d1c906cdf688af580Werner Dietl @Override 12810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali public Kind getKind() { 12910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return Kind.BOUND_LOCATION; 13010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 13110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali 1324735bdd95fe3025e721476ae821d0aca6127f80aMichael Ernst /** {@inheritDoc} */ 1330c0bd9d1e50a213629b2031d1c906cdf688af580Werner Dietl @Override 13410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali public String toString() { 13510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali return "BoundCriterion: at param index: " + paramIndex + 13610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali " at bound index: " + boundIndex; 13710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali } 13810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali} 139