Search in sources :

Example 6 with AnnotatedExecutableType

use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType 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)

Example 7 with AnnotatedExecutableType

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

the class DefaultReflectionResolver method resolveMethodCall.

/**
 * Resolves a call to {@link Method#invoke(Object, Object...)}.
 *
 * @param factory the {@link AnnotatedTypeFactory} of the underlying type system
 * @param tree the method invocation tree that has to be resolved
 * @param origResult the original result from {@code factory.methodFromUse}.
 */
private Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolveMethodCall(AnnotatedTypeFactory factory, MethodInvocationTree tree, Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> origResult) {
    debugReflection("Try to resolve reflective method call: " + tree);
    List<MethodInvocationTree> possibleMethods = resolveReflectiveMethod(tree, factory);
    // Reflective method could not be resolved
    if (possibleMethods.size() == 0) {
        return origResult;
    }
    Set<? extends AnnotationMirror> returnLub = null;
    Set<? extends AnnotationMirror> receiverGlb = null;
    Set<? extends AnnotationMirror> paramsGlb = null;
    // and parameter types
    for (MethodInvocationTree resolvedTree : possibleMethods) {
        debugReflection("Resolved method invocation: " + resolvedTree);
        if (!checkMethodAgruments(resolvedTree)) {
            debugReflection("Spoofed tree's arguments did not match declaration" + resolvedTree.toString());
            // in QualifierPolymorphism.PolyCollector.visitArray(...)
            continue;
        }
        Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolvedResult = factory.methodFromUse(resolvedTree);
        // Lub return types
        returnLub = lub(returnLub, resolvedResult.first.getReturnType().getAnnotations(), factory);
        // Check for static methods whose receiver is null
        if (resolvedResult.first.getReceiverType() == null) {
            // If the method is static the first argument to Method.invoke isn't used,
            // so assume top.
            receiverGlb = glb(receiverGlb, factory.getQualifierHierarchy().getTopAnnotations(), factory);
        } else {
            receiverGlb = glb(receiverGlb, resolvedResult.first.getReceiverType().getAnnotations(), factory);
        }
        // the types of different formal parameters.
        for (AnnotatedTypeMirror mirror : resolvedResult.first.getParameterTypes()) {
            paramsGlb = glb(paramsGlb, mirror.getAnnotations(), factory);
        }
    }
    if (returnLub == null) {
        // None of the spoofed tree's arguments matched the declared method
        return origResult;
    }
    /*
         * Clear all original (return, receiver, parameter type) annotations and
         * set lub/glb annotations from resolved method(s)
         */
    // return value
    origResult.first.getReturnType().clearAnnotations();
    origResult.first.getReturnType().addAnnotations(returnLub);
    // receiver type
    origResult.first.getParameterTypes().get(0).clearAnnotations();
    origResult.first.getParameterTypes().get(0).addAnnotations(receiverGlb);
    // parameter types
    if (paramsGlb != null) {
        AnnotatedArrayType origArrayType = (AnnotatedArrayType) origResult.first.getParameterTypes().get(1);
        origArrayType.getComponentType().clearAnnotations();
        origArrayType.getComponentType().addAnnotations(paramsGlb);
    }
    debugReflection("Resolved annotations: " + origResult.first);
    return origResult;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) List(java.util.List) ArrayList(java.util.ArrayList) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 8 with AnnotatedExecutableType

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

the class SyntheticArrays method replaceReturnType.

/**
 * @param methodElem identifies a method that should have an AnnotatedArrayType as its return
 *     type
 * @param newReturnType identifies a type that should replace methodElem's return type
 * @return the annotated type of methodElem with its return type replaced by newReturnType
 */
public static AnnotatedExecutableType replaceReturnType(final Element methodElem, final AnnotatedArrayType newReturnType) {
    final AnnotatedExecutableType method = (AnnotatedExecutableType) newReturnType.atypeFactory.getAnnotatedType(methodElem);
    method.returnType = newReturnType;
    return method;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)

Example 9 with AnnotatedExecutableType

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

the class TypeFromExpressionVisitor method visitNewClass.

/**
 * Creates an AnnotatedDeclaredType for the NewClassTree and adds, for each hierarchy, one of:
 *
 * <ul>
 *   <li>an explicit annotation on the new class expression ({@code new @HERE MyClass()}), or
 *   <li>an explicit annotation on the declaration of the class ({@code @HERE class MyClass
 *       {}}), or
 *   <li>an explicit annotation on the declaration of the constructor ({@code @HERE public
 *       MyClass() {}}), or
 *   <li>no annotation for this hierarchy.
 * </ul>
 *
 * @param node NewClassTree
 * @param f the type factory
 * @return AnnotatedDeclaredType of {@code node}
 */
@Override
public AnnotatedTypeMirror visitNewClass(NewClassTree node, AnnotatedTypeFactory f) {
    // constructorFromUse return type has implicits
    // so use fromNewClass which does diamond inference and only
    // contains explicit annotations and those inherited from the class declaration
    AnnotatedDeclaredType type = f.fromNewClass(node);
    // TODO: is there more to check? Can one annotate them?
    if (isNewEnum(type)) {
        return type;
    }
    // Add annotations that are on the constructor declaration.
    // constructorFromUse gives us resolution of polymorphic qualifiers.
    // However, it also applies defaulting, so we might apply too many qualifiers.
    // Therefore, ensure to only add the qualifiers that are explicitly on
    // the constructor, but then take the possibly substituted qualifier.
    AnnotatedExecutableType ex = f.constructorFromUse(node).first;
    AnnotatedTypes.copyOnlyExplicitConstructorAnnotations(f, type, ex);
    return type;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)

Example 10 with AnnotatedExecutableType

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

the class AnnotatedTypeComparer method visitExecutable.

@Override
public final R visitExecutable(AnnotatedExecutableType type, AnnotatedTypeMirror p) {
    assert p instanceof AnnotatedExecutableType : p;
    AnnotatedExecutableType ex = (AnnotatedExecutableType) p;
    R r = scan(type.getReturnType(), ex.getReturnType());
    if (type.getReceiverType() != null) {
        r = scanAndReduce(type.getReceiverType(), ex.getReceiverType(), r);
    }
    r = scanAndReduce(type.getParameterTypes(), ex.getParameterTypes(), r);
    r = scanAndReduce(type.getThrownTypes(), ex.getThrownTypes(), r);
    r = scanAndReduce(type.getTypeVariables(), ex.getTypeVariables(), r);
    return r;
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)

Aggregations

AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)42 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)19 ExecutableElement (javax.lang.model.element.ExecutableElement)17 ArrayList (java.util.ArrayList)15 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)15 ExpressionTree (com.sun.source.tree.ExpressionTree)13 MethodTree (com.sun.source.tree.MethodTree)13 List (java.util.List)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)12 Tree (com.sun.source.tree.Tree)12 VariableTree (com.sun.source.tree.VariableTree)12 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)9 AssignmentTree (com.sun.source.tree.AssignmentTree)7 ClassTree (com.sun.source.tree.ClassTree)7 NewArrayTree (com.sun.source.tree.NewArrayTree)7 ReturnTree (com.sun.source.tree.ReturnTree)7 NewClassTree (com.sun.source.tree.NewClassTree)6 VariableElement (javax.lang.model.element.VariableElement)6 AnnotationTree (com.sun.source.tree.AnnotationTree)5