Search in sources :

Example 31 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class JavaLangClash method check.

private Description check(Tree tree, Name simpleName, VisitorState state) {
    Symtab symtab = state.getSymtab();
    PackageSymbol javaLang = symtab.enterPackage(symtab.java_base, Names.instance(state.context).java_lang);
    Symbol other = getFirst(javaLang.members().getSymbolsByName(simpleName, s -> s.getModifiers().contains(PUBLIC)), null);
    Symbol symbol = ASTHelpers.getSymbol(tree);
    if (other == null || other.equals(symbol)) {
        return NO_MATCH;
    }
    return buildDescription(tree).setMessage(String.format("%s clashes with %s\n", symbol, other)).build();
}
Also used : Symtab(com.sun.tools.javac.code.Symtab) Symtab(com.sun.tools.javac.code.Symtab) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) PUBLIC(javax.lang.model.element.Modifier.PUBLIC) Symbol(com.sun.tools.javac.code.Symbol) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) Names(com.sun.tools.javac.util.Names) TypeParameterTree(com.sun.source.tree.TypeParameterTree) Iterables.getFirst(com.google.common.collect.Iterables.getFirst) VisitorState(com.google.errorprone.VisitorState) TypeParameterTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.TypeParameterTreeMatcher) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) Description(com.google.errorprone.matchers.Description) StandardTags(com.google.errorprone.BugPattern.StandardTags) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) JDK(com.google.errorprone.BugPattern.Category.JDK) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Tree(com.sun.source.tree.Tree) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Name(com.sun.tools.javac.util.Name) ASTHelpers(com.google.errorprone.util.ASTHelpers) ClassTree(com.sun.source.tree.ClassTree) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol)

Example 32 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class LambdaFunctionalInterface method matchMethod.

/**
 * Identifies methods with parameters that have a generic argument with Int, Long, or Double. If
 * pre-conditions are met, it refactors them to the primitive specializations.
 *
 * <pre>PreConditions:
 * (1): The method declaration has to be private (to do a safe refactoring)
 * (2): Its parameters have to meet the following conditions:
 *    2.1 Contain type java.util.function.Function
 *    2.2 At least one argument type of the Function must be subtype of Number
 * (3): All its invocations in the top-level enclosing class have to meet the following
 * conditions as well:
 *    3.1: lambda argument of Kind.LAMBDA_EXPRESSION
 *    3.2: same as 2.1
 *    3.3: same as 2.2
 * </pre>
 *
 * <pre>
 * Refactoring Changes for matched methods:
 * (1) Add the imports
 * (2) Change the method signature to use utility function instead of Function
 * (3) Find and change the 'apply' calls to the corresponding applyAsT
 * </pre>
 */
@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    MethodSymbol methodSym = ASTHelpers.getSymbol(tree);
    // precondition (1)
    if (!methodSym.getModifiers().contains(Modifier.PRIVATE)) {
        return Description.NO_MATCH;
    }
    ImmutableList<Tree> params = tree.getParameters().stream().filter(param -> hasFunctionAsArg(param, state)).filter(param -> isFunctionArgSubtypeOf(param, 0, state.getTypeFromString(JAVA_LANG_NUMBER), state) || isFunctionArgSubtypeOf(param, 1, state.getTypeFromString(JAVA_LANG_NUMBER), state)).collect(toImmutableList());
    // preconditions (2) and (3)
    if (params.isEmpty() || !methodCallsMeetConditions(methodSym, state)) {
        return Description.NO_MATCH;
    }
    SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
    for (Tree param : params) {
        getMappingForFunctionFromTree(param).ifPresent(mappedFunction -> {
            fixBuilder.addImport(getImportName(mappedFunction));
            fixBuilder.replace(param, getFunctionName(mappedFunction) + " " + ASTHelpers.getSymbol(param).name);
            refactorInternalApplyMethods(tree, fixBuilder, param, mappedFunction);
        });
    }
    return describeMatch(tree, fixBuilder.build());
}
Also used : Optional.empty(java.util.Optional.empty) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) Modifier(javax.lang.model.element.Modifier) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Kind(com.sun.source.tree.Tree.Kind) ImmutableList(com.google.common.collect.ImmutableList) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ImmutableMap(com.google.common.collect.ImmutableMap) ASTHelpers.getReceiver(com.google.errorprone.util.ASTHelpers.getReceiver) Optional.ofNullable(java.util.Optional.ofNullable) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) Streams(com.google.common.collect.Streams) TreeScanner(com.sun.source.util.TreeScanner) Description(com.google.errorprone.matchers.Description) Optional(java.util.Optional) SUGGESTION(com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MethodTree(com.sun.source.tree.MethodTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree)

Example 33 with VisitorState

use of com.google.errorprone.VisitorState 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);
                List<Type> classTypeClosure = state.getTypes().closure(classType);
                List<Type> superTypes = classTypeClosure.size() <= 1 ? Collections.emptyList() : classTypeClosure.subList(1, classTypeClosure.size());
                for (Type type : superTypes) {
                    Scope scope = type.tsym.members();
                    ImmutableList.Builder<VarSymbol> varsList = ImmutableList.builder();
                    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) Collections(java.util.Collections) Resolve(com.sun.tools.javac.comp.Resolve) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) 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) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) StatementTree(com.sun.source.tree.StatementTree) ClassType(com.sun.tools.javac.code.Type.ClassType) Type(com.sun.tools.javac.code.Type) ImmutableSet(com.google.common.collect.ImmutableSet) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) Scope(com.sun.tools.javac.code.Scope) 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) TryTree(com.sun.source.tree.TryTree) ImportTree(com.sun.source.tree.ImportTree)

Example 34 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class Matchers method inSynchronized.

/**
 * Matches if this Tree is enclosed by either a synchronized block or a synchronized method.
 */
public static final <T extends Tree> Matcher<T> inSynchronized() {
    return new Matcher<T>() {

        @Override
        public boolean matches(T tree, VisitorState state) {
            SynchronizedTree synchronizedTree = ASTHelpers.findEnclosingNode(state.getPath(), SynchronizedTree.class);
            if (synchronizedTree != null) {
                return true;
            }
            MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
            return methodTree != null && methodTree.getModifiers().getFlags().contains(Modifier.SYNCHRONIZED);
        }
    };
}
Also used : SynchronizedTree(com.sun.source.tree.SynchronizedTree) InstanceMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.InstanceMethodMatcher) AnyMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.AnyMethodMatcher) StaticMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.StaticMethodMatcher) ConstructorMatcher(com.google.errorprone.matchers.method.MethodMatchers.ConstructorMatcher) VisitorState(com.google.errorprone.VisitorState) MethodTree(com.sun.source.tree.MethodTree)

Example 35 with VisitorState

use of com.google.errorprone.VisitorState in project error-prone by google.

the class Matchers method inLoop.

/**
 * Matches if the given tree is inside a loop.
 */
public static <T extends Tree> Matcher<T> inLoop() {
    return new Matcher<T>() {

        @Override
        public boolean matches(Tree tree, VisitorState state) {
            TreePath path = state.getPath().getParentPath();
            Tree node = path.getLeaf();
            while (path != null) {
                switch(node.getKind()) {
                    case METHOD:
                    case CLASS:
                        return false;
                    case WHILE_LOOP:
                    case FOR_LOOP:
                    case ENHANCED_FOR_LOOP:
                    case DO_WHILE_LOOP:
                        return true;
                    default:
                        path = path.getParentPath();
                        node = path.getLeaf();
                        break;
                }
            }
            return false;
        }
    };
}
Also used : TreePath(com.sun.source.util.TreePath) InstanceMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.InstanceMethodMatcher) AnyMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.AnyMethodMatcher) StaticMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.StaticMethodMatcher) ConstructorMatcher(com.google.errorprone.matchers.method.MethodMatchers.ConstructorMatcher) VisitorState(com.google.errorprone.VisitorState) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ContinueTree(com.sun.source.tree.ContinueTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) 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)

Aggregations

VisitorState (com.google.errorprone.VisitorState)52 Tree (com.sun.source.tree.Tree)31 ASTHelpers (com.google.errorprone.util.ASTHelpers)29 Description (com.google.errorprone.matchers.Description)28 BugPattern (com.google.errorprone.BugPattern)27 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)23 Symbol (com.sun.tools.javac.code.Symbol)23 ClassTree (com.sun.source.tree.ClassTree)22 Type (com.sun.tools.javac.code.Type)22 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)21 ExpressionTree (com.sun.source.tree.ExpressionTree)21 MethodTree (com.sun.source.tree.MethodTree)21 JDK (com.google.errorprone.BugPattern.Category.JDK)19 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)18 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)16 List (java.util.List)16 NO_MATCH (com.google.errorprone.matchers.Description.NO_MATCH)14 Optional (java.util.Optional)14 VariableTree (com.sun.source.tree.VariableTree)13 ArrayList (java.util.ArrayList)13