Search in sources :

Example 11 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 (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.getContext().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 : AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) ArrayList(java.util.ArrayList) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 12 with AnnotationMirrorSet

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

the class ConstraintMap method addTargetSupertype.

/**
 * Add a constraint indicating that target is a supertype of subtype in the given qualifier
 * hierarchies
 *
 * @param hierarchies a set of TOP annotations
 */
public void addTargetSupertype(final TypeVariable target, final TypeVariable subtype, AnnotationMirrorSet hierarchies) {
    final Supertypes supertypes = targetToRecords.get(target).supertypes;
    final AnnotationMirrorSet supertypeTops = supertypes.targets.get(subtype);
    if (supertypeTops == null) {
        supertypes.targets.put(subtype, new AnnotationMirrorSet(hierarchies));
    } else {
        supertypeTops.addAll(hierarchies);
    }
}
Also used : AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) Supertypes(org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Supertypes)

Example 13 with AnnotationMirrorSet

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

the class ConstraintMap method addPrimarySupertype.

/**
 * Add a constraint indicating that target's primary annotations are subtypes of the given
 * annotations
 */
public void addPrimarySupertype(final TypeVariable target, QualifierHierarchy qualifierHierarchy, final AnnotationMirrorSet annos) {
    final Supertypes supertypes = targetToRecords.get(target).supertypes;
    for (final AnnotationMirror anno : annos) {
        final AnnotationMirror top = qualifierHierarchy.getTopAnnotation(anno);
        AnnotationMirrorSet entries = supertypes.primaries.get(top);
        if (entries == null) {
            entries = new AnnotationMirrorSet();
            supertypes.primaries.put(top, entries);
        }
        entries.add(anno);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) Supertypes(org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Supertypes)

Example 14 with AnnotationMirrorSet

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

the class ConstraintMap method addTypeEqualities.

/**
 * Add a constraint indicating that target is equal to type in the given hierarchies
 *
 * @param hierarchies a set of TOP annotations
 */
public void addTypeEqualities(TypeVariable target, AnnotatedTypeMirror type, AnnotationMirrorSet hierarchies) {
    final Equalities equalities = targetToRecords.get(target).equalities;
    final AnnotationMirrorSet equalityTops = equalities.types.get(type);
    if (equalityTops == null) {
        equalities.types.put(type, new AnnotationMirrorSet(hierarchies));
    } else {
        equalityTops.addAll(hierarchies);
    }
}
Also used : Equalities(org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Equalities) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet)

Example 15 with AnnotationMirrorSet

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

the class ConstraintMapBuilder method build.

/**
 * Let Ti be a the ith target being inferred Let ATV(i) be the annotated type variable that
 * represents as use of Ti which may or may not have primary annotations. Let ATM be an
 * annotated type mirror that may or may not be target Tx, or have a component target Tx Let Ai
 * be the type argument we are trying to infer for Ti
 *
 * <p>We have a set of constraints of the form: {@code ATV(i) <?> ATM}
 *
 * <p>Where {@code <?>} is either a subtype ({@code <:}), supertype ({@code :>}), or equality
 * relationship ({@code =}).
 *
 * <p>Regardless of what {@code <?>} is, a constraint will only imply constraints on Ai in a
 * given hierarchy if ATV(i) does NOT have a primary annotation in that hierarchy. That is:
 *
 * <p>E.g. Let ATV(i) be @NonNull Ti, the constraints @NonNull Ti = @NonNull @Initialized String
 * does not imply any primary annotation in the Nullness hierarchy for type argument Ai because
 * the Annotated type mirror has a primary annotation in the NUllness hierarchy.
 *
 * <p>However, it does imply that Ai has a primary annotation of @Initialized since ATV(i) has
 * no primary annotation in the initialization hierarchy.
 *
 * <p>Note, constraints come in 2 forms:
 *
 * <ul>
 *   <li>between a target and a concrete AnnotatedTypeMirror. E.g., As seen above {@code
 *       (@NonNull Ti = @NonNull @Initialized String)}
 *   <li>between two targets E.g., {@code (@NonNull Ti = Tj)}
 * </ul>
 */
public ConstraintMap build(Set<TypeVariable> targets, Set<TUConstraint> constraints, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    final ConstraintMap result = new ConstraintMap(targets);
    final AnnotationMirrorSet tAnnos = new AnnotationMirrorSet();
    final AnnotationMirrorSet uAnnos = new AnnotationMirrorSet();
    final AnnotationMirrorSet hierarchiesInRelation = new AnnotationMirrorSet();
    for (TUConstraint constraint : constraints) {
        tAnnos.clear();
        uAnnos.clear();
        hierarchiesInRelation.clear();
        final AnnotatedTypeVariable typeT = constraint.typeVariable;
        final AnnotatedTypeMirror typeU = constraint.relatedType;
        // The inferred type of T should be T.
        if (!constraint.uIsArg && typeU.getKind() == TypeKind.TYPEVAR && targets.contains((TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()))) {
            if (typeT.getAnnotations().isEmpty() && typeU.getAnnotations().isEmpty()) {
                hierarchiesInRelation.addAll(tops);
            } else {
                for (AnnotationMirror top : tops) {
                    final AnnotationMirror tAnno = typeT.getAnnotationInHierarchy(top);
                    final AnnotationMirror uAnno = typeU.getAnnotationInHierarchy(top);
                    if (tAnno == null) {
                        if (uAnno == null) {
                            hierarchiesInRelation.add(top);
                        } else {
                            tAnnos.add(uAnno);
                        }
                    } else {
                        if (uAnno == null) {
                            uAnnos.add(tAnno);
                        } else {
                        // This tells us nothing, they both should be equal but either way
                        // we gain no information if both type vars have annotations
                        }
                    }
                }
                // This case also covers the case where i = j.
                if (!tAnnos.isEmpty()) {
                    addToPrimaryRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), constraint, result, tAnnos, qualifierHierarchy);
                }
                if (!uAnnos.isEmpty()) {
                    addToPrimaryRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()), constraint, result, uAnnos, qualifierHierarchy);
                }
            }
            // <?> Tj and i != j)
            if (!TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()).equals(TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()))) {
                addToTargetRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), (TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()), result, constraint, hierarchiesInRelation);
            }
        } else {
            for (AnnotationMirror top : tops) {
                final AnnotationMirror tAnno = typeT.getAnnotationInHierarchy(top);
                if (tAnno == null) {
                    hierarchiesInRelation.add(top);
                }
            }
            addToTypeRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), typeU, result, constraint, hierarchiesInRelation);
        }
    }
    return result;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) TUConstraint(org.checkerframework.framework.util.typeinference.constraint.TUConstraint) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)24 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)15 AnnotationMirror (javax.lang.model.element.AnnotationMirror)12 TypeVariable (javax.lang.model.type.TypeVariable)8 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)8 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)7 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)6 LinkedHashMap (java.util.LinkedHashMap)4 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)4 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 Map (java.util.Map)2 Entry (java.util.Map.Entry)2 Types (javax.lang.model.util.Types)2 AnnotatedPrimitiveType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType)1 TypeHierarchy (org.checkerframework.framework.type.TypeHierarchy)1 AnnotatedTypes (org.checkerframework.framework.util.AnnotatedTypes)1 TUConstraint (org.checkerframework.framework.util.typeinference.constraint.TUConstraint)1