Search in sources :

Example 1 with TypeHierarchy

use of org.checkerframework.framework.type.TypeHierarchy in project checker-framework by typetools.

the class DefaultTypeArgumentInference method combineSupertypeAndAssignmentResults.

/**
 * Step 4. Combine the results from using the Supertype constraints the Equality constraints
 * from the assignment context.
 */
private InferenceResult combineSupertypeAndAssignmentResults(Set<TypeVariable> targets, AnnotatedTypeFactory typeFactory, InferenceResult equalityResult, InferenceResult supertypeResult) {
    final TypeHierarchy typeHierarchy = typeFactory.getTypeHierarchy();
    final InferenceResult result = new InferenceResult();
    for (final TypeVariable target : targets) {
        final InferredValue equalityInferred = equalityResult.get(target);
        final InferredValue supertypeInferred = supertypeResult.get(target);
        final InferredValue outputValue;
        if (equalityInferred != null && equalityInferred instanceof InferredType) {
            if (supertypeInferred != null && supertypeInferred instanceof InferredType) {
                AnnotatedTypeMirror superATM = ((InferredType) supertypeInferred).type;
                AnnotatedTypeMirror equalityATM = ((InferredType) equalityInferred).type;
                if (TypesUtils.isErasedSubtype(equalityATM.getUnderlyingType(), superATM.getUnderlyingType(), typeFactory.getContext().getTypeUtils())) {
                    // If the underlying type of equalityATM is a subtype of the underlying
                    // type of superATM, then the call to isSubtype below will issue an error.
                    // So call asSuper so that the isSubtype call below works correctly.
                    equalityATM = AnnotatedTypes.asSuper(typeFactory, equalityATM, superATM);
                }
                if (typeHierarchy.isSubtype(superATM, equalityATM)) {
                    outputValue = equalityInferred;
                } else {
                    outputValue = supertypeInferred;
                }
            } else {
                outputValue = equalityInferred;
            }
        } else {
            if (supertypeInferred != null) {
                outputValue = supertypeInferred;
            } else {
                outputValue = null;
            }
        }
        if (outputValue != null) {
            result.put(target, outputValue);
        }
    }
    return result;
}
Also used : InferredValue(org.checkerframework.framework.util.typeinference.solver.InferredValue) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) InferenceResult(org.checkerframework.framework.util.typeinference.solver.InferenceResult) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 2 with TypeHierarchy

use of org.checkerframework.framework.type.TypeHierarchy in project checker-framework by typetools.

the class BaseTypeVisitor method testTypevarContainment.

/**
 * @return true if both types are type variables and outer contains inner Outer contains inner
 *     implies: {@literal inner.upperBound <: outer.upperBound outer.lowerBound <:
 *     inner.lowerBound }
 */
protected boolean testTypevarContainment(final AnnotatedTypeMirror inner, final AnnotatedTypeMirror outer) {
    if (inner.getKind() == TypeKind.TYPEVAR && outer.getKind() == TypeKind.TYPEVAR) {
        final AnnotatedTypeVariable innerAtv = (AnnotatedTypeVariable) inner;
        final AnnotatedTypeVariable outerAtv = (AnnotatedTypeVariable) outer;
        if (AnnotatedTypes.areCorrespondingTypeVariables(elements, innerAtv, outerAtv)) {
            final TypeHierarchy typeHierarchy = atypeFactory.getTypeHierarchy();
            return typeHierarchy.isSubtype(innerAtv.getUpperBound(), outerAtv.getUpperBound()) && typeHierarchy.isSubtype(outerAtv.getLowerBound(), innerAtv.getLowerBound());
        }
    }
    return false;
}
Also used : TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 3 with TypeHierarchy

use of org.checkerframework.framework.type.TypeHierarchy 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)

Aggregations

TypeHierarchy (org.checkerframework.framework.type.TypeHierarchy)3 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)2 ArrayList (java.util.ArrayList)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 TypeVariable (javax.lang.model.type.TypeVariable)1 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)1 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)1 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)1 InferenceResult (org.checkerframework.framework.util.typeinference.solver.InferenceResult)1 InferredValue (org.checkerframework.framework.util.typeinference.solver.InferredValue)1 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)1