use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class LockVisitor method visitMethod.
/**
* Issues an error if a method (explicitly or implicitly) annotated with @MayReleaseLocks has a
* formal parameter or receiver (explicitly or implicitly) annotated with @GuardSatisfied. Also
* issues an error if a synchronized method has a @LockingFree, @SideEffectFree or @Pure
* annotation.
*
* @param node the MethodTree of the method definition to visit
*/
@Override
public Void visitMethod(MethodTree node, Void p) {
ExecutableElement methodElement = TreeUtils.elementFromDeclaration(node);
issueErrorIfMoreThanOneLockPreconditionMethodAnnotationPresent(methodElement, node);
SideEffectAnnotation sea = atypeFactory.methodSideEffectAnnotation(methodElement, true);
if (sea == SideEffectAnnotation.MAYRELEASELOCKS) {
boolean issueGSwithMRLWarning = false;
VariableTree receiver = node.getReceiverParameter();
if (receiver != null) {
if (atypeFactory.getAnnotatedType(receiver).hasAnnotation(checkerGuardSatisfiedClass)) {
issueGSwithMRLWarning = true;
}
}
if (!issueGSwithMRLWarning) {
// Skip loop if we already decided to issue the warning.
for (VariableTree vt : node.getParameters()) {
if (atypeFactory.getAnnotatedType(vt).hasAnnotation(checkerGuardSatisfiedClass)) {
issueGSwithMRLWarning = true;
break;
}
}
}
if (issueGSwithMRLWarning) {
checker.report(Result.failure("guardsatisfied.with.mayreleaselocks"), node);
}
}
// @GuardSatisfied without an index.
if (methodElement != null && methodElement.getKind() != ElementKind.CONSTRUCTOR) {
AnnotatedTypeMirror returnTypeATM = atypeFactory.getAnnotatedType(node).getReturnType();
if (returnTypeATM != null && returnTypeATM.hasAnnotation(GuardSatisfied.class)) {
int returnGuardSatisfiedIndex = atypeFactory.getGuardSatisfiedIndex(returnTypeATM);
if (returnGuardSatisfiedIndex == -1) {
checker.report(Result.failure("guardsatisfied.return.must.have.index"), node);
}
}
}
if (!sea.isWeakerThan(SideEffectAnnotation.LOCKINGFREE) && methodElement.getModifiers().contains(Modifier.SYNCHRONIZED)) {
checker.report(Result.failure("lockingfree.synchronized.method", sea), node);
}
return super.visitMethod(node, p);
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class NullnessAnnotatedTypeFactory method getUninitializedInvariantFields.
@Override
public List<VariableTree> getUninitializedInvariantFields(NullnessStore store, TreePath path, boolean isStatic, List<? extends AnnotationMirror> receiverAnnotations) {
List<VariableTree> candidates = super.getUninitializedInvariantFields(store, path, isStatic, receiverAnnotations);
List<VariableTree> result = new ArrayList<>();
for (VariableTree c : candidates) {
AnnotatedTypeMirror type = getAnnotatedType(c);
boolean isPrimitive = TypesUtils.isPrimitive(type.getUnderlyingType());
if (!isPrimitive) {
// primitives do not need to be initialized
result.add(c);
}
}
return result;
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class SameLenAnnotatedTypeFactory method getAnnotatedTypeLhs.
/**
* Handles case 2.
*/
@Override
public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree tree) {
AnnotatedTypeMirror atm = super.getAnnotatedTypeLhs(tree);
if (tree.getKind() == Tree.Kind.VARIABLE) {
Receiver r;
try {
r = FlowExpressionParseUtil.internalReprOfVariable(this, (VariableTree) tree);
} catch (FlowExpressionParseException ex) {
r = null;
}
if (r != null) {
String varName = r.toString();
AnnotationMirror anm = atm.getAnnotation(SameLen.class);
if (anm != null) {
List<String> slArrays = IndexUtil.getValueOfAnnotationWithStringArgument(anm);
if (slArrays.contains(varName)) {
slArrays.remove(varName);
}
if (slArrays.size() == 0) {
atm.replaceAnnotation(UNKNOWN);
} else {
atm.replaceAnnotation(createSameLen(slArrays.toArray(new String[0])));
}
}
}
}
return atm;
}
use of com.sun.source.tree.VariableTree 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;
}
}
use of com.sun.source.tree.VariableTree in project checker-framework by typetools.
the class BaseTypeValidator method extractParameterizedTypeTree.
private Pair<ParameterizedTypeTree, AnnotatedDeclaredType> extractParameterizedTypeTree(Tree tree, AnnotatedDeclaredType type) {
ParameterizedTypeTree typeargtree = null;
switch(tree.getKind()) {
case VARIABLE:
Tree lt = ((VariableTree) tree).getType();
if (lt instanceof ParameterizedTypeTree) {
typeargtree = (ParameterizedTypeTree) lt;
} else {
// System.out.println("Found a: " + lt);
}
break;
case PARAMETERIZED_TYPE:
typeargtree = (ParameterizedTypeTree) tree;
break;
case NEW_CLASS:
NewClassTree nct = (NewClassTree) tree;
ExpressionTree nctid = nct.getIdentifier();
if (nctid.getKind() == Tree.Kind.PARAMETERIZED_TYPE) {
typeargtree = (ParameterizedTypeTree) nctid;
/*
* This is quite tricky... for anonymous class instantiations,
* the type at this point has no type arguments. By doing the
* following, we get the type arguments again.
*/
type = (AnnotatedDeclaredType) atypeFactory.getAnnotatedType(typeargtree);
}
break;
case ANNOTATED_TYPE:
AnnotatedTypeTree tr = (AnnotatedTypeTree) tree;
ExpressionTree undtr = tr.getUnderlyingType();
if (undtr instanceof ParameterizedTypeTree) {
typeargtree = (ParameterizedTypeTree) undtr;
} else if (undtr instanceof IdentifierTree) {
// @Something D -> Nothing to do
} else {
// TODO: add more test cases to ensure that nested types are
// handled correctly,
// e.g. @Nullable() List<@Nullable Object>[][]
Pair<ParameterizedTypeTree, AnnotatedDeclaredType> p = extractParameterizedTypeTree(undtr, type);
typeargtree = p.first;
type = p.second;
}
break;
case IDENTIFIER:
case ARRAY_TYPE:
case NEW_ARRAY:
case MEMBER_SELECT:
case UNBOUNDED_WILDCARD:
case EXTENDS_WILDCARD:
case SUPER_WILDCARD:
case TYPE_PARAMETER:
// ParameterizedTypeTree));
break;
default:
// No need to do anything further.
break;
}
return Pair.of(typeargtree, type);
}
Aggregations