Search in sources :

Example 6 with AnnotatedDeclaredType

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

the class AnnotatedTypeFactory method getStringType.

/**
 * Returns AnnotatedDeclaredType with underlying type String and annotations copied from type.
 * Subclasses may change the annotations.
 *
 * @param type type to convert to String
 * @return AnnotatedTypeMirror that results from converting type to a String type
 */
// TODO: Test that this is called in all the correct locations
// See Issue #715
// https://github.com/typetools/checker-framework/issues/715
public AnnotatedDeclaredType getStringType(AnnotatedTypeMirror type) {
    TypeMirror stringTypeMirror = TypesUtils.typeFromClass(String.class, types, elements);
    AnnotatedDeclaredType stringATM = (AnnotatedDeclaredType) AnnotatedTypeMirror.createType(stringTypeMirror, this, type.isDeclaration());
    stringATM.addAnnotations(type.getEffectiveAnnotations());
    return stringATM;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)

Example 7 with AnnotatedDeclaredType

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType 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 8 with AnnotatedDeclaredType

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

the class AsSuperVisitor method ensurePrimaryIsCorrectForUnionsAndIntersections.

/**
 * The code in this class is assuming that the primary annotation of an {@link
 * AnnotatedIntersectionType} is the greatest lower bound of the annotations on its direct super
 * types and that the primary annotation of an {@link AnnotatedUnionType} is the least upper
 * bound of its alternatives. This method makes this assumption true.
 */
private void ensurePrimaryIsCorrectForUnionsAndIntersections(AnnotatedTypeMirror type) {
    if (type.getKind() == TypeKind.INTERSECTION) {
        AnnotatedIntersectionType intersectionType = (AnnotatedIntersectionType) type;
        Set<AnnotationMirror> glbs = null;
        for (AnnotatedDeclaredType directST : intersectionType.directSuperTypes()) {
            if (glbs == null) {
                glbs = directST.getAnnotations();
            } else {
                Set<AnnotationMirror> newGlbs = AnnotationUtils.createAnnotationSet();
                for (AnnotationMirror glb : glbs) {
                    AnnotationMirror anno = directST.getAnnotationInHierarchy(glb);
                    newGlbs.add(annotatedTypeFactory.getQualifierHierarchy().greatestLowerBound(anno, glb));
                }
                glbs = newGlbs;
            }
        }
        type.replaceAnnotations(glbs);
    } else if (type.getKind() == TypeKind.UNION) {
        AnnotatedUnionType annotatedUnionType = (AnnotatedUnionType) type;
        Set<AnnotationMirror> lubs = null;
        for (AnnotatedDeclaredType altern : annotatedUnionType.getAlternatives()) {
            if (lubs == null) {
                lubs = altern.getAnnotations();
            } else {
                Set<AnnotationMirror> newLubs = AnnotationUtils.createAnnotationSet();
                for (AnnotationMirror lub : lubs) {
                    AnnotationMirror anno = altern.getAnnotationInHierarchy(lub);
                    newLubs.add(annotatedTypeFactory.getQualifierHierarchy().leastUpperBound(anno, lub));
                }
                lubs = newLubs;
            }
        }
        type.replaceAnnotations(lubs);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) Set(java.util.Set) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) AnnotatedUnionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType)

Example 9 with AnnotatedDeclaredType

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType 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 10 with AnnotatedDeclaredType

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

the class BaseTypeVisitor method visitReturn.

/**
 * Checks that the type of the return expression is a subtype of the enclosing method required
 * return type. If not, it issues a "return.type.incompatible" error.
 */
@Override
public Void visitReturn(ReturnTree node, Void p) {
    // Don't try to check return expressions for void methods.
    if (node.getExpression() == null) {
        return super.visitReturn(node, p);
    }
    Pair<Tree, AnnotatedTypeMirror> preAssCtxt = visitorState.getAssignmentContext();
    try {
        Tree enclosing = TreeUtils.enclosingOfKind(getCurrentPath(), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
        AnnotatedTypeMirror ret = null;
        if (enclosing.getKind() == Tree.Kind.METHOD) {
            MethodTree enclosingMethod = TreeUtils.enclosingMethod(getCurrentPath());
            boolean valid = validateTypeOf(enclosing);
            if (valid) {
                ret = atypeFactory.getMethodReturnType(enclosingMethod, node);
            }
        } else {
            Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = atypeFactory.getFnInterfaceFromTree((LambdaExpressionTree) enclosing);
            ret = result.second.getReturnType();
        }
        if (ret != null) {
            visitorState.setAssignmentContext(Pair.of((Tree) node, ret));
            commonAssignmentCheck(ret, node.getExpression(), "return.type.incompatible");
        }
        return super.visitReturn(node, p);
    } finally {
        visitorState.setAssignmentContext(preAssCtxt);
    }
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) MethodTree(com.sun.source.tree.MethodTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ThrowTree(com.sun.source.tree.ThrowTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) JCTree(com.sun.tools.javac.tree.JCTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)72 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)26 ArrayList (java.util.ArrayList)19 ExpressionTree (com.sun.source.tree.ExpressionTree)18 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)18 MethodTree (com.sun.source.tree.MethodTree)17 Tree (com.sun.source.tree.Tree)16 ClassTree (com.sun.source.tree.ClassTree)14 VariableTree (com.sun.source.tree.VariableTree)14 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)13 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)12 NewClassTree (com.sun.source.tree.NewClassTree)12 ExecutableElement (javax.lang.model.element.ExecutableElement)11 IdentifierTree (com.sun.source.tree.IdentifierTree)10 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)10 NewArrayTree (com.sun.source.tree.NewArrayTree)9 ReturnTree (com.sun.source.tree.ReturnTree)9 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)9 AnnotatedWildcardType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)9 AssignmentTree (com.sun.source.tree.AssignmentTree)8