use of javax.lang.model.util.Types in project checker-framework by typetools.
the class TypeArgInferenceUtil method getMappingFromReturnType.
/**
* Returns a mapping of type variable to type argument computed using the type of {@code
* methodInvocationTree} and the return type of {@code methodType}.
*/
private static Map<TypeVariable, TypeMirror> getMappingFromReturnType(ExpressionTree methodInvocationTree, ExecutableType methodType, ProcessingEnvironment env) {
TypeMirror methodCallType = TreeUtils.typeOf(methodInvocationTree);
Types types = env.getTypeUtils();
GetMapping mapping = new GetMapping(methodType.getTypeVariables(), types);
mapping.visit(methodType.getReturnType(), methodCallType);
return mapping.subs;
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class TypeArgInferenceUtil method correctResults.
/**
* If the type arguments computed by DefaultTypeArgumentInference don't match the return type
* mirror of {@code invocation}, then replace those type arguments with an uninferred wildcard.
*/
protected static Map<TypeVariable, AnnotatedTypeMirror> correctResults(Map<TypeVariable, AnnotatedTypeMirror> result, ExpressionTree invocation, ExecutableType methodType, AnnotatedTypeFactory factory) {
ProcessingEnvironment env = factory.getProcessingEnv();
Types types = env.getTypeUtils();
Map<TypeVariable, TypeMirror> fromReturn = getMappingFromReturnType(invocation, methodType, env);
for (Map.Entry<TypeVariable, AnnotatedTypeMirror> entry : // result is side-effected by this loop, so iterate over a copy
new ArrayList<>(result.entrySet())) {
TypeVariable typeVariable = entry.getKey();
if (!fromReturn.containsKey(typeVariable)) {
continue;
}
TypeMirror correctType = fromReturn.get(typeVariable);
TypeMirror inferredType = entry.getValue().getUnderlyingType();
if (types.isSameType(types.erasure(correctType), types.erasure(inferredType))) {
if (areSameCapture(correctType, inferredType)) {
continue;
}
}
if (!types.isSameType(correctType, inferredType)) {
AnnotatedWildcardType wt = factory.getUninferredWildcardType((AnnotatedTypeVariable) AnnotatedTypeMirror.createType(typeVariable, factory, false));
wt.replaceAnnotations(entry.getValue().getAnnotations());
result.put(typeVariable, wt);
}
}
return result;
}
use of javax.lang.model.util.Types 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;
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class GlbUtil method sortForGlb.
/**
* Sort the list of type mirrors, placing supertypes first and subtypes last.
*
* <p>E.g. the list: {@code ArrayList<String>, List<String>, AbstractList<String>} becomes: {@code
* List<String>, AbstractList<String>, ArrayList<String>}
*/
public static void sortForGlb(final List<? extends AnnotatedTypeMirror> typeMirrors, final AnnotatedTypeFactory typeFactory) {
final QualifierHierarchy qualifierHierarchy = typeFactory.getQualifierHierarchy();
final Types types = typeFactory.getProcessingEnv().getTypeUtils();
Collections.sort(typeMirrors, new Comparator<AnnotatedTypeMirror>() {
@Override
public int compare(AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) {
final TypeMirror underlyingType1 = type1.getUnderlyingType();
final TypeMirror underlyingType2 = type2.getUnderlyingType();
if (types.isSameType(underlyingType1, underlyingType2)) {
return compareAnnotations(qualifierHierarchy, type1, type2);
}
if (types.isSubtype(underlyingType1, underlyingType2)) {
return 1;
}
// if they're incomparable or type2 is a subtype of type1
return -1;
}
private int compareAnnotations(final QualifierHierarchy qualHierarchy, final AnnotatedTypeMirror type1, final AnnotatedTypeMirror type2) {
if (AnnotationUtils.areSame(type1.getAnnotations(), type2.getAnnotations())) {
return 0;
}
if (qualHierarchy.isSubtype(type1.getAnnotations(), type2.getAnnotations())) {
return 1;
} else {
return -1;
}
}
});
}
use of javax.lang.model.util.Types in project checker-framework by typetools.
the class AnnotatedTypes method castedAsSuper.
/**
* Calls asSuper and casts the result to the same type as the input supertype.
*
* @param subtype subtype to be transformed to supertype
* @param supertype supertype that subtype is transformed to
* @param <T> the type of supertype and return type
* @return subtype as an instance of supertype
*/
public static <T extends AnnotatedTypeMirror> T castedAsSuper(final AnnotatedTypeFactory atypeFactory, final AnnotatedTypeMirror subtype, final T supertype) {
final Types types = atypeFactory.getProcessingEnv().getTypeUtils();
final Elements elements = atypeFactory.getProcessingEnv().getElementUtils();
if (subtype.getKind() == TypeKind.NULL) {
// Make a copy of the supertype so that if supertype is a composite type, the
// returned type will be fully annotated. (For example, if sub is @C null and super is
// @A List<@B String>, then the returned type is @C List<@B String>.)
@SuppressWarnings("unchecked") T copy = (T) supertype.deepCopy();
copy.replaceAnnotations(subtype.getAnnotations());
return copy;
}
final T asSuperType = AnnotatedTypes.asSuper(atypeFactory, subtype, supertype);
fixUpRawTypes(subtype, asSuperType, supertype, types);
// @1 Enum<E extends @2 Enum<E>>
if (asSuperType != null && AnnotatedTypes.isEnum(asSuperType) && AnnotatedTypes.isDeclarationOfJavaLangEnum(types, elements, supertype)) {
final AnnotatedDeclaredType resultAtd = ((AnnotatedDeclaredType) supertype).deepCopy();
resultAtd.clearPrimaryAnnotations();
resultAtd.addAnnotations(asSuperType.getAnnotations());
final AnnotatedDeclaredType asSuperAdt = (AnnotatedDeclaredType) asSuperType;
if (!resultAtd.getTypeArguments().isEmpty() && !asSuperAdt.getTypeArguments().isEmpty()) {
final AnnotatedTypeMirror sourceTypeArg = asSuperAdt.getTypeArguments().get(0);
final AnnotatedTypeMirror resultTypeArg = resultAtd.getTypeArguments().get(0);
resultTypeArg.clearPrimaryAnnotations();
if (resultTypeArg.getKind() == TypeKind.TYPEVAR) {
// Only change the upper bound of a type variable.
AnnotatedTypeVariable resultTypeArgTV = (AnnotatedTypeVariable) resultTypeArg;
resultTypeArgTV.getUpperBound().addAnnotations(sourceTypeArg.getAnnotations());
} else {
resultTypeArg.addAnnotations(sourceTypeArg.getEffectiveAnnotations());
}
@SuppressWarnings("unchecked") T result = (T) resultAtd;
return result;
}
}
return asSuperType;
}
Aggregations