use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class DoubleAnnotatedTypeScanner method visitWildcard.
@Override
public R visitWildcard(AnnotatedWildcardType type, AnnotatedTypeMirror p) {
if (visitedNodes.containsKey(type)) {
return visitedNodes.get(type);
}
visitedNodes.put(type, null);
R r;
if (p instanceof AnnotatedWildcardType) {
AnnotatedWildcardType w = (AnnotatedWildcardType) p;
r = scan(type.getExtendsBound(), w.getExtendsBound());
visitedNodes.put(type, r);
r = scanAndReduce(type.getSuperBound(), w.getSuperBound(), r);
visitedNodes.put(type, r);
} else {
r = scan(type.getExtendsBound(), p.getErased());
visitedNodes.put(type, r);
r = scanAndReduce(type.getSuperBound(), p.getErased(), r);
visitedNodes.put(type, r);
}
return r;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypeFactory method methodFromUse.
/**
* Determines the type of the invoked method based on the passed method invocation tree.
*
* <p>The returned method type has all type variables resolved, whether based on receiver type,
* passed type parameters if any, and method invocation parameter.
*
* <p>Subclasses may override this method to customize inference of types or qualifiers based on
* method invocation parameters.
*
* <p>As an implementation detail, this method depends on {@link AnnotatedTypes#asMemberOf(Types,
* AnnotatedTypeFactory, AnnotatedTypeMirror, Element)}, and customization based on receiver type
* should be in accordance to its specification.
*
* <p>The return type is a pair of the type of the invoked method and the (inferred) type
* arguments. Note that neither the explicitly passed nor the inferred type arguments are
* guaranteed to be subtypes of the corresponding upper bounds. See method {@link
* org.checkerframework.common.basetype.BaseTypeVisitor#checkTypeArguments} for the checks of type
* argument well-formedness.
*
* <p>Note that "this" and "super" constructor invocations are also handled by this method
* (explicit or implicit ones, at the beginning of a constructor). Method {@link
* #constructorFromUse(NewClassTree)} is only used for a constructor invocation in a "new"
* expression.
*
* @param tree the method invocation tree
* @return the method type being invoked with tree and the (inferred) type arguments
*/
public ParameterizedExecutableType methodFromUse(MethodInvocationTree tree) {
ExecutableElement methodElt = TreeUtils.elementFromUse(tree);
AnnotatedTypeMirror receiverType = getReceiverType(tree);
if (receiverType == null && TreeUtils.isSuperConstructorCall(tree)) {
// super() calls don't have a receiver, but they should be view-point adapted as if
// "this" is the receiver.
receiverType = getSelfType(tree);
}
if (receiverType != null && receiverType.getKind() == TypeKind.DECLARED) {
receiverType = applyCaptureConversion(receiverType);
}
ParameterizedExecutableType result = methodFromUse(tree, methodElt, receiverType);
if (checker.shouldResolveReflection() && reflectionResolver.isReflectiveMethodInvocation(tree)) {
result = reflectionResolver.resolveReflectiveCall(this, tree, result);
}
AnnotatedExecutableType method = result.executableType;
if (method.getReturnType().getKind() == TypeKind.WILDCARD && ((AnnotatedWildcardType) method.getReturnType()).isUninferredTypeArgument()) {
// Get the correct Java type from the tree and use it as the upper bound of the wildcard.
TypeMirror tm = TreeUtils.typeOf(tree);
AnnotatedTypeMirror t = toAnnotatedType(tm, false);
AnnotatedWildcardType wildcard = (AnnotatedWildcardType) method.getReturnType();
if (ignoreUninferredTypeArguments) {
// Remove the annotations so that default annotations are used instead.
// (See call to addDefaultAnnotations below.)
t.clearPrimaryAnnotations();
} else {
t.replaceAnnotations(wildcard.getExtendsBound().getAnnotations());
}
wildcard.setExtendsBound(t);
addDefaultAnnotations(wildcard);
}
return result;
}
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)
* @param tree getClass method invocation tree
*/
protected void adaptGetClassReturnTypeToReceiver(AnnotatedExecutableType getClassType, AnnotatedTypeMirror receiverType, ExpressionTree tree) {
TypeMirror type = TreeUtils.typeOf(tree);
AnnotatedTypeMirror returnType = AnnotatedTypeMirror.createType(type, this, false);
if (returnType == null || !(returnType.getKind() == TypeKind.DECLARED) || ((AnnotatedDeclaredType) returnType).getTypeArguments().size() != 1) {
throw new BugInCF("Unexpected type passed to AnnotatedTypes.adaptGetClassReturnTypeToReceiver%n" + "getClassType=%s%nreceiverType=%s", getClassType, receiverType);
}
AnnotatedWildcardType classWildcardArg = (AnnotatedWildcardType) ((AnnotatedDeclaredType) getClassType.getReturnType()).getTypeArguments().get(0);
getClassType.setReturnType(returnType);
// 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.
Set<AnnotationMirror> newAnnos = AnnotationUtils.createAnnotationSet();
Set<AnnotationMirror> typeBoundAnnos = getTypeDeclarationBounds(receiverType.getErased().getUnderlyingType());
Set<AnnotationMirror> wildcardBoundAnnos = classWildcardArg.getExtendsBound().getAnnotations();
for (AnnotationMirror typeBoundAnno : typeBoundAnnos) {
AnnotationMirror wildcardAnno = qualHierarchy.findAnnotationInSameHierarchy(wildcardBoundAnnos, typeBoundAnno);
if (qualHierarchy.isSubtype(typeBoundAnno, wildcardAnno)) {
newAnnos.add(typeBoundAnno);
} else {
newAnnos.add(wildcardAnno);
}
}
AnnotatedTypeMirror newTypeArg = ((AnnotatedDeclaredType) getClassType.getReturnType()).getTypeArguments().get(0);
((AnnotatedTypeVariable) newTypeArg).getUpperBound().replaceAnnotations(newAnnos);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypeFactory method getUninferredWildcardType.
/**
* Returns a wildcard type to be used as a type argument when the correct type could not be
* inferred. The wildcard will be marked as an uninferred wildcard so that {@link
* AnnotatedWildcardType#isUninferredTypeArgument()} returns true.
*
* <p>This method should only be used by type argument inference.
* org.checkerframework.framework.util.AnnotatedTypes.inferTypeArguments(ProcessingEnvironment,
* AnnotatedTypeFactory, ExpressionTree, ExecutableElement)
*
* @param typeVar TypeVariable which could not be inferred
* @return a wildcard that is marked as an uninferred type argument
*/
public AnnotatedWildcardType getUninferredWildcardType(AnnotatedTypeVariable typeVar) {
final boolean intersectionType;
final TypeMirror boundType;
if (typeVar.getUpperBound().getKind() == TypeKind.INTERSECTION) {
boundType = typeVar.getUpperBound().directSupertypes().get(0).getUnderlyingType();
intersectionType = true;
} else {
boundType = typeVar.getUnderlyingType().getUpperBound();
intersectionType = false;
}
WildcardType wc = types.getWildcardType(boundType, null);
AnnotatedWildcardType wctype = (AnnotatedWildcardType) AnnotatedTypeMirror.createType(wc, this, false);
wctype.setTypeVariable(typeVar.getUnderlyingType());
if (!intersectionType) {
wctype.setExtendsBound(typeVar.getUpperBound().deepCopy());
} else {
wctype.getExtendsBound().addAnnotations(typeVar.getUpperBound().getAnnotations());
}
wctype.setSuperBound(typeVar.getLowerBound().deepCopy());
wctype.addAnnotations(typeVar.getAnnotations());
addDefaultAnnotations(wctype);
wctype.setUninferredTypeArgument();
return wctype;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType in project checker-framework by typetools.
the class AnnotatedTypeCopier method visitWildcard.
@Override
public AnnotatedTypeMirror visitWildcard(AnnotatedWildcardType original, IdentityHashMap<AnnotatedTypeMirror, AnnotatedTypeMirror> originalToCopy) {
if (originalToCopy.containsKey(original)) {
return originalToCopy.get(original);
}
final AnnotatedWildcardType copy = makeOrReturnCopy(original, originalToCopy);
if (original.isUninferredTypeArgument()) {
copy.setUninferredTypeArgument();
}
if (original.getExtendsBoundField() != null) {
copy.setExtendsBound(visit(original.getExtendsBoundField(), originalToCopy).asUse());
}
if (original.getSuperBoundField() != null) {
copy.setSuperBound(visit(original.getSuperBoundField(), originalToCopy).asUse());
}
copy.setTypeVariable(original.getTypeVariable());
return copy;
}
Aggregations