Search in sources :

Example 11 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class AnnotatedTypes method annotatedGLB.

/**
 * Returns the "annotated greatest lower bound" of {@code type1} and {@code type2}.
 *
 * <p>Suppose that there is an expression e with annotated type T. The underlying type of T must
 * be the same as javac's type for e. (This is a requirement of the Checker Framework.) As a
 * corollary, when computing a glb of atype1 and atype2, it is required that
 * underlyingType(cfGLB(atype1, atype2) == glb(javacGLB(underlyingType(atype1),
 * underlyingType(atype2)). Because of this requirement, the return value of this method (the
 * "annotated GLB") may not be a subtype of one of the types.
 *
 * <p>The "annotated greatest lower bound" is defined as follows:
 *
 * <ol>
 *   <li>If the underlying type of {@code type1} and {@code type2} are the same, then return a
 *       copy of {@code type1} whose primary annotations are the greatest lower bound of the
 *       primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} is a subtype of the underlying type of {@code
 *       type2}, then return a copy of {@code type1} whose primary annotations are the greatest
 *       lower bound of the primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} is a supertype of the underlying type of {@code
 *       type2}, then return a copy of {@code type2} whose primary annotations are the greatest
 *       lower bound of the primary annotations on {@code type1} and {@code type2}.
 *   <li>If the underlying type of {@code type1} and {@code type2} are not in a subtyping
 *       relationship, then return an annotated intersection type whose bounds are {@code type1}
 *       and {@code type2}.
 * </ol>
 *
 * @param atypeFactory the AnnotatedTypeFactory
 * @param type1 annotated type
 * @param type2 annotated type
 * @return the annotated glb of type1 and type2
 */
public static AnnotatedTypeMirror annotatedGLB(AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) {
    TypeMirror glbJava = TypesUtils.greatestLowerBound(type1.getUnderlyingType(), type2.getUnderlyingType(), atypeFactory.getProcessingEnv());
    Types types = atypeFactory.types;
    if (types.isSubtype(type1.getUnderlyingType(), type2.getUnderlyingType())) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type1, type2);
    } else if (types.isSubtype(type2.getUnderlyingType(), type1.getUnderlyingType())) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type2, type1);
    }
    if (types.isSameType(type1.getUnderlyingType(), glbJava)) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type1, type2);
    } else if (types.isSameType(type2.getUnderlyingType(), glbJava)) {
        return glbSubtype(atypeFactory.getQualifierHierarchy(), type2, type1);
    }
    if (glbJava.getKind() != TypeKind.INTERSECTION) {
        // If one type isn't a subtype of the other, then GLB must be an intersection.
        throw new BugInCF("AnnotatedTypes#annotatedGLB: expected intersection, got [%s] %s. " + "type1: %s, type2: %s", glbJava.getKind(), glbJava, type1, type2);
    }
    QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
    Set<AnnotationMirror> set1 = AnnotatedTypes.findEffectiveLowerBoundAnnotations(qualifierHierarchy, type1);
    Set<AnnotationMirror> set2 = AnnotatedTypes.findEffectiveLowerBoundAnnotations(qualifierHierarchy, type2);
    Set<? extends AnnotationMirror> glbAnno = qualifierHierarchy.greatestLowerBounds(set1, set2);
    AnnotatedIntersectionType glb = (AnnotatedIntersectionType) AnnotatedTypeMirror.createType(glbJava, atypeFactory, false);
    List<AnnotatedTypeMirror> newBounds = new ArrayList<>(2);
    for (AnnotatedTypeMirror bound : glb.getBounds()) {
        if (types.isSameType(bound.getUnderlyingType(), type1.getUnderlyingType())) {
            newBounds.add(type1.deepCopy());
        } else if (types.isSameType(bound.getUnderlyingType(), type2.getUnderlyingType())) {
            newBounds.add(type2.deepCopy());
        } else if (type1.getKind() == TypeKind.INTERSECTION) {
            AnnotatedIntersectionType intertype1 = (AnnotatedIntersectionType) type1;
            for (AnnotatedTypeMirror otherBound : intertype1.getBounds()) {
                if (types.isSameType(bound.getUnderlyingType(), otherBound.getUnderlyingType())) {
                    newBounds.add(otherBound.deepCopy());
                }
            }
        } else if (type2.getKind() == TypeKind.INTERSECTION) {
            AnnotatedIntersectionType intertype2 = (AnnotatedIntersectionType) type2;
            for (AnnotatedTypeMirror otherBound : intertype2.getBounds()) {
                if (types.isSameType(bound.getUnderlyingType(), otherBound.getUnderlyingType())) {
                    newBounds.add(otherBound.deepCopy());
                }
            }
        } else {
            throw new BugInCF("Neither %s nor %s is one of the intersection bounds in %s. Bound: %s", type1, type2, bound, glb);
        }
    }
    glb.setBounds(newBounds);
    glb.addAnnotations(glbAnno);
    return glb;
}
Also used : Types(javax.lang.model.util.Types) AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) ArrayList(java.util.ArrayList) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 12 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class MethodApplier method applyThrowsAnnotations.

/**
 * For each thrown type, collect all the annotations for that type and apply them.
 */
private void applyThrowsAnnotations(final List<Attribute.TypeCompound> annos) throws UnexpectedAnnotationLocationException {
    final List<AnnotatedTypeMirror> thrown = methodType.getThrownTypes();
    if (thrown.isEmpty()) {
        return;
    }
    Map<AnnotatedTypeMirror, List<TypeCompound>> typeToAnnos = new LinkedHashMap<>();
    for (final AnnotatedTypeMirror thrownType : thrown) {
        typeToAnnos.put(thrownType, new ArrayList<>());
    }
    for (TypeCompound anno : annos) {
        final TypeAnnotationPosition annoPos = anno.position;
        if (annoPos.type_index >= 0 && annoPos.type_index < thrown.size()) {
            final AnnotatedTypeMirror thrownType = thrown.get(annoPos.type_index);
            typeToAnnos.get(thrownType).add(anno);
        } else {
            throw new BugInCF("MethodApplier.applyThrowsAnnotation: " + "invalid throws index " + annoPos.type_index + " for annotation: " + anno + " for element: " + ElementUtils.getQualifiedName(element));
        }
    }
    for (final Map.Entry<AnnotatedTypeMirror, List<TypeCompound>> typeToAnno : typeToAnnos.entrySet()) {
        ElementAnnotationUtil.annotateViaTypeAnnoPosition(typeToAnno.getKey(), typeToAnno.getValue());
    }
}
Also used : TypeCompound(com.sun.tools.javac.code.Attribute.TypeCompound) ArrayList(java.util.ArrayList) List(java.util.List) TypeAnnotationPosition(com.sun.tools.javac.code.TypeAnnotationPosition) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Example 13 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class TypeParamElementAnnotationApplier method applyUpperBounds.

/**
 * Applies a list of annotations to the upperBound of the type parameter. If the type of the upper
 * bound is an intersection we must first find the correct location for each annotation.
 */
private void applyUpperBounds(final List<TypeCompound> upperBounds) {
    if (!upperBounds.isEmpty()) {
        final AnnotatedTypeMirror upperBoundType = typeParam.getUpperBound();
        if (upperBoundType.getKind() == TypeKind.INTERSECTION) {
            final List<AnnotatedTypeMirror> bounds = ((AnnotatedIntersectionType) upperBoundType).getBounds();
            final int boundIndexOffset = ElementAnnotationUtil.getBoundIndexOffset(bounds);
            for (final TypeCompound anno : upperBounds) {
                final int boundIndex = anno.position.bound_index + boundIndexOffset;
                if (boundIndex < 0 || boundIndex > bounds.size()) {
                    throw new BugInCF("Invalid bound index on element annotation ( " + anno + " ) " + "for type ( " + typeParam + " ) with " + "upper bound ( " + typeParam.getUpperBound() + " ) " + "and boundIndex( " + boundIndex + " ) ");
                }
                // TODO: WHY NOT ADD?
                bounds.get(boundIndex).replaceAnnotation(anno);
            }
            ((AnnotatedIntersectionType) upperBoundType).copyIntersectionBoundAnnotations();
        } else {
            upperBoundType.addAnnotations(upperBounds);
        }
    }
}
Also used : TypeCompound(com.sun.tools.javac.code.Attribute.TypeCompound) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 14 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class AnnotatedTypes method asMemberOfImpl.

/**
 * Helper for {@link AnnotatedTypes#asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror,
 * Element)}.
 *
 * @param types the Types instance to use
 * @param atypeFactory the type factory to use
 * @param receiverType the receiver type
 * @param member the element that should be viewed as member of receiverType
 * @param memberType unsubstituted type of member
 * @return the type of member as a member of receiverType; can be an alias to memberType
 */
private static AnnotatedTypeMirror asMemberOfImpl(final Types types, final AnnotatedTypeFactory atypeFactory, final AnnotatedTypeMirror receiverType, final Element member, final AnnotatedTypeMirror memberType) {
    switch(receiverType.getKind()) {
        case ARRAY:
            // rather than Object.
            if (SyntheticArrays.isArrayClone(receiverType, member)) {
                return SyntheticArrays.replaceReturnType(member, (AnnotatedArrayType) receiverType);
            }
            return memberType;
        case TYPEVAR:
            return asMemberOf(types, atypeFactory, atypeFactory.applyCaptureConversion(((AnnotatedTypeVariable) receiverType).getUpperBound()), member, memberType);
        case WILDCARD:
            if (((AnnotatedWildcardType) receiverType).isUninferredTypeArgument()) {
                return substituteUninferredTypeArgs(atypeFactory, member, memberType);
            }
            return asMemberOf(types, atypeFactory, ((AnnotatedWildcardType) receiverType).getExtendsBound().deepCopy(), member, memberType);
        case INTERSECTION:
            AnnotatedTypeMirror result = memberType;
            TypeMirror enclosingElementType = member.getEnclosingElement().asType();
            for (AnnotatedTypeMirror bound : ((AnnotatedIntersectionType) receiverType).getBounds()) {
                if (TypesUtils.isErasedSubtype(bound.getUnderlyingType(), enclosingElementType, types)) {
                    result = substituteTypeVariables(types, atypeFactory, atypeFactory.applyCaptureConversion(bound), member, result);
                }
            }
            return result;
        case UNION:
        case DECLARED:
            return substituteTypeVariables(types, atypeFactory, receiverType, member, memberType);
        default:
            throw new BugInCF("asMemberOf called on unexpected type.%nt: %s", receiverType);
    }
}
Also used : AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 15 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class StringToJavaExpression method atFieldAccess.

/**
 * uf found Parses a string as if it were written at the declaration of the field and then
 * viewpoint-adapts the result to the use.
 *
 * @param expression a Java expression to parse
 * @param fieldAccess the field access tree
 * @param checker checker used to get the {@link
 *     javax.annotation.processing.ProcessingEnvironment} and current {@link
 *     com.sun.source.tree.CompilationUnitTree}
 * @return a {@code JavaExpression} for {@code expression}
 * @throws JavaExpressionParseException if {@code expression} cannot be parsed
 */
static JavaExpression atFieldAccess(String expression, MemberSelectTree fieldAccess, SourceChecker checker) throws JavaExpressionParseException {
    Element ele = TreeUtils.elementFromUse(fieldAccess);
    if (ele.getKind() != ElementKind.FIELD && ele.getKind() != ElementKind.ENUM_CONSTANT) {
        throw new BugInCF("Expected a field, but found %s for %s", ele.getKind(), fieldAccess);
    }
    VariableElement fieldEle = (VariableElement) ele;
    JavaExpression receiver = JavaExpression.fromTree(fieldAccess.getExpression());
    JavaExpression javaExpr = StringToJavaExpression.atFieldDecl(expression, fieldEle, checker);
    return javaExpr.atFieldAccess(receiver);
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) ViewpointAdaptJavaExpression(org.checkerframework.dataflow.expression.ViewpointAdaptJavaExpression) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) BugInCF(org.checkerframework.javacutil.BugInCF)

Aggregations

BugInCF (org.checkerframework.javacutil.BugInCF)127 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)29 ArrayList (java.util.ArrayList)28 AnnotationMirror (javax.lang.model.element.AnnotationMirror)26 TypeElement (javax.lang.model.element.TypeElement)26 TypeMirror (javax.lang.model.type.TypeMirror)25 ExecutableElement (javax.lang.model.element.ExecutableElement)24 MethodTree (com.sun.source.tree.MethodTree)20 ExpressionTree (com.sun.source.tree.ExpressionTree)18 VariableTree (com.sun.source.tree.VariableTree)18 Element (javax.lang.model.element.Element)18 ClassTree (com.sun.source.tree.ClassTree)17 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)17 NewClassTree (com.sun.source.tree.NewClassTree)17 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)16 IOException (java.io.IOException)16 Tree (com.sun.source.tree.Tree)15 Map (java.util.Map)15 List (java.util.List)14 VariableElement (javax.lang.model.element.VariableElement)14