Search in sources :

Example 36 with AnnotatedDeclaredType

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

the class AnnotatedTypeFactory method getBoxedType.

/**
 * Returns the annotated boxed type of the given primitive type. The returned type would only
 * have the annotations on the given type.
 *
 * <p>Subclasses may override this method safely to override this behavior.
 *
 * @param type the primitive type
 * @return the boxed declared type of the passed primitive type
 */
public AnnotatedDeclaredType getBoxedType(AnnotatedPrimitiveType type) {
    TypeElement typeElt = types.boxedClass(type.getUnderlyingType());
    AnnotatedDeclaredType dt = fromElement(typeElt);
    dt.addAnnotations(type.getAnnotations());
    return dt;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)

Example 37 with AnnotatedDeclaredType

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

the class AnnotatedTypeFactory method fromNewClass.

/**
 * Creates an AnnotatedDeclaredType for a NewClassTree. Adds explicit annotations and
 * annotations inherited from class declarations {@link
 * #annotateInheritedFromClass(AnnotatedTypeMirror)}.
 *
 * <p>If the NewClassTree has type arguments, then any explicit (or inherited from class)
 * annotations on those type arguments are included. If the NewClassTree has a diamond operator,
 * then the annotations on the type arguments are inferred using the assignment context.
 *
 * <p>(Subclass beside {@link GenericAnnotatedTypeFactory} should not override this method.)
 *
 * @param newClassTree NewClassTree
 * @return AnnotatedDeclaredType
 */
public AnnotatedDeclaredType fromNewClass(NewClassTree newClassTree) {
    if (TreeUtils.isDiamondTree(newClassTree)) {
        AnnotatedDeclaredType type = (AnnotatedDeclaredType) toAnnotatedType(TreeUtils.typeOf(newClassTree), false);
        if (((com.sun.tools.javac.code.Type) type.actualType).tsym.getTypeParameters().nonEmpty()) {
            Pair<Tree, AnnotatedTypeMirror> ctx = this.visitorState.getAssignmentContext();
            if (ctx != null) {
                AnnotatedTypeMirror ctxtype = ctx.second;
                fromNewClassContextHelper(type, ctxtype);
            }
        }
        return type;
    } else if (newClassTree.getClassBody() != null) {
        AnnotatedDeclaredType type = (AnnotatedDeclaredType) toAnnotatedType(TreeUtils.typeOf(newClassTree), false);
        // If newClassTree creates an anonymous class, then annotations in this location:
        // new @HERE Class() {}
        // are on not on the identifier newClassTree, but rather on the modifier newClassTree.
        List<? extends AnnotationTree> annos = newClassTree.getClassBody().getModifiers().getAnnotations();
        type.addAnnotations(TreeUtils.annotationsFromTypeAnnotationTrees(annos));
        return type;
    } else {
        // new @HERE Class()
        return (AnnotatedDeclaredType) fromTypeTree(newClassTree.getIdentifier());
    }
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) IntersectionType(javax.lang.model.type.IntersectionType) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType) DeclaredType(javax.lang.model.type.DeclaredType) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) AnnotatedNullType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedNullType) WildcardType(javax.lang.model.type.WildcardType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) Type(com.sun.tools.javac.code.Type) ElementType(java.lang.annotation.ElementType) PrimitiveType(javax.lang.model.type.PrimitiveType) 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) AnnotationTree(com.sun.source.tree.AnnotationTree)

Example 38 with AnnotatedDeclaredType

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

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

the class AnnotatedTypeFactory method getImplicitReceiverType.

// **********************************************************************
// Utilities method for getting specific types from trees or elements
// **********************************************************************
/**
 * Return the implicit receiver type of an expression tree.
 *
 * <p>The result is null for expressions that don't have a receiver, e.g. for a local variable
 * or method parameter access.
 *
 * @param tree the expression that might have an implicit receiver
 * @return the type of the receiver
 */
/*
     * TODO: receiver annotations on outer this.
     * TODO: Better document the difference between getImplicitReceiverType and getSelfType?
     * TODO: this method assumes that the tree is within the current
     * Compilation Unit. This assumption fails in testcase Bug109_A/B, where
     * a chain of dependencies leads into a different compilation unit.
     * I didn't find a way how to handle this better and conservatively
     * return null. See TODO comment below.
     *
     */
protected AnnotatedDeclaredType getImplicitReceiverType(ExpressionTree tree) {
    assert (tree.getKind() == Tree.Kind.IDENTIFIER || tree.getKind() == Tree.Kind.MEMBER_SELECT || tree.getKind() == Tree.Kind.METHOD_INVOCATION || tree.getKind() == Tree.Kind.NEW_CLASS) : "Unexpected tree kind: " + tree.getKind();
    Element element = TreeUtils.elementFromTree(tree);
    assert element != null : "Unexpected null element for tree: " + tree;
    // Return null if the element kind has no receiver.
    if (!ElementUtils.hasReceiver(element)) {
        return null;
    }
    ExpressionTree receiver = TreeUtils.getReceiverTree(tree);
    if (receiver == null) {
        if (isMostEnclosingThisDeref(tree)) {
            // TODO: is this fixed?
            return getSelfType(tree);
        } else {
            TreePath path = getPath(tree);
            if (path == null) {
                // This only arises in the Nullness Checker when substituting rawness.
                return null;
            }
            TypeElement typeElt = ElementUtils.enclosingClass(element);
            if (typeElt == null) {
                ErrorReporter.errorAbort("AnnotatedTypeFactory.getImplicitReceiver: enclosingClass()==null for element: " + element);
            }
            // TODO: method receiver annotations on outer this
            return getEnclosingType(typeElt, tree);
        }
    }
    Element rcvelem = TreeUtils.elementFromTree(receiver);
    assert rcvelem != null : "Unexpected null element for receiver: " + receiver;
    if (!ElementUtils.hasReceiver(rcvelem)) {
        return null;
    }
    if (receiver.getKind() == Tree.Kind.IDENTIFIER && ((IdentifierTree) receiver).getName().contentEquals("this")) {
        // TODO: also "super"?
        return this.getSelfType(tree);
    }
    TypeElement typeElt = ElementUtils.enclosingClass(rcvelem);
    if (typeElt == null) {
        ErrorReporter.errorAbort("AnnotatedTypeFactory.getImplicitReceiver: enclosingClass()==null for element: " + rcvelem);
    }
    AnnotatedDeclaredType type = getAnnotatedType(typeElt);
    // TODO: go through _all_ enclosing methods to see whether any of them has a
    // receiver annotation of the correct type.
    // TODO: Can we reuse getSelfType for outer this accesses?
    AnnotatedDeclaredType methodReceiver = getCurrentMethodReceiver(tree);
    if (shouldTakeFromReceiver(methodReceiver)) {
        // TODO: this only takes the main annotations.
        // What about other annotations (annotations on the type argument, outer types, ...)
        type.clearAnnotations();
        type.addAnnotations(methodReceiver.getAnnotations());
    }
    return type;
}
Also used : TreePath(com.sun.source.util.TreePath) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeParameterElement(javax.lang.model.element.TypeParameterElement) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree)

Example 40 with AnnotatedDeclaredType

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

the class AsSuperVisitor method visitDeclared_Intersection.

@Override
public AnnotatedTypeMirror visitDeclared_Intersection(AnnotatedDeclaredType type, AnnotatedIntersectionType superType, Void p) {
    List<AnnotatedDeclaredType> newDirectSupertypes = new ArrayList<>();
    // in the intersection.
    for (AnnotatedDeclaredType superDirect : superType.directSuperTypes()) {
        AnnotatedDeclaredType found = (AnnotatedDeclaredType) visit(type, superDirect, p);
        newDirectSupertypes.add(found);
    }
    // The ATM for each type in an intersection is stored in the direct super types field.
    superType.setDirectSuperTypes(newDirectSupertypes);
    return copyPrimaryAnnos(type, superType);
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList)

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