Search in sources :

Example 1 with AnnotatedArrayType

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

the class WholeProgramInferenceScenesHelper method updateTypeElementFromATM.

/**
 * Updates an {@link scenelib.annotations.el.ATypeElement} to have the annotations of an {@link
 * org.checkerframework.framework.type.AnnotatedTypeMirror} passed as argument. Annotations in
 * the original set that should be ignored (see {@link #shouldIgnore}) are not added to the
 * resulting set. This method also checks if the AnnotatedTypeMirror has explicit annotations in
 * source code, and if that is the case no annotations are added for that location.
 *
 * <p>This method removes from the ATypeElement all annotations supported by atf before
 * inserting new ones. It is assumed that every time this method is called, the
 * AnnotatedTypeMirror has a better type estimate for the ATypeElement. Therefore, it is not a
 * problem to remove all annotations before inserting the new annotations.
 *
 * @param newATM the AnnotatedTypeMirror whose annotations will be added to the ATypeElement
 * @param curATM used to check if the element which will be updated has explicit annotations in
 *     source code
 * @param atf the annotated type factory of a given type system, whose type hierarchy will be
 *     used
 * @param typeToUpdate the ATypeElement which will be updated
 * @param idx used to write annotations on compound types of an ATypeElement
 * @param defLoc the location where the annotation will be added
 */
private void updateTypeElementFromATM(AnnotatedTypeMirror newATM, AnnotatedTypeMirror curATM, AnnotatedTypeFactory atf, ATypeElement typeToUpdate, int idx, TypeUseLocation defLoc) {
    // The others stay intact.
    if (idx == 1) {
        // This if avoids clearing the annotations multiple times in cases
        // of type variables and compound types.
        Set<Annotation> annosToRemove = getSupportedAnnosInSet(typeToUpdate.tlAnnotationsHere, atf);
        // This method may be called consecutive times for the same ATypeElement.
        // Each time it is called, the AnnotatedTypeMirror has a better type
        // estimate for the ATypeElement. Therefore, it is not a problem to remove
        // all annotations before inserting the new annotations.
        typeToUpdate.tlAnnotationsHere.removeAll(annosToRemove);
    }
    // Only update the ATypeElement if there are no explicit annotations
    if (curATM.getExplicitAnnotations().size() == 0) {
        for (AnnotationMirror am : newATM.getAnnotations()) {
            addAnnotationsToATypeElement(newATM, atf, typeToUpdate, defLoc, am, curATM.hasEffectiveAnnotation(am));
        }
    } else if (curATM.getKind() == TypeKind.TYPEVAR) {
        // vars upper bound from being inserted.
        for (AnnotationMirror am : newATM.getAnnotations()) {
            if (curATM.getAnnotationInHierarchy(am) != null) {
                // in the same hierarchy.
                break;
            }
            addAnnotationsToATypeElement(newATM, atf, typeToUpdate, defLoc, am, curATM.hasEffectiveAnnotation(am));
        }
    }
    // Recursively update compound type and type variable type if they exist.
    if (newATM.getKind() == TypeKind.ARRAY && curATM.getKind() == TypeKind.ARRAY) {
        AnnotatedArrayType newAAT = (AnnotatedArrayType) newATM;
        AnnotatedArrayType oldAAT = (AnnotatedArrayType) curATM;
        updateTypeElementFromATM(newAAT.getComponentType(), oldAAT.getComponentType(), atf, typeToUpdate.innerTypes.vivify(new InnerTypeLocation(TypeAnnotationPosition.getTypePathFromBinary(Collections.nCopies(2 * idx, 0)))), idx + 1, defLoc);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) InnerTypeLocation(scenelib.annotations.el.InnerTypeLocation) Annotation(scenelib.annotations.Annotation)

Example 2 with AnnotatedArrayType

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

the class StubParser method annotateAsArray.

/**
 * Add the annotations from {@code type} to {@code atype}. Type annotations that parsed as
 * declaration annotations (ie those in {@code declAnnos} are applied to the innermost component
 * type.
 *
 * @param atype annotated type to which to add annotations
 * @param type parsed type
 * @param declAnnos annotations stored on the declaration of the variable with this type or null
 */
private void annotateAsArray(AnnotatedArrayType atype, ReferenceType type, NodeList<AnnotationExpr> declAnnos) {
    annotateInnermostComponentType(atype, declAnnos);
    Type typeDef = type;
    AnnotatedTypeMirror currentAtype = atype;
    while (typeDef.isArrayType() && currentAtype.getKind() == TypeKind.ARRAY) {
        // handle generic type
        clearAnnotations(currentAtype, typeDef);
        List<AnnotationExpr> annotations = typeDef.getAnnotations();
        if (annotations != null) {
            annotate(currentAtype, annotations);
        }
        typeDef = ((com.github.javaparser.ast.type.ArrayType) typeDef).getComponentType();
        currentAtype = ((AnnotatedArrayType) currentAtype).getComponentType();
        if (typeDef.isArrayType() ^ currentAtype.getKind() == TypeKind.ARRAY) {
            stubWarn("Mismatched array lengths; atype: " + atype + "%n  type: " + type);
        }
    }
}
Also used : ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) Type(com.github.javaparser.ast.type.Type) ArrayType(javax.lang.model.type.ArrayType) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) ReferenceType(com.github.javaparser.ast.type.ReferenceType) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) WildcardType(com.github.javaparser.ast.type.WildcardType) AnnotationExpr(com.github.javaparser.ast.expr.AnnotationExpr) MarkerAnnotationExpr(com.github.javaparser.ast.expr.MarkerAnnotationExpr) SingleMemberAnnotationExpr(com.github.javaparser.ast.expr.SingleMemberAnnotationExpr) NormalAnnotationExpr(com.github.javaparser.ast.expr.NormalAnnotationExpr) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 3 with AnnotatedArrayType

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

the class DefaultReflectionResolver method resolveMethodCall.

/**
 * Resolves a call to {@link Method#invoke(Object, Object...)}.
 *
 * @param factory the {@link AnnotatedTypeFactory} of the underlying type system
 * @param tree the method invocation tree that has to be resolved
 * @param origResult the original result from {@code factory.methodFromUse}.
 */
private Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolveMethodCall(AnnotatedTypeFactory factory, MethodInvocationTree tree, Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> origResult) {
    debugReflection("Try to resolve reflective method call: " + tree);
    List<MethodInvocationTree> possibleMethods = resolveReflectiveMethod(tree, factory);
    // Reflective method could not be resolved
    if (possibleMethods.size() == 0) {
        return origResult;
    }
    Set<? extends AnnotationMirror> returnLub = null;
    Set<? extends AnnotationMirror> receiverGlb = null;
    Set<? extends AnnotationMirror> paramsGlb = null;
    // and parameter types
    for (MethodInvocationTree resolvedTree : possibleMethods) {
        debugReflection("Resolved method invocation: " + resolvedTree);
        if (!checkMethodAgruments(resolvedTree)) {
            debugReflection("Spoofed tree's arguments did not match declaration" + resolvedTree.toString());
            // in QualifierPolymorphism.PolyCollector.visitArray(...)
            continue;
        }
        Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolvedResult = factory.methodFromUse(resolvedTree);
        // Lub return types
        returnLub = lub(returnLub, resolvedResult.first.getReturnType().getAnnotations(), factory);
        // Check for static methods whose receiver is null
        if (resolvedResult.first.getReceiverType() == null) {
            // If the method is static the first argument to Method.invoke isn't used,
            // so assume top.
            receiverGlb = glb(receiverGlb, factory.getQualifierHierarchy().getTopAnnotations(), factory);
        } else {
            receiverGlb = glb(receiverGlb, resolvedResult.first.getReceiverType().getAnnotations(), factory);
        }
        // the types of different formal parameters.
        for (AnnotatedTypeMirror mirror : resolvedResult.first.getParameterTypes()) {
            paramsGlb = glb(paramsGlb, mirror.getAnnotations(), factory);
        }
    }
    if (returnLub == null) {
        // None of the spoofed tree's arguments matched the declared method
        return origResult;
    }
    /*
         * Clear all original (return, receiver, parameter type) annotations and
         * set lub/glb annotations from resolved method(s)
         */
    // return value
    origResult.first.getReturnType().clearAnnotations();
    origResult.first.getReturnType().addAnnotations(returnLub);
    // receiver type
    origResult.first.getParameterTypes().get(0).clearAnnotations();
    origResult.first.getParameterTypes().get(0).addAnnotations(receiverGlb);
    // parameter types
    if (paramsGlb != null) {
        AnnotatedArrayType origArrayType = (AnnotatedArrayType) origResult.first.getParameterTypes().get(1);
        origArrayType.getComponentType().clearAnnotations();
        origArrayType.getComponentType().addAnnotations(paramsGlb);
    }
    debugReflection("Resolved annotations: " + origResult.first);
    return origResult;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) List(java.util.List) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 4 with AnnotatedArrayType

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

the class TypeFromExpressionVisitor method visitNewArray.

@Override
public AnnotatedTypeMirror visitNewArray(NewArrayTree node, AnnotatedTypeFactory f) {
    // Don't use fromTypeTree here, because node.getType() is not an
    // array type!
    AnnotatedArrayType result = (AnnotatedArrayType) f.type(node);
    if (// e.g., byte[] b = {(byte)1, (byte)2};
    node.getType() == null)
        return result;
    annotateArrayAsArray(result, node, f);
    return result;
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)

Example 5 with AnnotatedArrayType

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

the class AnnotatedTypes method getAnnotatedTypeMirrorOfParameter.

/**
 * Given an AnnotatedExecutableType of a method or constructor declaration, get the parameter
 * type expect at the indexth position (unwrapping var args if necessary).
 *
 * @param methodType AnnotatedExecutableType of method or constructor containing parameter to
 *     return
 * @param index position of parameter type to return
 * @return if that parameter is a varArgs, return the component of the var args and NOT the
 *     array type. Otherwise, return the exact type of the parameter in the index position.
 */
public static AnnotatedTypeMirror getAnnotatedTypeMirrorOfParameter(AnnotatedExecutableType methodType, int index) {
    List<AnnotatedTypeMirror> parameterTypes = methodType.getParameterTypes();
    boolean hasVarArg = methodType.getElement().isVarArgs();
    final int lastIndex = parameterTypes.size() - 1;
    final AnnotatedTypeMirror lastType = parameterTypes.get(lastIndex);
    final boolean parameterBeforeVarargs = index < lastIndex;
    if (!parameterBeforeVarargs && lastType instanceof AnnotatedArrayType) {
        final AnnotatedArrayType arrayType = (AnnotatedArrayType) lastType;
        if (hasVarArg) {
            return arrayType.getComponentType();
        }
    }
    return parameterTypes.get(index);
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)23 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)15 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)6 ExpressionTree (com.sun.source.tree.ExpressionTree)4 NewArrayTree (com.sun.source.tree.NewArrayTree)4 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)4 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)3 Tree (com.sun.source.tree.Tree)3 TypeCastTree (com.sun.source.tree.TypeCastTree)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 AnnotationMirror (javax.lang.model.element.AnnotationMirror)3 AnnotatedWildcardType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)3 AnnotationTree (com.sun.source.tree.AnnotationTree)2 AssignmentTree (com.sun.source.tree.AssignmentTree)2 ClassTree (com.sun.source.tree.ClassTree)2 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)2 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)2 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)2 IdentifierTree (com.sun.source.tree.IdentifierTree)2