Search in sources :

Example 16 with AnnotationMirrorSet

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

the class EqualitiesSolver method updateTargetsWithPartiallyInferredType.

// If we determined that this target T1 is equal to a type ATM in hierarchies @A,@B,@C
// for each of those hierarchies, if a target is equal to T1 in that hierarchy it is also equal
// to ATM
// e.g.
// if : T1 == @A @B @C ATM in only the A,B hierarchies
// and T1 == T2 only in @A hierarchy
// 
// then T2 == @A @B @C only in the @A hierarchy
// 
public boolean updateTargetsWithPartiallyInferredType(final Equalities equalities, ConstraintMap constraintMap, AnnotatedTypeFactory typeFactory) {
    boolean updated = false;
    if (!equalities.types.isEmpty()) {
        if (equalities.types.size() != 1) {
            ErrorReporter.errorAbort("Equalities should have at most 1 constraint.");
        }
        Entry<AnnotatedTypeMirror, AnnotationMirrorSet> remainingTypeEquality;
        remainingTypeEquality = equalities.types.entrySet().iterator().next();
        final AnnotatedTypeMirror remainingType = remainingTypeEquality.getKey();
        final AnnotationMirrorSet remainingHierarchies = remainingTypeEquality.getValue();
        // update targets
        for (Map.Entry<TypeVariable, AnnotationMirrorSet> targetToHierarchies : equalities.targets.entrySet()) {
            final TypeVariable equalTarget = targetToHierarchies.getKey();
            final AnnotationMirrorSet hierarchies = targetToHierarchies.getValue();
            final AnnotationMirrorSet equalTypeHierarchies = new AnnotationMirrorSet(remainingHierarchies);
            equalTypeHierarchies.retainAll(hierarchies);
            final Map<AnnotatedTypeMirror, AnnotationMirrorSet> otherTargetsEqualTypes = constraintMap.getConstraints(equalTarget).equalities.types;
            AnnotationMirrorSet equalHierarchies = otherTargetsEqualTypes.get(remainingType);
            if (equalHierarchies == null) {
                equalHierarchies = new AnnotationMirrorSet(equalTypeHierarchies);
                otherTargetsEqualTypes.put(remainingType, equalHierarchies);
                updated = true;
            } else {
                final int size = equalHierarchies.size();
                equalHierarchies.addAll(equalTypeHierarchies);
                updated = size == equalHierarchies.size();
            }
        }
    }
    return updated;
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 17 with AnnotationMirrorSet

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

the class EqualitiesSolver method rewriteWithInferredType.

/**
 * Let Ti be a target type parameter. When we reach this method we have inferred an argument,
 * Ai, for Ti
 *
 * <p>However, there still may be constraints of the form {@literal Ti = Tj}, {@literal Ti <:
 * Tj}, {@literal Tj <: Ti} in the constraint map. In this case we need to replace Ti with the
 * type. That is, they become {@literal Ai = Tj}, {@literal Ai <: Tj}, and {@literal Tj <: Ai}
 *
 * <p>To do this, we find the TargetConstraints for Tj and add these constraints to the
 * appropriate map in TargetConstraints. We can then clear the constraints for the current
 * target since we have inferred a type.
 *
 * @param target the target for which we have inferred a concrete type argument
 * @param type the type inferred
 */
private void rewriteWithInferredType(final TypeVariable target, final AnnotatedTypeMirror type, final ConstraintMap constraints) {
    final TargetConstraints targetRecord = constraints.getConstraints(target);
    final Map<TypeVariable, AnnotationMirrorSet> equivalentTargets = targetRecord.equalities.targets;
    // hierarchies as the inferred type
    for (final Entry<TypeVariable, AnnotationMirrorSet> eqEntry : equivalentTargets.entrySet()) {
        constraints.addTypeEqualities(eqEntry.getKey(), type, eqEntry.getValue());
    }
    for (TypeVariable otherTarget : constraints.getTargets()) {
        if (otherTarget != target) {
            final TargetConstraints record = constraints.getConstraints(otherTarget);
            // each target that was equivalent to this one needs to be equivalent in the same
            // hierarchies as the inferred type
            final AnnotationMirrorSet hierarchies = record.equalities.targets.get(target);
            if (hierarchies != null) {
                record.equalities.targets.remove(target);
                constraints.addTypeEqualities(otherTarget, type, hierarchies);
            }
            // otherTypes may have AnnotatedTypeVariables of type target, run substitution on
            // these with type
            Map<AnnotatedTypeMirror, AnnotationMirrorSet> toIterate = new LinkedHashMap<>(record.equalities.types);
            record.equalities.types.clear();
            for (AnnotatedTypeMirror otherType : toIterate.keySet()) {
                final AnnotatedTypeMirror copy = TypeArgInferenceUtil.substitute(target, type, otherType);
                final AnnotationMirrorSet otherHierarchies = toIterate.get(otherType);
                record.equalities.types.put(copy, otherHierarchies);
            }
        }
    }
    for (TypeVariable otherTarget : constraints.getTargets()) {
        if (otherTarget != target) {
            final TargetConstraints record = constraints.getConstraints(otherTarget);
            // each target that was equivalent to this one needs to be equivalent in the same
            // hierarchies as the inferred type
            final AnnotationMirrorSet hierarchies = record.supertypes.targets.get(target);
            if (hierarchies != null) {
                record.supertypes.targets.remove(target);
                constraints.addTypeEqualities(otherTarget, type, hierarchies);
            }
            // otherTypes may have AnnotatedTypeVariables of type target, run substitution on
            // these with type
            Map<AnnotatedTypeMirror, AnnotationMirrorSet> toIterate = new LinkedHashMap<>(record.supertypes.types);
            record.supertypes.types.clear();
            for (AnnotatedTypeMirror otherType : toIterate.keySet()) {
                final AnnotatedTypeMirror copy = TypeArgInferenceUtil.substitute(target, type, otherType);
                final AnnotationMirrorSet otherHierarchies = toIterate.get(otherType);
                record.supertypes.types.put(copy, otherHierarchies);
            }
        }
    }
    targetRecord.equalities.clear();
    targetRecord.supertypes.clear();
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap)

Example 18 with AnnotationMirrorSet

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

the class EqualitiesSolver method rewriteWithInferredTarget.

/**
 * Let Ti be a target type parameter. When we reach this method we have inferred that Ti has the
 * exact same argument as another target Tj
 *
 * <p>Therefore, we want to stop solving for Ti and instead wait till we solve for Tj and use
 * that result.
 *
 * <p>Let ATM be any annotated type mirror and Tk be a target type parameter where k != i and k
 * != j Even though we've inferred Ti = Tj, there still may be constraints of the form Ti = ATM
 * or {@literal Ti <: Tk} These constraints are still useful for inferring a argument for Ti/Tj.
 * So, we replace Ti in these constraints with Tj and place those constraints in the
 * TargetConstraints object for Tj.
 *
 * <p>We then clear the constraints for Ti.
 *
 * @param target the target for which we know another target is exactly equal to this target
 * @param inferredTarget the other target inferred to be equal
 */
private void rewriteWithInferredTarget(final TypeVariable target, final TypeVariable inferredTarget, final ConstraintMap constraints, final AnnotatedTypeFactory typeFactory) {
    final TargetConstraints targetRecord = constraints.getConstraints(target);
    final Map<AnnotatedTypeMirror, AnnotationMirrorSet> equivalentTypes = targetRecord.equalities.types;
    final Map<AnnotatedTypeMirror, AnnotationMirrorSet> supertypes = targetRecord.supertypes.types;
    // to the inferred target
    for (final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> eqEntry : equivalentTypes.entrySet()) {
        constraints.addTypeEqualities(inferredTarget, eqEntry.getKey(), eqEntry.getValue());
    }
    for (final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> superEntry : supertypes.entrySet()) {
        constraints.addTypeSupertype(inferredTarget, superEntry.getKey(), superEntry.getValue());
    }
    for (TypeVariable otherTarget : constraints.getTargets()) {
        if (otherTarget != target && otherTarget != inferredTarget) {
            final TargetConstraints record = constraints.getConstraints(otherTarget);
            // each target that was equivalent to this one needs to be equivalent in the same
            // hierarchies as the inferred target
            final AnnotationMirrorSet hierarchies = record.equalities.targets.get(target);
            if (hierarchies != null) {
                record.equalities.targets.remove(target);
                constraints.addTargetEquality(otherTarget, inferredTarget, hierarchies);
            }
            // otherTypes may have AnnotatedTypeVariables of type target, run substitution on
            // these with type
            Map<AnnotatedTypeMirror, AnnotationMirrorSet> toIterate = new LinkedHashMap<>(record.equalities.types);
            record.equalities.types.clear();
            for (AnnotatedTypeMirror otherType : toIterate.keySet()) {
                final AnnotatedTypeMirror copy = TypeArgInferenceUtil.substitute(target, createAnnotatedTypeVar(target, typeFactory), otherType);
                final AnnotationMirrorSet otherHierarchies = toIterate.get(otherType);
                record.equalities.types.put(copy, otherHierarchies);
            }
        }
    }
    for (TypeVariable otherTarget : constraints.getTargets()) {
        if (otherTarget != target && otherTarget != inferredTarget) {
            final TargetConstraints record = constraints.getConstraints(otherTarget);
            final AnnotationMirrorSet hierarchies = record.supertypes.targets.get(target);
            if (hierarchies != null) {
                record.supertypes.targets.remove(target);
                constraints.addTargetSupertype(otherTarget, inferredTarget, hierarchies);
            }
            // otherTypes may have AnnotatedTypeVariables of type target, run substitution on
            // these with type
            Map<AnnotatedTypeMirror, AnnotationMirrorSet> toIterate = new LinkedHashMap<>(record.supertypes.types);
            record.supertypes.types.clear();
            for (AnnotatedTypeMirror otherType : toIterate.keySet()) {
                final AnnotatedTypeMirror copy = TypeArgInferenceUtil.substitute(target, createAnnotatedTypeVar(target, typeFactory), otherType);
                final AnnotationMirrorSet otherHierarchies = toIterate.get(otherType);
                record.supertypes.types.put(copy, otherHierarchies);
            }
        }
    }
    targetRecord.equalities.clear();
    targetRecord.supertypes.clear();
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap)

Example 19 with AnnotationMirrorSet

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

the class EqualitiesSolver method mergeTypesAndPrimaries.

/**
 * @param typesToHierarchies a mapping of (types &rarr; hierarchies) that indicate that the
 *     argument being inferred is equal to the types in each of the hierarchies
 * @param primaries a map (hierarchy &rarr; annotation in hierarchy) where the annotation in
 *     hierarchy is equal to the primary annotation on the argument being inferred
 * @param tops the set of top annotations in the qualifier hierarchy
 * @return a concrete type argument or null if there was not enough information to infer one
 */
private InferredType mergeTypesAndPrimaries(Map<AnnotatedTypeMirror, AnnotationMirrorSet> typesToHierarchies, AnnotationMirrorMap<AnnotationMirror> primaries, final AnnotationMirrorSet tops) {
    final AnnotationMirrorSet missingAnnos = new AnnotationMirrorSet(tops);
    Iterator<Entry<AnnotatedTypeMirror, AnnotationMirrorSet>> entryIterator = typesToHierarchies.entrySet().iterator();
    if (!entryIterator.hasNext()) {
        ErrorReporter.errorAbort("Merging a list of empty types!");
    }
    final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> head = entryIterator.next();
    AnnotatedTypeMirror mergedType = head.getKey();
    missingAnnos.removeAll(head.getValue());
    // AnnotatedDeclaredTypes, AnnotatedTypeVariables, and AnnotatedArrayTypes
    while (entryIterator.hasNext() && !missingAnnos.isEmpty()) {
        final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> current = entryIterator.next();
        final AnnotatedTypeMirror currentType = current.getKey();
        final AnnotationMirrorSet currentHierarchies = current.getValue();
        AnnotationMirrorSet found = new AnnotationMirrorSet();
        for (AnnotationMirror top : missingAnnos) {
            if (currentHierarchies.contains(top)) {
                final AnnotationMirror newAnno = currentType.getAnnotationInHierarchy(top);
                if (newAnno != null) {
                    mergedType.replaceAnnotation(newAnno);
                    found.add(top);
                } else if (mergedType.getKind() == TypeKind.TYPEVAR && currentType.getUnderlyingType().equals(mergedType.getUnderlyingType())) {
                    // the options here are we are merging with the same typevar, in which case
                    // we can just remove the annotation from the missing list
                    found.add(top);
                } else {
                    // otherwise the other type is missing an annotation
                    ErrorReporter.errorAbort("Missing annotation.\n" + "\nmergedType=" + mergedType + "\ncurrentType=" + currentType);
                }
            }
        }
        missingAnnos.removeAll(found);
    }
    // add all the annotations from the primaries
    final AnnotationMirrorSet foundHierarchies = new AnnotationMirrorSet();
    for (final AnnotationMirror top : missingAnnos) {
        final AnnotationMirror anno = primaries.get(top);
        if (anno != null) {
            foundHierarchies.add(top);
            mergedType.replaceAnnotation(anno);
        }
    }
    typesToHierarchies.clear();
    if (missingAnnos.isEmpty()) {
        return new InferredType(mergedType);
    }
    // TODO: we probably can do more with this information than just putting it back into the
    // TODO: ConstraintMap (which is what's happening here)
    final AnnotationMirrorSet hierarchies = new AnnotationMirrorSet(tops);
    hierarchies.removeAll(missingAnnos);
    typesToHierarchies.put(mergedType, hierarchies);
    return null;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Entry(java.util.Map.Entry) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 20 with AnnotationMirrorSet

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

the class SupertypesSolver method groundMissingHierarchies.

/**
 * For each type in typeToHierarchies, if that type does not have a corresponding annotation for
 * a given hierarchy replace it with the corresponding value in lowerBoundAnnos
 */
public static AnnotatedTypeMirror groundMissingHierarchies(final Entry<AnnotatedTypeMirror, AnnotationMirrorSet> typeToHierarchies, final AnnotationMirrorMap<AnnotationMirror> lowerBoundAnnos) {
    final AnnotationMirrorSet presentHierarchies = typeToHierarchies.getValue();
    final AnnotationMirrorSet missingAnnos = new AnnotationMirrorSet();
    for (AnnotationMirror top : lowerBoundAnnos.keySet()) {
        if (!presentHierarchies.contains(top)) {
            missingAnnos.add(lowerBoundAnnos.get(top));
        }
    }
    if (!missingAnnos.isEmpty()) {
        AnnotatedTypeMirror copy = typeToHierarchies.getKey().deepCopy();
        copy.replaceAnnotations(missingAnnos);
        return copy;
    }
    return typeToHierarchies.getKey();
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) 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