Search in sources :

Example 81 with ClassTree

use of com.sun.source.tree.ClassTree in project checker-framework by typetools.

the class QualifierDefaults method nearestEnclosingExceptLocal.

/**
 * Determines the nearest enclosing element for a tree by climbing the tree toward the root and
 * obtaining the element for the first declaration (variable, method, or class) that encloses the
 * tree. Initializers of local variables are handled in a special way: within an initializer we
 * look for the DefaultQualifier(s) annotation and keep track of the previously visited tree.
 * TODO: explain the behavior better.
 *
 * @param tree the tree
 * @return the nearest enclosing element for a tree
 */
private Element nearestEnclosingExceptLocal(Tree tree) {
    TreePath path = atypeFactory.getPath(tree);
    if (path == null) {
        Element element = atypeFactory.getEnclosingElementForArtificialTree(tree);
        if (element != null) {
            return element;
        } else {
            return TreeUtils.elementFromTree(tree);
        }
    }
    Tree prev = null;
    for (Tree t : path) {
        switch(TreeUtils.getKindRecordAsClass(t)) {
            case ANNOTATED_TYPE:
            case ANNOTATION:
                // If the tree is in an annotation, then there is no relevant scope.
                return null;
            case VARIABLE:
                VariableTree vtree = (VariableTree) t;
                ExpressionTree vtreeInit = vtree.getInitializer();
                // check cached value
                @SuppressWarnings("interning:not.interned") boolean sameAsPrev = (vtreeInit != null && prev == vtreeInit);
                if (sameAsPrev) {
                    Element elt = TreeUtils.elementFromDeclaration((VariableTree) t);
                    AnnotationMirror d = atypeFactory.getDeclAnnotation(elt, DefaultQualifier.class);
                    AnnotationMirror ds = atypeFactory.getDeclAnnotation(elt, DefaultQualifier.List.class);
                    if (d == null && ds == null) {
                        break;
                    }
                }
                if (prev != null && prev.getKind() == Tree.Kind.MODIFIERS) {
                    // argument became incompatible with the declared type.
                    break;
                }
                return TreeUtils.elementFromDeclaration((VariableTree) t);
            case METHOD:
                return TreeUtils.elementFromDeclaration((MethodTree) t);
            // Including RECORD
            case CLASS:
            case ENUM:
            case INTERFACE:
            case ANNOTATION_TYPE:
                return TreeUtils.elementFromDeclaration((ClassTree) t);
            // Do nothing.
            default:
        }
        prev = t;
    }
    return null;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) Element(javax.lang.model.element.Element) PackageElement(javax.lang.model.element.PackageElement) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeParameterElement(javax.lang.model.element.TypeParameterElement) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) DefaultQualifier(org.checkerframework.framework.qual.DefaultQualifier)

Example 82 with ClassTree

use of com.sun.source.tree.ClassTree in project checker-framework by typetools.

the class InitializationTransfer method initializedFieldsAfterCall.

/**
 * Returns the fields that can safely be considered initialized after the method call {@code
 * node}.
 *
 * @param node a method call
 * @return the fields that are initialized after the method call
 */
protected List<VariableElement> initializedFieldsAfterCall(MethodInvocationNode node) {
    List<VariableElement> result = new ArrayList<>();
    MethodInvocationTree tree = node.getTree();
    ExecutableElement method = TreeUtils.elementFromUse(tree);
    boolean isConstructor = method.getSimpleName().contentEquals("<init>");
    Node receiver = node.getTarget().getReceiver();
    String methodString = tree.getMethodSelect().toString();
    // invariant fields are guaranteed to be initialized.
    if (isConstructor && receiver instanceof ThisNode && methodString.equals("this")) {
        ClassTree clazz = TreePathUtil.enclosingClass(analysis.getTypeFactory().getPath(tree));
        TypeElement clazzElem = TreeUtils.elementFromDeclaration(clazz);
        markInvariantFieldsAsInitialized(result, clazzElem);
    }
    // invariant fields of any super class are guaranteed to be initialized.
    if (isConstructor && receiver instanceof ThisNode && methodString.equals("super")) {
        ClassTree clazz = TreePathUtil.enclosingClass(analysis.getTypeFactory().getPath(tree));
        TypeElement clazzElem = TreeUtils.elementFromDeclaration(clazz);
        TypeMirror superClass = clazzElem.getSuperclass();
        while (superClass != null && superClass.getKind() != TypeKind.NONE) {
            clazzElem = (TypeElement) analysis.getTypes().asElement(superClass);
            superClass = clazzElem.getSuperclass();
            markInvariantFieldsAsInitialized(result, clazzElem);
        }
    }
    return result;
}
Also used : ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) ArrayList(java.util.ArrayList) ClassTree(com.sun.source.tree.ClassTree) VariableElement(javax.lang.model.element.VariableElement)

Example 83 with ClassTree

use of com.sun.source.tree.ClassTree in project checker-framework by typetools.

the class NullnessVisitor method processClassTree.

@Override
public void processClassTree(ClassTree classTree) {
    Tree extendsClause = classTree.getExtendsClause();
    if (extendsClause != null) {
        reportErrorIfSupertypeContainsNullnessAnnotation(extendsClause);
    }
    for (Tree implementsClause : classTree.getImplementsClause()) {
        reportErrorIfSupertypeContainsNullnessAnnotation(implementsClause);
    }
    if (classTree.getKind() == Tree.Kind.ENUM) {
        for (Tree member : classTree.getMembers()) {
            if (member.getKind() == Tree.Kind.VARIABLE && TreeUtils.elementFromDeclaration((VariableTree) member).getKind() == ElementKind.ENUM_CONSTANT) {
                VariableTree varDecl = (VariableTree) member;
                List<? extends AnnotationTree> annoTrees = varDecl.getModifiers().getAnnotations();
                Tree type = varDecl.getType();
                if (atypeFactory.containsNullnessAnnotation(annoTrees, type)) {
                    checker.reportError(member, "nullness.on.enum");
                }
            }
        }
    }
    super.processClassTree(classTree);
}
Also used : VariableTree(com.sun.source.tree.VariableTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) SwitchTree(com.sun.source.tree.SwitchTree) ThrowTree(com.sun.source.tree.ThrowTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) ExpressionTree(com.sun.source.tree.ExpressionTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree)

Example 84 with ClassTree

use of com.sun.source.tree.ClassTree in project checker-framework by typetools.

the class LockTransfer method initialStore.

@Override
public LockStore initialStore(UnderlyingAST underlyingAST, List<LocalVariableNode> parameters) {
    LockStore store = super.initialStore(underlyingAST, parameters);
    Kind astKind = underlyingAST.getKind();
    // Handle synchronized methods and constructors.
    if (astKind == UnderlyingAST.Kind.METHOD) {
        CFGMethod method = (CFGMethod) underlyingAST;
        MethodTree methodTree = method.getMethod();
        ExecutableElement methodElement = TreeUtils.elementFromDeclaration(methodTree);
        if (methodElement.getModifiers().contains(Modifier.SYNCHRONIZED)) {
            final ClassTree classTree = method.getClassTree();
            TypeMirror classType = TreeUtils.typeOf(classTree);
            if (methodElement.getModifiers().contains(Modifier.STATIC)) {
                store.insertValue(new ClassName(classType), atypeFactory.LOCKHELD);
            } else {
                store.insertThisValue(atypeFactory.LOCKHELD, classType);
            }
        } else if (methodElement.getKind() == ElementKind.CONSTRUCTOR) {
            store.setInConstructorOrInitializer();
        }
    } else if (astKind == Kind.ARBITRARY_CODE) {
        // Handle initializers
        store.setInConstructorOrInitializer();
    }
    return store;
}
Also used : CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) MethodTree(com.sun.source.tree.MethodTree) TypeMirror(javax.lang.model.type.TypeMirror) ElementKind(javax.lang.model.element.ElementKind) Kind(org.checkerframework.dataflow.cfg.UnderlyingAST.Kind) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassTree(com.sun.source.tree.ClassTree) ClassName(org.checkerframework.dataflow.expression.ClassName)

Example 85 with ClassTree

use of com.sun.source.tree.ClassTree in project checker-framework by typetools.

the class CFAbstractTransfer method visitReturn.

@Override
public TransferResult<V, S> visitReturn(ReturnNode n, TransferInput<V, S> p) {
    TransferResult<V, S> result = super.visitReturn(n, p);
    if (shouldPerformWholeProgramInference(n.getTree())) {
        // Retrieves class containing the method
        ClassTree classTree = analysis.getContainingClass(n.getTree());
        // classTree is null e.g. if this is a return statement in a lambda.
        if (classTree == null) {
            return result;
        }
        ClassSymbol classSymbol = (ClassSymbol) TreeUtils.elementFromTree(classTree);
        ExecutableElement methodElem = TreeUtils.elementFromDeclaration(analysis.getContainingMethod(n.getTree()));
        Map<AnnotatedDeclaredType, ExecutableElement> overriddenMethods = AnnotatedTypes.overriddenMethods(analysis.atypeFactory.getElementUtils(), analysis.atypeFactory, methodElem);
        // Updates the inferred return type of the method
        analysis.atypeFactory.getWholeProgramInference().updateFromReturn(n, classSymbol, analysis.getContainingMethod(n.getTree()), overriddenMethods);
    }
    return result;
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ExecutableElement(javax.lang.model.element.ExecutableElement) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ClassTree(com.sun.source.tree.ClassTree)

Aggregations

ClassTree (com.sun.source.tree.ClassTree)119 Tree (com.sun.source.tree.Tree)76 MethodTree (com.sun.source.tree.MethodTree)66 VariableTree (com.sun.source.tree.VariableTree)59 NewClassTree (com.sun.source.tree.NewClassTree)48 ExpressionTree (com.sun.source.tree.ExpressionTree)45 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)40 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)31 AnnotationTree (com.sun.source.tree.AnnotationTree)29 BlockTree (com.sun.source.tree.BlockTree)28 IdentifierTree (com.sun.source.tree.IdentifierTree)27 NewArrayTree (com.sun.source.tree.NewArrayTree)26 AssignmentTree (com.sun.source.tree.AssignmentTree)25 MemberSelectTree (com.sun.source.tree.MemberSelectTree)25 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)24 TypeElement (javax.lang.model.element.TypeElement)24 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)23 ArrayList (java.util.ArrayList)23 ReturnTree (com.sun.source.tree.ReturnTree)22 TreePath (com.sun.source.util.TreePath)22