use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypeFactory method adaptGetClassReturnTypeToReceiver.
/**
* Java special-cases the return type of {@link java.lang.Class#getClass() getClass()}. Though
* the method has a return type of {@code Class<?>}, the compiler special cases this return-type
* and changes the bound of the type argument to the erasure of the receiver type. For example:
*
* <ul>
* <li>{@code x.getClass()} has the type {@code Class< ? extends erasure_of_x >}
* <li>{@code someInteger.getClass()} has the type {@code Class< ? extends Integer >}
* </ul>
*
* @param getClassType this must be a type representing a call to Object.getClass otherwise a
* runtime exception will be thrown. It is modified by side effect.
* @param receiverType the receiver type of the method invocation (not the declared receiver
* type)
*/
protected void adaptGetClassReturnTypeToReceiver(final AnnotatedExecutableType getClassType, final AnnotatedTypeMirror receiverType) {
// TODO: should the receiver type ever be a declaration??
// Work on removing the asUse() call.
final AnnotatedTypeMirror newBound = receiverType.getErased().asUse();
final AnnotatedTypeMirror returnType = getClassType.getReturnType();
if (returnType == null || !(returnType.getKind() == TypeKind.DECLARED) || ((AnnotatedDeclaredType) returnType).getTypeArguments().size() != 1) {
ErrorReporter.errorAbort("Unexpected type passed to AnnotatedTypes.adaptGetClassReturnTypeToReceiver\n" + "getClassType=" + getClassType + "\n" + "receiverType=" + receiverType);
}
final AnnotatedDeclaredType returnAdt = (AnnotatedDeclaredType) getClassType.getReturnType();
final List<AnnotatedTypeMirror> typeArgs = returnAdt.getTypeArguments();
// Usually, the only locations that will add annotations to the return type are getClass in
// stub files defaults and propagation tree annotator. Since getClass is final they cannot
// come from source code. Also, since the newBound is an erased type we have no type
// arguments. So, we just copy the annotations from the bound of the declared type to the
// new bound.
final AnnotatedWildcardType classWildcardArg = (AnnotatedWildcardType) typeArgs.get(0);
newBound.replaceAnnotations(classWildcardArg.getExtendsBound().getAnnotations());
classWildcardArg.setExtendsBound(newBound);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypeComparer method visitWildcard.
@Override
public R visitWildcard(AnnotatedWildcardType type, AnnotatedTypeMirror p) {
assert p instanceof AnnotatedWildcardType : p;
AnnotatedWildcardType w = (AnnotatedWildcardType) p;
if (visitedNodes.containsKey(type)) {
return visitedNodes.get(type);
}
visitedNodes.put(type, null);
R r = scan(type.getExtendsBound(), w.getExtendsBound());
visitedNodes.put(type, r);
r = scanAndReduce(type.getSuperBound(), w.getSuperBound(), r);
visitedNodes.put(type, r);
return r;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class NullnessAnnotatedTypeFactory method adaptGetClassReturnTypeToReceiver.
@Override
public void adaptGetClassReturnTypeToReceiver(final AnnotatedExecutableType getClassType, final AnnotatedTypeMirror receiverType) {
super.adaptGetClassReturnTypeToReceiver(getClassType, receiverType);
// Make the wildcard always @NonNull, regardless of the declared type.
final AnnotatedDeclaredType returnAdt = (AnnotatedDeclaredType) getClassType.getReturnType();
final List<AnnotatedTypeMirror> typeArgs = returnAdt.getTypeArguments();
final AnnotatedWildcardType classWildcardArg = (AnnotatedWildcardType) typeArgs.get(0);
classWildcardArg.getExtendsBoundField().replaceAnnotation(NONNULL);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class QualifierDefaults method getWildcardBoundType.
/**
* Returns the BoundType of annotatedWildcard. If it is unbounded, use the type parameter to which
* its an argument.
*
* @param annotatedWildcard the annotated wildcard type
* @return the BoundType of annotatedWildcard. If it is unbounded, use the type parameter to which
* its an argument
*/
public BoundType getWildcardBoundType(final AnnotatedWildcardType annotatedWildcard) {
final WildcardType wildcard = (WildcardType) annotatedWildcard.getUnderlyingType();
final BoundType boundType;
if (wildcard.isUnbound() && wildcard.bound != null) {
boundType = getTypeVarBoundType((TypeParameterElement) wildcard.bound.asElement());
} else {
// note: isSuperBound will be true for unbounded and lowers, but the unbounded case is
// already handled
boundType = wildcard.isSuperBound() ? BoundType.LOWER : BoundType.UPPER;
}
return boundType;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypes method asMemberOfImpl.
/**
* Helper for {@link AnnotatedTypes#asMemberOf(Types, AnnotatedTypeFactory, AnnotatedTypeMirror,
* Element)}.
*
* @param types the Types instance to use
* @param atypeFactory the type factory to use
* @param receiverType the receiver type
* @param member the element that should be viewed as member of receiverType
* @param memberType unsubstituted type of member
* @return the type of member as a member of receiverType; can be an alias to memberType
*/
private static AnnotatedTypeMirror asMemberOfImpl(final Types types, final AnnotatedTypeFactory atypeFactory, final AnnotatedTypeMirror receiverType, final Element member, final AnnotatedTypeMirror memberType) {
switch(receiverType.getKind()) {
case ARRAY:
// rather than Object.
if (SyntheticArrays.isArrayClone(receiverType, member)) {
return SyntheticArrays.replaceReturnType(member, (AnnotatedArrayType) receiverType);
}
return memberType;
case TYPEVAR:
return asMemberOf(types, atypeFactory, atypeFactory.applyCaptureConversion(((AnnotatedTypeVariable) receiverType).getUpperBound()), member, memberType);
case WILDCARD:
if (((AnnotatedWildcardType) receiverType).isUninferredTypeArgument()) {
return substituteUninferredTypeArgs(atypeFactory, member, memberType);
}
return asMemberOf(types, atypeFactory, ((AnnotatedWildcardType) receiverType).getExtendsBound().deepCopy(), member, memberType);
case INTERSECTION:
AnnotatedTypeMirror result = memberType;
TypeMirror enclosingElementType = member.getEnclosingElement().asType();
for (AnnotatedTypeMirror bound : ((AnnotatedIntersectionType) receiverType).getBounds()) {
if (TypesUtils.isErasedSubtype(bound.getUnderlyingType(), enclosingElementType, types)) {
result = substituteTypeVariables(types, atypeFactory, atypeFactory.applyCaptureConversion(bound), member, result);
}
}
return result;
case UNION:
case DECLARED:
return substituteTypeVariables(types, atypeFactory, receiverType, member, memberType);
default:
throw new BugInCF("asMemberOf called on unexpected type.%nt: %s", receiverType);
}
}
Aggregations