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 StubParser method annotate.
/**
* Add to {@code atype}:
*
* <ol>
* <li>the annotations from {@code typeDef}, and
* <li>any type annotations that parsed as declaration annotations (ie those in {@code
* declAnnos}).
* </ol>
*
* @param atype annotated type to which to add annotations
* @param typeDef parsed type
* @param declAnnos annotations stored on the declaration of the variable with this type, or
* null
*/
private void annotate(AnnotatedTypeMirror atype, Type typeDef, NodeList<AnnotationExpr> declAnnos) {
if (atype.getKind() == TypeKind.ARRAY) {
annotateAsArray((AnnotatedArrayType) atype, (ReferenceType) typeDef, declAnnos);
return;
}
clearAnnotations(atype, typeDef);
// Primary annotations for the type of a variable declaration are not stored in typeDef, but
// rather as declaration annotations (passed as declAnnos to this method). But, if typeDef
// is not the type of a variable, then the primary annotations are stored in typeDef.
NodeList<AnnotationExpr> primaryAnnotations;
if (typeDef.getAnnotations().isEmpty() && declAnnos != null) {
primaryAnnotations = declAnnos;
} else {
primaryAnnotations = typeDef.getAnnotations();
}
if (atype.getKind() != TypeKind.WILDCARD) {
// The primary annotation on a wildcard applies to the super or extends bound and
// are added below.
annotate(atype, primaryAnnotations);
}
switch(atype.getKind()) {
case DECLARED:
ClassOrInterfaceType declType = unwrapDeclaredType(typeDef);
if (declType == null) {
break;
}
AnnotatedDeclaredType adeclType = (AnnotatedDeclaredType) atype;
if (declType.getTypeArguments().isPresent() && !declType.getTypeArguments().get().isEmpty() && !adeclType.getTypeArguments().isEmpty()) {
assert declType.getTypeArguments().get().size() == adeclType.getTypeArguments().size() : String.format("Mismatch in type argument size between %s (%d) and %s (%d)", declType, declType.getTypeArguments().get().size(), adeclType, adeclType.getTypeArguments().size());
for (int i = 0; i < declType.getTypeArguments().get().size(); ++i) {
annotate(adeclType.getTypeArguments().get(i), declType.getTypeArguments().get().get(i), null);
}
}
break;
case WILDCARD:
AnnotatedWildcardType wildcardType = (AnnotatedWildcardType) atype;
WildcardType wildcardDef = (WildcardType) typeDef;
if (wildcardDef.getExtendedType().isPresent()) {
annotate(wildcardType.getExtendsBound(), wildcardDef.getExtendedType().get(), null);
annotate(wildcardType.getSuperBound(), primaryAnnotations);
} else if (wildcardDef.getSuperType().isPresent()) {
annotate(wildcardType.getSuperBound(), wildcardDef.getSuperType().get(), null);
annotate(wildcardType.getExtendsBound(), primaryAnnotations);
} else {
annotate(atype, primaryAnnotations);
}
break;
case TYPEVAR:
// Add annotations from the declaration of the TypeVariable
AnnotatedTypeVariable typeVarUse = (AnnotatedTypeVariable) atype;
for (AnnotatedTypeVariable typePar : typeParameters) {
if (typePar.getUnderlyingType() == atype.getUnderlyingType()) {
AnnotatedTypeMerger.merge(typePar.getUpperBound(), typeVarUse.getUpperBound());
AnnotatedTypeMerger.merge(typePar.getLowerBound(), typeVarUse.getLowerBound());
}
}
break;
default:
}
}
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 = (AnnotatedWildcardType) AnnotatedTypeMirror.createType(original.getUnderlyingType(), original.atypeFactory, original.isDeclaration());
if (original.isUninferredTypeArgument()) {
copy.setUninferredTypeArgument();
}
maybeCopyPrimaryAnnotations(original, copy);
originalToCopy.put(original, copy);
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;
}
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 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(Tree, List, List,
* List)} for the checks of type argument well-formedness.
*
* <p>Note that "this" and "super" constructor invocations are also handled by this method.
* 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 Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> methodFromUse(MethodInvocationTree tree) {
ExecutableElement methodElt = TreeUtils.elementFromUse(tree);
AnnotatedTypeMirror receiverType = getReceiverType(tree);
Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> mfuPair = methodFromUse(tree, methodElt, receiverType);
if (checker.shouldResolveReflection() && reflectionResolver.isReflectiveMethodInvocation(tree)) {
mfuPair = reflectionResolver.resolveReflectiveCall(this, tree, mfuPair);
}
AnnotatedExecutableType method = mfuPair.first;
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.clearAnnotations();
} else {
t.replaceAnnotations(wildcard.getExtendsBound().getAnnotations());
}
wildcard.setExtendsBound(t);
addDefaultAnnotations(wildcard);
}
return mfuPair;
}
Aggregations