Search in sources :

Example 16 with AnnotatedTypeVariable

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.

the class AnnotatedTypes method addTypeVarMappings.

private static void addTypeVarMappings(Types types, AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror t, TypeElement enclosingClassOfElem, Map<TypeVariable, AnnotatedTypeMirror> mappings) {
    if (enclosingClassOfElem.getTypeParameters().isEmpty()) {
        return;
    }
    AnnotatedDeclaredType enclosingType = atypeFactory.getAnnotatedType(enclosingClassOfElem);
    AnnotatedDeclaredType base = (AnnotatedDeclaredType) asOuterSuper(types, atypeFactory, t, enclosingType);
    final List<AnnotatedTypeVariable> ownerParams = new ArrayList<>(enclosingType.getTypeArguments().size());
    for (final AnnotatedTypeMirror typeParam : enclosingType.getTypeArguments()) {
        if (typeParam.getKind() != TypeKind.TYPEVAR) {
            ErrorReporter.errorAbort("Type arguments of a declaration should be type variables\n" + "enclosingClassOfElem=" + enclosingClassOfElem + "\n" + "enclosingType=" + enclosingType + "\n" + "typeMirror=" + t);
        }
        ownerParams.add((AnnotatedTypeVariable) typeParam);
    }
    List<AnnotatedTypeMirror> baseParams = base.getTypeArguments();
    if (ownerParams.size() != baseParams.size() && !base.wasRaw()) {
        ErrorReporter.errorAbort("Unexpected number of parameters.\n" + "enclosingType=" + enclosingType + "\n" + "baseType=" + base);
    }
    if (!ownerParams.isEmpty() && baseParams.isEmpty() && base.wasRaw()) {
        List<AnnotatedTypeMirror> newBaseParams = new ArrayList<>();
        for (AnnotatedTypeVariable arg : ownerParams) {
            // If base type was raw and the type arguments are missing,
            // set them to the erased type of the type variable.
            // (which is the erased type of the upper bound.)
            newBaseParams.add(arg.getErased());
        }
        baseParams = newBaseParams;
    }
    for (int i = 0; i < ownerParams.size(); ++i) {
        mappings.put(ownerParams.get(i).getUnderlyingType(), baseParams.get(i));
    }
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 17 with AnnotatedTypeVariable

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.

the class AnnotatedTypes method findTypeArguments.

/**
 * Given a method or constructor invocation, return a mapping of the type variables to their
 * type arguments, if any exist.
 *
 * <p>It uses the method or constructor invocation type arguments if they were specified and
 * otherwise it infers them based on the passed arguments or the return type context, according
 * to JLS 15.12.2.
 *
 * @param atypeFactory the annotated type factory
 * @param expr the method or constructor invocation tree; the passed argument has to be a
 *     subtype of MethodInvocationTree or NewClassTree
 * @param elt the element corresponding to the tree
 * @param preType the (partially annotated) type corresponding to the tree - the result of
 *     AnnotatedTypes.asMemberOf with the receiver and elt.
 * @return the mapping of the type variables to type arguments for this method or constructor
 *     invocation
 */
public static Map<TypeVariable, AnnotatedTypeMirror> findTypeArguments(final ProcessingEnvironment processingEnv, final AnnotatedTypeFactory atypeFactory, final ExpressionTree expr, final ExecutableElement elt, final AnnotatedExecutableType preType) {
    // Is the method a generic method?
    if (elt.getTypeParameters().isEmpty()) {
        return Collections.emptyMap();
    }
    List<? extends Tree> targs;
    if (expr instanceof MethodInvocationTree) {
        targs = ((MethodInvocationTree) expr).getTypeArguments();
    } else if (expr instanceof NewClassTree) {
        targs = ((NewClassTree) expr).getTypeArguments();
    } else if (expr instanceof MemberReferenceTree) {
        targs = ((MemberReferenceTree) expr).getTypeArguments();
        if (targs == null) {
            // TODO: Add type argument inference as part of fix for #979
            return new HashMap<>();
        }
    } else {
        // This case should never happen.
        ErrorReporter.errorAbort("AnnotatedTypes.findTypeArguments: unexpected tree: " + expr);
        // dead code
        return null;
    }
    // Has the user supplied type arguments?
    if (!targs.isEmpty()) {
        List<? extends AnnotatedTypeVariable> tvars = preType.getTypeVariables();
        Map<TypeVariable, AnnotatedTypeMirror> typeArguments = new HashMap<>();
        for (int i = 0; i < elt.getTypeParameters().size(); ++i) {
            AnnotatedTypeVariable typeVar = tvars.get(i);
            AnnotatedTypeMirror typeArg = atypeFactory.getAnnotatedTypeFromTypeTree(targs.get(i));
            // TODO: the call to getTypeParameterDeclaration shouldn't be necessary - typeVar
            // already should be a declaration.
            typeArguments.put(typeVar.getUnderlyingType(), typeArg);
        }
        return typeArguments;
    } else {
        return atypeFactory.getTypeArgumentInference().inferTypeArgs(atypeFactory, expr, elt, preType);
    }
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) NewClassTree(com.sun.source.tree.NewClassTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 18 with AnnotatedTypeVariable

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.

the class BaseTypeVisitor method visitMethodInvocation.

/**
 * Performs a method invocation check.
 *
 * <p>An invocation of a method, m, on the receiver, r is valid only if:
 *
 * <ul>
 *   <li>passed arguments are subtypes of corresponding m parameters
 *   <li>r is a subtype of m receiver type
 *   <li>if m is generic, passed type arguments are subtypes of m type variables
 * </ul>
 */
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
    // hard to check), also see CFGBuilder.visitMethodInvocation.
    if (TreeUtils.elementFromUse(node) == null || TreeUtils.isEnumSuper(node)) {
        return super.visitMethodInvocation(node, p);
    }
    if (shouldSkipUses(node)) {
        return super.visitMethodInvocation(node, p);
    }
    Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> mfuPair = atypeFactory.methodFromUse(node);
    AnnotatedExecutableType invokedMethod = mfuPair.first;
    List<AnnotatedTypeMirror> typeargs = mfuPair.second;
    if (!atypeFactory.ignoreUninferredTypeArguments) {
        for (AnnotatedTypeMirror typearg : typeargs) {
            if (typearg.getKind() == TypeKind.WILDCARD && ((AnnotatedWildcardType) typearg).isUninferredTypeArgument()) {
                checker.report(Result.failure("type.arguments.not.inferred", invokedMethod.getElement().getSimpleName()), node);
                // only issue error once per method
                break;
            }
        }
    }
    List<AnnotatedTypeParameterBounds> paramBounds = new ArrayList<>();
    for (AnnotatedTypeVariable param : invokedMethod.getTypeVariables()) {
        paramBounds.add(param.getBounds());
    }
    checkTypeArguments(node, paramBounds, typeargs, node.getTypeArguments());
    List<AnnotatedTypeMirror> params = AnnotatedTypes.expandVarArgs(atypeFactory, invokedMethod, node.getArguments());
    checkArguments(params, node.getArguments());
    checkVarargs(invokedMethod, node);
    if (isVectorCopyInto(invokedMethod)) {
        typeCheckVectorCopyIntoArgument(node, params);
    }
    ExecutableElement invokedMethodElement = invokedMethod.getElement();
    if (!ElementUtils.isStatic(invokedMethodElement) && !TreeUtils.isSuperCall(node)) {
        checkMethodInvocability(invokedMethod, node);
    }
    // check precondition annotations
    checkPreconditions(node, contractsUtils.getPreconditions(invokedMethodElement));
    // Do not call super, as that would observe the arguments without
    // a set assignment context.
    scan(node.getMethodSelect(), p);
    // super.visitMethodInvocation(node, p);
    return null;
}
Also used : AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 19 with AnnotatedTypeVariable

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.

the class BaseTypeVisitor method testTypevarContainment.

/**
 * @return true if both types are type variables and outer contains inner Outer contains inner
 *     implies: {@literal inner.upperBound <: outer.upperBound outer.lowerBound <:
 *     inner.lowerBound }
 */
protected boolean testTypevarContainment(final AnnotatedTypeMirror inner, final AnnotatedTypeMirror outer) {
    if (inner.getKind() == TypeKind.TYPEVAR && outer.getKind() == TypeKind.TYPEVAR) {
        final AnnotatedTypeVariable innerAtv = (AnnotatedTypeVariable) inner;
        final AnnotatedTypeVariable outerAtv = (AnnotatedTypeVariable) outer;
        if (AnnotatedTypes.areCorrespondingTypeVariables(elements, innerAtv, outerAtv)) {
            final TypeHierarchy typeHierarchy = atypeFactory.getTypeHierarchy();
            return typeHierarchy.isSubtype(innerAtv.getUpperBound(), outerAtv.getUpperBound()) && typeHierarchy.isSubtype(outerAtv.getLowerBound(), innerAtv.getLowerBound());
        }
    }
    return false;
}
Also used : TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 20 with AnnotatedTypeVariable

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable in project checker-framework by typetools.

the class BaseTypeVisitor method visitNewClass.

/**
 * Performs a new class invocation check.
 *
 * <p>An invocation of a constructor, c, is valid only if:
 *
 * <ul>
 *   <li>passed arguments are subtypes of corresponding c parameters
 *   <li>if c is generic, passed type arguments are subtypes of c type variables
 * </ul>
 */
@Override
public Void visitNewClass(NewClassTree node, Void p) {
    if (checker.shouldSkipUses(TreeUtils.constructor(node))) {
        return super.visitNewClass(node, p);
    }
    Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> fromUse = atypeFactory.constructorFromUse(node);
    AnnotatedExecutableType constructor = fromUse.first;
    List<AnnotatedTypeMirror> typeargs = fromUse.second;
    List<? extends ExpressionTree> passedArguments = node.getArguments();
    List<AnnotatedTypeMirror> params = AnnotatedTypes.expandVarArgs(atypeFactory, constructor, passedArguments);
    checkArguments(params, passedArguments);
    checkVarargs(constructor, node);
    List<AnnotatedTypeParameterBounds> paramBounds = new ArrayList<>();
    for (AnnotatedTypeVariable param : constructor.getTypeVariables()) {
        paramBounds.add(param.getBounds());
    }
    checkTypeArguments(node, paramBounds, typeargs, node.getTypeArguments());
    boolean valid = validateTypeOf(node);
    if (valid) {
        AnnotatedDeclaredType dt = atypeFactory.getAnnotatedType(node);
        if (atypeFactory.getDependentTypesHelper() != null) {
            atypeFactory.getDependentTypesHelper().checkType(dt, node);
        }
        checkConstructorInvocation(dt, constructor, node);
    }
    // Do not call super, as that would observe the arguments without
    // a set assignment context.
    scan(node.getEnclosingExpression(), p);
    scan(node.getIdentifier(), p);
    scan(node.getClassBody(), p);
    return null;
}
Also used : AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Aggregations

AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)40 TypeVariable (javax.lang.model.type.TypeVariable)16 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)16 ArrayList (java.util.ArrayList)13 AnnotationMirror (javax.lang.model.element.AnnotationMirror)9 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)9 AnnotatedWildcardType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)7 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)5 HashMap (java.util.HashMap)4 LinkedHashMap (java.util.LinkedHashMap)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 TypeElement (javax.lang.model.element.TypeElement)3 QualifierHierarchy (org.checkerframework.framework.type.QualifierHierarchy)3 AnnotationMirrorSet (org.checkerframework.framework.util.AnnotationMirrorSet)3 TUConstraint (org.checkerframework.framework.util.typeinference.constraint.TUConstraint)3 TypeParameter (com.github.javaparser.ast.type.TypeParameter)2 ClassTree (com.sun.source.tree.ClassTree)2 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)2 MethodTree (com.sun.source.tree.MethodTree)2 TypeParameterTree (com.sun.source.tree.TypeParameterTree)2