Search in sources :

Example 16 with QualifierHierarchy

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

the class LubGlbChecker method initChecker.

@Override
public void initChecker() {
    super.initChecker();
    Elements elements = processingEnv.getElementUtils();
    A = AnnotationBuilder.fromClass(elements, A.class);
    B = AnnotationBuilder.fromClass(elements, B.class);
    C = AnnotationBuilder.fromClass(elements, C.class);
    D = AnnotationBuilder.fromClass(elements, D.class);
    E = AnnotationBuilder.fromClass(elements, E.class);
    F = AnnotationBuilder.fromClass(elements, F.class);
    POLY = AnnotationBuilder.fromClass(elements, Poly.class);
    QualifierHierarchy qh = ((BaseTypeVisitor<?>) visitor).getTypeFactory().getQualifierHierarchy();
    // System.out.println("LUB of D and E: " + qh.leastUpperBound(D, E));
    assert AnnotationUtils.areSame(qh.leastUpperBound(D, E), C) : "LUB of D and E is not C!";
    // System.out.println("LUB of E and D: " + qh.leastUpperBound(E, D));
    assert AnnotationUtils.areSame(qh.leastUpperBound(E, D), C) : "LUB of E and D is not C!";
    // System.out.println("GLB of B and C: " + qh.greatestLowerBound(B, C));
    assert AnnotationUtils.areSame(qh.greatestLowerBound(B, C), D) : "GLB of B and C is not D!";
    // System.out.println("GLB of C and B: " + qh.greatestLowerBound(C, B));
    assert AnnotationUtils.areSame(qh.greatestLowerBound(C, B), D) : "GLB of C and B is not D!";
    assert AnnotationUtils.areSame(qh.greatestLowerBound(POLY, B), F) : "GLB of POLY and B is not F!";
    assert AnnotationUtils.areSame(qh.greatestLowerBound(POLY, F), F) : "GLB of POLY and F is not F!";
    assert AnnotationUtils.areSame(qh.greatestLowerBound(POLY, A), POLY) : "GLB of POLY and A is not POLY!";
    assert AnnotationUtils.areSame(qh.leastUpperBound(POLY, B), A) : "LUB of POLY and B is not A!";
    assert AnnotationUtils.areSame(qh.leastUpperBound(POLY, F), POLY) : "LUB of POLY and F is not POLY!";
    assert AnnotationUtils.areSame(qh.leastUpperBound(POLY, A), A) : "LUB of POLY and A is not A!";
}
Also used : A(lubglb.quals.A) B(lubglb.quals.B) C(lubglb.quals.C) D(lubglb.quals.D) E(lubglb.quals.E) F(lubglb.quals.F) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) Poly(lubglb.quals.Poly) Elements(javax.lang.model.util.Elements)

Example 17 with QualifierHierarchy

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

the class QualifierDefaults method addUncheckedStandardDefaults.

/**
 * Add standard unchecked defaults that do not conflict with previously added defaults.
 */
public void addUncheckedStandardDefaults() {
    QualifierHierarchy qualHierarchy = this.atypeFactory.getQualifierHierarchy();
    Set<? extends AnnotationMirror> tops = qualHierarchy.getTopAnnotations();
    Set<? extends AnnotationMirror> bottoms = qualHierarchy.getBottomAnnotations();
    for (TypeUseLocation loc : standardUncheckedDefaultsTop) {
        // Only add standard defaults in locations where a default has not be specified
        for (AnnotationMirror top : tops) {
            if (!conflictsWithExistingDefaults(uncheckedCodeDefaults, top, loc)) {
                addUncheckedCodeDefault(top, loc);
            }
        }
    }
    for (TypeUseLocation loc : standardUncheckedDefaultsBottom) {
        for (AnnotationMirror bottom : bottoms) {
            // Only add standard defaults in locations where a default has not be specified
            if (!conflictsWithExistingDefaults(uncheckedCodeDefaults, bottom, loc)) {
                addUncheckedCodeDefault(bottom, loc);
            }
        }
    }
}
Also used : TypeUseLocation(org.checkerframework.framework.qual.TypeUseLocation) AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy)

Example 18 with QualifierHierarchy

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

the class DefaultTypeArgumentInference method clampToLowerBound.

/**
 * If we have inferred a type argument from the supertype constraints and this type argument is
 * BELOW the lower bound, make it AT the lower bound
 *
 * <p>e.g.
 *
 * <pre>{@code
 * <@Initialized T extends @Initialized Object> void id(T t) { return t; }
 * id(null);
 *
 * // The invocation of id will result in a type argument with primary annotations of @FBCBottom @Nullable
 * // but this is below the lower bound of T in the initialization hierarchy so instead replace
 * //@FBCBottom with @Initialized
 *
 * // This should happen ONLY with supertype constraints because raising the primary annotation would still
 * // be valid for these constraints (since we just LUB the arguments involved) but would violate any
 * // equality constraints
 * }</pre>
 *
 * TODO: NOTE WE ONLY DO THIS FOR InferredType results for now but we should probably include
 * targest as well
 *
 * @param fromArgSupertypes types inferred from LUBbing types from the arguments to the formal
 *     parameters
 * @param targetDeclarations the declared types of the type parameters whose arguments are being
 *     inferred
 */
private void clampToLowerBound(InferenceResult fromArgSupertypes, List<AnnotatedTypeVariable> targetDeclarations, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    for (AnnotatedTypeVariable targetDecl : targetDeclarations) {
        InferredValue inferred = fromArgSupertypes.get(targetDecl.getUnderlyingType());
        if (inferred != null && inferred instanceof InferredType) {
            final AnnotatedTypeMirror lowerBoundAsArgument = targetDecl.getLowerBound();
            for (AnnotationMirror top : tops) {
                final AnnotationMirror lowerBoundAnno = lowerBoundAsArgument.getEffectiveAnnotationInHierarchy(top);
                final AnnotationMirror argAnno = ((InferredType) inferred).type.getEffectiveAnnotationInHierarchy(top);
                if (qualifierHierarchy.isSubtype(argAnno, lowerBoundAnno)) {
                    ((InferredType) inferred).type.replaceAnnotation(lowerBoundAnno);
                }
            }
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) InferredValue(org.checkerframework.framework.util.typeinference.solver.InferredValue) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) 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)

Example 19 with QualifierHierarchy

use of org.checkerframework.framework.type.QualifierHierarchy 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 20 with QualifierHierarchy

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

the class GlbUtil method sortForGlb.

/**
 * Sort the list of type mirrors, placing supertypes first and subtypes last.
 *
 * <p>E.g. the list: {@code ArrayList<String>, List<String>, AbstractList<String>} becomes:
 * {@code List<String>, AbstractList<String>, ArrayList<String>}
 */
public static void sortForGlb(final List<? extends AnnotatedTypeMirror> typeMirrors, final AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    Collections.sort(typeMirrors, new Comparator<AnnotatedTypeMirror>() {

        @Override
        public int compare(AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) {
            final TypeMirror underlyingType1 = type1.getUnderlyingType();
            final TypeMirror underlyingType2 = type2.getUnderlyingType();
            if (types.isSameType(underlyingType1, underlyingType2)) {
                return compareAnnotations(qualifierHierarchy, type1, type2);
            }
            if (types.isSubtype(underlyingType1, underlyingType2)) {
                return 1;
            }
            // if they're incomparable or type2 is a subtype of type1
            return -1;
        }

        private int compareAnnotations(final QualifierHierarchy qualHierarchy, final AnnotatedTypeMirror type1, final AnnotatedTypeMirror type2) {
            if (AnnotationUtils.areSame(type1.getAnnotations(), type2.getAnnotations())) {
                return 0;
            }
            if (qualHierarchy.isSubtype(type1.getAnnotations(), type2.getAnnotations())) {
                return 1;
            } else {
                return -1;
            }
        }
    });
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)25 AnnotationMirror (javax.lang.model.element.AnnotationMirror)22 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)9 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)6 ArrayList (java.util.ArrayList)4 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)4 TypeVariable (javax.lang.model.type.TypeVariable)3 Elements (javax.lang.model.util.Elements)3 Types (javax.lang.model.util.Types)3 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)3 TypeUseLocation (org.checkerframework.framework.qual.TypeUseLocation)2 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)2 InferredType (org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType)2 AnnotationBuilder (org.checkerframework.javacutil.AnnotationBuilder)2 MethodTree (com.sun.source.tree.MethodTree)1 Entry (java.util.Map.Entry)1 TypeMirror (javax.lang.model.type.TypeMirror)1 A (lubglb.quals.A)1 B (lubglb.quals.B)1 C (lubglb.quals.C)1