Search in sources :

Example 1 with AnnotatedTypeMirror

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

the class WholeProgramInferenceScenes method updateInferredMethodReceiverType.

/**
 * Updates the receiver type of the method {@code methodElt} in the Scene of the method's
 * enclosing class based on the overridden method {@code overriddenMethod} receiver type.
 *
 * <p>For the receiver in methodElt:
 *
 * <ul>
 *   <li>If the Scene does not contain an annotated type for the receiver, then the type of the
 *       receiver on the overridden method will be added to the receiver in the Scene.
 *   <li>If the Scene previously contained an annotated type for the receiver, then its new type
 *       will be the LUB between the previous type and the type of the receiver on the
 *       overridden method.
 * </ul>
 *
 * <p>
 *
 * @param methodTree the tree of the method that contains the receiver
 * @param methodElt the element of the method
 * @param overriddenMethod the overridden method
 * @param atf the annotated type factory of a given type system, whose type hierarchy will be
 *     used to update the receiver type
 */
@Override
public void updateInferredMethodReceiverType(MethodTree methodTree, ExecutableElement methodElt, AnnotatedExecutableType overriddenMethod, AnnotatedTypeFactory atf) {
    ClassSymbol classSymbol = getEnclosingClassSymbol(methodTree);
    String className = classSymbol.flatname.toString();
    String jaifPath = helper.getJaifPath(className);
    AClass clazz = helper.getAClass(className, jaifPath);
    String methodName = JVMNames.getJVMMethodName(methodElt);
    AMethod method = clazz.methods.vivify(methodName);
    AnnotatedDeclaredType argADT = overriddenMethod.getReceiverType();
    if (argADT != null) {
        AnnotatedTypeMirror paramATM = atf.getAnnotatedType(methodTree).getReceiverType();
        if (paramATM != null) {
            AField receiver = method.receiver;
            helper.updateAnnotationSetInScene(receiver.type, atf, jaifPath, argADT, paramATM, TypeUseLocation.RECEIVER);
        }
    }
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) AClass(scenelib.annotations.el.AClass) AMethod(scenelib.annotations.el.AMethod) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AField(scenelib.annotations.el.AField)

Example 2 with AnnotatedTypeMirror

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

the class WholeProgramInferenceScenes method updateInferredExecutableParameterTypes.

/**
 * Helper method for updating parameter types based on calls to a method or constructor.
 */
private void updateInferredExecutableParameterTypes(ExecutableElement methodElt, AnnotatedTypeFactory atf, String jaifPath, AMethod method, List<Node> arguments) {
    for (int i = 0; i < arguments.size(); i++) {
        VariableElement ve = methodElt.getParameters().get(i);
        AnnotatedTypeMirror paramATM = atf.getAnnotatedType(ve);
        Node arg = arguments.get(i);
        Tree treeNode = arg.getTree();
        if (treeNode == null) {
            // https://github.com/typetools/checker-framework/issues/682
            continue;
        }
        AnnotatedTypeMirror argATM = atf.getAnnotatedType(treeNode);
        AField param = method.parameters.vivify(i);
        helper.updateAnnotationSetInScene(param.type, atf, jaifPath, argATM, paramATM, TypeUseLocation.PARAMETER);
    }
}
Also used : FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) ImplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ImplicitThisLiteralNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) Node(org.checkerframework.dataflow.cfg.node.Node) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) VariableElement(javax.lang.model.element.VariableElement) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AField(scenelib.annotations.el.AField)

Example 3 with AnnotatedTypeMirror

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

the class WholeProgramInferenceScenes method updateInferredParameterType.

/**
 * Updates the parameter type represented by lhs of the method methodTree in the Scene of the
 * receiverTree's enclosing class based on assignments to the parameter inside the method body.
 *
 * <ul>
 *   <li>If the Scene does not contain an annotated type for that parameter, then the type of
 *       the respective value passed as argument in the method call methodInvNode will be added
 *       to the parameter in the Scene.
 *   <li>If the Scene previously contained an annotated type for that parameter, then its new
 *       type will be the LUB between the previous type and the type of the respective value
 *       passed as argument in the method call.
 * </ul>
 *
 * <p>
 *
 * @param lhs the node representing the parameter
 * @param rhs the node being assigned to the parameter
 * @param classTree the tree of the class that contains the parameter
 * @param methodTree the tree of the method that contains the parameter
 * @param atf the annotated type factory of a given type system, whose type hierarchy will be
 *     used to update the parameter type
 */
@Override
public void updateInferredParameterType(LocalVariableNode lhs, Node rhs, ClassTree classTree, MethodTree methodTree, AnnotatedTypeFactory atf) {
    ClassSymbol classSymbol = getEnclosingClassSymbol(classTree, lhs);
    // https://github.com/typetools/checker-framework/issues/682
    if (classSymbol == null)
        return;
    String className = classSymbol.flatname.toString();
    String jaifPath = helper.getJaifPath(className);
    AClass clazz = helper.getAClass(className, jaifPath);
    String methodName = JVMNames.getJVMMethodName(methodTree);
    AMethod method = clazz.methods.vivify(methodName);
    List<? extends VariableTree> params = methodTree.getParameters();
    // Look-up parameter by name:
    for (int i = 0; i < params.size(); i++) {
        VariableTree vt = params.get(i);
        if (vt.getName().contentEquals(lhs.getName())) {
            Tree treeNode = rhs.getTree();
            if (treeNode == null) {
                // https://github.com/typetools/checker-framework/issues/682
                continue;
            }
            AnnotatedTypeMirror paramATM = atf.getAnnotatedType(vt);
            AnnotatedTypeMirror argATM = atf.getAnnotatedType(treeNode);
            AField param = method.parameters.vivify(i);
            helper.updateAnnotationSetInScene(param.type, atf, jaifPath, argATM, paramATM, TypeUseLocation.PARAMETER);
            break;
        }
    }
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) VariableTree(com.sun.source.tree.VariableTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) AClass(scenelib.annotations.el.AClass) AMethod(scenelib.annotations.el.AMethod) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AField(scenelib.annotations.el.AField)

Example 4 with AnnotatedTypeMirror

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

the class WholeProgramInferenceScenes method updateInferredMethodReturnType.

/**
 * Updates the return type of the method methodTree in the Scene of the class with symbol
 * classSymbol.
 *
 * <p>If the Scene does not contain an annotated return type for the method methodTree, then the
 * type of the value passed to the return expression will be added to the return type of that
 * method in the Scene. If the Scene previously contained an annotated return type for the
 * method methodTree, its new type will be the LUB between the previous type and the type of the
 * value passed to the return expression.
 *
 * <p>
 *
 * @param retNode the node that contains the expression returned
 * @param classSymbol the symbol of the class that contains the method
 * @param methodTree the tree of the method whose return type may be updated
 * @param atf the annotated type factory of a given type system, whose type hierarchy will be
 *     used to update the method's return type
 */
@Override
public void updateInferredMethodReturnType(ReturnNode retNode, ClassSymbol classSymbol, MethodTree methodTree, AnnotatedTypeFactory atf) {
    // TODO: Handle anonymous classes.
    if (classSymbol == null)
        return;
    String className = classSymbol.flatname.toString();
    String jaifPath = helper.getJaifPath(className);
    AClass clazz = helper.getAClass(className, jaifPath);
    AMethod method = clazz.methods.vivify(JVMNames.getJVMMethodName(methodTree));
    // Method return type
    AnnotatedTypeMirror lhsATM = atf.getAnnotatedType(methodTree).getReturnType();
    // Type of the expression returned
    AnnotatedTypeMirror rhsATM = atf.getAnnotatedType(retNode.getTree().getExpression());
    helper.updateAnnotationSetInScene(method.returnType, atf, jaifPath, rhsATM, lhsATM, TypeUseLocation.RETURN);
}
Also used : AClass(scenelib.annotations.el.AClass) AMethod(scenelib.annotations.el.AMethod) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 5 with AnnotatedTypeMirror

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

the class WholeProgramInferenceScenesHelper method shouldIgnore.

/**
 * Returns true if {@code am} should not be inserted in source code, for example {@link
 * org.checkerframework.common.value.qual.BottomVal}. This happens when {@code am} cannot be
 * inserted in source code or is the default for the location passed as argument.
 *
 * <p>Invisible qualifiers, which are annotations that contain the {@link
 * org.checkerframework.framework.qual.InvisibleQualifier} meta-annotation, also return true.
 *
 * <p>TODO: Merge functionality somewhere else with {@link
 * org.checkerframework.framework.type.GenericAnnotatedTypeFactory#createQualifierDefaults}.
 * Look into the createQualifierDefaults method before changing anything here. See Issue 683
 * https://github.com/typetools/checker-framework/issues/683
 */
private boolean shouldIgnore(AnnotationMirror am, TypeUseLocation location, AnnotatedTypeFactory atf, AnnotatedTypeMirror atm) {
    Element elt = am.getAnnotationType().asElement();
    // Checks if am is an implementation detail (a type qualifier used
    // internally by the type system and not meant to be seen by the user.)
    Target target = elt.getAnnotation(Target.class);
    if (target != null && target.value().length == 0)
        return true;
    if (elt.getAnnotation(InvisibleQualifier.class) != null)
        return true;
    // Checks if am is default
    if (elt.getAnnotation(DefaultQualifierInHierarchy.class) != null) {
        return true;
    }
    DefaultQualifier defaultQual = elt.getAnnotation(DefaultQualifier.class);
    if (defaultQual != null) {
        for (TypeUseLocation loc : defaultQual.locations()) {
            if (loc == TypeUseLocation.ALL || loc == location) {
                return true;
            }
        }
    }
    DefaultFor defaultQualForLocation = elt.getAnnotation(DefaultFor.class);
    if (defaultQualForLocation != null) {
        for (TypeUseLocation loc : defaultQualForLocation.value()) {
            if (loc == TypeUseLocation.ALL || loc == location) {
                return true;
            }
        }
    }
    // Checks if am is an implicit annotation.
    // This case checks if it is meta-annotated with @ImplicitFor.
    // TODO: Handle cases of implicit annotations added via an
    // org.checkerframework.framework.type.treeannotator.ImplicitsTreeAnnotator.
    ImplicitFor implicitFor = elt.getAnnotation(ImplicitFor.class);
    if (implicitFor != null) {
        org.checkerframework.framework.qual.TypeKind[] types = implicitFor.types();
        TypeKind atmKind = atm.getUnderlyingType().getKind();
        if (hasMatchingTypeKind(atmKind, types)) {
            return true;
        }
        try {
            Class<?>[] names = implicitFor.typeNames();
            for (Class<?> c : names) {
                TypeMirror underlyingtype = atm.getUnderlyingType();
                while (underlyingtype instanceof javax.lang.model.type.ArrayType) {
                    underlyingtype = ((javax.lang.model.type.ArrayType) underlyingtype).getComponentType();
                }
                if (c.getCanonicalName().equals(atm.getUnderlyingType().toString())) {
                    return true;
                }
            }
        } catch (MirroredTypesException e) {
        }
    }
    return false;
}
Also used : MirroredTypesException(javax.lang.model.type.MirroredTypesException) ImplicitFor(org.checkerframework.framework.qual.ImplicitFor) ATypeElement(scenelib.annotations.el.ATypeElement) Element(javax.lang.model.element.Element) TypeKind(javax.lang.model.type.TypeKind) InvisibleQualifier(org.checkerframework.framework.qual.InvisibleQualifier) DefaultFor(org.checkerframework.framework.qual.DefaultFor) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) TypeUseLocation(org.checkerframework.framework.qual.TypeUseLocation) Target(java.lang.annotation.Target) DefaultQualifierInHierarchy(org.checkerframework.framework.qual.DefaultQualifierInHierarchy) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) AClass(scenelib.annotations.el.AClass) DefaultQualifier(org.checkerframework.framework.qual.DefaultQualifier)

Aggregations

AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)299 AnnotationMirror (javax.lang.model.element.AnnotationMirror)84 ExpressionTree (com.sun.source.tree.ExpressionTree)53 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)44 ExecutableElement (javax.lang.model.element.ExecutableElement)41 Tree (com.sun.source.tree.Tree)40 TypeMirror (javax.lang.model.type.TypeMirror)38 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)38 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)38 MethodTree (com.sun.source.tree.MethodTree)34 ArrayList (java.util.ArrayList)34 BugInCF (org.checkerframework.javacutil.BugInCF)32 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)30 TypeElement (javax.lang.model.element.TypeElement)29 VariableElement (javax.lang.model.element.VariableElement)29 VariableTree (com.sun.source.tree.VariableTree)28 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)27 AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)26 ClassTree (com.sun.source.tree.ClassTree)25 Map (java.util.Map)24