Search in sources :

Example 66 with MethodTree

use of com.sun.source.tree.MethodTree in project error-prone by google.

the class MustBeClosedChecker method matchNewClassOrMethodInvocation.

/**
   * Check that constructors and methods annotated with {@link MustBeClosed} occur within the
   * resource variable initializer of a try-with-resources statement.
   *
   * @param name The name of the method or constructor.
   */
private Description matchNewClassOrMethodInvocation(String name, Tree tree, VisitorState state) {
    if (!HAS_MUST_BE_CLOSED_ANNOTATION.matches(tree, state)) {
        // {@link MustBeClosed}.
        return NO_MATCH;
    }
    String errorMessage = String.format("%s must be called within the resource variable initializer of a try-with-resources" + " statement.", name);
    MethodTree callerMethodTree = enclosingMethod(state);
    if (state.getPath().getParentPath().getLeaf().getKind() == Tree.Kind.RETURN && callerMethodTree != null) {
        if (HAS_MUST_BE_CLOSED_ANNOTATION.matches(callerMethodTree, state)) {
            // statement of an annotated caller method, since invocations of the caller are enforced.
            return NO_MATCH;
        }
        // enforced. Suggest fixing this by annotating the caller method.
        return buildDescription(tree).addFix(SuggestedFix.builder().prefixWith(callerMethodTree, "@MustBeClosed\n").addImport(MustBeClosed.class.getCanonicalName()).build()).setMessage(errorMessage).build();
    }
    if (!inTWR(state)) {
        // initializer of a try-with-resources statement.
        return buildDescription(tree).setMessage(errorMessage).build();
    }
    return NO_MATCH;
}
Also used : MethodTree(com.sun.source.tree.MethodTree) MustBeClosed(com.google.errorprone.annotations.MustBeClosed)

Example 67 with MethodTree

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

the class JavaSource2CFGDOT method getMethodTreeAndCompilationUnit.

/**
 * @return the AST of a specific method in a specific class as well as the {@link
 *     CompilationUnitTree} in a specific file (or null they do not exist).
 */
public static Entry<@Nullable MethodTree, @Nullable CompilationUnitTree> getMethodTreeAndCompilationUnit(String file, final String method, String clas) {
    final MethodTree[] m = { null };
    final CompilationUnitTree[] c = { null };
    BasicTypeProcessor typeProcessor = new BasicTypeProcessor() {

        @Override
        protected TreePathScanner<?, ?> createTreePathScanner(CompilationUnitTree root) {
            c[0] = root;
            return new TreePathScanner<Void, Void>() {

                @Override
                public Void visitMethod(MethodTree node, Void p) {
                    ExecutableElement el = TreeUtils.elementFromDeclaration(node);
                    if (el.getSimpleName().contentEquals(method)) {
                        m[0] = node;
                        // compilation).
                        throw new RuntimeException();
                    }
                    return null;
                }
            };
        }
    };
    Context context = new Context();
    Options.instance(context).put("compilePolicy", "ATTR_ONLY");
    JavaCompiler javac = new JavaCompiler(context);
    JavacFileManager fileManager = (JavacFileManager) context.get(JavaFileManager.class);
    JavaFileObject l = fileManager.getJavaFileObjectsFromStrings(List.of(file)).iterator().next();
    PrintStream err = System.err;
    try {
        // redirect syserr to nothing (and prevent the compiler from issuing
        // warnings about our exception.
        System.setErr(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
            }
        }));
        javac.compile(List.of(l), List.of(clas), List.of(typeProcessor));
    } catch (Throwable e) {
    // ok
    } finally {
        System.setErr(err);
    }
    return new Entry<MethodTree, CompilationUnitTree>() {

        @Override
        public CompilationUnitTree setValue(CompilationUnitTree value) {
            return null;
        }

        @Override
        public CompilationUnitTree getValue() {
            return c[0];
        }

        @Override
        public MethodTree getKey() {
            return m[0];
        }
    };
}
Also used : Context(com.sun.tools.javac.util.Context) PrintStream(java.io.PrintStream) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) MethodTree(com.sun.source.tree.MethodTree) JavaFileManager(javax.tools.JavaFileManager) ExecutableElement(javax.lang.model.element.ExecutableElement) OutputStream(java.io.OutputStream) TreePathScanner(com.sun.source.util.TreePathScanner) JavaCompiler(com.sun.tools.javac.main.JavaCompiler) JavacFileManager(com.sun.tools.javac.file.JavacFileManager) JavaFileObject(javax.tools.JavaFileObject) Entry(java.util.Map.Entry) BasicTypeProcessor(org.checkerframework.javacutil.BasicTypeProcessor)

Example 68 with MethodTree

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

the class AnnotatedTypeFactory method getSelfType.

/**
 * Returns the type of {@code this} in the current location, which can be used if {@code this}
 * has a special semantics (e.g. {@code this} is non-null).
 *
 * <p>The parameter is an arbitrary tree and does not have to mention "this", neither explicitly
 * nor implicitly. This method should be overridden for type-system specific behavior.
 *
 * <p>TODO: in 1.8.2, handle all receiver type annotations. TODO: handle enclosing classes
 * correctly.
 */
public AnnotatedDeclaredType getSelfType(Tree tree) {
    TreePath path = getPath(tree);
    ClassTree enclosingClass = TreeUtils.enclosingClass(path);
    if (enclosingClass == null) {
        // I hope this only happens when tree is a fake tree that
        // we created, e.g. when desugaring enhanced-for-loops.
        enclosingClass = getCurrentClassTree(tree);
    }
    AnnotatedDeclaredType type = getAnnotatedType(enclosingClass);
    MethodTree enclosingMethod = TreeUtils.enclosingMethod(path);
    if (enclosingClass.getSimpleName().length() != 0 && enclosingMethod != null) {
        AnnotatedDeclaredType methodReceiver;
        if (TreeUtils.isConstructor(enclosingMethod)) {
            methodReceiver = (AnnotatedDeclaredType) getAnnotatedType(enclosingMethod).getReturnType();
        } else {
            methodReceiver = getAnnotatedType(enclosingMethod).getReceiverType();
        }
        if (shouldTakeFromReceiver(methodReceiver)) {
            // TODO  what about all annotations on the receiver?
            // Code is also duplicated above.
            type.clearAnnotations();
            type.addAnnotations(methodReceiver.getAnnotations());
        }
    }
    return type;
}
Also used : TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree)

Example 69 with MethodTree

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

the class DependentTypesHelper method standardizeVariable.

public void standardizeVariable(Tree node, AnnotatedTypeMirror type, Element ele) {
    if (!hasDependentType(type)) {
        return;
    }
    TreePath path = factory.getPath(node);
    if (path == null) {
        return;
    }
    switch(ele.getKind()) {
        case PARAMETER:
            Tree enclTree = TreeUtils.enclosingOfKind(path, new HashSet<>(Arrays.asList(Kind.METHOD, Kind.LAMBDA_EXPRESSION)));
            if (enclTree.getKind() == Kind.METHOD) {
                // If the most enclosing tree is a method, the parameter is a method parameter
                MethodTree methodTree = (MethodTree) enclTree;
                TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
                FlowExpressionContext parameterContext = FlowExpressionContext.buildContextForMethodDeclaration(methodTree, enclosingType, factory.getContext());
                standardizeDoNotUseLocals(parameterContext, path, type);
            } else {
                // Otherwise, the parameter is a lambda parameter
                LambdaExpressionTree lambdaTree = (LambdaExpressionTree) enclTree;
                FlowExpressionContext parameterContext = FlowExpressionContext.buildContextForLambda(lambdaTree, path, factory.getContext());
                // TODO: test this.
                // TODO: use path.getParentPath to prevent a StackOverflowError, see Issue
                // #1027.
                standardizeUseLocals(parameterContext, path.getParentPath(), type);
            }
            break;
        case LOCAL_VARIABLE:
        case RESOURCE_VARIABLE:
        case EXCEPTION_PARAMETER:
            TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
            FlowExpressions.Receiver receiver = FlowExpressions.internalReprOfPseudoReceiver(path, enclosingType);
            List<Receiver> params = FlowExpressions.getParametersOfEnclosingMethod(factory, path);
            FlowExpressionContext localContext = new FlowExpressionContext(receiver, params, factory.getContext());
            standardizeUseLocals(localContext, path, type);
            break;
        case FIELD:
            FlowExpressions.Receiver receiverF;
            if (node.getKind() == Tree.Kind.IDENTIFIER) {
                FlowExpressions.Receiver r = FlowExpressions.internalReprOf(factory, (IdentifierTree) node);
                receiverF = r instanceof FlowExpressions.FieldAccess ? ((FlowExpressions.FieldAccess) r).getReceiver() : r;
            } else {
                receiverF = FlowExpressions.internalReprOfImplicitReceiver(ele);
            }
            FlowExpressionContext fieldContext = new FlowExpressionContext(receiverF, null, factory.getContext());
            standardizeDoNotUseLocals(fieldContext, path, type);
            break;
        default:
    }
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 70 with MethodTree

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

the class BaseTypeVisitor method resolveContracts.

/**
 * Takes a set of contracts identified by their expression and annotation strings and resolves
 * them to the correct {@link Receiver} and {@link AnnotationMirror}.
 */
private Set<Pair<Receiver, AnnotationMirror>> resolveContracts(Set<? extends Contract> contractSet, AnnotatedExecutableType method) {
    Set<Pair<Receiver, AnnotationMirror>> result = new HashSet<>();
    MethodTree methodTree = visitorState.getMethodTree();
    TreePath path = atypeFactory.getPath(methodTree);
    FlowExpressionContext flowExprContext = null;
    for (Contract p : contractSet) {
        String expression = p.expression;
        AnnotationMirror annotation = p.annotation;
        if (flowExprContext == null) {
            flowExprContext = FlowExpressionContext.buildContextForMethodDeclaration(methodTree, method.getReceiverType().getUnderlyingType(), checker.getContext());
        }
        annotation = standardizeAnnotationFromContract(annotation, flowExprContext, path);
        try {
            // TODO: currently, these expressions are parsed many times.
            // this could
            // be optimized to store the result the first time.
            // (same for other annotations)
            FlowExpressions.Receiver expr = FlowExpressionParseUtil.parse(expression, flowExprContext, path, false);
            result.add(Pair.of(expr, annotation));
        } catch (FlowExpressionParseException e) {
            // report errors here
            checker.report(e.getResult(), methodTree);
        }
    }
    return result;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Contract(org.checkerframework.framework.util.ContractsUtils.Contract) Pair(org.checkerframework.javacutil.Pair) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

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