Search in sources :

Example 61 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.report(Result.failure("throw.type.invalid", found, required), node.getExpression());
            }
            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.report(Result.failure("throw.type.invalid", foundEffective, required), node.getExpression());
            }
            break;
        case UNION:
            AnnotatedUnionType unionType = (AnnotatedUnionType) throwType;
            Set<AnnotationMirror> foundPrimary = unionType.getAnnotations();
            if (!atypeFactory.getQualifierHierarchy().isSubtype(foundPrimary, required)) {
                checker.report(Result.failure("throw.type.invalid", foundPrimary, required), node.getExpression());
            }
            for (AnnotatedTypeMirror altern : unionType.getAlternatives()) {
                if (!atypeFactory.getQualifierHierarchy().isSubtype(altern.getAnnotations(), required)) {
                    checker.report(Result.failure("throw.type.invalid", altern.getAnnotations(), required), node.getExpression());
                }
            }
            break;
        default:
            ErrorReporter.errorAbort("Unexpected throw expression type: " + throwType.getKind());
            break;
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedUnionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType)

Example 62 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.invalid" 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.
        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) && !atypeFactory.getTypeHierarchy().isSubtype(treeReceiver, methodReceiver)) {
        checker.report(Result.failure("method.invocation.invalid", TreeUtils.elementFromUse(node), treeReceiver.toString(), methodReceiver.toString()), node);
    }
}
Also used : AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 63 with AnnotatedTypeMirror

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

the class BaseTypeVisitor method visitNewClass.

/**
 * Performs a new class invocation check.
 *
 * <p>An invocation of a constructor, c, is valid only if:
 *
 * <ul>
 *   <li>passed arguments are subtypes of corresponding c parameters
 *   <li>if c is generic, passed type arguments are subtypes of c type variables
 * </ul>
 */
@Override
public Void visitNewClass(NewClassTree node, Void p) {
    if (checker.shouldSkipUses(TreeUtils.constructor(node))) {
        return super.visitNewClass(node, p);
    }
    Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> fromUse = atypeFactory.constructorFromUse(node);
    AnnotatedExecutableType constructor = fromUse.first;
    List<AnnotatedTypeMirror> typeargs = fromUse.second;
    List<? extends ExpressionTree> passedArguments = node.getArguments();
    List<AnnotatedTypeMirror> params = AnnotatedTypes.expandVarArgs(atypeFactory, constructor, passedArguments);
    checkArguments(params, passedArguments);
    checkVarargs(constructor, node);
    List<AnnotatedTypeParameterBounds> paramBounds = new ArrayList<>();
    for (AnnotatedTypeVariable param : constructor.getTypeVariables()) {
        paramBounds.add(param.getBounds());
    }
    checkTypeArguments(node, paramBounds, typeargs, node.getTypeArguments());
    boolean valid = validateTypeOf(node);
    if (valid) {
        AnnotatedDeclaredType dt = atypeFactory.getAnnotatedType(node);
        if (atypeFactory.getDependentTypesHelper() != null) {
            atypeFactory.getDependentTypesHelper().checkType(dt, node);
        }
        checkConstructorInvocation(dt, constructor, node);
    }
    // Do not call super, as that would observe the arguments without
    // a set assignment context.
    scan(node.getEnclosingExpression(), p);
    scan(node.getIdentifier(), p);
    scan(node.getClassBody(), p);
    return null;
}
Also used : AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 64 with AnnotatedTypeMirror

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

the class BaseTypeVisitor method visitTypeCast.

@Override
public Void visitTypeCast(TypeCastTree node, Void p) {
    // validate "node" instead of "node.getType()" to prevent duplicate errors.
    boolean valid = validateTypeOf(node) && validateTypeOf(node.getExpression());
    if (valid) {
        checkTypecastSafety(node, p);
        checkTypecastRedundancy(node, p);
    }
    if (atypeFactory.getDependentTypesHelper() != null) {
        AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(node);
        atypeFactory.getDependentTypesHelper().checkType(type, node.getType());
    }
    return super.visitTypeCast(node, p);
// return scan(node.getExpression(), p);
}
Also used : AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 65 with AnnotatedTypeMirror

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

the class BaseTypeVisitor method checkFieldInvariantDeclarations.

/**
 * Check that the field invariant declaration annotations meet the following requirements:
 *
 * <ol>
 *   <!-- The item numbering is referred to in the body of the method.-->
 *   <li value="1">If the superclass of {@code classTree} has a field invariant, then the field
 *       invariant for {@code classTree} must include all the fields in the superclass invariant
 *       and those fields' annotations must be a subtype (or equal) to the annotations for those
 *       fields in the superclass.
 *   <li value="2">The fields in the invariant must be a.) final and b.) declared in a
 *       superclass of {@code classTree}.
 *   <li value="3">The qualifier for each field must be a subtype of the annotation on the
 *       declaration of that field.
 *   <li value="4">The field invariant has an equal number of fields and qualifiers, or it has
 *       one qualifier and at least one field.
 * </ol>
 *
 * @param classTree class that might have a field invariant
 * @checker_framework.manual #field-invariants Field invariants
 */
protected void checkFieldInvariantDeclarations(ClassTree classTree) {
    TypeElement elt = TreeUtils.elementFromDeclaration(classTree);
    FieldInvariants invariants = atypeFactory.getFieldInvariants(elt);
    if (invariants == null) {
        // No invariants to check
        return;
    }
    // Where to issue an error, if any.
    Tree errorTree = atypeFactory.getFieldInvariantAnnotationTree(classTree.getModifiers().getAnnotations());
    if (errorTree == null) {
        // If the annotation was inherited, then there is no annotation tree, so issue the
        // error on the class.
        errorTree = classTree;
    }
    // Checks #4 (see method Javadoc)
    if (!invariants.isWellFormed()) {
        checker.report(Result.failure("field.invariant.not.wellformed"), errorTree);
        return;
    }
    TypeMirror superClass = elt.getSuperclass();
    List<String> fieldsNotFound = new ArrayList<>(invariants.getFields());
    Set<VariableElement> fieldElts = ElementUtils.findFieldsInTypeOrSuperType(superClass, fieldsNotFound);
    // Checks that fields are declared in super class. (#2b)
    if (!fieldsNotFound.isEmpty()) {
        String notFoundString = PluginUtil.join(", ", fieldsNotFound);
        checker.report(Result.failure("field.invariant.not.found", notFoundString), errorTree);
    }
    FieldInvariants superInvar = atypeFactory.getFieldInvariants(TypesUtils.getTypeElement(superClass));
    if (superInvar != null) {
        // Checks #3 (see method Javadoc)
        Result superError = invariants.isSuperInvariant(superInvar, atypeFactory);
        if (superError != null) {
            checker.report(superError, errorTree);
        }
    }
    List<String> notFinal = new ArrayList<>();
    for (VariableElement field : fieldElts) {
        String fieldName = field.getSimpleName().toString();
        if (!ElementUtils.isFinal(field)) {
            notFinal.add(fieldName);
        }
        AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(field);
        List<AnnotationMirror> annos = invariants.getQualifiersFor(field.getSimpleName());
        for (AnnotationMirror invariantAnno : annos) {
            AnnotationMirror declaredAnno = type.getEffectiveAnnotationInHierarchy(invariantAnno);
            if (declaredAnno == null) {
                // invariant anno isn't in this hierarchy
                continue;
            }
            if (!atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, declaredAnno)) {
                // Checks #3
                checker.report(Result.failure("field.invariant.not.subtype", fieldName, invariantAnno, declaredAnno), errorTree);
            }
        }
    }
    // Checks #2a
    if (!notFinal.isEmpty()) {
        String notFinalString = PluginUtil.join(", ", notFinal);
        checker.report(Result.failure("field.invariant.not.final", notFinalString), errorTree);
    }
}
Also used : FieldInvariants(org.checkerframework.framework.util.FieldInvariants) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TransferResult(org.checkerframework.dataflow.analysis.TransferResult) PurityResult(org.checkerframework.dataflow.util.PurityChecker.PurityResult) Result(org.checkerframework.framework.source.Result) AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) 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) 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) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) 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)

Aggregations

AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)188 AnnotationMirror (javax.lang.model.element.AnnotationMirror)42 ExpressionTree (com.sun.source.tree.ExpressionTree)32 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)27 Tree (com.sun.source.tree.Tree)25 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)25 VariableTree (com.sun.source.tree.VariableTree)22 ArrayList (java.util.ArrayList)22 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)21 MethodTree (com.sun.source.tree.MethodTree)20 TypeVariable (javax.lang.model.type.TypeVariable)19 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)18 AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)17 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)16 TypeMirror (javax.lang.model.type.TypeMirror)16 VariableElement (javax.lang.model.element.VariableElement)15 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)13 MemberSelectTree (com.sun.source.tree.MemberSelectTree)13 NewClassTree (com.sun.source.tree.NewClassTree)13 Element (javax.lang.model.element.Element)13