1b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietlpackage annotator.scanner; 2b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 30d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brownimport com.sun.source.tree.BlockTree; 4cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishakimport com.sun.source.tree.ClassTree; 5b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietlimport com.sun.source.tree.Tree; 6b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietlimport com.sun.source.util.TreePath; 7b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietlimport com.sun.source.util.TreePathScanner; 8b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 9b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl/** 10b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl * The common base-class for all scanners that contains shared tree-traversal 11b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl * methods. 12b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl */ 13b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietlpublic class CommonScanner extends TreePathScanner<Void, Void> { 1483312c84f13dd9f468e13dc377dec3b21ff10c1aDan Brown public static boolean hasClassKind(Tree tree) { 1508ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown Tree.Kind kind = tree.getKind(); 1683312c84f13dd9f468e13dc377dec3b21ff10c1aDan Brown // Tree.Kind.NEW_CLASS is excluded here because 1) there is no 1783312c84f13dd9f468e13dc377dec3b21ff10c1aDan Brown // type name to be annotated on an anonymous inner class, and 184ae81f26445bc9397bd3e1edb062e0388ed82a6fMichael Ernst // consequently 2) NEW_CLASS insertions are handled separately. 1908ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown return kind == Tree.Kind.CLASS 2008ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown || kind == Tree.Kind.INTERFACE 2108ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown || kind == Tree.Kind.ENUM 2208ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown || kind == Tree.Kind.ANNOTATION_TYPE; 2308ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown } 2408ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown 2508ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown /** 2696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl * The counting context for new, typecast, instanceof, and locals. 270d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown * This is a path to a method or a field/instance/static initializer. 2896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl */ 2996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static TreePath findCountingContext(TreePath path) { 3096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl while (path != null) { 3196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl if (path.getLeaf().getKind() == Tree.Kind.METHOD || 3296b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl isFieldInit(path) || 330d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown isInitBlock(path)) { 3496b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 3596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 3696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl path = path.getParentPath(); 3796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 3896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 3996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 40b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 4196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl // classes 42b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 4396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static TreePath findEnclosingClass(TreePath path) { 449cd9f6b7c30b3760513d10b0ba298aa59477e50cDan Brown while (!hasClassKind(path.getLeaf()) 459cd9f6b7c30b3760513d10b0ba298aa59477e50cDan Brown || path.getParentPath().getLeaf().getKind() == 469cd9f6b7c30b3760513d10b0ba298aa59477e50cDan Brown Tree.Kind.NEW_CLASS) { 4796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl path = path.getParentPath(); 4896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl if (path == null) { 4996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return null; 5096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 5196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 5296b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 5396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 54b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 5596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl // methods 56b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 5796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static TreePath findEnclosingMethod(TreePath path) { 5896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl while (path.getLeaf().getKind() != Tree.Kind.METHOD) { 5996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl path = path.getParentPath(); 6096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl if (path == null) { 6196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return null; 6296b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 6396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 6496b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 6596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 66b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 6796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl // Field Initializers 68b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 6996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static boolean isFieldInit(TreePath path) { 7096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path.getLeaf().getKind() == Tree.Kind.VARIABLE 7196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl && path.getParentPath() != null 7208ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown && hasClassKind(path.getParentPath().getLeaf()); 7396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 74b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl 7596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static TreePath findEnclosingFieldInit(TreePath path) { 7696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl while (!isFieldInit(path)) { 7796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl path = path.getParentPath(); 7896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl if (path == null) { 7996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return null; 8096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 8196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 8296b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 8396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 8496b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl 850d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown // initializer blocks 8696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl 870d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static boolean isInitBlock(TreePath path, boolean isStatic) { 880d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return isInitBlock(path) 890d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown && ((BlockTree) path.getLeaf()).isStatic() == isStatic; 900d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 910d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown 920d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static boolean isInitBlock(TreePath path) { 9396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path.getParentPath() != null 9408ae9016db8867035a89c6531a49be1c7ff83ffeDan Brown && hasClassKind(path.getParentPath().getLeaf()) 9596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl && path.getLeaf().getKind() == Tree.Kind.BLOCK; 9696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 9796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl 980d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static TreePath findEnclosingInitBlock(TreePath path, 990d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown boolean isStatic) { 1000d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown while (!isInitBlock(path, isStatic)) { 1010d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown path = path.getParentPath(); 1020d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown if (path == null) { 1030d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return null; 1040d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1050d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1060d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return path; 1070d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1080d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown 1090d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static boolean isStaticInit(TreePath path) { 1100d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return isInitBlock(path, true); 1110d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1120d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown 11396b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl public static TreePath findEnclosingStaticInit(TreePath path) { 11496b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl while (!isStaticInit(path)) { 11596b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl path = path.getParentPath(); 11696b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl if (path == null) { 11796b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return null; 11896b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 11996b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 12096b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl return path; 12196b9e10ce2e7b999443ac79a6f01d2022aee5fdbwdietl } 122cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishak 1230d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static boolean isInstanceInit(TreePath path) { 1240d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return isInitBlock(path, false); 1250d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1260d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown 1270d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown public static TreePath findEnclosingInstanceInit(TreePath path) { 1280d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown while (!isInstanceInit(path)) { 1290d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown path = path.getParentPath(); 1300d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown if (path == null) { 1310d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return null; 1320d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1330d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1340d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown return path; 1350d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown } 1360d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown 1370d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown // Don't scan into any classes so that occurrences in nested classes 1380d161b87d0b1b90ba1967ca4d4071b09e83cc907Dan Brown // aren't counted. 139cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishak @Override 140cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishak public Void visitClass(ClassTree node, Void p) { 141cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishak return p; 142cf59b33aad9acd4dc8bedf0c298b8ffeb7912ee9Eric Spishak } 143b69d7f043ea1c0f9ab185c163948e9d95fe5f952Werner Dietl} 144