Search in sources :

Example 66 with TypeVariable

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

the class ConstraintMapBuilder method build.

/**
 * Let Ti be a the ith target being inferred Let ATV(i) be the annotated type variable that
 * represents as use of Ti which may or may not have primary annotations. Let ATM be an annotated
 * type mirror that may or may not be target Tx, or have a component target Tx Let Ai be the type
 * argument we are trying to infer for Ti
 *
 * <p>We have a set of constraints of the form: {@code ATV(i) <?> ATM}
 *
 * <p>Where {@code <?>} is either a subtype ({@code <:}), supertype ({@code :>}), or equality
 * relationship ({@code =}).
 *
 * <p>Regardless of what {@code <?>} is, a constraint will only imply constraints on Ai in a given
 * hierarchy if ATV(i) does NOT have a primary annotation in that hierarchy. That is:
 *
 * <p>E.g. Let ATV(i) be @NonNull Ti, the constraints @NonNull Ti = @NonNull @Initialized String
 * does not imply any primary annotation in the Nullness hierarchy for type argument Ai because
 * the Annotated type mirror has a primary annotation in the NUllness hierarchy.
 *
 * <p>However, it does imply that Ai has a primary annotation of @Initialized since ATV(i) has no
 * primary annotation in the initialization hierarchy.
 *
 * <p>Note, constraints come in 2 forms:
 *
 * <ul>
 *   <li>between a target and a concrete AnnotatedTypeMirror. E.g., As seen above {@code (@NonNull
 *       Ti = @NonNull @Initialized String)}
 *   <li>between two targets E.g., {@code (@NonNull Ti = Tj)}
 * </ul>
 */
public ConstraintMap build(Set<TypeVariable> targets, Set<TUConstraint> constraints, AnnotatedTypeFactory typeFactory) {
    final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
    final AnnotationMirrorSet tops = new AnnotationMirrorSet(qualifierHierarchy.getTopAnnotations());
    final ConstraintMap result = new ConstraintMap(targets);
    final AnnotationMirrorSet tAnnos = new AnnotationMirrorSet();
    final AnnotationMirrorSet uAnnos = new AnnotationMirrorSet();
    final AnnotationMirrorSet hierarchiesInRelation = new AnnotationMirrorSet();
    for (TUConstraint constraint : constraints) {
        tAnnos.clear();
        uAnnos.clear();
        hierarchiesInRelation.clear();
        final AnnotatedTypeVariable typeT = constraint.typeVariable;
        final AnnotatedTypeMirror typeU = constraint.relatedType;
        // The inferred type of T should be T.
        if (!constraint.uIsArg && typeU.getKind() == TypeKind.TYPEVAR && targets.contains((TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()))) {
            if (typeT.getAnnotations().isEmpty() && typeU.getAnnotations().isEmpty()) {
                hierarchiesInRelation.addAll(tops);
            } else {
                for (AnnotationMirror top : tops) {
                    final AnnotationMirror tAnno = typeT.getAnnotationInHierarchy(top);
                    final AnnotationMirror uAnno = typeU.getAnnotationInHierarchy(top);
                    if (tAnno == null) {
                        if (uAnno == null) {
                            hierarchiesInRelation.add(top);
                        } else {
                            tAnnos.add(uAnno);
                        }
                    } else {
                        if (uAnno == null) {
                            uAnnos.add(tAnno);
                        } else {
                        // This tells us nothing, they both should be equal but either way
                        // we gain no information if both type vars have annotations
                        }
                    }
                }
                // This case also covers the case where i = j.
                if (!tAnnos.isEmpty()) {
                    addToPrimaryRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), constraint, result, tAnnos, qualifierHierarchy);
                }
                if (!uAnnos.isEmpty()) {
                    addToPrimaryRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()), constraint, result, uAnnos, qualifierHierarchy);
                }
            }
            // <?> Tj and i != j)
            if (!typeFactory.types.isSameType(TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()))) {
                addToTargetRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), (TypeVariable) TypeAnnotationUtils.unannotatedType(typeU.getUnderlyingType()), result, constraint, hierarchiesInRelation);
            }
        } else {
            for (AnnotationMirror top : tops) {
                final AnnotationMirror tAnno = typeT.getAnnotationInHierarchy(top);
                if (tAnno == null) {
                    hierarchiesInRelation.add(top);
                }
            }
            addToTypeRelationship((TypeVariable) TypeAnnotationUtils.unannotatedType(typeT.getUnderlyingType()), typeU, result, constraint, hierarchiesInRelation);
        }
    }
    return result;
}
Also used : 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) TUConstraint(org.checkerframework.framework.util.typeinference.constraint.TUConstraint) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 67 with TypeVariable

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

the class InferenceResult method mergeSubordinate.

/**
 * Merges values in subordinate into this result, keeping the results form any type arguments that
 * were already contained by this InferenceResult.
 *
 * @param subordinate a result which we wish to merge into this result
 */
public void mergeSubordinate(final InferenceResult subordinate) {
    final LinkedHashSet<TypeVariable> previousKeySet = new LinkedHashSet<>(this.keySet());
    final LinkedHashSet<TypeVariable> remainingSubKeys = new LinkedHashSet<>(subordinate.keySet());
    remainingSubKeys.removeAll(keySet());
    for (TypeVariable target : previousKeySet) {
        mergeTarget(target, subordinate);
    }
    for (TypeVariable target : remainingSubKeys) {
        this.put(target, subordinate.get(target));
    }
    resolveChainedTargets();
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TypeVariable(javax.lang.model.type.TypeVariable)

Example 68 with TypeVariable

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

the class CFAbstractValue method getEffectTypeVar.

/**
 * Returns the AnnotatedTypeVariable associated with the given TypeMirror or null.
 *
 * <p>If {@code typeMirror} is a type variable, then the {@link AnnotatedTypeVariable} of its
 * declaration is returned. If {@code typeMirror} is a wildcard whose extends bounds is a type
 * variable, then the {@link AnnotatedTypeVariable} for its declaration is returned. Otherwise,
 * {@code null} is returned.
 *
 * @param typeMirror a type mirror
 * @return the AnnotatedTypeVariable associated with the given TypeMirror or null
 */
@Nullable
private AnnotatedTypeVariable getEffectTypeVar(@Nullable TypeMirror typeMirror) {
    if (typeMirror == null) {
        return null;
    } else if (typeMirror.getKind() == TypeKind.WILDCARD) {
        return getEffectTypeVar(((WildcardType) typeMirror).getExtendsBound());
    } else if (typeMirror.getKind() == TypeKind.TYPEVAR) {
        TypeVariable typevar = ((TypeVariable) typeMirror);
        AnnotatedTypeMirror atm = analysis.getTypeFactory().getAnnotatedType(typevar.asElement());
        return (AnnotatedTypeVariable) atm;
    } else {
        return null;
    }
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) WildcardType(javax.lang.model.type.WildcardType) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 69 with TypeVariable

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

the class AnnotatedTypeFactory method captureMethodTypeArgs.

/**
 * Apply capture conversion to the type arguments of a method invocation.
 *
 * @param typeVarToAnnotatedTypeArg mapping from type variable in the method declaration to the
 *     corresponding (annotated) type argument at the method invocation
 * @param declTypeVar list of the (annotated) type variable declarations in the method
 * @return a mapping from type variable in the method declaration to its captured type argument.
 *     Its keys are the same as in {@code typeVarToAnnotatedTypeArg}, and the values are their
 *     captures (for a non-wildcard, capture conversion is the identity).
 */
// TODO: This should happen as part of Java 8 inference and this method should be removed when
// #979 is fixed.
private Map<TypeVariable, AnnotatedTypeMirror> captureMethodTypeArgs(Map<TypeVariable, AnnotatedTypeMirror> typeVarToAnnotatedTypeArg, List<AnnotatedTypeVariable> declTypeVar) {
    Map<TypeVariable, AnnotatedTypeVariable> typeParameter = new HashMap<>();
    for (AnnotatedTypeVariable t : declTypeVar) {
        typeParameter.put(t.getUnderlyingType(), t);
    }
    // `newTypeVarToAnnotatedTypeArg` is the result of this method.
    Map<TypeVariable, AnnotatedTypeMirror> newTypeVarToAnnotatedTypeArg = new HashMap<>();
    Map<TypeVariable, AnnotatedTypeVariable> capturedTypeVarToAnnotatedTypeVar = new HashMap<>();
    // The first loop replaces each wildcard by a fresh type variable.
    for (Map.Entry<TypeVariable, AnnotatedTypeMirror> entry : typeVarToAnnotatedTypeArg.entrySet()) {
        TypeVariable typeVariable = entry.getKey();
        AnnotatedTypeMirror originalTypeArg = entry.getValue();
        if (originalTypeArg.containsUninferredTypeArguments()) {
            // Don't capture uninferred type arguments; return the argument.
            return typeVarToAnnotatedTypeArg;
        }
        if (originalTypeArg.getKind() == TypeKind.WILDCARD) {
            TypeMirror cap = TypesUtils.freshTypeVariable(originalTypeArg.getUnderlyingType(), processingEnv);
            AnnotatedTypeMirror capturedArg = AnnotatedTypeMirror.createType(cap, this, false);
            newTypeVarToAnnotatedTypeArg.put(typeVariable, capturedArg);
            capturedTypeVarToAnnotatedTypeVar.put((TypeVariable) cap, (AnnotatedTypeVariable) capturedArg);
        } else {
            newTypeVarToAnnotatedTypeArg.put(typeVariable, originalTypeArg);
        }
    }
    // The second loop captures: it side-effects the new type variables.
    List<TypeVariable> order = TypesUtils.order(typeVarToAnnotatedTypeArg.keySet(), types);
    for (TypeVariable typeVariable : order) {
        AnnotatedTypeMirror originalTypeArg = typeVarToAnnotatedTypeArg.get(typeVariable);
        AnnotatedTypeMirror newTypeArg = newTypeVarToAnnotatedTypeArg.get(typeVariable);
        if (TypesUtils.isCapturedTypeVariable(newTypeArg.getUnderlyingType()) && originalTypeArg.getKind() == TypeKind.WILDCARD) {
            annotateCapturedTypeVar(newTypeVarToAnnotatedTypeArg, capturedTypeVarToAnnotatedTypeVar, (AnnotatedWildcardType) originalTypeArg, typeParameter.get(typeVariable), (AnnotatedTypeVariable) newTypeArg);
        }
    }
    return newTypeVarToAnnotatedTypeArg;
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) TypeMirror(javax.lang.model.type.TypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap)

Example 70 with TypeVariable

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

the class DefaultInferredTypesApplier method removePrimaryTypeVarApplyUpperBound.

private void removePrimaryTypeVarApplyUpperBound(AnnotatedTypeMirror type, TypeMirror inferredTypeMirror, AnnotationMirror top, AnnotationMirror notInferred) {
    if (inferredTypeMirror.getKind() != TypeKind.TYPEVAR) {
        throw new BugInCF("Inferred value should not be missing annotations: " + inferredTypeMirror);
    }
    if (TypesUtils.isCapturedTypeVariable(inferredTypeMirror)) {
        return;
    }
    TypeVariable typeVar = (TypeVariable) inferredTypeMirror;
    AnnotatedTypeVariable typeVariableDecl = (AnnotatedTypeVariable) factory.getAnnotatedType(typeVar.asElement());
    AnnotationMirror upperBound = typeVariableDecl.getEffectiveAnnotationInHierarchy(top);
    if (omitSubtypingCheck || hierarchy.isSubtype(upperBound, notInferred)) {
        type.replaceAnnotation(upperBound);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) BugInCF(org.checkerframework.javacutil.BugInCF) 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