Search in sources :

Example 21 with AnnotationMirrorSet

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

the class SupertypesSolver method targetToTypeLubs.

/**
 * For each target, lub all of the types/annotations in its supertypes constraints and return
 * the lubs
 *
 * @param remainingTargets targets that do not already have an inferred type argument
 * @param constraintMap the set of constraints for all targets
 * @return the lub determined for each target that has at least 1 supertype constraint
 */
private Lubs targetToTypeLubs(Set<TypeVariable> remainingTargets, ConstraintMap constraintMap, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    Lubs solution = new Lubs();
    AnnotationMirrorMap<AnnotationMirror> lubOfPrimaries = new AnnotationMirrorMap<>();
    List<TypeVariable> targetsSupertypesLast = new ArrayList<>(remainingTargets);
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    // If we have two type variables <A, A extends B> order them B then A
    // this is required because we will use the fact that A must be above B
    // when determining the LUB of A
    Collections.sort(targetsSupertypesLast, new Comparator<TypeVariable>() {

        @Override
        public int compare(TypeVariable o1, TypeVariable o2) {
            if (types.isSubtype(o1, o2)) {
                return -1;
            } else if (types.isSubtype(o2, o1)) {
                return 1;
            }
            return 0;
        }
    });
    for (final TypeVariable target : targetsSupertypesLast) {
        TargetConstraints targetRecord = constraintMap.getConstraints(target);
        final AnnotationMirrorMap<AnnotationMirrorSet> subtypeAnnos = targetRecord.supertypes.primaries;
        final Map<AnnotatedTypeMirror, AnnotationMirrorSet> subtypesOfTarget = targetRecord.supertypes.types;
        // If this target is a supertype of other targets and those targets have already been
        // lubbed add that LUB to the list of lubs for this target (as it must be above this
        // target).
        propagatePreviousLubs(targetRecord, solution, subtypesOfTarget);
        // lub all the primary annotations and put them in lubOfPrimaries
        lubPrimaries(lubOfPrimaries, subtypeAnnos, tops, qualifierHierarchy);
        solution.addPrimaries(target, lubOfPrimaries);
        if (subtypesOfTarget.keySet().size() > 0) {
            final AnnotatedTypeMirror lub = leastUpperBound(target, typeFactory, subtypesOfTarget);
            final AnnotationMirrorSet effectiveLubAnnos = new AnnotationMirrorSet(lub.getEffectiveAnnotations());
            for (AnnotationMirror lubAnno : effectiveLubAnnos) {
                final AnnotationMirror hierarchy = qualifierHierarchy.getTopAnnotation(lubAnno);
                final AnnotationMirror primaryLub = lubOfPrimaries.get(hierarchy);
                if (primaryLub != null) {
                    if (qualifierHierarchy.isSubtype(lubAnno, primaryLub) && !AnnotationUtils.areSame(lubAnno, primaryLub)) {
                        lub.replaceAnnotation(primaryLub);
                    }
                }
            }
            solution.addType(target, lub);
        }
    }
    return solution;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) 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)

Example 22 with AnnotationMirrorSet

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

the class SupertypesSolver method mergeLubTypeWithEqualities.

/**
 * We previously found a type that is equal to target but not in all hierarchies. Use the
 * primary annotations from the lub type 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 mergeLubTypeWithEqualities(final TypeVariable target, final AnnotatedTypeMirror lub, 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 one equality type if any at this point
        final 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 = lub.getAnnotationInHierarchy(top);
                if (lubAnno == null) {
                    // unannotated then "NO ANNOTATION" is the correct choice.
                    if (lub.getKind() == TypeKind.TYPEVAR && equalityType.getUnderlyingType().equals(lub.getUnderlyingType())) {
                        equalityAnnos.add(top);
                    } else {
                        failed = true;
                    }
                } else {
                    equalityType.replaceAnnotation(lubAnno);
                    equalityAnnos.add(top);
                }
            }
        }
        if (!failed) {
            return new InferredType(equalityType);
        }
    }
    return new InferredType(lub);
}
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) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 23 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet 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 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) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 24 with AnnotationMirrorSet

use of org.checkerframework.framework.util.AnnotationMirrorSet 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<Entry<AnnotatedTypeMirror, AnnotationMirrorSet>> typesIter = types.entrySet().iterator();
    if (!typesIter.hasNext()) {
        ErrorReporter.errorAbort("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 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) Entry(java.util.Map.Entry) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType)

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