Search in sources :

Example 46 with VisitorState

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

the class EqualsIncompatibleType method compatibilityOfTypes.

public static TypeCompatibilityReport compatibilityOfTypes(Type receiverType, Type argumentType, Set<Type> previousReceiverTypes, Set<Type> previousArgumentTypes, VisitorState state) {
    if (receiverType == null || argumentType == null) {
        return TypeCompatibilityReport.createCompatibleReport();
    }
    // 1.7: java.lang.Object can be cast to primitives (implicitly through the boxed primitive type)
    if (ASTHelpers.isCastable(argumentType, receiverType, state)) {
        return leastUpperBoundGenericMismatch(receiverType, argumentType, previousReceiverTypes, previousArgumentTypes, state);
    }
    // Otherwise, we explore the superclasses of the receiver type as well as the interfaces it
    // implements and we collect all overrides of java.lang.Object.equals(). If one of those
    // overrides is inherited by the argument, then we don't flag the equality test.
    Types types = state.getTypes();
    Predicate<MethodSymbol> equalsPredicate = methodSymbol -> !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && types.isSameType(methodSymbol.getReturnType(), state.getSymtab().booleanType) && methodSymbol.getParameters().size() == 1 && types.isSameType(methodSymbol.getParameters().get(0).type, state.getSymtab().objectType);
    Set<MethodSymbol> overridesOfEquals = ASTHelpers.findMatchingMethods(state.getName("equals"), equalsPredicate, receiverType, types);
    Symbol argumentClass = ASTHelpers.getUpperBound(argumentType, state.getTypes()).tsym;
    for (MethodSymbol method : overridesOfEquals) {
        ClassSymbol methodClass = method.enclClass();
        if (argumentClass.isSubClass(methodClass, types) && !methodClass.equals(state.getSymtab().objectType.tsym) && !methodClass.equals(state.getSymtab().enumSym)) {
            // These should be compatible, but check any generic types for their compatbilities.
            return leastUpperBoundGenericMismatch(receiverType, argumentType, previousReceiverTypes, previousArgumentTypes, state);
        }
    }
    return TypeCompatibilityReport.incompatible(receiverType, argumentType);
}
Also used : Matchers.anyOf(com.google.errorprone.matchers.Matchers.anyOf) Matchers.toType(com.google.errorprone.matchers.Matchers.toType) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Matchers.instanceMethod(com.google.errorprone.matchers.Matchers.instanceMethod) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Signatures(com.google.errorprone.util.Signatures) TypeTag(com.sun.tools.javac.code.TypeTag) Matchers.allOf(com.google.errorprone.matchers.Matchers.allOf) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Matcher(com.google.errorprone.matchers.Matcher) Matchers.isSameType(com.google.errorprone.matchers.Matchers.isSameType) Tree(com.sun.source.tree.Tree) Nullable(javax.annotation.Nullable) MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) ImmutableSet(com.google.common.collect.ImmutableSet) Matchers.staticMethod(com.google.errorprone.matchers.Matchers.staticMethod) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) Streams(com.google.common.collect.Streams) BOOLEAN_TYPE(com.google.errorprone.suppliers.Suppliers.BOOLEAN_TYPE) Sets(com.google.common.collect.Sets) List(java.util.List) Types(com.sun.tools.javac.code.Types) Predicate(com.google.common.base.Predicate) Description(com.google.errorprone.matchers.Description) AutoValue(com.google.auto.value.AutoValue) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) Flags(com.sun.tools.javac.code.Flags) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) Types(com.sun.tools.javac.code.Types) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol)

Example 47 with VisitorState

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

the class FloatCast method matchTypeCast.

@Override
public Description matchTypeCast(TypeCastTree tree, VisitorState state) {
    Tree parent = state.getPath().getParentPath().getLeaf();
    if (!(parent instanceof BinaryTree)) {
        return NO_MATCH;
    }
    BinaryTree binop = (BinaryTree) parent;
    if (!binop.getLeftOperand().equals(tree)) {
        // the precedence is unambiguous for e.g. `i + (int) f`
        return NO_MATCH;
    }
    if (binop.getKind() != Kind.MULTIPLY) {
        // there's a bound on the imprecision for +, -, /
        return NO_MATCH;
    }
    Type castType = ASTHelpers.getType(tree.getType());
    Type operandType = ASTHelpers.getType(tree.getExpression());
    if (castType == null || operandType == null) {
        return NO_MATCH;
    }
    Symtab symtab = state.getSymtab();
    if (isSameType(ASTHelpers.getType(parent), symtab.stringType, state)) {
        // string concatenation doesn't count
        return NO_MATCH;
    }
    switch(castType.getKind()) {
        case LONG:
        case INT:
        case SHORT:
        case CHAR:
        case BYTE:
            break;
        default:
            return NO_MATCH;
    }
    switch(operandType.getKind()) {
        case FLOAT:
        case DOUBLE:
            break;
        default:
            return NO_MATCH;
    }
    if (BLACKLIST.matches(tree.getExpression(), state)) {
        return NO_MATCH;
    }
    if (POW.matches(tree.getExpression(), state)) {
        MethodInvocationTree pow = (MethodInvocationTree) tree.getExpression();
        if (pow.getArguments().stream().map(ASTHelpers::getType).filter(x -> x != null).map(state.getTypes()::unboxedTypeOrType).map(Type::getKind).allMatch(INTEGRAL::contains)) {
            return NO_MATCH;
        }
    }
    // Find the outermost enclosing binop, to suggest e.g. `(long) (f * a * b)` instead of
    // `(long) (f * a) * b`.
    Tree enclosing = binop;
    TreePath path = state.getPath().getParentPath().getParentPath();
    while (path != null) {
        if (!(path.getLeaf() instanceof BinaryTree)) {
            break;
        }
        BinaryTree enclosingBinop = (BinaryTree) path.getLeaf();
        if (!enclosingBinop.getLeftOperand().equals(enclosing)) {
            break;
        }
        enclosing = enclosingBinop;
        path = path.getParentPath();
    }
    return buildDescription(tree).addFix(SuggestedFix.builder().prefixWith(tree.getExpression(), "(").postfixWith(enclosing, ")").build()).addFix(SuggestedFix.builder().prefixWith(tree, "(").postfixWith(tree, ")").build()).build();
}
Also used : Symtab(com.sun.tools.javac.code.Symtab) Symtab(com.sun.tools.javac.code.Symtab) TypeCastTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.TypeCastTreeMatcher) BinaryTree(com.sun.source.tree.BinaryTree) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Kind(com.sun.source.tree.Tree.Kind) TypeCastTree(com.sun.source.tree.TypeCastTree) BugPattern(com.google.errorprone.BugPattern) Matcher(com.google.errorprone.matchers.Matcher) Tree(com.sun.source.tree.Tree) EnumSet(java.util.EnumSet) TreePath(com.sun.source.util.TreePath) ExpressionTree(com.sun.source.tree.ExpressionTree) Set(java.util.Set) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) TypeKind(javax.lang.model.type.TypeKind) MethodMatchers.staticMethod(com.google.errorprone.matchers.method.MethodMatchers.staticMethod) Description(com.google.errorprone.matchers.Description) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) Pattern(java.util.regex.Pattern) ASTHelpers.isSameType(com.google.errorprone.util.ASTHelpers.isSameType) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) ASTHelpers.isSameType(com.google.errorprone.util.ASTHelpers.isSameType) Type(com.sun.tools.javac.code.Type) TreePath(com.sun.source.util.TreePath) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) BinaryTree(com.sun.source.tree.BinaryTree) BinaryTree(com.sun.source.tree.BinaryTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeCastTree(com.sun.source.tree.TypeCastTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) ASTHelpers(com.google.errorprone.util.ASTHelpers)

Example 48 with VisitorState

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

the class FunctionalInterfaceClash method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ClassSymbol origin = getSymbol(tree);
    Types types = state.getTypes();
    // collect declared and inherited methods whose signature contains a functional interface
    Multimap<String, MethodSymbol> methods = HashMultimap.create();
    for (Symbol sym : types.membersClosure(getType(tree), /*skipInterface=*/
    false).getSymbols()) {
        if (!(sym instanceof MethodSymbol)) {
            continue;
        }
        if (isBugCheckerSuppressed((MethodSymbol) sym)) {
            continue;
        }
        MethodSymbol msym = (MethodSymbol) sym;
        if (msym.getParameters().stream().noneMatch(p -> maybeFunctionalInterface(p.type, types, state))) {
            continue;
        }
        if (msym.isConstructor() && !msym.owner.equals(origin)) {
            continue;
        }
        methods.put(functionalInterfaceSignature(state, msym), msym);
    }
    // (don't report clashes between inherited members)
    for (Tree member : tree.getMembers()) {
        if (!(member instanceof MethodTree)) {
            continue;
        }
        MethodSymbol msym = getSymbol((MethodTree) member);
        if (msym.getParameters().stream().noneMatch(p -> maybeFunctionalInterface(p.type, types, state))) {
            continue;
        }
        Collection<MethodSymbol> clash = new ArrayList<>(methods.removeAll(functionalInterfaceSignature(state, msym)));
        // Ignore inherited methods that are overridden in the original class. Note that we have to
        // handle transitive inheritance explicitly to handle cases where the visibility of an
        // overridded method is expanded somewhere in the type hierarchy.
        Deque<MethodSymbol> worklist = new ArrayDeque<>();
        worklist.push(msym);
        clash.remove(msym);
        while (!worklist.isEmpty()) {
            MethodSymbol msym2 = worklist.removeFirst();
            ImmutableList<MethodSymbol> overrides = clash.stream().filter(m -> msym2.overrides(m, origin, types, /*checkResult=*/
            false)).collect(toImmutableList());
            worklist.addAll(overrides);
            clash.removeAll(overrides);
        }
        if (!clash.isEmpty()) {
            // ignore if there are overridden clashing methods in class
            if (ASTHelpers.findSuperMethod(msym, types).isPresent() && clash.stream().anyMatch(methodSymbol -> ASTHelpers.findSuperMethod(methodSymbol, types).isPresent())) {
                return NO_MATCH;
            }
            String message = "When passing lambda arguments to this function, callers will need a cast to" + " disambiguate with: " + clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining("\n    "));
            state.reportMatch(buildDescription(member).setMessage(message).build());
        }
    }
    return NO_MATCH;
}
Also used : Arrays(java.util.Arrays) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) MethodTree(com.sun.source.tree.MethodTree) DiagnosticPosition(com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) Multimap(com.google.common.collect.Multimap) Deque(java.util.Deque) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) HashMultimap(com.google.common.collect.HashMultimap) ImmutableList(com.google.common.collect.ImmutableList) Signatures(com.google.errorprone.util.Signatures) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Collection(java.util.Collection) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) Collectors.joining(java.util.stream.Collectors.joining) List(com.sun.tools.javac.util.List) Types(com.sun.tools.javac.code.Types) CompletionFailure(com.sun.tools.javac.code.Symbol.CompletionFailure) Check(com.sun.tools.javac.comp.Check) Description(com.google.errorprone.matchers.Description) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ArrayDeque(java.util.ArrayDeque) Collections(java.util.Collections) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) 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) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ASTHelpers.getSymbol(com.google.errorprone.util.ASTHelpers.getSymbol) Symbol(com.sun.tools.javac.code.Symbol) ArrayList(java.util.ArrayList) ArrayDeque(java.util.ArrayDeque) 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)

Example 49 with VisitorState

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

the class FunctionalInterfaceMethodChanged method matchMethod.

@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
    ClassTree enclosingClazz = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class);
    if (tree.getModifiers().getFlags().contains(Modifier.DEFAULT) && IS_FUNCTIONAL_INTERFACE.matches(enclosingClazz, state)) {
        Types types = Types.instance(state.context);
        Set<Symbol> functionalSuperInterfaceSams = enclosingClazz.getImplementsClause().stream().filter(t -> IS_FUNCTIONAL_INTERFACE.matches(t, state)).map(ASTHelpers::getSymbol).map(TypeSymbol.class::cast).map(// TypeSymbol to single abstract method of the type
        types::findDescriptorSymbol).collect(toImmutableSet());
        // We designate an override of a superinterface SAM "behavior preserving" if it just
        // calls the SAM of this interface.
        Symbol thisInterfaceSam = types.findDescriptorSymbol(ASTHelpers.getSymbol(enclosingClazz));
        // relatively crude: doesn't verify that the same args are passed in the same order
        // so it can get false positives for behavior-preservingness (false negatives for the check)
        TreeVisitor<Boolean, VisitorState> behaviorPreserving = new BehaviorPreservingChecker(thisInterfaceSam);
        if (!Collections.disjoint(ASTHelpers.findSuperMethods(ASTHelpers.getSymbol(tree), types), functionalSuperInterfaceSams) && !tree.accept(behaviorPreserving, state)) {
            return describeMatch(tree);
        }
    }
    return Description.NO_MATCH;
}
Also used : Types(com.sun.tools.javac.code.Types) VisitorState(com.google.errorprone.VisitorState) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassTree(com.sun.source.tree.ClassTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 50 with VisitorState

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

the class CatchFail method deleteFix.

// Extract the argument to a call to assertWithMessage, e.g. in:
// assertWithMessage("message").fail();
Optional<Fix> deleteFix(TryTree tree, ImmutableList<CatchTree> catchBlocks, VisitorState state) {
    SuggestedFix.Builder fix = SuggestedFix.builder();
    if (tree.getFinallyBlock() != null || catchBlocks.size() < tree.getCatches().size()) {
        // If the try statement has a finally region, or other catch blocks, delete only the
        // unnecessary blocks.
        catchBlocks.stream().forEachOrdered(fix::delete);
    } else {
        // The try statement has no finally region and all catch blocks are unnecessary. Replace it
        // with the try statements, deleting all catches.
        List<? extends StatementTree> tryStatements = tree.getBlock().getStatements();
        String source = state.getSourceCode().toString();
        // Replace the full region to work around a GJF partial formatting bug that prevents it from
        // re-indenting unchanged lines. This means that fixes may overlap, but that's (hopefully)
        // unlikely.
        // TODO(b/24140798): emit more precise replacements if GJF is fixed
        fix.replace(tree, source.substring(((JCTree) tryStatements.get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(tryStatements))));
    }
    MethodTree enclosing = findEnclosing(state.getPath());
    if (enclosing == null) {
        // There isn't an enclosing method, possibly because we're in a lambda or initializer block.
        return Optional.empty();
    }
    if (isExpectedExceptionTest(ASTHelpers.getSymbol(enclosing), state)) {
        // tests, so don't use that fix for methods annotated with @Test(expected=...).
        return Optional.empty();
    }
    // Fix up the enclosing method's throws declaration to include the new thrown exception types.
    Collection<Type> thrownTypes = ASTHelpers.getSymbol(enclosing).getThrownTypes();
    Types types = state.getTypes();
    // Find all types in the deleted catch blocks that are not already in the throws declaration.
    ImmutableList<Type> toThrow = catchBlocks.stream().map(c -> ASTHelpers.getType(c.getParameter())).flatMap(t -> t instanceof UnionClassType ? ImmutableList.copyOf(((UnionClassType) t).getAlternativeTypes()).stream() : Stream.of(t)).filter(t -> thrownTypes.stream().noneMatch(x -> types.isAssignable(t, x))).collect(toImmutableList());
    if (!toThrow.isEmpty()) {
        if (!TEST_CASE.matches(enclosing, state)) {
            // not be a safe local refactoring.
            return Optional.empty();
        }
        String throwsString = toThrow.stream().map(t -> SuggestedFixes.qualifyType(state, fix, t)).distinct().collect(joining(", "));
        if (enclosing.getThrows().isEmpty()) {
            // Add a new throws declaration.
            fix.prefixWith(enclosing.getBody(), "throws " + throwsString);
        } else {
            // Append to an existing throws declaration.
            fix.postfixWith(Iterables.getLast(enclosing.getThrows()), ", " + throwsString);
        }
    }
    return Optional.of(fix.build());
}
Also used : SuggestedFixes(com.google.errorprone.fixes.SuggestedFixes) Iterables(com.google.common.collect.Iterables) Matchers.anyOf(com.google.errorprone.matchers.Matchers.anyOf) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Matchers.expressionStatement(com.google.errorprone.matchers.Matchers.expressionStatement) ImmutableList(com.google.common.collect.ImmutableList) TryTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) BugPattern(com.google.errorprone.BugPattern) Matcher(com.google.errorprone.matchers.Matcher) Fix(com.google.errorprone.fixes.Fix) Tree(com.sun.source.tree.Tree) MethodNameMatcher(com.google.errorprone.matchers.method.MethodMatchers.MethodNameMatcher) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TreePath(com.sun.source.util.TreePath) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Matchers.hasAnnotation(com.google.errorprone.matchers.Matchers.hasAnnotation) Collection(java.util.Collection) Compound(com.sun.tools.javac.code.Attribute.Compound) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) JCTree(com.sun.tools.javac.tree.JCTree) JUNIT4_TEST_ANNOTATION(com.google.errorprone.matchers.JUnitMatchers.JUNIT4_TEST_ANNOTATION) Collectors.joining(java.util.stream.Collectors.joining) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) JUnitMatchers.isJunit3TestCase(com.google.errorprone.matchers.JUnitMatchers.isJunit3TestCase) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) List(java.util.List) MethodMatchers.staticMethod(com.google.errorprone.matchers.method.MethodMatchers.staticMethod) Types(com.sun.tools.javac.code.Types) Stream(java.util.stream.Stream) JUnitMatchers(com.google.errorprone.matchers.JUnitMatchers) Description(com.google.errorprone.matchers.Description) StatementTree(com.sun.source.tree.StatementTree) TryTree(com.sun.source.tree.TryTree) Optional(java.util.Optional) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) 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) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) JCTree(com.sun.tools.javac.tree.JCTree) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Type(com.sun.tools.javac.code.Type) SuggestedFix(com.google.errorprone.fixes.SuggestedFix)

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