Search in sources :

Example 31 with AnnotatedTypeMirror

use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.

the class BaseTypeVisitor method checkThrownExpression.

/**
 * Checks the type of the thrown expression.
 *
 * <p>By default, this method checks that the thrown expression is a subtype of top.
 *
 * <p>Issue error if the thrown expression is not a sub type of the annotation given by {@link
 * #getThrowUpperBoundAnnotations()}, the same as {@link
 * #getExceptionParameterLowerBoundAnnotations()} by default.
 *
 * <p>Subclasses may override this method to change the behavior of this check. Subclasses wishing
 * to enforce that the thrown expression be a subtype of a type besides {@link
 * #getExceptionParameterLowerBoundAnnotations}, should override {@link
 * #getThrowUpperBoundAnnotations()}.
 *
 * @param node ThrowTree to check
 */
protected void checkThrownExpression(ThrowTree node) {
    AnnotatedTypeMirror throwType = atypeFactory.getAnnotatedType(node.getExpression());
    Set<? extends AnnotationMirror> required = getThrowUpperBoundAnnotations();
    switch(throwType.getKind()) {
        case NULL:
        case DECLARED:
            Set<AnnotationMirror> found = throwType.getAnnotations();
            if (!atypeFactory.getQualifierHierarchy().isSubtype(found, required)) {
                checker.reportError(node.getExpression(), "throw", found, required);
            }
            break;
        case TYPEVAR:
        case WILDCARD:
            // TODO: this code might change after the type var changes.
            Set<AnnotationMirror> foundEffective = throwType.getEffectiveAnnotations();
            if (!atypeFactory.getQualifierHierarchy().isSubtype(foundEffective, required)) {
                checker.reportError(node.getExpression(), "throw", foundEffective, required);
            }
            break;
        case UNION:
            AnnotatedUnionType unionType = (AnnotatedUnionType) throwType;
            Set<AnnotationMirror> foundPrimary = unionType.getAnnotations();
            if (!atypeFactory.getQualifierHierarchy().isSubtype(foundPrimary, required)) {
                checker.reportError(node.getExpression(), "throw", foundPrimary, required);
            }
            for (AnnotatedTypeMirror altern : unionType.getAlternatives()) {
                if (!atypeFactory.getQualifierHierarchy().isSubtype(altern.getAnnotations(), required)) {
                    checker.reportError(node.getExpression(), "throw", altern.getAnnotations(), required);
                }
            }
            break;
        default:
            throw new BugInCF("Unexpected throw expression type: " + throwType.getKind());
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedUnionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType)

Example 32 with AnnotatedTypeMirror

use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.

the class BaseTypeVisitor method commonAssignmentCheck.

/**
 * Checks the validity of an assignment (or pseudo-assignment) from a value to a variable and
 * emits an error message (through the compiler's messaging interface) if it is not valid.
 *
 * @param varType the annotated type for the lvalue (usually a variable)
 * @param valueExp the AST node for the rvalue (the new value)
 * @param errorKey the error message key to use if the check fails
 * @param extraArgs arguments to the error message key, before "found" and "expected" types
 */
protected void commonAssignmentCheck(AnnotatedTypeMirror varType, ExpressionTree valueExp, @CompilerMessageKey String errorKey, Object... extraArgs) {
    if (shouldSkipUses(valueExp)) {
        return;
    }
    if (valueExp.getKind() == Tree.Kind.MEMBER_REFERENCE || valueExp.getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
        // and do not need to be checked again as arguments.
        return;
    }
    if (varType.getKind() == TypeKind.ARRAY && valueExp instanceof NewArrayTree && ((NewArrayTree) valueExp).getType() == null) {
        AnnotatedTypeMirror compType = ((AnnotatedArrayType) varType).getComponentType();
        NewArrayTree arrayTree = (NewArrayTree) valueExp;
        assert arrayTree.getInitializers() != null : "array initializers are not expected to be null in: " + valueExp;
        checkArrayInitialization(compType, arrayTree.getInitializers());
    }
    if (!validateTypeOf(valueExp)) {
        return;
    }
    AnnotatedTypeMirror valueType = atypeFactory.getAnnotatedType(valueExp);
    assert valueType != null : "null type for expression: " + valueExp;
    commonAssignmentCheck(varType, valueType, valueExp, errorKey, extraArgs);
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) NewArrayTree(com.sun.source.tree.NewArrayTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 33 with AnnotatedTypeMirror

use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.

the class BaseTypeVisitor method checkMethodInvocability.

/**
 * Tests whether the method can be invoked using the receiver of the 'node' method invocation, and
 * issues a "method.invocation" if the invocation is invalid.
 *
 * <p>This implementation tests whether the receiver in the method invocation is a subtype of the
 * method receiver type. This behavior can be specialized by overriding skipReceiverSubtypeCheck.
 *
 * @param method the type of the invoked method
 * @param node the method invocation node
 */
protected void checkMethodInvocability(AnnotatedExecutableType method, MethodInvocationTree node) {
    if (method.getReceiverType() == null) {
        // Static methods don't have a receiver to check.
        return;
    }
    if (method.getElement().getKind() == ElementKind.CONSTRUCTOR) {
        // ((AnnotatedExecutableType)atypeFactory.getAnnotatedType(atypeFactory.getEnclosingMethod(node))).getReceiverType();
        return;
    }
    AnnotatedTypeMirror methodReceiver = method.getReceiverType().getErased();
    AnnotatedTypeMirror treeReceiver = methodReceiver.shallowCopy(false);
    AnnotatedTypeMirror rcv = atypeFactory.getReceiverType(node);
    treeReceiver.addAnnotations(rcv.getEffectiveAnnotations());
    if (!skipReceiverSubtypeCheck(node, methodReceiver, rcv)) {
        // The diagnostic can be a bit misleading because the check is of the receiver but `node` is
        // the entire method invocation (where the receiver might be implicit).
        commonAssignmentCheckStartDiagnostic(methodReceiver, treeReceiver, node);
        boolean success = atypeFactory.getTypeHierarchy().isSubtype(treeReceiver, methodReceiver);
        commonAssignmentCheckEndDiagnostic(success, null, methodReceiver, treeReceiver, node);
        if (!success) {
            reportMethodInvocabilityError(node, treeReceiver, methodReceiver);
        }
    }
}
Also used : AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 34 with AnnotatedTypeMirror

use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.

the class BaseTypeVisitor method visitReturn.

/**
 * Checks that the type of the return expression is a subtype of the enclosing method required
 * return type. If not, it issues a "return" error.
 */
@Override
public Void visitReturn(ReturnTree node, Void p) {
    // Don't try to check return expressions for void methods.
    if (node.getExpression() == null) {
        return super.visitReturn(node, p);
    }
    Tree enclosing = TreePathUtil.enclosingOfKind(getCurrentPath(), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
    AnnotatedTypeMirror ret = null;
    if (enclosing.getKind() == Tree.Kind.METHOD) {
        MethodTree enclosingMethod = TreePathUtil.enclosingMethod(getCurrentPath());
        boolean valid = validateTypeOf(enclosing);
        if (valid) {
            ret = atypeFactory.getMethodReturnType(enclosingMethod, node);
        }
    } else {
        AnnotatedExecutableType result = atypeFactory.getFunctionTypeFromTree((LambdaExpressionTree) enclosing);
        ret = result.getReturnType();
    }
    if (ret != null) {
        commonAssignmentCheck(ret, node.getExpression(), "return");
    }
    return super.visitReturn(node, p);
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) MethodTree(com.sun.source.tree.MethodTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ThrowTree(com.sun.source.tree.ThrowTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) UnaryTree(com.sun.source.tree.UnaryTree) 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) ExpressionTree(com.sun.source.tree.ExpressionTree) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) JCTree(com.sun.tools.javac.tree.JCTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 35 with AnnotatedTypeMirror

use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.

the class BaseTypeVisitor method checkQualifierParameter.

/**
 * Issues an error if {@code classTree} has polymorphic fields but is not annotated with
 * {@code @HasQualifierParameter}. Always issue a warning if the type of a static field is
 * annotated with a polymorphic qualifier.
 *
 * <p>Issues an error if {@code classTree} extends or implements a class/interface that has a
 * qualifier parameter, but this class does not.
 *
 * @param classTree the ClassTree to check for polymorphic fields
 */
protected void checkQualifierParameter(ClassTree classTree) {
    // Set of polymorphic qualifiers for hierarchies that do not have a qualifier parameter and
    // therefor cannot appear on a field.
    Set<AnnotationMirror> illegalOnFieldsPolyQual = AnnotationUtils.createAnnotationSet();
    // Set of polymorphic annotations for all hierarchies
    Set<AnnotationMirror> polys = AnnotationUtils.createAnnotationSet();
    TypeElement classElement = TreeUtils.elementFromDeclaration(classTree);
    for (AnnotationMirror top : atypeFactory.getQualifierHierarchy().getTopAnnotations()) {
        AnnotationMirror poly = atypeFactory.getQualifierHierarchy().getPolymorphicAnnotation(top);
        if (poly != null) {
            polys.add(poly);
        }
        if (atypeFactory.hasExplicitQualifierParameterInHierarchy(classElement, top) && atypeFactory.hasExplicitNoQualifierParameterInHierarchy(classElement, top)) {
            checker.reportError(classTree, "conflicting.qual.param", top);
        }
        if (atypeFactory.hasQualifierParameterInHierarchy(classElement, top)) {
            continue;
        }
        if (poly != null) {
            illegalOnFieldsPolyQual.add(poly);
        }
        Element extendsEle = TypesUtils.getTypeElement(classElement.getSuperclass());
        if (extendsEle != null && atypeFactory.hasQualifierParameterInHierarchy(extendsEle, top)) {
            checker.reportError(classTree, "missing.has.qual.param", top);
        } else {
            for (TypeMirror interfaceType : classElement.getInterfaces()) {
                Element interfaceEle = TypesUtils.getTypeElement(interfaceType);
                if (atypeFactory.hasQualifierParameterInHierarchy(interfaceEle, top)) {
                    checker.reportError(classTree, "missing.has.qual.param", top);
                    // only issue error once
                    break;
                }
            }
        }
    }
    for (Tree mem : classTree.getMembers()) {
        if (mem.getKind() == Tree.Kind.VARIABLE) {
            AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(mem);
            List<DiagMessage> hasIllegalPoly;
            if (ElementUtils.isStatic(TreeUtils.elementFromDeclaration((VariableTree) mem))) {
                // A polymorphic qualifier is not allowed on a static field even if the class
                // has a qualifier parameter.
                hasIllegalPoly = polyScanner.visit(fieldType, polys);
            } else {
                hasIllegalPoly = polyScanner.visit(fieldType, illegalOnFieldsPolyQual);
            }
            for (DiagMessage dm : hasIllegalPoly) {
                checker.report(mem, dm);
            }
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) DiagMessage(org.checkerframework.framework.source.DiagMessage) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ThrowTree(com.sun.source.tree.ThrowTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) UnaryTree(com.sun.source.tree.UnaryTree) 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) ExpressionTree(com.sun.source.tree.ExpressionTree) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) JCTree(com.sun.tools.javac.tree.JCTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)299 AnnotationMirror (javax.lang.model.element.AnnotationMirror)84 ExpressionTree (com.sun.source.tree.ExpressionTree)53 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)44 ExecutableElement (javax.lang.model.element.ExecutableElement)41 Tree (com.sun.source.tree.Tree)40 TypeMirror (javax.lang.model.type.TypeMirror)38 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)38 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)38 MethodTree (com.sun.source.tree.MethodTree)34 ArrayList (java.util.ArrayList)34 BugInCF (org.checkerframework.javacutil.BugInCF)32 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)30 TypeElement (javax.lang.model.element.TypeElement)29 VariableElement (javax.lang.model.element.VariableElement)29 VariableTree (com.sun.source.tree.VariableTree)28 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)27 AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)26 ClassTree (com.sun.source.tree.ClassTree)25 Map (java.util.Map)24