Search in sources :

Example 16 with ClassTree

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

the class EqualsHashCode method matchClass.

@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
    TypeSymbol symbol = ASTHelpers.getSymbol(classTree);
    if (symbol.getKind() != ElementKind.CLASS) {
        return Description.NO_MATCH;
    }
    MethodTree equals = null;
    for (Tree member : classTree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodTree methodTree = (MethodTree) member;
        if (EQUALS_MATCHER.matches(methodTree, state)) {
            equals = methodTree;
        }
    }
    if (equals == null) {
        return Description.NO_MATCH;
    }
    MethodSymbol hashCodeSym = ASTHelpers.resolveExistingMethod(state, symbol, state.getName("hashCode"), ImmutableList.<Type>of(), ImmutableList.<Type>of());
    if (hashCodeSym.owner.equals(state.getSymtab().objectType.tsym)) {
        return describeMatch(equals);
    }
    return Description.NO_MATCH;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 17 with ClassTree

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

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

the class ReferenceEquality method matchArgument.

@Override
protected boolean matchArgument(ExpressionTree tree, VisitorState state) {
    Type type = ASTHelpers.getType(tree);
    if (!type.isReference()) {
        return false;
    }
    ClassTree classTree = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class);
    if (classTree == null) {
        return false;
    }
    Type classType = ASTHelpers.getType(classTree);
    if (classType == null) {
        return false;
    }
    if (inEqualsOrCompareTo(classType, type, state)) {
        return false;
    }
    if (ASTHelpers.isSubtype(type, state.getSymtab().enumSym.type, state)) {
        return false;
    }
    if (ASTHelpers.isSubtype(type, state.getSymtab().classType, state)) {
        return false;
    }
    if (!implementsEquals(type, state)) {
        return false;
    }
    return true;
}
Also used : Type(com.sun.tools.javac.code.Type) ClassTree(com.sun.source.tree.ClassTree)

Example 19 with ClassTree

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

the class Util method addPrivateConstructor.

// TODO(dpb): Account for indentation level.
private static SuggestedFix.Builder addPrivateConstructor(ClassTree classTree) {
    SuggestedFix.Builder fix = SuggestedFix.builder();
    String indent = "  ";
    for (Tree member : classTree.getMembers()) {
        if (member.getKind().equals(METHOD) && !isGeneratedConstructor((MethodTree) member)) {
            fix.prefixWith(member, indent + "private " + classTree.getSimpleName() + "() {} // no instances\n" + indent);
            break;
        }
        if (!member.getKind().equals(METHOD)) {
            indent = "";
        }
    }
    return fix;
}
Also used : SuggestedFix(com.google.errorprone.fixes.SuggestedFix) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 20 with ClassTree

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

the class AutoFactoryAtInject method matchAnnotation.

@Override
public final Description matchAnnotation(AnnotationTree annotationTree, VisitorState state) {
    if (!IS_APPLICATION_OF_AT_INJECT.matches(annotationTree, state)) {
        return Description.NO_MATCH;
    }
    Tree annotatedTree = getCurrentlyAnnotatedNode(state);
    if (!annotatedTree.getKind().equals(METHOD) || !methodIsConstructor().matches((MethodTree) annotatedTree, state)) {
        return Description.NO_MATCH;
    }
    ClassTree classTree = findEnclosingNode(state.getPath(), ClassTree.class);
    ImmutableList<Tree> potentiallyAnnotatedTrees = new ImmutableList.Builder<Tree>().add(classTree).addAll(getConstructors(classTree)).build();
    for (Tree potentiallyAnnotatedTree : potentiallyAnnotatedTrees) {
        if (HAS_AUTO_FACTORY_ANNOTATION.matches(potentiallyAnnotatedTree, state)) {
            return describeMatch(annotationTree, SuggestedFix.delete(annotationTree));
        }
    }
    return Description.NO_MATCH;
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) ClassTree(com.sun.source.tree.ClassTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree)

Aggregations

ClassTree (com.sun.source.tree.ClassTree)24 Tree (com.sun.source.tree.Tree)18 MethodTree (com.sun.source.tree.MethodTree)13 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)8 Symbol (com.sun.tools.javac.code.Symbol)7 ArrayList (java.util.ArrayList)6 VisitorState (com.google.errorprone.VisitorState)5 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)5 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)5 BlockTree (com.sun.source.tree.BlockTree)4 TreePath (com.sun.source.util.TreePath)4 ImmutableList (com.google.common.collect.ImmutableList)3 BinaryTree (com.sun.source.tree.BinaryTree)3 ExpressionTree (com.sun.source.tree.ExpressionTree)3 IdentifierTree (com.sun.source.tree.IdentifierTree)3 MemberSelectTree (com.sun.source.tree.MemberSelectTree)3 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)3 ReturnTree (com.sun.source.tree.ReturnTree)3 VariableTree (com.sun.source.tree.VariableTree)3 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)3