Search in sources :

Example 26 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project error-prone by google.

the class NullableVoid method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    MethodSymbol sym = ASTHelpers.getSymbol(tree);
    if (sym == null) {
        return NO_MATCH;
    }
    if (sym.getReturnType().getKind() != TypeKind.VOID) {
        return NO_MATCH;
    }
    AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Nullable");
    if (annotation == null) {
        return NO_MATCH;
    }
    return describeMatch(annotation, SuggestedFix.delete(annotation));
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) AnnotationTree(com.sun.source.tree.AnnotationTree)

Example 27 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project checker-framework by typetools.

the class BaseTypeVisitor method warnAboutTypeAnnotationsTooEarly.

/**
 * Warn if a type annotation is written before a modifier such as "public" or before a declaration
 * annotation.
 *
 * @param node a VariableTree or a MethodTree
 * @param modifiersTree the modifiers sub-tree of node
 */
private void warnAboutTypeAnnotationsTooEarly(Tree node, ModifiersTree modifiersTree) {
    // the effort to do so.
    if (node.getKind() == Tree.Kind.VARIABLE) {
        ElementKind varKind = TreeUtils.elementFromDeclaration((VariableTree) node).getKind();
        switch(varKind) {
            case ENUM_CONSTANT:
                // appears to be before "public".
                return;
            case RESOURCE_VARIABLE:
                // appears to be before "final".
                return;
            default:
                if (TreeUtils.isAutoGeneratedRecordMember(node)) {
                    // a warning about those.
                    return;
                }
        }
    }
    Set<Modifier> modifierSet = modifiersTree.getFlags();
    List<? extends AnnotationTree> annotations = modifiersTree.getAnnotations();
    if (annotations.isEmpty()) {
        return;
    }
    // Warn about type annotations written before modifiers such as "public".  javac retains no
    // information about modifier locations.  So, this is a very partial check:  Issue a warning if
    // a type annotation is at the very beginning of the VariableTree, and a modifier follows it.
    // Check if a type annotation precedes a declaration annotation.
    int lastDeclAnnoIndex = -1;
    for (int i = annotations.size() - 1; i > 0; i--) {
        // no need to check index 0
        if (!isTypeAnnotation(annotations.get(i))) {
            lastDeclAnnoIndex = i;
            break;
        }
    }
    if (lastDeclAnnoIndex != -1) {
        List<AnnotationTree> badTypeAnnos = new ArrayList<>();
        for (int i = 0; i < lastDeclAnnoIndex; i++) {
            AnnotationTree anno = annotations.get(i);
            if (isTypeAnnotation(anno)) {
                badTypeAnnos.add(anno);
            }
        }
        if (!badTypeAnnos.isEmpty()) {
            checker.reportWarning(node, "type.anno.before.decl.anno", badTypeAnnos, annotations.get(lastDeclAnnoIndex));
        }
    }
    // Determine the length of the text that ought to precede the first type annotation.
    // If the type annotation appears before that text could appear, then warn that a
    // modifier appears after the type annotation.
    // TODO: in the future, account for the lengths of declaration annotations.  Length of toString
    // of the annotation isn't useful, as it might be different length than original input.  Can use
    // JCTree.getEndPosition(EndPosTable) and com.sun.tools.javac.tree.EndPosTable, but it requires
    // -Xjcov.
    AnnotationTree firstAnno = annotations.get(0);
    if (!modifierSet.isEmpty() && isTypeAnnotation(firstAnno)) {
        int precedingTextLength = 0;
        for (Modifier m : modifierSet) {
            // +1 for the space
            precedingTextLength += m.toString().length() + 1;
        }
        int annoStartPos = ((JCTree) firstAnno).getStartPosition();
        int varStartPos = ((JCTree) node).getStartPosition();
        if (annoStartPos < varStartPos + precedingTextLength) {
            checker.reportWarning(node, "type.anno.before.modifier", firstAnno, modifierSet);
        }
    }
}
Also used : ElementKind(javax.lang.model.element.ElementKind) VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) JCTree(com.sun.tools.javac.tree.JCTree) AnnotationTree(com.sun.source.tree.AnnotationTree) Modifier(javax.lang.model.element.Modifier)

Example 28 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project checker-framework by typetools.

the class NullnessVisitor method processClassTree.

@Override
public void processClassTree(ClassTree classTree) {
    Tree extendsClause = classTree.getExtendsClause();
    if (extendsClause != null) {
        reportErrorIfSupertypeContainsNullnessAnnotation(extendsClause);
    }
    for (Tree implementsClause : classTree.getImplementsClause()) {
        reportErrorIfSupertypeContainsNullnessAnnotation(implementsClause);
    }
    if (classTree.getKind() == Tree.Kind.ENUM) {
        for (Tree member : classTree.getMembers()) {
            if (member.getKind() == Tree.Kind.VARIABLE && TreeUtils.elementFromDeclaration((VariableTree) member).getKind() == ElementKind.ENUM_CONSTANT) {
                VariableTree varDecl = (VariableTree) member;
                List<? extends AnnotationTree> annoTrees = varDecl.getModifiers().getAnnotations();
                Tree type = varDecl.getType();
                if (atypeFactory.containsNullnessAnnotation(annoTrees, type)) {
                    checker.reportError(member, "nullness.on.enum");
                }
            }
        }
    }
    super.processClassTree(classTree);
}
Also used : VariableTree(com.sun.source.tree.VariableTree) 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) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) SwitchTree(com.sun.source.tree.SwitchTree) ThrowTree(com.sun.source.tree.ThrowTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree)

Example 29 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project checker-framework by typetools.

the class NullnessVisitor method checkExceptionParameter.

@Override
protected void checkExceptionParameter(CatchTree node) {
    VariableTree param = node.getParameter();
    List<? extends AnnotationTree> annoTrees = param.getModifiers().getAnnotations();
    Tree paramType = param.getType();
    if (atypeFactory.containsNullnessAnnotation(annoTrees, paramType)) {
        // This is a warning rather than an error because writing `@Nullable` could make sense
        // if the catch block re-assigns the variable to null.  (That would be bad style.)
        checker.reportWarning(param, "nullness.on.exception.parameter");
    }
// Don't call super.
// BasetypeVisitor forces annotations on exception parameters to be top, but because exceptions
// can never be null, the Nullness Checker does not require this check.
}
Also used : VariableTree(com.sun.source.tree.VariableTree) 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) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) SwitchTree(com.sun.source.tree.SwitchTree) ThrowTree(com.sun.source.tree.ThrowTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree)

Example 30 with AnnotationTree

use of com.sun.source.tree.AnnotationTree in project checker-framework by typetools.

the class AnnotatedTypeFactory method fromNewClass.

/**
 * Creates an AnnotatedDeclaredType for a NewClassTree. Only adds explicit annotations, unless
 * newClassTree has a diamond operator. In that case, the annotations on the type arguments are
 * inferred using the assignment context and contain defaults.
 *
 * <p>Also, fully annotates the enclosing type of the returned declared type.
 *
 * <p>(Subclass beside {@link GenericAnnotatedTypeFactory} should not override this method.)
 *
 * @param newClassTree NewClassTree
 * @return AnnotatedDeclaredType
 */
public AnnotatedDeclaredType fromNewClass(NewClassTree newClassTree) {
    AnnotatedDeclaredType enclosingType = (AnnotatedDeclaredType) getReceiverType(newClassTree);
    // Diamond trees that are not anonymous classes.
    if (TreeUtils.isDiamondTree(newClassTree) && newClassTree.getClassBody() == null) {
        AnnotatedDeclaredType type = (AnnotatedDeclaredType) toAnnotatedType(TreeUtils.typeOf(newClassTree), false);
        if (((com.sun.tools.javac.code.Type) type.underlyingType).tsym.getTypeParameters().nonEmpty()) {
            TreePath p = getPath(newClassTree);
            AnnotatedTypeMirror ctxtype = TypeArgInferenceUtil.assignedTo(this, p);
            if (ctxtype != null) {
                fromNewClassContextHelper(type, ctxtype);
            } else {
                // give up trying and set to raw.
                type.setIsUnderlyingTypeRaw();
            }
        }
        AnnotatedDeclaredType fromTypeTree = (AnnotatedDeclaredType) TypeFromTree.fromTypeTree(this, newClassTree.getIdentifier());
        type.replaceAnnotations(fromTypeTree.getAnnotations());
        type.setEnclosingType(enclosingType);
        return type;
    } else if (newClassTree.getClassBody() != null) {
        AnnotatedDeclaredType type = (AnnotatedDeclaredType) toAnnotatedType(TreeUtils.typeOf(newClassTree), false);
        // In Java 11 and lower, if newClassTree creates an anonymous class, then annotations in this
        // location:
        // new @HERE Class() {}
        // are on not on the identifier newClassTree, but rather on the modifier newClassTree.
        List<? extends AnnotationTree> annos = newClassTree.getClassBody().getModifiers().getAnnotations();
        type.addAnnotations(TreeUtils.annotationsFromTypeAnnotationTrees(annos));
        // In Java 17+, the annotations are on the identifier, so copy them.
        AnnotatedDeclaredType identifierType = (AnnotatedDeclaredType) TypeFromTree.fromTypeTree(this, newClassTree.getIdentifier());
        type.addAnnotations(identifierType.getAnnotations());
        type.setEnclosingType(enclosingType);
        return type;
    } else {
        // If newClassTree does not create an anonymous class (or if this is Java 17+),
        // newClassTree.getIdentifier includes the explicit annotations in this location:
        // new @HERE Class()
        AnnotatedDeclaredType type = (AnnotatedDeclaredType) TypeFromTree.fromTypeTree(this, newClassTree.getIdentifier());
        type.setEnclosingType(enclosingType);
        return type;
    }
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) IntersectionType(javax.lang.model.type.IntersectionType) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType) DeclaredType(javax.lang.model.type.DeclaredType) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedNullType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedNullType) WildcardType(javax.lang.model.type.WildcardType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) Type(com.sun.tools.javac.code.Type) ElementType(java.lang.annotation.ElementType) PrimitiveType(javax.lang.model.type.PrimitiveType) TreePath(com.sun.source.util.TreePath) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) List(java.util.List) AnnotationTree(com.sun.source.tree.AnnotationTree)

Aggregations

AnnotationTree (com.sun.source.tree.AnnotationTree)40 Tree (com.sun.source.tree.Tree)17 ExpressionTree (com.sun.source.tree.ExpressionTree)15 VariableTree (com.sun.source.tree.VariableTree)15 MethodTree (com.sun.source.tree.MethodTree)14 ClassTree (com.sun.source.tree.ClassTree)12 MemberSelectTree (com.sun.source.tree.MemberSelectTree)11 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)11 AnnotatedTypeTree (com.sun.source.tree.AnnotatedTypeTree)10 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)10 IdentifierTree (com.sun.source.tree.IdentifierTree)10 ModifiersTree (com.sun.source.tree.ModifiersTree)10 NewClassTree (com.sun.source.tree.NewClassTree)9 ArrayAccessTree (com.sun.source.tree.ArrayAccessTree)8 BinaryTree (com.sun.source.tree.BinaryTree)8 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)8 NewArrayTree (com.sun.source.tree.NewArrayTree)8 ParameterizedTypeTree (com.sun.source.tree.ParameterizedTypeTree)8 TypeCastTree (com.sun.source.tree.TypeCastTree)8 UnaryTree (com.sun.source.tree.UnaryTree)8