use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.
the class DefaultTypeArgumentInference method handleNullTypeArguments.
/**
* If one of the inferredArgs are NullType, then re-run inference ignoring null method arguments.
* Then lub the result of the second inference with the NullType and put the new result back into
* inferredArgs.
*
* @param typeFactory type factory
* @param methodElem element of the method
* @param methodType annotated type of the method
* @param argTypes annotated types of arguments to the method
* @param assignedTo annotated type to which the result of the method invocation is assigned
* @param targets set of type variables to infer
* @param inferredArgs map of type variables to the annotated types of their type arguments
*/
private void handleNullTypeArguments(AnnotatedTypeFactory typeFactory, ExecutableElement methodElem, AnnotatedExecutableType methodType, List<AnnotatedTypeMirror> argTypes, AnnotatedTypeMirror assignedTo, Set<TypeVariable> targets, Map<TypeVariable, AnnotatedTypeMirror> inferredArgs) {
if (!hasNullType(inferredArgs)) {
return;
}
final Map<TypeVariable, AnnotatedTypeMirror> inferredArgsWithoutNull = infer(typeFactory, argTypes, assignedTo, methodElem, methodType, targets, false);
for (AnnotatedTypeVariable atv : methodType.getTypeVariables()) {
TypeVariable typeVar = atv.getUnderlyingType();
AnnotatedTypeMirror result = inferredArgs.get(typeVar);
if (result == null) {
AnnotatedTypeMirror withoutNullResult = inferredArgsWithoutNull.get(typeVar);
if (withoutNullResult != null) {
inferredArgs.put(typeVar, withoutNullResult);
}
} else if (result.getKind() == TypeKind.NULL) {
AnnotatedTypeMirror withoutNullResult = inferredArgsWithoutNull.get(typeVar);
if (withoutNullResult == null) {
// withoutNullResult is null when the only constraint on a type argument is
// where a method argument is null.
withoutNullResult = atv.getUpperBound().deepCopy();
}
AnnotatedTypeMirror lub = AnnotatedTypes.leastUpperBound(typeFactory, withoutNullResult, result);
inferredArgs.put(typeVar, lub);
}
}
}
use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.
the class TypeArgInferenceUtil method substitute.
/**
* Create a copy of toModify. In the copy, for each pair {@code typeVariable => annotated type}
* replace uses of typeVariable with the corresponding annotated type using normal substitution
* rules (@see TypeVariableSubstitutor). Return the copy.
*/
public static AnnotatedTypeMirror substitute(Map<TypeVariable, AnnotatedTypeMirror> substitutions, final AnnotatedTypeMirror toModify) {
final AnnotatedTypeMirror substitution;
if (toModify.getKind() == TypeKind.TYPEVAR) {
substitution = substitutions.get((TypeVariable) TypeAnnotationUtils.unannotatedType(toModify.getUnderlyingType()));
} else {
substitution = null;
}
if (substitution != null) {
return substitution.deepCopy();
}
final AnnotatedTypeMirror toModifyCopy = toModify.deepCopy();
substitutor.substitute(substitutions, toModifyCopy);
return toModifyCopy;
}
use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.
the class EqualitiesSolver method solveEqualities.
/**
* For each target, if there is one or more equality constraints involving concrete types that
* lets us infer a primary annotation in all qualifier hierarchies then infer a concrete type
* argument. else if there is one or more equality constraints involving other targets that lets
* us infer a primary annotation in all qualifier hierarchies then infer that type argument is the
* other type argument
*
* <p>if we have inferred either a concrete type or another target as type argument rewrite all of
* the constraints for the current target to instead use the inferred type/target
*
* <p>We do this iteratively until NO new inferred type argument is found
*
* @param targets the list of type parameters for which we are inferring type arguments
* @param constraintMap the set of constraints over the set of targets
* @return a Map from target to (inferred type or target)
*/
public InferenceResult solveEqualities(Set<TypeVariable> targets, ConstraintMap constraintMap, AnnotatedTypeFactory typeFactory) {
final InferenceResult solution = new InferenceResult();
do {
dirty = false;
for (TypeVariable target : targets) {
if (solution.containsKey(target)) {
continue;
}
Equalities equalities = constraintMap.getConstraints(target).equalities;
InferredValue inferred = mergeConstraints(target, equalities, solution, constraintMap, typeFactory);
if (inferred != null) {
if (inferred instanceof InferredType) {
rewriteWithInferredType(target, ((InferredType) inferred).type, constraintMap);
} else {
rewriteWithInferredTarget(target, ((InferredTarget) inferred).target, constraintMap, typeFactory);
}
solution.put(target, inferred);
}
}
} while (dirty);
solution.resolveChainedTargets();
return solution;
}
use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.
the class EqualitiesSolver method findEqualTarget.
/**
* Attempt to find a target which is equal to this target.
*
* @return a target equal to this target in all hierarchies, or null
*/
public InferredTarget findEqualTarget(final Equalities equalities, AnnotationMirrorSet tops) {
for (Map.Entry<TypeVariable, AnnotationMirrorSet> targetToHierarchies : equalities.targets.entrySet()) {
final TypeVariable equalTarget = targetToHierarchies.getKey();
final AnnotationMirrorSet hierarchies = targetToHierarchies.getValue();
// Now see if target is equal to equalTarget in all hierarchies
boolean targetIsEqualInAllHierarchies = hierarchies.size() == tops.size();
if (targetIsEqualInAllHierarchies) {
return new InferredTarget(equalTarget, new AnnotationMirrorSet());
} else {
// annos in primaries that are not covered by the target's list of equal hierarchies
final AnnotationMirrorSet requiredPrimaries = new AnnotationMirrorSet(equalities.primaries.keySet());
requiredPrimaries.removeAll(hierarchies);
boolean typeWithPrimariesIsEqual = (requiredPrimaries.size() + hierarchies.size()) == tops.size();
if (typeWithPrimariesIsEqual) {
return new InferredTarget(equalTarget, requiredPrimaries);
}
}
}
return null;
}
use of javax.lang.model.type.TypeVariable in project checker-framework by typetools.
the class SupertypesSolver method solveFromSupertypes.
/**
* Infers type arguments using supertype constraints.
*
* @param remainingTargets targets for which we still need to infer a value
* @param constraintMap the set of constraints for all targets
* @return a mapping from target to inferred type. Note this class always infers concrete types
* and will not infer that the target is equivalent to another target.
*/
public InferenceResult solveFromSupertypes(final Set<TypeVariable> remainingTargets, final ConstraintMap constraintMap, final AnnotatedTypeFactory typeFactory) {
// infer a type for all targets that have supertype constraints
final Lubs lubs = targetToTypeLubs(remainingTargets, constraintMap, typeFactory);
// add the lub types to the outgoing solution
final InferenceResult solution = new InferenceResult();
for (final TypeVariable target : remainingTargets) {
final AnnotatedTypeMirror lub = lubs.getType(target);
AnnotationMirrorMap<AnnotationMirror> lubAnnos = lubs.getPrimaries(target);
// we may have a partial solution present in the equality constraints, override
// any annotations found in the lub with annotations from the equality constraints
final InferredValue inferred;
if (lub != null) {
inferred = mergeLubTypeWithEqualities(target, lub, constraintMap, typeFactory);
} else if (lubAnnos != null) {
inferred = mergeLubAnnosWithEqualities(target, lubAnnos, constraintMap, typeFactory);
} else {
inferred = null;
}
if (inferred != null) {
solution.put(target, inferred);
}
}
return solution;
}
Aggregations