use of com.sun.source.util.TreePath in project buck by facebook.
the class TreeContextScanner method scan.
@Override
@Nullable
public R scan(Tree tree, @Nullable P p) {
if (tree == null) {
return null;
}
TreePath previousPath = currentPath;
Element previousEnclosingElement = enclosingElement;
currentPath = new TreePath(currentPath, tree);
switch(tree.getKind()) {
case ANNOTATION_TYPE:
case CLASS:
case COMPILATION_UNIT:
case ENUM:
case INTERFACE:
case METHOD:
case VARIABLE:
case TYPE_PARAMETER:
enclosingElement = Preconditions.checkNotNull(trees.getElement(currentPath));
break;
// $CASES-OMITTED$
default:
break;
}
try {
// This super call will actually visit the tree, now with all the context set up
return super.scan(tree, p);
} finally {
currentPath = previousPath;
enclosingElement = previousEnclosingElement;
}
}
use of com.sun.source.util.TreePath in project buck by facebook.
the class InterfaceValidator method validate.
public void validate(List<? extends CompilationUnitTree> compilationUnits) {
try (BuckTracing.TraceSection trace = BUCK_TRACING.traceSection("buck.abi.validate")) {
new InterfaceTypeAndConstantReferenceFinder(trees, new InterfaceTypeAndConstantReferenceFinder.Listener() {
private final Set<Element> importedTypes = new HashSet<>();
@Override
public void onTypeImported(TypeElement type) {
importedTypes.add(type);
}
@Override
public void onTypeReferenceFound(TypeElement referencedType, TreePath path, Element enclosingElement) {
PackageElement enclosingPackage = getPackageElement(enclosingElement);
if (typeWillBeAvailable(referencedType) || referenceIsLegalForMissingTypes(path, enclosingPackage, referencedType)) {
// All good!
return;
}
String minimalQualifiedName = findMinimalQualifiedName(path, enclosingPackage, referencedType);
// TODO(jkeljo): Clearer message
trees.printMessage(messageKind, String.format("Must qualify the name: %s", minimalQualifiedName), path.getLeaf(), path.getCompilationUnit());
}
@Override
public void onConstantReferenceFound(VariableElement constant, TreePath path, Element enclosingElement) {
TypeElement constantEnclosingType = (TypeElement) constant.getEnclosingElement();
if (typeWillBeAvailable(constantEnclosingType)) {
// All good!
return;
}
// TODO(jkeljo): Clearer message
trees.printMessage(messageKind, String.format("Must inline the constant value: %s", constant.getConstantValue()), path.getLeaf(), path.getCompilationUnit());
}
private boolean typeWillBeAvailable(TypeElement type) {
return isCompiledInCurrentRun(type) || isOnBootClasspath(type);
}
private boolean isCompiledInCurrentRun(TypeElement typeElement) {
return trees.getPath(typeElement) != null;
}
private boolean isOnBootClasspath(TypeElement typeElement) {
return bootClasspathOracle.isOnBootClasspath(elements.getBinaryName(typeElement).toString());
}
private boolean referenceIsLegalForMissingTypes(TreePath path, PackageElement enclosingPackage, TypeElement referencedTypeElement) {
return isImported(referencedTypeElement) || isTopLevelTypeInPackage(referencedTypeElement, enclosingPackage) || isFullyQualified(path, referencedTypeElement);
}
private boolean isImported(TypeElement referencedTypeElement) {
return importedTypes.contains(referencedTypeElement);
}
private boolean isTopLevelTypeInPackage(TypeElement referencedTypeElement, PackageElement enclosingPackage) {
return enclosingPackage == referencedTypeElement.getEnclosingElement();
}
private boolean isFullyQualified(TreePath path, TypeElement referencedTypeElement) {
return referencedTypeElement.getQualifiedName().contentEquals(TreeBackedTrees.treeToName(path.getLeaf()));
}
private String findMinimalQualifiedName(TreePath path, PackageElement enclosingPackage, TypeElement typeElement) {
List<QualifiedNameable> enclosingElements = new ArrayList<>();
QualifiedNameable walker = typeElement;
while (walker.getKind() != ElementKind.PACKAGE && !referenceIsLegalForMissingTypes(path, enclosingPackage, (TypeElement) walker)) {
enclosingElements.add(walker);
walker = (QualifiedNameable) walker.getEnclosingElement();
}
enclosingElements.add(walker);
StringBuilder resultBuilder = new StringBuilder();
for (int i = enclosingElements.size() - 1; i >= 0; i--) {
QualifiedNameable element = enclosingElements.get(i);
if (element.getKind() == ElementKind.PACKAGE) {
resultBuilder.append(element.getQualifiedName());
} else {
resultBuilder.append(element.getSimpleName());
}
if (i > 0) {
resultBuilder.append(".");
}
}
return resultBuilder.toString();
}
}).findReferences(compilationUnits);
}
}
use of com.sun.source.util.TreePath in project buck by facebook.
the class TreeBackedTreesTest method testGetTreeGetPathRoundtripTypeElement.
@Test
public void testGetTreeGetPathRoundtripTypeElement() throws IOException {
compile("class Foo<T, U> { }");
TypeElement fooElement = elements.getTypeElement("Foo");
Tree fooTree = trees.getTree(fooElement);
TreePath fooPath = trees.getPath(fooElement);
assertSame(fooPath.getLeaf(), fooTree);
assertSame(fooElement, trees.getElement(fooPath));
}
use of com.sun.source.util.TreePath in project bazel by bazelbuild.
the class TreeUtils method getAssignmentContext.
/**
* Returns the tree with the assignment context for the treePath
* leaf node.
*
* The assignment context for the treepath is the most enclosing
* tree of type:
* <ul>
* <li>AssignmentTree </li>
* <li>CompoundAssignmentTree </li>
* <li>MethodInvocationTree</li>
* <li>NewArrayTree</li>
* <li>NewClassTree</li>
* <li>ReturnTree</li>
* <li>VariableTree</li>
* </ul>
*
* @param treePath
* @return the assignment context as described.
*/
public static Tree getAssignmentContext(final TreePath treePath) {
TreePath path = treePath.getParentPath();
if (path == null)
return null;
Tree node = path.getLeaf();
if ((node instanceof AssignmentTree) || (node instanceof CompoundAssignmentTree) || (node instanceof MethodInvocationTree) || (node instanceof NewArrayTree) || (node instanceof NewClassTree) || (node instanceof ReturnTree) || (node instanceof VariableTree))
return node;
return null;
}
use of com.sun.source.util.TreePath in project bazel by bazelbuild.
the class TreeUtils method enclosingOfKind.
/**
* Gets the first enclosing tree in path, with any one of the specified kinds.
*
* @param path the path defining the tree node
* @param kinds the set of kinds of the desired tree
* @return the enclosing tree of the given type as given by the path
*/
public static Tree enclosingOfKind(final TreePath path, final Set<Tree.Kind> kinds) {
TreePath p = path;
while (p != null) {
Tree leaf = p.getLeaf();
assert leaf != null;
/*nninvariant*/
if (kinds.contains(leaf.getKind()))
return leaf;
p = p.getParentPath();
}
return null;
}
Aggregations