Search in sources :

Example 1 with AnnotatedIntersectionType

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

the class TypeVarUseApplier method extractAndApply.

/**
 * Applies the bound annotations from the declaration of the type parameter and then applies the
 * explicit annotations written on the type variable
 */
public void extractAndApply() {
    ElementAnnotationUtil.addAnnotationsFromElement(typeVariable, useElem.getAnnotationMirrors());
    // apply declaration annotations
    ElementAnnotationApplier.apply(typeVariable, declarationElem, typeFactory);
    final List<Attribute.TypeCompound> annotations = getAnnotations(useElem, declarationElem);
    final List<Attribute.TypeCompound> typeVarAnnotations;
    if (arrayType != null) {
        // if the outer-most type is an array type then we want to ensure the outer annotations
        // are not applied as the type variables primary annotation
        typeVarAnnotations = removeComponentAnnotations(arrayType, annotations);
        ElementAnnotationUtil.annotateViaTypeAnnoPosition(arrayType, annotations);
    } else {
        typeVarAnnotations = annotations;
    }
    for (final Attribute.TypeCompound annotation : typeVarAnnotations) {
        typeVariable.removeAnnotationInHierarchy(annotation);
        typeVariable.addAnnotation(annotation);
        final List<? extends AnnotatedTypeMirror> upperBounds;
        if (typeVariable.getUpperBound() instanceof AnnotatedIntersectionType) {
            upperBounds = typeVariable.getUpperBound().directSuperTypes();
        } else {
            upperBounds = Arrays.asList(typeVariable.getUpperBound());
        }
        // TODO: to all of them?  Que dealio?  What should we do?
        for (final AnnotatedTypeMirror bound : upperBounds) {
            bound.removeAnnotationInHierarchy(annotation);
            bound.addAnnotation(annotation);
        }
    }
}
Also used : AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) Attribute(com.sun.tools.javac.code.Attribute) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 2 with AnnotatedIntersectionType

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

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

the class AnnotatedTypeCopier method visitIntersection.

@Override
public AnnotatedTypeMirror visitIntersection(AnnotatedIntersectionType original, IdentityHashMap<AnnotatedTypeMirror, AnnotatedTypeMirror> originalToCopy) {
    if (originalToCopy.containsKey(original)) {
        return originalToCopy.get(original);
    }
    final AnnotatedIntersectionType copy = (AnnotatedIntersectionType) AnnotatedTypeMirror.createType(original.getUnderlyingType(), original.atypeFactory, original.isDeclaration());
    maybeCopyPrimaryAnnotations(original, copy);
    originalToCopy.put(original, copy);
    if (original.supertypes != null) {
        final List<AnnotatedDeclaredType> copySupertypes = new ArrayList<>();
        for (final AnnotatedDeclaredType supertype : original.supertypes) {
            copySupertypes.add((AnnotatedDeclaredType) visit(supertype, originalToCopy));
        }
        copy.supertypes = Collections.unmodifiableList(copySupertypes);
    }
    return copy;
}
Also used : AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList)

Example 4 with AnnotatedIntersectionType

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

the class AnnotatedTypeFactory method getFunctionalInterfaceType.

/**
 * Get the AnnotatedDeclaredType for the FunctionalInterface from assignment context of the
 * method reference or lambda expression which may be a variable assignment, a method call, or a
 * cast.
 *
 * <p>The assignment context is not always correct, so we must search up the AST. It will
 * recursively search for lambdas nested in lambdas.
 *
 * @param tree the tree of the lambda or method reference
 * @return the functional interface type
 */
private AnnotatedDeclaredType getFunctionalInterfaceType(Tree tree) {
    Tree parentTree = getPath(tree).getParentPath().getLeaf();
    switch(parentTree.getKind()) {
        case PARENTHESIZED:
            return getFunctionalInterfaceType(parentTree);
        case TYPE_CAST:
            TypeCastTree cast = (TypeCastTree) parentTree;
            assert isFunctionalInterface(trees.getTypeMirror(getPath(cast.getType())), parentTree, tree);
            AnnotatedTypeMirror castATM = getAnnotatedType(cast.getType());
            if (castATM.getKind() == TypeKind.INTERSECTION) {
                AnnotatedIntersectionType itype = (AnnotatedIntersectionType) castATM;
                for (AnnotatedTypeMirror t : itype.directSuperTypes()) {
                    if (TypesUtils.isFunctionalInterface(t.getUnderlyingType(), getProcessingEnv())) {
                        return (AnnotatedDeclaredType) t;
                    }
                }
                // We should never reach here: isFunctionalInterface performs the same check
                // and would have raised an error already.
                ErrorReporter.errorAbort(String.format("Expected the type of a cast tree in an assignment context to contain a functional interface bound. " + "Found type: %s for tree: %s in lambda tree: %s", castATM, cast, tree));
            }
            return (AnnotatedDeclaredType) castATM;
        case NEW_CLASS:
            NewClassTree newClass = (NewClassTree) parentTree;
            int indexOfLambda = newClass.getArguments().indexOf(tree);
            Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> con = this.constructorFromUse(newClass);
            AnnotatedTypeMirror constructorParam = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(con.first, indexOfLambda);
            assert isFunctionalInterface(constructorParam.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) constructorParam;
        case NEW_ARRAY:
            NewArrayTree newArray = (NewArrayTree) parentTree;
            AnnotatedArrayType newArrayATM = getAnnotatedType(newArray);
            AnnotatedTypeMirror elementATM = newArrayATM.getComponentType();
            assert isFunctionalInterface(elementATM.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) elementATM;
        case METHOD_INVOCATION:
            MethodInvocationTree method = (MethodInvocationTree) parentTree;
            int index = method.getArguments().indexOf(tree);
            Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> exe = this.methodFromUse(method);
            AnnotatedTypeMirror param = AnnotatedTypes.getAnnotatedTypeMirrorOfParameter(exe.first, index);
            if (param.getKind() == TypeKind.WILDCARD) {
                // param is an uninferred wildcard.
                TypeMirror typeMirror = TreeUtils.typeOf(tree);
                param = AnnotatedTypeMirror.createType(typeMirror, this, false);
                addDefaultAnnotations(param);
            }
            assert isFunctionalInterface(param.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) param;
        case VARIABLE:
            VariableTree varTree = (VariableTree) parentTree;
            assert isFunctionalInterface(TreeUtils.typeOf(varTree), parentTree, tree);
            return (AnnotatedDeclaredType) getAnnotatedType(varTree.getType());
        case ASSIGNMENT:
            AssignmentTree assignmentTree = (AssignmentTree) parentTree;
            assert isFunctionalInterface(TreeUtils.typeOf(assignmentTree), parentTree, tree);
            return (AnnotatedDeclaredType) getAnnotatedType(assignmentTree.getVariable());
        case RETURN:
            Tree enclosing = TreeUtils.enclosingOfKind(getPath(parentTree), new HashSet<>(Arrays.asList(Tree.Kind.METHOD, Tree.Kind.LAMBDA_EXPRESSION)));
            if (enclosing.getKind() == Tree.Kind.METHOD) {
                MethodTree enclosingMethod = (MethodTree) enclosing;
                return (AnnotatedDeclaredType) getAnnotatedType(enclosingMethod.getReturnType());
            } else {
                LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) enclosing;
                Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
                AnnotatedExecutableType methodExe = result.second;
                return (AnnotatedDeclaredType) methodExe.getReturnType();
            }
        case LAMBDA_EXPRESSION:
            LambdaExpressionTree enclosingLambda = (LambdaExpressionTree) parentTree;
            Pair<AnnotatedDeclaredType, AnnotatedExecutableType> result = getFnInterfaceFromTree(enclosingLambda);
            AnnotatedExecutableType methodExe = result.second;
            return (AnnotatedDeclaredType) methodExe.getReturnType();
        case CONDITIONAL_EXPRESSION:
            ConditionalExpressionTree conditionalExpressionTree = (ConditionalExpressionTree) parentTree;
            final AnnotatedTypeMirror falseType = getAnnotatedType(conditionalExpressionTree.getFalseExpression());
            final AnnotatedTypeMirror trueType = getAnnotatedType(conditionalExpressionTree.getTrueExpression());
            // Known cases where we must use LUB because falseType/trueType will not be equal:
            // a) when one of the types is a type variable that extends a functional interface
            // or extends a type variable that extends a functional interface
            // b) When one of the two sides of the expression is a reference to a sub-interface.
            // e.g.   interface ConsumeStr {
            // public void consume(String s)
            // }
            // interface SubConsumer extends ConsumeStr {
            // default void someOtherMethod() { ... }
            // }
            // SubConsumer s = ...;
            // ConsumeStr stringConsumer = (someCondition) ? s : System.out::println;
            AnnotatedTypeMirror conditionalType = AnnotatedTypes.leastUpperBound(this, trueType, falseType);
            assert isFunctionalInterface(conditionalType.getUnderlyingType(), parentTree, tree);
            return (AnnotatedDeclaredType) conditionalType;
        default:
            ErrorReporter.errorAbort("Could not find functional interface from assignment context. " + "Unexpected tree type: " + parentTree.getKind() + " For lambda tree: " + tree);
            return null;
    }
}
Also used : TypeCastTree(com.sun.source.tree.TypeCastTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) NewClassTree(com.sun.source.tree.NewClassTree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) NewArrayTree(com.sun.source.tree.NewArrayTree) TypeMirror(javax.lang.model.type.TypeMirror) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ReturnTree(com.sun.source.tree.ReturnTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) 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) ArrayList(java.util.ArrayList) List(java.util.List) AssignmentTree(com.sun.source.tree.AssignmentTree)

Example 5 with AnnotatedIntersectionType

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

the class TypeFromTypeTreeVisitor method visitTypeParameter.

@Override
public AnnotatedTypeMirror visitTypeParameter(TypeParameterTree node, AnnotatedTypeFactory f) {
    List<AnnotatedTypeMirror> bounds = new ArrayList<>(node.getBounds().size());
    for (Tree t : node.getBounds()) {
        AnnotatedTypeMirror bound;
        if (visitedBounds.containsKey(t) && f == visitedBounds.get(t).atypeFactory) {
            bound = visitedBounds.get(t);
        } else {
            visitedBounds.put(t, f.type(t));
            bound = visit(t, f);
            visitedBounds.remove(t);
        }
        bounds.add(bound);
    }
    AnnotatedTypeVariable result = (AnnotatedTypeVariable) f.type(node);
    List<? extends AnnotationMirror> annotations = TreeUtils.annotationsFromTree(node);
    result.getLowerBound().addAnnotations(annotations);
    switch(bounds.size()) {
        case 0:
            break;
        case 1:
            result.setUpperBound(bounds.get(0));
            break;
        default:
            AnnotatedIntersectionType upperBound = (AnnotatedIntersectionType) result.getUpperBound();
            List<AnnotatedDeclaredType> superBounds = new ArrayList<>(bounds.size());
            for (AnnotatedTypeMirror b : bounds) {
                superBounds.add((AnnotatedDeclaredType) b);
            }
            upperBound.setDirectSuperTypes(superBounds);
    }
    return result;
}
Also used : AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) MethodTree(com.sun.source.tree.MethodTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) WildcardTree(com.sun.source.tree.WildcardTree) UnionTypeTree(com.sun.source.tree.UnionTypeTree) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Aggregations

AnnotatedIntersectionType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType)6 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)5 ArrayList (java.util.ArrayList)3 ClassTree (com.sun.source.tree.ClassTree)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 IdentifierTree (com.sun.source.tree.IdentifierTree)2 MethodTree (com.sun.source.tree.MethodTree)2 Tree (com.sun.source.tree.Tree)2 AnnotatedTypeTree (com.sun.source.tree.AnnotatedTypeTree)1 AnnotationTree (com.sun.source.tree.AnnotationTree)1 ArrayTypeTree (com.sun.source.tree.ArrayTypeTree)1 AssignmentTree (com.sun.source.tree.AssignmentTree)1 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)1 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)1 IntersectionTypeTree (com.sun.source.tree.IntersectionTypeTree)1 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)1 MemberReferenceTree (com.sun.source.tree.MemberReferenceTree)1 MemberSelectTree (com.sun.source.tree.MemberSelectTree)1 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)1 NewArrayTree (com.sun.source.tree.NewArrayTree)1