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;
}
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();
}
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;
}
}
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;
}
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);
}
}
Aggregations