Search in sources :

Example 31 with TypeVariable

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

the class InferenceResult method resolveChainedTargets.

/**
 * If we had a set of inferred results, (e.g. T1 = T2, T2 = T3, T3 = String) propagate any results
 * we have (the above constraints become T1 = String, T2 = String, T3 = String)
 */
public void resolveChainedTargets() {
    final Map<TypeVariable, InferredValue> inferredTypes = new LinkedHashMap<>(this.size());
    // TODO: we can probably make this a bit more efficient
    boolean grew = true;
    while (grew) {
        grew = false;
        for (final Map.Entry<TypeVariable, InferredValue> inferred : this.entrySet()) {
            final TypeVariable target = inferred.getKey();
            final InferredValue value = inferred.getValue();
            if (value instanceof InferredType) {
                inferredTypes.put(target, value);
            } else {
                final InferredTarget currentTarget = (InferredTarget) value;
                final InferredType equivalentType = (InferredType) inferredTypes.get(((InferredTarget) value).target);
                if (equivalentType != null) {
                    grew = true;
                    final AnnotatedTypeMirror type = equivalentType.type.deepCopy();
                    type.replaceAnnotations(currentTarget.additionalAnnotations);
                    final InferredType newConstraint = new InferredType(type);
                    inferredTypes.put(currentTarget.target, newConstraint);
                }
            }
        }
    }
    this.putAll(inferredTypes);
}
Also used : InferredTarget(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredTarget) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) TypeVariable(javax.lang.model.type.TypeVariable) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) LinkedHashMap(java.util.LinkedHashMap)

Example 32 with TypeVariable

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

the class SubtypesSolver method propagatePreviousGlbs.

/**
 * /** If the target corresponding to targetRecord must be a subtype of another target for which
 * we have already determined a GLB, add that target's GLB to the list of subtypes to be GLBed for
 * this target.
 */
protected static void propagatePreviousGlbs(final Subtypes targetSubtypes, InferenceResult solution, final Map<AnnotatedTypeMirror, AnnotationMirrorSet> subtypesOfTarget) {
    for (final Map.Entry<TypeVariable, AnnotationMirrorSet> subtypeTarget : targetSubtypes.targets.entrySet()) {
        final InferredValue subtargetInferredGlb = solution.get(subtypeTarget.getKey());
        if (subtargetInferredGlb != null) {
            final AnnotatedTypeMirror subtargetGlbType = ((InferredType) subtargetInferredGlb).type;
            AnnotationMirrorSet subtargetAnnos = subtypesOfTarget.get(subtargetGlbType);
            if (subtargetAnnos != null) {
                // there is already an equivalent type in the list of subtypes, just add
                // any hierarchies that are not in its list but are in the supertarget's list
                subtargetAnnos.addAll(subtypeTarget.getValue());
            } else {
                subtypesOfTarget.put(subtargetGlbType, subtypeTarget.getValue());
            }
        }
    }
}
Also used : InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) TypeVariable(javax.lang.model.type.TypeVariable) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) Map(java.util.Map) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 33 with TypeVariable

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

the class SubtypesSolver method glbSubtypes.

public InferenceResult glbSubtypes(final Set<TypeVariable> remainingTargets, final ConstraintMap constraints, final AnnotatedTypeFactory typeFactory) {
    final InferenceResult inferenceResult = new InferenceResult();
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    List<TypeVariable> targetsSubtypesLast = new ArrayList<>(remainingTargets);
    // If we have two type variables <A, A extends B> order them A then B
    // this is required because we will use the fact that B must be below A
    // when determining the glb of B
    Collections.sort(targetsSubtypesLast, 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 : targetsSubtypesLast) {
        Subtypes subtypes = constraints.getConstraints(target).subtypes;
        if (subtypes.types.isEmpty()) {
            continue;
        }
        propagatePreviousGlbs(subtypes, inferenceResult, subtypes.types);
        // if the subtypes size is only 1 then we need not do any GLBing on the underlying types
        // but we may have primary annotations that need to be GLBed
        AnnotationMirrorMap<AnnotationMirrorSet> primaries = subtypes.primaries;
        if (subtypes.types.size() == 1) {
            final Map.Entry<AnnotatedTypeMirror, AnnotationMirrorSet> entry = subtypes.types.entrySet().iterator().next();
            AnnotatedTypeMirror supertype = entry.getKey().deepCopy();
            for (AnnotationMirror top : entry.getValue()) {
                final AnnotationMirrorSet superAnnos = primaries.get(top);
                // if it is null we're just going to use the anno already on supertype
                if (superAnnos != null) {
                    final AnnotationMirror supertypeAnno = supertype.getAnnotationInHierarchy(top);
                    superAnnos.add(supertypeAnno);
                }
            }
            if (!primaries.isEmpty()) {
                for (AnnotationMirror top : qualifierHierarchy.getTopAnnotations()) {
                    final AnnotationMirror glb = greatestLowerBound(subtypes.primaries.get(top), qualifierHierarchy);
                    supertype.replaceAnnotation(glb);
                }
            }
            inferenceResult.put(target, new InferredType(supertype));
        } else {
            // GLB all of the types than combine this with the GLB of primary annotation constraints
            final AnnotatedTypeMirror glbType = GlbUtil.glbAll(subtypes.types, typeFactory);
            if (glbType != null) {
                if (!primaries.isEmpty()) {
                    for (AnnotationMirror top : qualifierHierarchy.getTopAnnotations()) {
                        final AnnotationMirror glb = greatestLowerBound(subtypes.primaries.get(top), qualifierHierarchy);
                        final AnnotationMirror currentAnno = glbType.getAnnotationInHierarchy(top);
                        if (currentAnno == null) {
                            glbType.addAnnotation(glb);
                        } else if (glb != null) {
                            glbType.replaceAnnotation(qualifierHierarchy.greatestLowerBound(glb, currentAnno));
                        }
                    }
                }
                inferenceResult.put(target, new InferredType(glbType));
            }
        }
    }
    return inferenceResult;
}
Also used : Types(javax.lang.model.util.Types) InferredType(org.checkerframework.framework.util.typeinference.solver.InferredValue.InferredType) ArrayList(java.util.ArrayList) Subtypes(org.checkerframework.framework.util.typeinference.solver.TargetConstraints.Subtypes) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeVariable(javax.lang.model.type.TypeVariable) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) AnnotationMirrorSet(org.checkerframework.framework.util.AnnotationMirrorSet) AnnotationMirrorMap(org.checkerframework.framework.util.AnnotationMirrorMap) Map(java.util.Map)

Example 34 with TypeVariable

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

the class AnnotatedTypeFactory method addAnnotationFromFieldInvariant.

/**
 * Adds the qualifier specified by a field invariant for {@code field} to {@code type}.
 *
 * @param type annotated type to which the annotation is added
 * @param accessedVia the annotated type of the receiver of the accessing tree. (Only used to get
 *     the type element of the underling type.)
 * @param field element representing the field
 */
protected void addAnnotationFromFieldInvariant(AnnotatedTypeMirror type, AnnotatedTypeMirror accessedVia, VariableElement field) {
    TypeMirror declaringType = accessedVia.getUnderlyingType();
    // Find the first upper bound that isn't a wildcard or type variable
    while (declaringType.getKind() == TypeKind.WILDCARD || declaringType.getKind() == TypeKind.TYPEVAR) {
        if (declaringType.getKind() == TypeKind.WILDCARD) {
            declaringType = TypesUtils.wildUpperBound(declaringType, processingEnv);
        } else if (declaringType.getKind() == TypeKind.TYPEVAR) {
            declaringType = ((TypeVariable) declaringType).getUpperBound();
        }
    }
    TypeElement typeElement = TypesUtils.getTypeElement(declaringType);
    if (ElementUtils.enclosingTypeElement(field).equals(typeElement)) {
        // cannot be this field, even if the field has the same name.
        return;
    }
    FieldInvariants invariants = getFieldInvariants(typeElement);
    if (invariants == null) {
        return;
    }
    List<AnnotationMirror> invariantAnnos = invariants.getQualifiersFor(field.getSimpleName());
    type.replaceAnnotations(invariantAnnos);
}
Also used : FieldInvariants(org.checkerframework.framework.util.FieldInvariants) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeElement(javax.lang.model.element.TypeElement) ATypeElement(scenelib.annotations.el.ATypeElement)

Example 35 with TypeVariable

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

the class AnnotatedTypeFactory method typeVariablesFromUse.

/**
 * Adapt the upper bounds of the type variables of a class relative to the type instantiation. In
 * some type systems, the upper bounds depend on the instantiation of the class. For example, in
 * the Generic Universe Type system, consider a class declaration
 *
 * <pre>{@code   class C<X extends @Peer Object> }</pre>
 *
 * then the instantiation
 *
 * <pre>{@code   @Rep C<@Rep Object> }</pre>
 *
 * is legal. The upper bounds of class C have to be adapted by the main modifier.
 *
 * <p>An example of an adaptation follows. Suppose, I have a declaration:
 *
 * <pre>{@code  class MyClass<E extends List<E>>}</pre>
 *
 * And an instantiation:
 *
 * <pre>{@code  new MyClass<@NonNull String>()}</pre>
 *
 * <p>The upper bound of E adapted to the argument String, would be {@code List<@NonNull String>}
 * and the lower bound would be an AnnotatedNullType.
 *
 * <p>TODO: ensure that this method is consistently used instead of directly querying the type
 * variables.
 *
 * @param type the use of the type
 * @param element the corresponding element
 * @return the adapted bounds of the type parameters
 */
public List<AnnotatedTypeParameterBounds> typeVariablesFromUse(AnnotatedDeclaredType type, TypeElement element) {
    AnnotatedDeclaredType generic = getAnnotatedType(element);
    List<AnnotatedTypeMirror> targs = type.getTypeArguments();
    List<AnnotatedTypeMirror> tvars = generic.getTypeArguments();
    assert targs.size() == tvars.size() : "Mismatch in type argument size between " + type + " and " + generic;
    // System.err.printf("TVFU%n  type: %s%n  generic: %s%n", type, generic);
    Map<TypeVariable, AnnotatedTypeMirror> typeParamToTypeArg = new HashMap<>();
    AnnotatedDeclaredType enclosing = type;
    while (enclosing != null) {
        List<AnnotatedTypeMirror> enclosingTArgs = enclosing.getTypeArguments();
        AnnotatedDeclaredType declaredType = getAnnotatedType((TypeElement) enclosing.getUnderlyingType().asElement());
        List<AnnotatedTypeMirror> enclosingTVars = declaredType.getTypeArguments();
        for (int i = 0; i < enclosingTArgs.size(); i++) {
            AnnotatedTypeVariable enclosingTVar = (AnnotatedTypeVariable) enclosingTVars.get(i);
            typeParamToTypeArg.put(enclosingTVar.getUnderlyingType(), enclosingTArgs.get(i));
        }
        enclosing = enclosing.getEnclosingType();
    }
    List<AnnotatedTypeParameterBounds> res = new ArrayList<>(tvars.size());
    for (AnnotatedTypeMirror atm : tvars) {
        AnnotatedTypeVariable atv = (AnnotatedTypeVariable) atm;
        AnnotatedTypeMirror upper = typeVarSubstitutor.substitute(typeParamToTypeArg, atv.getUpperBound());
        AnnotatedTypeMirror lower = typeVarSubstitutor.substitute(typeParamToTypeArg, atv.getLowerBound());
        res.add(new AnnotatedTypeParameterBounds(upper, lower));
    }
    return res;
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

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