Search in sources :

Example 11 with AnnotatedTypeVariable

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

the class AnnotatedTypeFactory method typeVariablesFromUse.

/**
 * Adapt the upper bounds of the type variables of a class relative to the type instantiation.
 * In some type systems, the upper bounds depend on the instantiation of the class. For example,
 * in the Generic Universe Type system, consider a class declaration
 *
 * <pre>{@code   class C<X extends @Peer Object> }</pre>
 *
 * then the instantiation
 *
 * <pre>{@code   @Rep C<@Rep Object> }</pre>
 *
 * is legal. The upper bounds of class C have to be adapted by the main modifier.
 *
 * <p>An example of an adaptation follows. Suppose, I have a declaration:
 *
 * <pre>{@code  class MyClass<E extends List<E>>}</pre>
 *
 * And an instantiation:
 *
 * <pre>{@code  new MyClass<@NonNull String>()}</pre>
 *
 * <p>The upper bound of E adapted to the argument String, would be {@code List<@NonNull
 * String>} and the lower bound would be an AnnotatedNullType.
 *
 * <p>TODO: ensure that this method is consistently used instead of directly querying the type
 * variables.
 *
 * @param type the use of the type
 * @param element the corresponding element
 * @return the adapted bounds of the type parameters
 */
public List<AnnotatedTypeParameterBounds> typeVariablesFromUse(AnnotatedDeclaredType type, TypeElement element) {
    AnnotatedDeclaredType generic = getAnnotatedType(element);
    List<AnnotatedTypeMirror> targs = type.getTypeArguments();
    List<AnnotatedTypeMirror> tvars = generic.getTypeArguments();
    assert targs.size() == tvars.size() : "Mismatch in type argument size between " + type + " and " + generic;
    // System.err.printf("TVFU\n  type: %s\n  generic: %s\n", type, generic);
    Map<TypeVariable, AnnotatedTypeMirror> mapping = new HashMap<>();
    AnnotatedDeclaredType enclosing = type;
    while (enclosing != null) {
        List<AnnotatedTypeMirror> enclosingTArgs = enclosing.getTypeArguments();
        AnnotatedDeclaredType declaredType = getAnnotatedType((TypeElement) enclosing.getUnderlyingType().asElement());
        List<AnnotatedTypeMirror> enclosingTVars = declaredType.getTypeArguments();
        for (int i = 0; i < enclosingTArgs.size(); i++) {
            AnnotatedTypeVariable enclosingTVar = (AnnotatedTypeVariable) enclosingTVars.get(i);
            mapping.put(enclosingTVar.getUnderlyingType(), enclosingTArgs.get(i));
        }
        enclosing = enclosing.getEnclosingType();
    }
    List<AnnotatedTypeParameterBounds> res = new ArrayList<>(tvars.size());
    for (AnnotatedTypeMirror atm : tvars) {
        AnnotatedTypeVariable atv = (AnnotatedTypeVariable) atm;
        AnnotatedTypeMirror upper = typeVarSubstitutor.substitute(mapping, atv.getUpperBound());
        AnnotatedTypeMirror lower = typeVarSubstitutor.substitute(mapping, atv.getLowerBound());
        res.add(new AnnotatedTypeParameterBounds(upper, lower));
    }
    return res;
}
Also used : TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) HashMap(java.util.HashMap) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 12 with AnnotatedTypeVariable

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

the class BoundsInitializer method initializeTypeArgs.

// ============================================================================================
// Static helper methods called from AnnotatedTypeMirror to initialize bounds of wildcards or
// type variables
// ============================================================================================
/**
 * Initializes the type arguments of {@code declaredType}. The upper bound of unbound wildcards
 * is set to the upper bound of the type parameter for which it is an argument. If {@code
 * declaredType} is raw, then the type arguments are uninferred wildcards.
 *
 * @param declaredType type whose arguments are initialized.
 */
public static void initializeTypeArgs(AnnotatedDeclaredType declaredType) {
    final DeclaredType actualType = (DeclaredType) declaredType.actualType;
    if (actualType.getTypeArguments().isEmpty() && !declaredType.wasRaw()) {
        // No type arguments to infer.
        return;
    }
    final TypeElement typeElement = (TypeElement) declaredType.atypeFactory.types.asElement(actualType);
    final List<AnnotatedTypeMirror> typeArgs = new ArrayList<>();
    // Create AnnotatedTypeMirror for each type argument and store them in the typeArgsMap.
    Map<TypeVariable, AnnotatedTypeMirror> typeArgMap = new HashMap<>();
    for (int i = 0; i < typeElement.getTypeParameters().size(); i++) {
        TypeMirror javaTypeArg;
        if (declaredType.wasRaw()) {
            TypeVariable typeVariable = (TypeVariable) typeElement.getTypeParameters().get(i).asType();
            javaTypeArg = getUpperBoundAsWildcard(typeVariable, declaredType.atypeFactory);
        } else {
            javaTypeArg = declaredType.getUnderlyingType().getTypeArguments().get(i);
        }
        final AnnotatedTypeMirror typeArg = AnnotatedTypeMirror.createType(javaTypeArg, declaredType.atypeFactory, false);
        if (typeArg.getKind() == TypeKind.WILDCARD) {
            AnnotatedWildcardType wildcardType = (AnnotatedWildcardType) typeArg;
            wildcardType.setTypeVariable(typeElement.getTypeParameters().get(i));
            if (declaredType.wasRaw()) {
                wildcardType.setUninferredTypeArgument();
            }
        }
        typeArgs.add(typeArg);
        typeArgMap.put((TypeVariable) typeElement.getTypeParameters().get(i).asType(), typeArg);
    }
    // Initialize type argument bounds using the typeArgsMap.
    for (AnnotatedTypeMirror typeArg : typeArgs) {
        switch(typeArg.getKind()) {
            case WILDCARD:
                AnnotatedWildcardType wildcardType = (AnnotatedWildcardType) typeArg;
                initializeExtendsBound(wildcardType, typeArgMap);
                initializeSuperBound(wildcardType, typeArgMap);
                break;
            case TYPEVAR:
                initializeBounds((AnnotatedTypeVariable) typeArg, typeArgMap);
                break;
            default:
        }
    }
    declaredType.typeArgs = Collections.unmodifiableList(typeArgs);
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) ArrayList(java.util.ArrayList) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) DeclaredType(javax.lang.model.type.DeclaredType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)

Example 13 with AnnotatedTypeVariable

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

the class DefaultInferredTypesApplier method removePrimaryAnnotationTypeVar.

private void removePrimaryAnnotationTypeVar(AnnotatedTypeVariable annotatedTypeVariable, TypeMirror inferredTypeMirror, AnnotationMirror top, AnnotationMirror previousAnnotation) {
    if (inferredTypeMirror.getKind() == TypeKind.WILDCARD) {
        // actually type variables.  Use the type variable instead.
        while (inferredTypeMirror.getKind() == TypeKind.WILDCARD) {
            inferredTypeMirror = ((WildcardType) inferredTypeMirror).getExtendsBound();
        }
    }
    if (inferredTypeMirror.getKind() != TypeKind.TYPEVAR) {
        ErrorReporter.errorAbort("Missing annos");
        return;
    }
    TypeVariable typeVar = (TypeVariable) inferredTypeMirror;
    AnnotatedTypeVariable typeVariableDecl = (AnnotatedTypeVariable) factory.getAnnotatedType(typeVar.asElement());
    AnnotationMirror upperBound = typeVariableDecl.getEffectiveAnnotationInHierarchy(top);
    if (omitSubtypingCheck || hierarchy.isSubtype(upperBound, previousAnnotation)) {
        annotatedTypeVariable.removeAnnotationInHierarchy(top);
        AnnotationMirror ub = typeVariableDecl.getUpperBound().getAnnotationInHierarchy(top);
        apply(annotatedTypeVariable.getUpperBound(), ub, typeVar.getUpperBound(), top);
        AnnotationMirror lb = typeVariableDecl.getLowerBound().getAnnotationInHierarchy(top);
        apply(annotatedTypeVariable.getLowerBound(), lb, typeVar.getLowerBound(), top);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 14 with AnnotatedTypeVariable

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

the class TypeFromTypeTreeVisitor method forTypeVariable.

private AnnotatedTypeMirror forTypeVariable(AnnotatedTypeMirror type, AnnotatedTypeFactory f) {
    if (type.getKind() != TypeKind.TYPEVAR) {
        ErrorReporter.errorAbort("TypeFromTree.forTypeVariable: should only be called on type variables");
        // dead code
        return null;
    }
    TypeVariable typeVar = (TypeVariable) type.getUnderlyingType();
    TypeParameterElement tpe = (TypeParameterElement) typeVar.asElement();
    Element elt = tpe.getGenericElement();
    if (elt instanceof TypeElement) {
        TypeElement typeElt = (TypeElement) elt;
        int idx = typeElt.getTypeParameters().indexOf(tpe);
        ClassTree cls = (ClassTree) f.declarationFromElement(typeElt);
        if (cls != null) {
            // `forTypeVariable` is called for Identifier, MemberSelect and UnionType trees,
            // none of which are declarations.  But `cls.getTypeParameters()` returns a list
            // of type parameter declarations (`TypeParameterTree`), so this recursive call
            // to `visit` will return a declaration ATV.  So we must copy the result and set
            // its `isDeclaration` field to `false`.
            AnnotatedTypeMirror result = visit(cls.getTypeParameters().get(idx), f).shallowCopy();
            ((AnnotatedTypeVariable) result).setDeclaration(false);
            return result;
        } else {
            // We already have all info from the element -> nothing to do.
            return type;
        }
    } else if (elt instanceof ExecutableElement) {
        ExecutableElement exElt = (ExecutableElement) elt;
        int idx = exElt.getTypeParameters().indexOf(tpe);
        MethodTree meth = (MethodTree) f.declarationFromElement(exElt);
        if (meth != null) {
            // This works the same as the case above.  Even though `meth` itself is not a
            // type declaration tree, the elements of `meth.getTypeParameters()` still are.
            AnnotatedTypeMirror result = visit(meth.getTypeParameters().get(idx), f).shallowCopy();
            ((AnnotatedTypeVariable) result).setDeclaration(false);
            return result;
        } else {
            // " + elt);
            return type;
        }
    } else {
        // not an element at all, namely Symtab.noSymbol.
        if (TypesUtils.isCaptured(typeVar)) {
            return type;
        } else {
            ErrorReporter.errorAbort("TypeFromTree.forTypeVariable: not a supported element: " + elt);
            // dead code
            return null;
        }
    }
}
Also used : AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) MethodTree(com.sun.source.tree.MethodTree) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeParameterElement(javax.lang.model.element.TypeParameterElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassTree(com.sun.source.tree.ClassTree) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 15 with AnnotatedTypeVariable

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

the class TypesIntoElements method storeTypeParameters.

private static void storeTypeParameters(ProcessingEnvironment processingEnv, Types types, AnnotatedTypeFactory atypeFactory, java.util.List<? extends TypeParameterTree> tps, Symbol sym) {
    boolean isClassOrInterface = sym.getKind().isClass() || sym.getKind().isInterface();
    List<Attribute.TypeCompound> tcs = List.nil();
    int tpidx = 0;
    for (TypeParameterTree tp : tps) {
        AnnotatedTypeVariable typeVar = (AnnotatedTypeVariable) atypeFactory.getAnnotatedTypeFromTypeTree(tp);
        // System.out.println("The Type for type parameter " + tp + " is " + type);
        TypeAnnotationPosition tapos;
        // the bounds may not be explicit and we couldn't look up separate pos.
        if (isClassOrInterface) {
            tapos = TypeAnnotationUtils.typeParameterTAPosition(tpidx, ((JCTree) tp).pos);
        } else {
            tapos = TypeAnnotationUtils.methodTypeParameterTAPosition(tpidx, ((JCTree) tp).pos);
        }
        {
            // This block is essentially direct annotations, perhaps we should refactor that
            // method out
            List<Attribute.TypeCompound> res = List.nil();
            for (AnnotationMirror am : typeVar.getLowerBound().getAnnotations()) {
                Attribute.TypeCompound tc = TypeAnnotationUtils.createTypeCompoundFromAnnotationMirror(am, tapos, processingEnv);
                res = res.prepend(tc);
            }
            tcs = tcs.appendList(res);
        }
        AnnotatedTypeMirror tpbound = typeVar.getUpperBound();
        java.util.List<? extends AnnotatedTypeMirror> bounds;
        if (tpbound.getKind() == TypeKind.INTERSECTION) {
            bounds = ((AnnotatedTypeMirror.AnnotatedIntersectionType) tpbound).directSuperTypes();
        } else {
            bounds = List.of(tpbound);
        }
        int bndidx = 0;
        for (AnnotatedTypeMirror bound : bounds) {
            if (bndidx == 0 && ((Type) bound.getUnderlyingType()).isInterface()) {
                // If the first bound is an interface, there is an implicit java.lang.Object
                ++bndidx;
            }
            if (isClassOrInterface) {
                tapos = TypeAnnotationUtils.typeParameterBoundTAPosition(tpidx, bndidx, ((JCTree) tp).pos);
            } else {
                tapos = TypeAnnotationUtils.methodTypeParameterBoundTAPosition(tpidx, bndidx, ((JCTree) tp).pos);
            }
            tcs = tcs.appendList(generateTypeCompounds(processingEnv, bound, tapos));
            ++bndidx;
        }
        ++tpidx;
    }
    // System.out.println("Adding " + tcs + " to " + sym);
    addUniqueTypeCompounds(types, sym, tcs);
}
Also used : TypeCompound(com.sun.tools.javac.code.Attribute.TypeCompound) TypeParameterTree(com.sun.source.tree.TypeParameterTree) Attribute(com.sun.tools.javac.code.Attribute) JCTree(com.sun.tools.javac.tree.JCTree) AnnotationMirror(javax.lang.model.element.AnnotationMirror) List(com.sun.tools.javac.util.List) TypeAnnotationPosition(com.sun.tools.javac.code.TypeAnnotationPosition) 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