Search in sources :

Example 26 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet in project checker-framework by typetools.

the class GlbUtil method glbAll.

/**
 * Note: This method can be improved for wildcards and type variables.
 *
 * @return the greatest lower bound of typeMirrors. If any of the type mirrors are incomparable,
 *     use an AnnotatedNullType that will contain the greatest lower bounds of the primary
 *     annotations of typeMirrors.
 */
public static AnnotatedTypeMirror glbAll(final Map<AnnotatedTypeMirror, AnnotationMirrorSet> typeMirrors, final AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    if (typeMirrors.isEmpty()) {
        return null;
    }
    // dtermine the greatest lower bounds for the primary annotations
    AnnotationMirrorMap<AnnotationMirror> glbPrimaries = new AnnotationMirrorMap<>();
    for (Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> tmEntry : typeMirrors.entrySet()) {
        final AnnotationMirrorSet typeAnnoHierarchies = tmEntry.getValue();
        final AnnotatedTypeMirror type = tmEntry.getKey();
        for (AnnotationMirror top : typeAnnoHierarchies) {
            // TODO: When all of the typeMirrors are either wildcards or type variables than the
            // greatest lower bound should involve handling the bounds individually rather than
            // using the effective annotation.  We are doing this for expediency.
            final AnnotationMirror typeAnno = type.getEffectiveAnnotationInHierarchy(top);
            final AnnotationMirror currentAnno = glbPrimaries.get(top);
            if (typeAnno != null && currentAnno != null) {
                glbPrimaries.put(top, qualifierHierarchy.greatestLowerBound(currentAnno, typeAnno));
            } else if (typeAnno != null) {
                glbPrimaries.put(top, typeAnno);
            }
        }
    }
    final List<AnnotatedTypeMirror> glbTypes = new ArrayList<>();
    // create a copy of all of the types and apply the glb primary annotation
    final AnnotationMirrorSet values = new AnnotationMirrorSet(glbPrimaries.values());
    for (AnnotatedTypeMirror type : typeMirrors.keySet()) {
        if (type.getKind() != TypeKind.TYPEVAR || !qualifierHierarchy.isSubtype(type.getEffectiveAnnotations(), values)) {
            final AnnotatedTypeMirror copy = type.deepCopy();
            copy.replaceAnnotations(values);
            glbTypes.add(copy);
        } else {
            // if the annotations came from the upper bound of this typevar
            // we do NOT want to place them as primary annotations (and destroy the
            // type vars lower bound)
            glbTypes.add(type);
        }
    }
    final TypeHierarchy typeHierarchy = typeFactory.getTypeHierarchy();
    // sort placing supertypes first
    sortForGlb(glbTypes, typeFactory);
    // find the lowest type in the list that is not an AnnotatedNullType
    AnnotatedTypeMirror glbType = glbTypes.get(0);
    int index = 1;
    while (index < glbTypes.size()) {
        // NULL types
        if (glbType.getKind() != TypeKind.NULL) {
            glbType = glbTypes.get(index);
        }
        index += 1;
    }
    // if the lowest type is a subtype of all glbTypes then it is the GLB, otherwise there are two
    // types in glbTypes that are incomparable and we need to use bottom (AnnotatedNullType)
    boolean incomparable = false;
    for (final AnnotatedTypeMirror type : glbTypes) {
        if (!incomparable && type.getKind() != TypeKind.NULL && (!TypesUtils.isErasedSubtype(glbType.getUnderlyingType(), type.getUnderlyingType(), typeFactory.getChecker().getTypeUtils()) || !typeHierarchy.isSubtype(glbType, type))) {
            incomparable = true;
        }
    }
    // we had two incomparable types in glbTypes
    if (incomparable) {
        return createBottom(typeFactory, glbType.getEffectiveAnnotations());
    }
    return glbType;
}
Also used : AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) Map(java.util.Map)

Example 27 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet in project checker-framework by typetools.

the class DefaultQualifierForUseTypeAnnotator method getDefaultAnnosForUses.

/**
 * Returns the set of qualifiers that should be applied to unannotated uses of this element.
 */
protected Set<AnnotationMirror> getDefaultAnnosForUses(Element element) {
    if (typeFactory.shouldCache && elementToDefaults.containsKey(element)) {
        return elementToDefaults.get(element);
    }
    Set<AnnotationMirror> explictAnnos = getExplicitAnnos(element);
    Set<AnnotationMirror> defaultAnnos = getDefaultQualifierForUses(element);
    Set<AnnotationMirror> noDefaultAnnos = getHierarchiesNoDefault(element);
    AnnotationMirrorSet annosToApply = new AnnotationMirrorSet();
    for (AnnotationMirror top : typeFactory.getQualifierHierarchy().getTopAnnotations()) {
        if (AnnotationUtils.containsSame(noDefaultAnnos, top)) {
            continue;
        }
        AnnotationMirror defaultAnno = typeFactory.getQualifierHierarchy().findAnnotationInHierarchy(defaultAnnos, top);
        if (defaultAnno != null) {
            annosToApply.add(defaultAnno);
        } else {
            AnnotationMirror explict = typeFactory.getQualifierHierarchy().findAnnotationInHierarchy(explictAnnos, top);
            if (explict != null) {
                annosToApply.add(explict);
            }
        }
    }
    // If parsing stub files, then the annosToApply is incomplete, so don't cache them.
    if (typeFactory.shouldCache && !typeFactory.stubTypes.isParsing() && !typeFactory.ajavaTypes.isParsing()) {
        elementToDefaults.put(element, annosToApply);
    }
    return annosToApply;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet)

Example 28 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet in project checker-framework by typetools.

the class AnnotatedTypeFactory method annotateCapturedTypeVar.

/**
 * Set the annotated bounds for fresh type variable {@code capturedTypeVar}, so that it is the
 * capture of {@code wildcard}. Also, sets {@code capturedTypeVar} primary annotation if the
 * annotation on the bounds is identical.
 *
 * @param typeVarToAnnotatedTypeArg mapping from a (type mirror) type variable to its (annotated
 *     type mirror) type argument
 * @param capturedTypeVarToAnnotatedTypeVar mapping from a captured type variable to its {@link
 *     AnnotatedTypeMirror}
 * @param wildcard wildcard which is converted to {@code capturedTypeVar}
 * @param typeVariable type variable for which {@code wildcard} is a type argument
 * @param capturedTypeVar the fresh type variable which is side-effected by this method
 */
private void annotateCapturedTypeVar(Map<TypeVariable, AnnotatedTypeMirror> typeVarToAnnotatedTypeArg, Map<TypeVariable, AnnotatedTypeVariable> capturedTypeVarToAnnotatedTypeVar, AnnotatedWildcardType wildcard, AnnotatedTypeVariable typeVariable, AnnotatedTypeVariable capturedTypeVar) {
    AnnotatedTypeMirror typeVarUpperBound = typeVarSubstitutor.substituteWithoutCopyingTypeArguments(typeVarToAnnotatedTypeArg, typeVariable.getUpperBound());
    AnnotatedTypeMirror upperBound = AnnotatedTypes.annotatedGLB(this, typeVarUpperBound, wildcard.getExtendsBound());
    // There is a bug in javac such that the upper bound of the captured type variable is not the
    // greatest lower bound. So the captureTypeVar.getUnderlyingType().getUpperBound() may not
    // be the same type as upperbound.getUnderlyingType().  See
    // framework/tests/all-systems/Issue4890Interfaces.java,
    // framework/tests/all-systems/Issue4890.java and framework/tests/all-systems/Issue4877.java.
    capturedTypeVar.setUpperBound(upperBound);
    // typeVariable's lower bound is a NullType, so there's nothing to substitute.
    AnnotatedTypeMirror lowerBound = AnnotatedTypes.leastUpperBound(this, typeVariable.getLowerBound(), wildcard.getSuperBound());
    capturedTypeVar.setLowerBound(lowerBound);
    // Add as a primary annotation any qualifiers that are the same on the upper and lower bound.
    AnnotationMirrorSet p = new AnnotationMirrorSet(capturedTypeVar.getUpperBound().getAnnotations());
    p.retainAll(capturedTypeVar.getLowerBound().getAnnotations());
    capturedTypeVar.replaceAnnotations(p);
    capturedTypeVarSubstitutor.substitute(capturedTypeVar, capturedTypeVarToAnnotatedTypeVar);
}
Also used : AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet)

Example 29 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet in project checker-framework by typetools.

the class QualifierUpperBounds method getBoundQualifiers.

/**
 * Returns the set of qualifiers that are the upper bounds for a use of the type.
 *
 * @param type the TypeMirror
 * @return the set of qualifiers that are the upper bounds for a use of the type
 */
public Set<AnnotationMirror> getBoundQualifiers(TypeMirror type) {
    AnnotationMirrorSet bounds = new AnnotationMirrorSet();
    String qname;
    if (type.getKind() == TypeKind.DECLARED) {
        DeclaredType declaredType = (DeclaredType) type;
        bounds.addAll(getAnnotationFromElement(declaredType.asElement()));
        qname = TypesUtils.getQualifiedName(declaredType);
    } else if (type.getKind().isPrimitive()) {
        qname = type.toString();
    } else {
        qname = null;
    }
    if (qname != null && types.containsKey(qname)) {
        Set<AnnotationMirror> fnd = types.get(qname);
        addMissingAnnotations(bounds, fnd);
    }
    if (typeKinds.containsKey(type.getKind())) {
        Set<AnnotationMirror> fnd = typeKinds.get(type.getKind());
        addMissingAnnotations(bounds, fnd);
    }
    addMissingAnnotations(bounds, atypeFactory.getDefaultTypeDeclarationBounds());
    return bounds;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)29 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)17 AnnotationMirror (javax.lang.model.element.AnnotationMirror)16 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)12 Map (java.util.Map)11 LinkedHashMap (java.util.LinkedHashMap)8 TypeVariable (javax.lang.model.type.TypeVariable)8 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)8 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)8 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)6 Equalities (org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities)4 Subtypes (org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Subtypes)4 ArrayList (java.util.ArrayList)3 Supertypes (org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Supertypes)3 BugInCF (org.checkerframework.javacutil.BugInCF)3 Types (javax.lang.model.util.Types)2 Entry (java.util.Map.Entry)1 DeclaredType (javax.lang.model.type.DeclaredType)1 AnnotatedPrimitiveType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType)1 TypeHierarchy (org.checkerframework.framework.type.TypeHierarchy)1