use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class KeyForPropagator method propagateNewClassTree.
/**
* Propagate annotations from the type arguments of {@code type} to the assignment context of
* {@code newClassTree} if one exists.
*
* @param newClassTree new class tree
* @param type annotated type of {@code newClassTree}
* @param atypeFactory factory
*/
public void propagateNewClassTree(NewClassTree newClassTree, AnnotatedTypeMirror type, KeyForAnnotatedTypeFactory atypeFactory) {
Pair<Tree, AnnotatedTypeMirror> context = atypeFactory.getVisitorState().getAssignmentContext();
if (type.getKind() != TypeKind.DECLARED || context == null || context.first == null) {
return;
}
TreePath path = atypeFactory.getPath(newClassTree);
if (path == null) {
return;
}
AnnotatedTypeMirror assignedTo = TypeArgInferenceUtil.assignedTo(atypeFactory, path);
if (assignedTo == null) {
return;
}
// array types and boxed primitives etc don't require propagation
if (assignedTo.getKind() == TypeKind.DECLARED) {
propagate((AnnotatedDeclaredType) type, (AnnotatedDeclaredType) assignedTo, PropagationDirection.TO_SUBTYPE, atypeFactory);
}
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class SignednessVisitor method isMaskedShift.
/**
* Determines if a right shift operation, {@code >>} or {@code >>>}, is masked with a masking
* operation of the form {@code shiftExpr & maskLit} or {@code shiftExpr | maskLit} such that
* the mask renders the shift signedness ({@code >>} vs {@code >>>}) irrelevent by destroying
* the bits duplicated into the shift result. For example, the following pairs of right shifts
* on {@code byte b} both produce the same results under any input, because of their masks:
*
* <p>{@code (b >> 4) & 0x0F == (b >>> 4) & 0x0F;}
*
* <p>{@code (b >> 4) | 0xF0 == (b >>> 4) | 0xF0;}
*
* @param shiftExpr a right shift expression: {@code expr1 >> expr2} or {@code expr1 >>> expr2}
* @return true iff the right shift is masked such that a signed or unsigned right shift has the
* same effect
*/
private boolean isMaskedShift(BinaryTree shiftExpr) {
// enclosing is the operation or statement that immediately contains shiftExpr
Tree enclosing;
// enclosingChild is the top node in the chain of nodes from shiftExpr to parent
Tree enclosingChild;
{
TreePath parentPath = visitorState.getPath().getParentPath();
enclosing = parentPath.getLeaf();
enclosingChild = enclosing;
// Strip away all parentheses from the shift operation
while (enclosing.getKind() == Kind.PARENTHESIZED) {
parentPath = parentPath.getParentPath();
enclosingChild = enclosing;
enclosing = parentPath.getLeaf();
}
}
if (!isMask(enclosing)) {
return false;
}
BinaryTree maskExpr = (BinaryTree) enclosing;
ExpressionTree shiftAmountExpr = shiftExpr.getRightOperand();
// Determine which child of maskExpr leads to shiftExpr. The other one is the mask.
ExpressionTree mask = maskExpr.getRightOperand() == enclosingChild ? maskExpr.getLeftOperand() : maskExpr.getRightOperand();
// Strip away the parentheses from the mask if any exist
mask = TreeUtils.skipParens(mask);
if (!isLiteral(shiftAmountExpr) || !isLiteral(mask)) {
return false;
}
LiteralTree shiftLit = (LiteralTree) shiftAmountExpr;
LiteralTree maskLit = (LiteralTree) mask;
return maskIgnoresMSB(maskExpr.getKind(), shiftLit, maskLit);
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class SameLenTransfer method propagateCombinedSameLen.
/**
* Insert combinedSameLen into the store as the SameLen type of each array listed in
* combinedSameLen.
*
* @param combinedSameLen a Samelen annotation. Not just an annotation in the SameLen hierarchy;
* this annotation MUST be @SameLen().
* @param node the node in the tree where the combination is happening. Used for context.
* @param store the store to modify
*/
private void propagateCombinedSameLen(AnnotationMirror combinedSameLen, Node node, CFStore store) {
TreePath currentPath = aTypeFactory.getPath(node.getTree());
if (currentPath == null) {
return;
}
for (String s : IndexUtil.getValueOfAnnotationWithStringArgument(combinedSameLen)) {
Receiver recS;
try {
recS = aTypeFactory.getReceiverFromJavaExpressionString(s, currentPath);
} catch (FlowExpressionParseUtil.FlowExpressionParseException e) {
continue;
}
store.clearValue(recS);
store.insertValue(recS, combinedSameLen);
}
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class Resolver method getEnvForPath.
/**
* Determine the environment for the given path.
*
* @param path the tree path to the local scope
* @return the corresponding attribution environment
*/
public Env<AttrContext> getEnvForPath(TreePath path) {
TreePath iter = path;
JavacScope scope = null;
while (scope == null && iter != null) {
try {
scope = (JavacScope) trees.getScope(iter);
} catch (Throwable t) {
// Work around Issue #1059 by skipping through the TreePath until something
// doesn't crash. This probably returns the class scope, so users might not
// get the variables they expect. But that is better than crashing.
iter = iter.getParentPath();
}
}
if (scope != null) {
return scope.getEnv();
} else {
ErrorReporter.errorAbort("Could not determine any possible scope for path: " + path.getLeaf());
return null;
}
}
use of com.sun.source.util.TreePath in project checker-framework by typetools.
the class TreeUtils method getAssignmentContext.
/**
* Returns the tree with the assignment context for the treePath leaf node. (Does not handle
* pseudo-assignment of an argument to a parameter or a receiver expression to a receiver.)
*
* <p>The assignment context for the {@code treePath} is the leaf of its parent, if the parent
* is one of the following trees:
*
* <ul>
* <li>AssignmentTree
* <li>CompoundAssignmentTree
* <li>MethodInvocationTree
* <li>NewArrayTree
* <li>NewClassTree
* <li>ReturnTree
* <li>VariableTree
* </ul>
*
* If the parent is a ConditionalExpressionTree we need to distinguish two cases: If the leaf is
* either the then or else branch of the ConditionalExpressionTree, then recurse on the parent.
* If the leaf is the condition of the ConditionalExpressionTree, then return null to not
* consider this assignment context.
*
* <p>If the leaf is a ParenthesizedTree, then recurse on the parent.
*
* <p>Otherwise, null is returned.
*
* @return the assignment context as described
*/
public static Tree getAssignmentContext(final TreePath treePath) {
TreePath parentPath = treePath.getParentPath();
if (parentPath == null) {
return null;
}
Tree parent = parentPath.getLeaf();
switch(parent.getKind()) {
case PARENTHESIZED:
return getAssignmentContext(parentPath);
case CONDITIONAL_EXPRESSION:
ConditionalExpressionTree cet = (ConditionalExpressionTree) parent;
if (cet.getCondition() == treePath.getLeaf()) {
// No point in going on.
return null;
}
// Otherwise use the context of the ConditionalExpressionTree.
return getAssignmentContext(parentPath);
case ASSIGNMENT:
case METHOD_INVOCATION:
case NEW_ARRAY:
case NEW_CLASS:
case RETURN:
case VARIABLE:
return parent;
default:
// so use instanceof rather than listing all 11.
if (parent instanceof CompoundAssignmentTree) {
return parent;
}
return null;
}
}
Aggregations