Search in sources :

Example 11 with MemberSelectTree

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

the class NonRuntimeAnnotation method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!instanceMethod().onDescendantOf("java.lang.Class").named("getAnnotation").matches(tree, state)) {
        return Description.NO_MATCH;
    }
    MemberSelectTree memTree = (MemberSelectTree) tree.getArguments().get(0);
    TypeSymbol annotation = ASTHelpers.getSymbol(memTree.getExpression()).type.tsym;
    Retention retention = ASTHelpers.getAnnotation(annotation, Retention.class);
    if (retention != null && retention.value().equals(RUNTIME)) {
        return Description.NO_MATCH;
    }
    return describeMatch(tree, SuggestedFix.replace(tree, "null"));
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Retention(java.lang.annotation.Retention)

Example 12 with MemberSelectTree

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

the class FindIdentifiers method findAllIdents.

/**
   * Finds the set of all bare variable identifiers in scope at the current location. Identifiers
   * are ordered by ascending distance/scope count from the current location to match shadowing
   * rules. That is, if two variables with the same simple names appear in the set, the one that
   * appears first in iteration order is the one you get if you use the bare name in the source
   * code.
   *
   * <p>We do not report variables that would require a qualfied access. We also do not handle
   * wildcard imports.
   */
public static LinkedHashSet<VarSymbol> findAllIdents(VisitorState state) {
    ImmutableSet.Builder<VarSymbol> result = new ImmutableSet.Builder<>();
    Tree prev = state.getPath().getLeaf();
    for (Tree curr : state.getPath().getParentPath()) {
        switch(curr.getKind()) {
            case BLOCK:
                for (StatementTree stmt : ((BlockTree) curr).getStatements()) {
                    if (stmt.equals(prev)) {
                        break;
                    }
                    addIfVariable(stmt, result);
                }
                break;
            case METHOD:
                for (VariableTree param : ((MethodTree) curr).getParameters()) {
                    result.add(ASTHelpers.getSymbol(param));
                }
                break;
            case CATCH:
                result.add(ASTHelpers.getSymbol(((CatchTree) curr).getParameter()));
                break;
            case CLASS:
            case INTERFACE:
            case ENUM:
            case ANNOTATION_TYPE:
                // field is referred to by qualified name, but we don't support that.
                for (Tree member : ((ClassTree) curr).getMembers()) {
                    if (member.equals(prev)) {
                        break;
                    }
                    addIfVariable(member, result);
                }
                // Collect inherited fields.
                Type classType = ASTHelpers.getType(curr);
                com.sun.tools.javac.util.List<Type> superTypes = state.getTypes().closure(classType).tail;
                for (Type type : superTypes) {
                    Scope scope = type.tsym.members();
                    ImmutableList.Builder<VarSymbol> varsList = new ImmutableList.Builder<VarSymbol>();
                    for (Symbol var : scope.getSymbols(VarSymbol.class::isInstance)) {
                        varsList.add((VarSymbol) var);
                    }
                    result.addAll(varsList.build().reverse());
                }
                break;
            case FOR_LOOP:
                addAllIfVariable(((ForLoopTree) curr).getInitializer(), result);
                break;
            case ENHANCED_FOR_LOOP:
                result.add(ASTHelpers.getSymbol(((EnhancedForLoopTree) curr).getVariable()));
                break;
            case TRY:
                TryTree tryTree = (TryTree) curr;
                boolean inResources = false;
                for (Tree resource : tryTree.getResources()) {
                    if (resource.equals(prev)) {
                        inResources = true;
                        break;
                    }
                }
                if (inResources) {
                    // Case 1: we're in one of the resource declarations
                    for (Tree resource : tryTree.getResources()) {
                        if (resource.equals(prev)) {
                            break;
                        }
                        addIfVariable(resource, result);
                    }
                } else if (tryTree.getBlock().equals(prev)) {
                    // Case 2: We're in the block (not a catch or finally)
                    addAllIfVariable(tryTree.getResources(), result);
                }
                break;
            case COMPILATION_UNIT:
                for (ImportTree importTree : ((CompilationUnitTree) curr).getImports()) {
                    if (importTree.isStatic() && importTree.getQualifiedIdentifier().getKind() == Kind.MEMBER_SELECT) {
                        MemberSelectTree memberSelectTree = (MemberSelectTree) importTree.getQualifiedIdentifier();
                        Scope scope = state.getTypes().membersClosure(ASTHelpers.getType(memberSelectTree.getExpression()), /*skipInterface*/
                        false);
                        for (Symbol var : scope.getSymbols(sym -> sym instanceof VarSymbol && sym.getSimpleName().equals(memberSelectTree.getIdentifier()))) {
                            result.add((VarSymbol) var);
                        }
                    }
                }
                break;
            default:
                // other node types don't introduce variables
                break;
        }
        prev = curr;
    }
    // TODO(eaftan): switch out collector for ImmutableSet.toImmutableSet()
    return result.build().stream().filter(var -> isVisible(var, state.getPath())).collect(Collectors.toCollection(LinkedHashSet::new));
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Modifier(javax.lang.model.element.Modifier) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) Method(java.lang.reflect.Method) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TreePath(com.sun.source.util.TreePath) ImmutableSet(com.google.common.collect.ImmutableSet) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) MemberSelectTree(com.sun.source.tree.MemberSelectTree) Env(com.sun.tools.javac.comp.Env) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) List(java.util.List) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) Flags(com.sun.tools.javac.code.Flags) Name(com.sun.tools.javac.util.Name) Scope(com.sun.tools.javac.code.Scope) Type(com.sun.tools.javac.code.Type) MethodTree(com.sun.source.tree.MethodTree) MemberEnter(com.sun.tools.javac.comp.MemberEnter) VariableTree(com.sun.source.tree.VariableTree) AttrContext(com.sun.tools.javac.comp.AttrContext) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) BiPredicate(java.util.function.BiPredicate) Kind(com.sun.source.tree.Tree.Kind) ImmutableList(com.google.common.collect.ImmutableList) NewClassTree(com.sun.source.tree.NewClassTree) StreamSupport(java.util.stream.StreamSupport) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Enter(com.sun.tools.javac.comp.Enter) ElementKind(javax.lang.model.element.ElementKind) KindSelector(com.sun.tools.javac.code.Kinds.KindSelector) TryTree(com.sun.source.tree.TryTree) Resolve(com.sun.tools.javac.comp.Resolve) MethodTree(com.sun.source.tree.MethodTree) CatchTree(com.sun.source.tree.CatchTree) ImmutableList(com.google.common.collect.ImmutableList) 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) MemberSelectTree(com.sun.source.tree.MemberSelectTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) StatementTree(com.sun.source.tree.StatementTree) ImmutableSet(com.google.common.collect.ImmutableSet) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Type(com.sun.tools.javac.code.Type) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) Scope(com.sun.tools.javac.code.Scope) TryTree(com.sun.source.tree.TryTree) ImportTree(com.sun.source.tree.ImportTree)

Example 13 with MemberSelectTree

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

the class WildcardImport method getWildcardImports.

/** Collect all on demand imports. */
private static ImmutableList<ImportTree> getWildcardImports(List<? extends ImportTree> imports) {
    ImmutableList.Builder<ImportTree> result = ImmutableList.builder();
    for (ImportTree tree : imports) {
        // javac represents on-demand imports as a member select where the selected name is '*'.
        Tree ident = tree.getQualifiedIdentifier();
        if (!(ident instanceof MemberSelectTree)) {
            continue;
        }
        MemberSelectTree select = (MemberSelectTree) ident;
        if (select.getIdentifier().contentEquals("*")) {
            result.add(tree);
        }
    }
    return result.build();
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) MemberSelectTree(com.sun.source.tree.MemberSelectTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CaseTree(com.sun.source.tree.CaseTree) JCTree(com.sun.tools.javac.tree.JCTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) ImportTree(com.sun.source.tree.ImportTree)

Example 14 with MemberSelectTree

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

the class SizeGreaterThanOrEqualsZero method matchBinary.

@Override
public Description matchBinary(BinaryTree tree, VisitorState state) {
    // Easy stuff: needs to be a binary expression of the form foo >= 0 or 0 <= foo
    ExpressionType expressionType = isGreaterThanEqualToZero(tree);
    if (expressionType == ExpressionType.MISMATCH) {
        return Description.NO_MATCH;
    }
    ExpressionTree operand = expressionType == ExpressionType.GREATER_THAN_EQUAL ? tree.getLeftOperand() : tree.getRightOperand();
    if (operand instanceof MethodInvocationTree) {
        MethodInvocationTree callToSize = (MethodInvocationTree) operand;
        if (INSTANCE_METHOD_MATCHER.matches(callToSize, state)) {
            return provideReplacementForMethodInvocation(tree, callToSize, state, expressionType);
        } else if (STATIC_METHOD_MATCHER.matches(callToSize, state)) {
            return provideReplacementForStaticMethodInvocation(tree, callToSize, state, expressionType);
        }
    } else if (operand instanceof MemberSelectTree) {
        if (ARRAY_LENGTH_MATCHER.matches((MemberSelectTree) operand, state)) {
            return removeEqualsFromComparison(tree, state, expressionType);
        }
    }
    return Description.NO_MATCH;
}
Also used : MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 15 with MemberSelectTree

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

the class MyCustomCheck method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!PRINT_METHOD.matches(tree, state)) {
        return NO_MATCH;
    }
    Symbol base = tree.getMethodSelect().accept(new TreeScanner<Symbol, Void>() {

        @Override
        public Symbol visitIdentifier(IdentifierTree node, Void unused) {
            return ASTHelpers.getSymbol(node);
        }

        @Override
        public Symbol visitMemberSelect(MemberSelectTree node, Void unused) {
            return super.visitMemberSelect(node, null);
        }
    }, null);
    if (!Objects.equals(base, state.getSymtab().systemType.tsym)) {
        return NO_MATCH;
    }
    ExpressionTree arg = Iterables.getOnlyElement(tree.getArguments());
    if (!STRING_FORMAT.matches(arg, state)) {
        return NO_MATCH;
    }
    List<? extends ExpressionTree> formatArgs = ((MethodInvocationTree) arg).getArguments();
    return describeMatch(tree, SuggestedFix.builder().replace(((JCTree) tree).getStartPosition(), ((JCTree) formatArgs.get(0)).getStartPosition(), "System.err.printf(").replace(state.getEndPosition((JCTree) getLast(formatArgs)), state.getEndPosition((JCTree) tree), ")").build());
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Aggregations

MemberSelectTree (com.sun.source.tree.MemberSelectTree)15 IdentifierTree (com.sun.source.tree.IdentifierTree)10 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)9 ExpressionTree (com.sun.source.tree.ExpressionTree)8 JCTree (com.sun.tools.javac.tree.JCTree)8 Tree (com.sun.source.tree.Tree)7 VariableTree (com.sun.source.tree.VariableTree)5 Symbol (com.sun.tools.javac.code.Symbol)4 ClassTree (com.sun.source.tree.ClassTree)3 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)3 NewClassTree (com.sun.source.tree.NewClassTree)3 Element (javax.lang.model.element.Element)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 TypeElement (javax.lang.model.element.TypeElement)3 VariableElement (javax.lang.model.element.VariableElement)3 ImmutableList (com.google.common.collect.ImmutableList)2 AssignmentTree (com.sun.source.tree.AssignmentTree)2 BinaryTree (com.sun.source.tree.BinaryTree)2 BlockTree (com.sun.source.tree.BlockTree)2 ImportTree (com.sun.source.tree.ImportTree)2