Search in sources :

Example 86 with MethodTree

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

the class MustCallConsistencyAnalyzer method isValidCreatesMustCallForExpression.

/**
 * Checks the validity of the given expression from an invoked method's {@link
 * org.checkerframework.checker.mustcall.qual.CreatesMustCallFor} annotation. Helper method for
 * {@link #checkCreatesMustCallForInvocation(Set, MethodInvocationNode)}.
 *
 * <p>An expression is valid if one of the following conditions is true: 1) the expression is an
 * owning pointer, 2) the expression already has a tracked Obligation (i.e. there is already a
 * resource alias in some Obligation's resource alias set that refers to the expression), or 3)
 * the method in which the invocation occurs also has an @CreatesMustCallFor annotation, with the
 * same expression.
 *
 * @param obligations the currently-tracked Obligations; this value is side-effected if there is
 *     an Obligation in it which tracks {@code expression} as one of its resource aliases
 * @param expression an element of a method's @CreatesMustCallFor annotation
 * @param path the path to the invocation of the method from whose @CreateMustCallFor annotation
 *     {@code expression} came
 * @return true iff the expression is valid, as defined above
 */
private boolean isValidCreatesMustCallForExpression(Set<Obligation> obligations, JavaExpression expression, TreePath path) {
    if (expression instanceof FieldAccess) {
        Element elt = ((FieldAccess) expression).getField();
        if (!checker.hasOption(MustCallChecker.NO_LIGHTWEIGHT_OWNERSHIP) && typeFactory.getDeclAnnotation(elt, Owning.class) != null) {
            // The expression is an Owning field.  This satisfies case 1.
            return true;
        }
    } else if (expression instanceof LocalVariable) {
        Element elt = ((LocalVariable) expression).getElement();
        if (!checker.hasOption(MustCallChecker.NO_LIGHTWEIGHT_OWNERSHIP) && typeFactory.getDeclAnnotation(elt, Owning.class) != null) {
            // This satisfies case 1.
            return true;
        } else {
            Obligation toRemove = null;
            Obligation toAdd = null;
            for (Obligation obligation : obligations) {
                ResourceAlias alias = obligation.getResourceAlias(expression);
                if (alias != null) {
                    // This satisfies case 2 above. Remove all its aliases, then return below.
                    if (toRemove != null) {
                        throw new TypeSystemError("tried to remove multiple sets containing a reset expression at once");
                    }
                    toRemove = obligation;
                    toAdd = new Obligation(ImmutableSet.of(alias));
                }
            }
            if (toRemove != null) {
                obligations.remove(toRemove);
                obligations.add(toAdd);
                // This satisfies case 2.
                return true;
            }
        }
    }
    // TODO: Getting this every time is inefficient if a method has many @CreatesMustCallFor
    // annotations, but that should be rare.
    MethodTree enclosingMethodTree = TreePathUtil.enclosingMethod(path);
    if (enclosingMethodTree == null) {
        return false;
    }
    ExecutableElement enclosingMethodElt = TreeUtils.elementFromDeclaration(enclosingMethodTree);
    MustCallAnnotatedTypeFactory mcAtf = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
    List<String> enclosingCmcfValues = ResourceLeakVisitor.getCreatesMustCallForValues(enclosingMethodElt, mcAtf, typeFactory);
    if (enclosingCmcfValues.isEmpty()) {
        return false;
    }
    for (String enclosingCmcfValue : enclosingCmcfValues) {
        JavaExpression enclosingTarget;
        try {
            enclosingTarget = StringToJavaExpression.atMethodBody(enclosingCmcfValue, enclosingMethodTree, checker);
        } catch (JavaExpressionParseException e) {
            // Do not issue an error here, because it would be a duplicate.
            // The error will be issued by the Transfer class of the checker,
            // via the CreatesMustCallForElementSupplier interface.
            enclosingTarget = null;
        }
        if (areSame(expression, enclosingTarget)) {
            // This satisfies case 3.
            return true;
        }
    }
    return false;
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) MethodTree(com.sun.source.tree.MethodTree) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) TypeSystemError(org.checkerframework.javacutil.TypeSystemError) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) NotOwning(org.checkerframework.checker.mustcall.qual.NotOwning) Owning(org.checkerframework.checker.mustcall.qual.Owning) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess)

Example 87 with MethodTree

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

the class MustCallVisitor method visitReturn.

@Override
public Void visitReturn(ReturnTree node, Void p) {
    // Only check return types if ownership is being transferred.
    if (!checker.hasOption(MustCallChecker.NO_LIGHTWEIGHT_OWNERSHIP)) {
        MethodTree enclosingMethod = TreePathUtil.enclosingMethod(this.getCurrentPath());
        // precisely?
        if (enclosingMethod != null) {
            ExecutableElement methodElt = TreeUtils.elementFromDeclaration(enclosingMethod);
            AnnotationMirror notOwningAnno = atypeFactory.getDeclAnnotation(methodElt, NotOwning.class);
            if (notOwningAnno != null) {
                // Checker won't check anyway.
                return null;
            }
        }
    }
    return super.visitReturn(node, p);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) MethodTree(com.sun.source.tree.MethodTree) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 88 with MethodTree

use of com.sun.source.tree.MethodTree 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 89 with MethodTree

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

the class TreeUtils method hasSyntheticArgument.

/**
 * Returns true if {@code tree} has a synthetic argument.
 *
 * <p>For some anonymous classes with an explicit enclosing expression, javac creates a synthetic
 * argument to the constructor that is the enclosing expression of the NewClassTree. Suppose a
 * programmer writes:
 *
 * <pre>{@code class Outer {
 *   class Inner { }
 *     void method() {
 *       this.new Inner(){};
 *     }
 * }}</pre>
 *
 * Java 9 javac creates the following synthetic tree for {@code this.new Inner(){}}:
 *
 * <pre>{@code new Inner(this) {
 *   (.Outer x0) {
 *     x0.super();
 *   }
 * }}</pre>
 *
 * Java 11 javac creates a different tree without the synthetic argument for {@code this.new
 * Inner(){}}; the first line in the below code differs:
 *
 * <pre>{@code this.new Inner() {
 *   (.Outer x0) {
 *     x0.super();
 *   }
 * }}</pre>
 *
 * @param tree a new class tree
 * @return true if {@code tree} has a synthetic argument
 */
public static boolean hasSyntheticArgument(NewClassTree tree) {
    if (tree.getClassBody() == null || tree.getEnclosingExpression() != null) {
        return false;
    }
    for (Tree member : tree.getClassBody().getMembers()) {
        if (member.getKind() == Tree.Kind.METHOD && isConstructor((MethodTree) member)) {
            MethodTree methodTree = (MethodTree) member;
            StatementTree f = methodTree.getBody().getStatements().get(0);
            return TreeUtils.getReceiverTree(((ExpressionStatementTree) f).getExpression()) != null;
        }
    }
    return false;
}
Also used : ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) StatementTree(com.sun.source.tree.StatementTree) MethodTree(com.sun.source.tree.MethodTree) 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) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CaseTree(com.sun.source.tree.CaseTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) StatementTree(com.sun.source.tree.StatementTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) 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) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree) UnionTypeTree(com.sun.source.tree.UnionTypeTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree)

Example 90 with MethodTree

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

the class TreePathUtil method isTreeInStaticScope.

/**
 * Returns true if the leaf of the tree path is in a static scope.
 *
 * @param path TreePath whose leaf may or may not be in static scope
 * @return true if the leaf of the tree path is in a static scope
 */
public static boolean isTreeInStaticScope(TreePath path) {
    MethodTree enclosingMethod = enclosingMethod(path);
    if (enclosingMethod != null) {
        return enclosingMethod.getModifiers().getFlags().contains(Modifier.STATIC);
    }
    // no enclosing method, check for static or initializer block
    BlockTree block = enclosingTopLevelBlock(path);
    if (block != null) {
        return block.isStatic();
    }
    // check if its in a variable initializer
    Tree t = enclosingVariable(path);
    if (t != null) {
        return ((VariableTree) t).getModifiers().getFlags().contains(Modifier.STATIC);
    }
    ClassTree classTree = enclosingClass(path);
    if (classTree != null) {
        return classTree.getModifiers().getFlags().contains(Modifier.STATIC);
    }
    return false;
}
Also used : MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) BlockTree(com.sun.source.tree.BlockTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) BlockTree(com.sun.source.tree.BlockTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree)

Aggregations

MethodTree (com.sun.source.tree.MethodTree)127 ClassTree (com.sun.source.tree.ClassTree)66 Tree (com.sun.source.tree.Tree)65 VariableTree (com.sun.source.tree.VariableTree)58 ExpressionTree (com.sun.source.tree.ExpressionTree)54 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)43 ExecutableElement (javax.lang.model.element.ExecutableElement)39 NewClassTree (com.sun.source.tree.NewClassTree)38 TreePath (com.sun.source.util.TreePath)33 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)32 MemberSelectTree (com.sun.source.tree.MemberSelectTree)28 AnnotationTree (com.sun.source.tree.AnnotationTree)25 IdentifierTree (com.sun.source.tree.IdentifierTree)25 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)23 ReturnTree (com.sun.source.tree.ReturnTree)22 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)22 ArrayList (java.util.ArrayList)22 TypeElement (javax.lang.model.element.TypeElement)21 AssignmentTree (com.sun.source.tree.AssignmentTree)20 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)20