Search in sources :

Example 61 with TypeVariable

use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.

the class TypeArgInferenceUtil method methodTypeToTargets.

/**
 * Given an AnnotatedExecutableType return a set of type variables that represents the generic
 * type parameters of that method.
 */
public static Set<TypeVariable> methodTypeToTargets(final AnnotatedExecutableType methodType) {
    final List<AnnotatedTypeVariable> annotatedTypeVars = methodType.getTypeVariables();
    final Set<TypeVariable> targets = new LinkedHashSet<>(annotatedTypeVars.size());
    for (final AnnotatedTypeVariable atv : annotatedTypeVars) {
        targets.add((TypeVariable) TypeAnnotationUtils.unannotatedType(atv.getUnderlyingType()));
    }
    return targets;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 62 with TypeVariable

use of javax.lang.model.type.TypeVariable 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
 * @param constraints the constraints that are side-effected by this method
 */
private void rewriteWithInferredType(@FindDistinct 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 Map.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) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap)

Example 63 with TypeVariable

use of javax.lang.model.type.TypeVariable 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) {
            throw new BugInCF("Equalities should have at most 1 constraint.");
        }
        Map.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) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 64 with TypeVariable

use of javax.lang.model.type.TypeVariable 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
 * @param constraints the constraints that are side-effected by this method
 * @param typeFactory type factory
 */
private void rewriteWithInferredTarget(@FindDistinct final TypeVariable target, @FindDistinct 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 Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> eqEntry : equivalentTypes.entrySet()) {
        constraints.addTypeEqualities(inferredTarget, eqEntry.getKey(), eqEntry.getValue());
    }
    for (final Map.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) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Example 65 with TypeVariable

use of javax.lang.model.type.TypeVariable 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.isEmpty()) {
            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)

Aggregations

TypeVariable (javax.lang.model.type.TypeVariable)80 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)38 TypeMirror (javax.lang.model.type.TypeMirror)30 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)22 TypeElement (javax.lang.model.element.TypeElement)21 ArrayList (java.util.ArrayList)16 DeclaredType (javax.lang.model.type.DeclaredType)15 HashMap (java.util.HashMap)14 LinkedHashMap (java.util.LinkedHashMap)13 Map (java.util.Map)13 ExecutableElement (javax.lang.model.element.ExecutableElement)12 TypeParameterElement (javax.lang.model.element.TypeParameterElement)12 Test (org.junit.Test)10 ArrayType (javax.lang.model.type.ArrayType)9 WildcardType (javax.lang.model.type.WildcardType)9 AnnotationMirror (javax.lang.model.element.AnnotationMirror)8 Element (javax.lang.model.element.Element)8 AnnotationMirrorMap (org.checkerframework.framework.util.AnnotationMirrorMap)8 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)8 VariableElement (javax.lang.model.element.VariableElement)7