Search in sources :

Example 26 with AnnotatedWildcardType

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;
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)

Example 27 with AnnotatedWildcardType

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;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) TypeMirror(javax.lang.model.type.TypeMirror) ExecutableElement(javax.lang.model.element.ExecutableElement) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)

Example 28 with AnnotatedWildcardType

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);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeMirror(javax.lang.model.type.TypeMirror) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 29 with AnnotatedWildcardType

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;
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) WildcardType(javax.lang.model.type.WildcardType) TypeMirror(javax.lang.model.type.TypeMirror) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)

Example 30 with AnnotatedWildcardType

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;
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)

Aggregations

AnnotatedWildcardType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)30 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)14 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)13 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)9 TypeMirror (javax.lang.model.type.TypeMirror)8 HashMap (java.util.HashMap)5 TypeElement (javax.lang.model.element.TypeElement)5 TypeVariable (javax.lang.model.type.TypeVariable)5 WildcardType (com.sun.tools.javac.code.Type.WildcardType)4 BugInCF (org.checkerframework.javacutil.BugInCF)4 ArrayList (java.util.ArrayList)3 DeclaredType (javax.lang.model.type.DeclaredType)3 AnnotationExpr (com.github.javaparser.ast.expr.AnnotationExpr)2 MarkerAnnotationExpr (com.github.javaparser.ast.expr.MarkerAnnotationExpr)2 NormalAnnotationExpr (com.github.javaparser.ast.expr.NormalAnnotationExpr)2 SingleMemberAnnotationExpr (com.github.javaparser.ast.expr.SingleMemberAnnotationExpr)2 ClassOrInterfaceType (com.github.javaparser.ast.type.ClassOrInterfaceType)2 WildcardType (com.github.javaparser.ast.type.WildcardType)2 IdentityHashMap (java.util.IdentityHashMap)2 Element (javax.lang.model.element.Element)2