Search in sources :

Example 6 with AnnotationMirrorMap

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

the class SupertypesSolver method leastUpperBound.

/**
 * Successively calls least upper bound on the elements of types. Unlike
 * AnnotatedTypes.leastUpperBound, this method will box primitives if necessary
 */
public static AnnotatedTypeMirror leastUpperBound(final TypeVariable target, final AnnotatedTypeFactory typeFactory, final Map<AnnotatedTypeMirror, AnnotationMirrorSet> types) {
    QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    AnnotatedTypeVariable targetsDeclaredType = (AnnotatedTypeVariable) typeFactory.getAnnotatedType(target.asElement());
    final AnnotationMirrorMap<AnnotationMirror> lowerBoundAnnos = TypeArgInferenceUtil.createHierarchyMap(new AnnotationMirrorSet(targetsDeclaredType.getLowerBound().getEffectiveAnnotations()), qualifierHierarchy);
    final Iterator<Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet>> typesIter = types.entrySet().iterator();
    if (!typesIter.hasNext()) {
        throw new BugInCF("Calling LUB on empty list.");
    }
    /**
     * If a constraint implies that a type parameter Ti is a supertype of an annotated type mirror
     * Ai but only in a subset of all qualifier hierarchies then for all other qualifier hierarchies
     * replace the primary annotation on Ai with the lowest possible annotation (ensuring that it
     * won't be the LUB unless there are no other constraints, or all other constraints imply the
     * bottom annotation is the LUB). Note: Even if we choose bottom as the lub here, the assignment
     * context may raise this annotation.
     */
    final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> head = typesIter.next();
    AnnotatedTypeMirror lubType = groundMissingHierarchies(head, lowerBoundAnnos);
    AnnotatedTypeMirror nextType = null;
    while (typesIter.hasNext()) {
        nextType = groundMissingHierarchies(typesIter.next(), lowerBoundAnnos);
        if (lubType.getKind().isPrimitive()) {
            if (!nextType.getKind().isPrimitive()) {
                lubType = typeFactory.getBoxedType((AnnotatedPrimitiveType) lubType);
            }
        } else if (nextType.getKind().isPrimitive()) {
            if (!lubType.getKind().isPrimitive()) {
                nextType = typeFactory.getBoxedType((AnnotatedPrimitiveType) nextType);
            }
        }
        lubType = AnnotatedTypes.leastUpperBound(typeFactory, lubType, nextType);
    }
    return lubType;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType)

Example 7 with AnnotationMirrorMap

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

the class SupertypesSolver method mergeLubAnnosWithEqualities.

/**
 * We previously found a type that is equal to target but not in all hierarchies. Use the primary
 * annotations from the lub annos to fill in the missing annotations in this type. Use that type
 * as the inferred argument.
 *
 * <p>If we failed to infer any annotation for a given hierarchy, either previously from
 * equalities or from the lub, return null.
 */
protected InferredType mergeLubAnnosWithEqualities(final TypeVariable target, final AnnotationMirrorMap<AnnotationMirror> lubAnnos, final ConstraintMap constraintMap, final AnnotatedTypeFactory typeFactory) {
    final Equalities equalities = constraintMap.getConstraints(target).equalities;
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(typeFactory.getQualifierHierarchy().getTopAnnotations());
    if (!equalities.types.isEmpty()) {
        // there should be only equality type if any at this point
        final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> eqEntry = equalities.types.entrySet().iterator().next();
        final AnnotatedTypeMirror equalityType = eqEntry.getKey();
        final AnnotationMirrorSet equalityAnnos = eqEntry.getValue();
        boolean failed = false;
        for (final AnnotationMirror top : tops) {
            if (!equalityAnnos.contains(top)) {
                final AnnotationMirror lubAnno = lubAnnos.get(top);
                if (lubAnno == null) {
                    failed = true;
                } else {
                    equalityType.replaceAnnotation(lubAnno);
                    equalityAnnos.add(top);
                }
            }
        }
        if (!failed) {
            return new InferredType(equalityType);
        }
    }
    return null;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) Equalities(org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 8 with AnnotationMirrorMap

use of org.checkerframework.framework.util.AnnotationMirrorMap 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 9 with AnnotationMirrorMap

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

the class DefaultQualifierPolymorphism method replace.

@Override
protected void replace(AnnotatedTypeMirror type, AnnotationMirrorMap<AnnotationMirror> replacements) {
    for (Map.Entry<AnnotationMirror, AnnotationMirror> pqentry : replacements.entrySet()) {
        AnnotationMirror poly = pqentry.getKey();
        if (type.hasAnnotation(poly)) {
            type.removeAnnotation(poly);
            AnnotationMirror qual;
            if (polyInstantiationForQualifierParameter.containsKey(poly)) {
                qual = polyInstantiationForQualifierParameter.get(poly);
            } else {
                qual = pqentry.getValue();
            }
            type.replaceAnnotation(qual);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Map(java.util.Map) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap)

Aggregations

AnnotationMirror (javax.lang.model.element.AnnotationMirror)9 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)9 Map (java.util.Map)7 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)6 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)6 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)4 ArrayList (java.util.ArrayList)3 LinkedHashMap (java.util.LinkedHashMap)3 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)3 TypeVariable (javax.lang.model.type.TypeVariable)2 Types (javax.lang.model.util.Types)2 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)2 BugInCF (org.checkerframework.javacutil.BugInCF)2 IdentityHashMap (java.util.IdentityHashMap)1 AnnotatedPrimitiveType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType)1 TypeHierarchy (org.checkerframework.framework.type.TypeHierarchy)1 AnnotatedTypes (org.checkerframework.framework.util.AnnotatedTypes)1 Equalities (org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities)1 Subtypes (org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Subtypes)1