Search in sources :

Example 1 with MethodTree

use of com.sun.source.tree.MethodTree in project bazel by bazelbuild.

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 Holder<MethodTree> m = new Holder<>();
    final Holder<CompilationUnitTree> c = new Holder<>();
    BasicTypeProcessor typeProcessor = new BasicTypeProcessor() {

        @Override
        protected TreePathScanner<?, ?> createTreePathScanner(CompilationUnitTree root) {
            c.value = 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.value = node;
                        // compilation).
                        throw new RuntimeException();
                    }
                    return null;
                }
            };
        }
    };
    Context context = new Context();
    JavaCompiler javac = new JavaCompiler(context);
    javac.attrParseOnly = true;
    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.value;
        }

        @Override
        public MethodTree getKey() {
            return m.value;
        }
    };
}
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) Holder(javax.xml.ws.Holder) 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 2 with MethodTree

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

the class UseBinds method matchMethod.

@Override
public Description matchMethod(MethodTree method, VisitorState state) {
    if (!CAN_BE_A_BINDS_METHOD.matches(method, state)) {
        return NO_MATCH;
    }
    JCClassDecl enclosingClass = ASTHelpers.findEnclosingNode(state.getPath(), JCClassDecl.class);
    // Dagger 1 modules don't support @Binds.
    if (!IS_DAGGER_2_MODULE.matches(enclosingClass, state)) {
        return NO_MATCH;
    }
    if (enclosingClass.getExtendsClause() != null) {
        return fixByDelegating();
    }
    for (Tree member : enclosingClass.getMembers()) {
        if (member.getKind().equals(Tree.Kind.METHOD) && !getSymbol(member).isConstructor()) {
            MethodTree siblingMethod = (MethodTree) member;
            Set<Modifier> siblingFlags = siblingMethod.getModifiers().getFlags();
            if (!(siblingFlags.contains(Modifier.STATIC) || siblingFlags.contains(Modifier.ABSTRACT)) && !CAN_BE_A_BINDS_METHOD.matches(siblingMethod, state)) {
                return fixByDelegating();
            }
        }
    }
    return fixByModifyingMethod(state, enclosingClass, method);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) MethodTree(com.sun.source.tree.MethodTree) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) Modifier(javax.lang.model.element.Modifier)

Example 3 with MethodTree

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

the class Overrides method matchMethod.

@Override
public Description matchMethod(MethodTree methodTree, VisitorState state) {
    MethodSymbol methodSymbol = ASTHelpers.getSymbol(methodTree);
    boolean isVarargs = (methodSymbol.flags() & Flags.VARARGS) != 0;
    Set<MethodSymbol> superMethods = ASTHelpers.findSuperMethods(methodSymbol, state.getTypes());
    // If there are no super methods, we're fine:
    if (superMethods.isEmpty()) {
        return Description.NO_MATCH;
    }
    Iterator<MethodSymbol> superMethodsIterator = superMethods.iterator();
    boolean areSupersVarargs = superMethodsIterator.next().isVarArgs();
    while (superMethodsIterator.hasNext()) {
        if (areSupersVarargs != superMethodsIterator.next().isVarArgs()) {
            // current method is inconsistent with some of its supermethods, so report a match.
            return describeMatch(methodTree);
        }
    }
    // The current method is consistent with all of its supermethods:
    if (isVarargs == areSupersVarargs) {
        return Description.NO_MATCH;
    }
    // The current method is inconsistent with all of its supermethods, so flip the varargs-ness
    // of the current method.
    List<? extends VariableTree> parameterTree = methodTree.getParameters();
    Tree paramType = parameterTree.get(parameterTree.size() - 1).getType();
    CharSequence paramTypeSource = state.getSourceForNode(paramType);
    if (paramTypeSource == null) {
        // No fix if we don't have tree end positions.
        return describeMatch(methodTree);
    }
    Description.Builder descriptionBuilder = buildDescription(methodTree);
    if (isVarargs) {
        descriptionBuilder.addFix(SuggestedFix.replace(paramType, "[]", paramTypeSource.length() - 3, 0));
    } else {
        // There may be a comment that includes a '[' character between the open and closed
        // brackets of the array type.  If so, we don't return a fix.
        int arrayOpenIndex = paramTypeSource.length() - 2;
        while (paramTypeSource.charAt(arrayOpenIndex) == ' ') {
            arrayOpenIndex--;
        }
        if (paramTypeSource.charAt(arrayOpenIndex) == '[') {
            descriptionBuilder.addFix(SuggestedFix.replace(paramType, "...", arrayOpenIndex, 0));
        }
    }
    return descriptionBuilder.build();
}
Also used : Description(com.google.errorprone.matchers.Description) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree)

Example 4 with MethodTree

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

the class AmbiguousMethodReference method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol origin = getSymbol(tree);
    Types types = state.getTypes();
    Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
    false).getSymbols();
    // collect declared and inherited methods, grouped by reference descriptor
    Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
    // look for groups of ambiguous method references
    for (Tree member : tree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodSymbol msym = getSymbol((MethodTree) member);
        if (isSuppressed(msym)) {
            continue;
        }
        List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
        if (clash == null) {
            continue;
        }
        clash.remove(msym);
        // ignore overridden inherited methods and hidden interface methods
        clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
        if (clash.isEmpty()) {
            continue;
        }
        String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
        state.reportMatch(buildDescription(member).setMessage(message).build());
    }
    return NO_MATCH;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Collectors.joining(java.util.stream.Collectors.joining) ArrayList(java.util.ArrayList) Collectors.toCollection(java.util.stream.Collectors.toCollection) VisitorState(com.google.errorprone.VisitorState) List(java.util.List) Types(com.sun.tools.javac.code.Types) StreamSupport.stream(java.util.stream.StreamSupport.stream) Signatures(com.google.errorprone.util.Signatures) Description(com.google.errorprone.matchers.Description) Map(java.util.Map) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) JDK(com.google.errorprone.BugPattern.Category.JDK) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ArrayList(java.util.ArrayList) List(java.util.List)

Example 5 with MethodTree

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

the class FindIdentifiers method findIdent.

/** Finds a declaration with the given name that is in scope at the current location. */
public static Symbol findIdent(String name, VisitorState state) {
    ClassType enclosingClass = ASTHelpers.getType(state.findEnclosing(ClassTree.class));
    if (enclosingClass == null || enclosingClass.tsym == null) {
        return null;
    }
    Env<AttrContext> env = Enter.instance(state.context).getClassEnv(enclosingClass.tsym);
    MethodTree enclosingMethod = state.findEnclosing(MethodTree.class);
    if (enclosingMethod != null) {
        env = MemberEnter.instance(state.context).getMethodEnv((JCMethodDecl) enclosingMethod, env);
    }
    try {
        Method method = Resolve.class.getDeclaredMethod("findIdent", Env.class, Name.class, KindSelector.class);
        method.setAccessible(true);
        Symbol result = (Symbol) method.invoke(Resolve.instance(state.context), env, state.getName(name), KindSelector.VAR);
        return result.exists() ? result : null;
    } catch (ReflectiveOperationException e) {
        throw new LinkageError(e.getMessage(), e);
    }
}
Also used : JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) MethodTree(com.sun.source.tree.MethodTree) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) Method(java.lang.reflect.Method) ClassType(com.sun.tools.javac.code.Type.ClassType) AttrContext(com.sun.tools.javac.comp.AttrContext)

Aggregations

MethodTree (com.sun.source.tree.MethodTree)91 Tree (com.sun.source.tree.Tree)46 ClassTree (com.sun.source.tree.ClassTree)45 VariableTree (com.sun.source.tree.VariableTree)39 ExpressionTree (com.sun.source.tree.ExpressionTree)36 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)28 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)22 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)20 TreePath (com.sun.source.util.TreePath)20 IdentifierTree (com.sun.source.tree.IdentifierTree)19 NewClassTree (com.sun.source.tree.NewClassTree)19 ReturnTree (com.sun.source.tree.ReturnTree)18 ExecutableElement (javax.lang.model.element.ExecutableElement)17 Symbol (com.sun.tools.javac.code.Symbol)16 ArrayList (java.util.ArrayList)15 AssignmentTree (com.sun.source.tree.AssignmentTree)14 BlockTree (com.sun.source.tree.BlockTree)14 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)14 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)14 MemberSelectTree (com.sun.source.tree.MemberSelectTree)14