use of com.sun.source.util.TreePath in project error-prone by google.
the class UMatches method makeVisitorState.
static VisitorState makeVisitorState(Tree target, Unifier unifier) {
Context context = unifier.getContext();
TreePath path = TreePath.getPath(context.get(JCCompilationUnit.class), target);
return new VisitorState(context).withPath(path);
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class CFAbstractTransfer method processPostconditionsAndConditionalPostconditions.
private void processPostconditionsAndConditionalPostconditions(MethodInvocationNode n, Tree tree, S thenStore, S elseStore, Set<? extends Contract> postconditions) {
FlowExpressionContext flowExprContext = null;
for (Contract p : postconditions) {
String expression = p.expression;
AnnotationMirror anno = p.annotation;
if (flowExprContext == null) {
flowExprContext = FlowExpressionContext.buildContextForMethodUse(n, analysis.checker.getContext());
}
TreePath localScope = analysis.atypeFactory.getPath(tree);
anno = standardizeAnnotationFromContract(anno, flowExprContext, localScope);
try {
FlowExpressions.Receiver r = FlowExpressionParseUtil.parse(expression, flowExprContext, localScope, false);
if (p.kind == Contract.Kind.CONDITIONALPOSTCONDTION) {
if (((ConditionalPostcondition) p).annoResult) {
thenStore.insertValue(r, anno);
} else {
elseStore.insertValue(r, anno);
}
} else {
thenStore.insertValue(r, anno);
}
} catch (FlowExpressionParseException e) {
Result result;
if (e.isFlowParseError()) {
Object[] args = new Object[e.args.length + 1];
args[0] = ElementUtils.getVerboseName(TreeUtils.elementFromUse(n.getTree()));
System.arraycopy(e.args, 0, args, 1, e.args.length);
result = Result.failure("flowexpr.parse.error.postcondition", args);
} else {
result = e.getResult();
}
// report errors here
analysis.checker.report(result, tree);
}
}
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class AnnotatedTypeFactory method getPath.
/**
* Gets the path for the given {@link Tree} under the current root by checking from the
* visitor's current path, and only using {@link Trees#getPath(CompilationUnitTree, Tree)}
* (which is much slower) only if {@code node} is not found on the current path.
*
* <p>Note that the given Tree has to be within the current compilation unit, otherwise null
* will be returned.
*
* @param node the {@link Tree} to get the path for
* @return the path for {@code node} under the current root
*/
public final TreePath getPath(Tree node) {
assert root != null : "AnnotatedTypeFactory.getPath: root needs to be set when used on trees; factory: " + this.getClass();
if (node == null) {
return null;
}
if (treePathCache.isCached(node)) {
return treePathCache.getPath(root, node);
}
TreePath currentPath = visitorState.getPath();
if (currentPath == null) {
return TreePath.getPath(root, node);
}
// If the current path you are visiting is for this node we are done
if (currentPath.getLeaf() == node) {
return currentPath;
}
// When testing on Daikon, two steps resulted in the best performance
if (currentPath.getParentPath() != null) {
currentPath = currentPath.getParentPath();
}
if (currentPath.getLeaf() == node) {
return currentPath;
}
if (currentPath.getParentPath() != null) {
currentPath = currentPath.getParentPath();
}
if (currentPath.getLeaf() == node) {
return currentPath;
}
final TreePath pathWithinSubtree = TreePath.getPath(currentPath, node);
if (pathWithinSubtree != null) {
return pathWithinSubtree;
}
// climb the current path till we see that
// Works when getPath called on the enclosing method, enclosing
// class
TreePath current = currentPath;
while (current != null) {
if (current.getLeaf() == node) {
return current;
}
current = current.getParentPath();
}
// OK, we give up. Use the cache to look up.
return treePathCache.getPath(root, node);
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class AnnotatedTypeFactory method getSelfType.
/**
* Returns the type of {@code this} in the current location, which can be used if {@code this}
* has a special semantics (e.g. {@code this} is non-null).
*
* <p>The parameter is an arbitrary tree and does not have to mention "this", neither explicitly
* nor implicitly. This method should be overridden for type-system specific behavior.
*
* <p>TODO: in 1.8.2, handle all receiver type annotations. TODO: handle enclosing classes
* correctly.
*/
public AnnotatedDeclaredType getSelfType(Tree tree) {
TreePath path = getPath(tree);
ClassTree enclosingClass = TreeUtils.enclosingClass(path);
if (enclosingClass == null) {
// I hope this only happens when tree is a fake tree that
// we created, e.g. when desugaring enhanced-for-loops.
enclosingClass = getCurrentClassTree(tree);
}
AnnotatedDeclaredType type = getAnnotatedType(enclosingClass);
MethodTree enclosingMethod = TreeUtils.enclosingMethod(path);
if (enclosingClass.getSimpleName().length() != 0 && enclosingMethod != null) {
AnnotatedDeclaredType methodReceiver;
if (TreeUtils.isConstructor(enclosingMethod)) {
methodReceiver = (AnnotatedDeclaredType) getAnnotatedType(enclosingMethod).getReturnType();
} else {
methodReceiver = getAnnotatedType(enclosingMethod).getReceiverType();
}
if (shouldTakeFromReceiver(methodReceiver)) {
// TODO what about all annotations on the receiver?
// Code is also duplicated above.
type.clearAnnotations();
type.addAnnotations(methodReceiver.getAnnotations());
}
}
return type;
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class AnnotatedTypeFactory method getCurrentMethodReceiver.
/**
* Returns the receiver type of the current method being visited, and returns null if the
* visited tree is not within a method or if that method has no receiver (e.g. a static method).
*
* <p>The method uses the parameter only if the most enclosing method cannot be found directly.
*
* @return receiver type of the most enclosing method being visited
*/
@Nullable
protected final AnnotatedDeclaredType getCurrentMethodReceiver(Tree tree) {
AnnotatedDeclaredType res = visitorState.getMethodReceiver();
if (res == null) {
TreePath path = getPath(tree);
if (path != null) {
MethodTree enclosingMethod = TreeUtils.enclosingMethod(path);
ClassTree enclosingClass = TreeUtils.enclosingClass(path);
boolean found = false;
for (Tree member : enclosingClass.getMembers()) {
if (member.getKind() == Tree.Kind.METHOD) {
if (member == enclosingMethod) {
found = true;
}
}
}
if (found && enclosingMethod != null) {
AnnotatedExecutableType method = getAnnotatedType(enclosingMethod);
res = method.getReceiverType();
// TODO: three tests fail if one adds the following, which would make
// sense, or not?
// visitorState.setMethodReceiver(res);
} else {
// We are within an anonymous class or field initializer
res = this.getAnnotatedType(enclosingClass);
}
}
}
return res;
}
Aggregations