Search in sources :

Example 61 with VariableTree

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);
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) SideEffectAnnotation(org.checkerframework.checker.lock.LockAnnotatedTypeFactory.SideEffectAnnotation) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) GuardSatisfied(org.checkerframework.checker.lock.qual.GuardSatisfied)

Example 62 with VariableTree

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;
}
Also used : VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 63 with VariableTree

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;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 64 with VariableTree

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;
    }
}
Also used : TreePath(com.sun.source.util.TreePath) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) StatementTree(com.sun.source.tree.StatementTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree)

Example 65 with VariableTree

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);
}
Also used : AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) VariableTree(com.sun.source.tree.VariableTree) VariableTree(com.sun.source.tree.VariableTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewClassTree(com.sun.source.tree.NewClassTree) Pair(org.checkerframework.javacutil.Pair)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)86 Tree (com.sun.source.tree.Tree)43 ClassTree (com.sun.source.tree.ClassTree)37 MethodTree (com.sun.source.tree.MethodTree)37 ExpressionTree (com.sun.source.tree.ExpressionTree)34 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)25 NewClassTree (com.sun.source.tree.NewClassTree)23 TreePath (com.sun.source.util.TreePath)23 IdentifierTree (com.sun.source.tree.IdentifierTree)22 JCTree (com.sun.tools.javac.tree.JCTree)21 MemberSelectTree (com.sun.source.tree.MemberSelectTree)19 AssignmentTree (com.sun.source.tree.AssignmentTree)17 ArrayList (java.util.ArrayList)17 BlockTree (com.sun.source.tree.BlockTree)16 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)13 Type (com.sun.tools.javac.code.Type)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 ReturnTree (com.sun.source.tree.ReturnTree)12 StatementTree (com.sun.source.tree.StatementTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)12