Search in sources :

Example 46 with Description

use of com.google.errorprone.matchers.Description 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 47 with Description

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

the class HidingField method matchClass.

@Override
public Description matchClass(ClassTree classTree, VisitorState visitorState) {
    List<VariableTree> originalClassMembers = classTree.getMembers().stream().filter(mem -> mem instanceof VariableTree).map(mem -> (VariableTree) mem).filter(mem -> !isSuppressed(ASTHelpers.getSymbol(mem)) && !isIgnoredType(mem) && !isStatic(mem)).collect(toCollection(ArrayList::new));
    ClassSymbol classSymbol = ASTHelpers.getSymbol(classTree);
    while (!Objects.equals(classSymbol.getSuperclass(), Type.noType)) {
        TypeSymbol parentSymbol = classSymbol.getSuperclass().asElement();
        List<Symbol> parentElements = parentSymbol.getEnclosedElements();
        Map<Name, VarSymbol> parentMembers = parentElements.stream().filter(mem -> (mem instanceof VarSymbol)).map(mem -> (VarSymbol) mem).filter(mem -> (!mem.isPrivate() && !mem.getModifiers().contains(Modifier.STATIC))).collect(Collectors.toMap(Symbol::getSimpleName, mem -> mem));
        checkForHiddenFields(originalClassMembers, parentMembers, parentSymbol.getSimpleName(), classTree, visitorState);
        classSymbol = (ClassSymbol) parentSymbol;
    }
    return Description.NO_MATCH;
}
Also used : ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) Modifier(javax.lang.model.element.Modifier) VariableTree(com.sun.source.tree.VariableTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ArrayList(java.util.ArrayList) Collectors.toCollection(java.util.stream.Collectors.toCollection) VisitorState(com.google.errorprone.VisitorState) Map(java.util.Map) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) ClassTree(com.sun.source.tree.ClassTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Name(javax.lang.model.element.Name) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) ImmutableSet(com.google.common.collect.ImmutableSet) Iterator(java.util.Iterator) Symbol(com.sun.tools.javac.code.Symbol) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) List(java.util.List) Description(com.google.errorprone.matchers.Description) Builder(com.google.errorprone.matchers.Description.Builder) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) VariableTree(com.sun.source.tree.VariableTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Name(javax.lang.model.element.Name)

Example 48 with Description

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

the class DefaultCharset method handlePrintWriterOutputStream.

private Description handlePrintWriterOutputStream(NewClassTree tree, VisitorState state) {
    Tree outputStream = tree.getArguments().get(0);
    Description.Builder description = buildDescription(tree);
    for (CharsetFix charsetFix : CharsetFix.values()) {
        SuggestedFix.Builder fix = SuggestedFix.builder().prefixWith(outputStream, "new BufferedWriter(new OutputStreamWriter(").postfixWith(outputStream, String.format(", %s))", charsetFix.replacement()));
        charsetFix.addImport(fix, state);
        fix.addImport("java.io.BufferedWriter");
        fix.addImport("java.io.OutputStreamWriter");
        description.addFix(fix.build());
    }
    return description.build();
}
Also used : Description(com.google.errorprone.matchers.Description) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 49 with Description

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

the class DefaultCharset method handleFileWriter.

private Description handleFileWriter(NewClassTree tree, VisitorState state) {
    Iterator<? extends ExpressionTree> it = tree.getArguments().iterator();
    Tree fileArg = it.next();
    Tree appendMode = it.hasNext() ? it.next() : null;
    Tree parent = state.getPath().getParentPath().getLeaf();
    Tree toReplace = BUFFERED_WRITER.matches(parent, state) ? parent : tree;
    Description.Builder description = buildDescription(tree);
    boolean useGuava = shouldUseGuava(state);
    for (CharsetFix charset : CharsetFix.values()) {
        if (appendMode == null && useGuava) {
            description.addFix(guavaFileWriterFix(state, fileArg, toReplace, charset));
        } else {
            description.addFix(nioFileWriterFix(state, appendMode, fileArg, toReplace, charset, useGuava));
        }
    }
    return description.build();
}
Also used : Description(com.google.errorprone.matchers.Description) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 50 with Description

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

the class DefaultCharset method handleFileReader.

private Description handleFileReader(NewClassTree tree, VisitorState state) {
    Tree arg = getOnlyElement(tree.getArguments());
    Tree parent = state.getPath().getParentPath().getLeaf();
    Tree toReplace = BUFFERED_READER.matches(parent, state) ? parent : tree;
    Description.Builder description = buildDescription(tree);
    fileReaderFix(description, state, arg, toReplace);
    return description.build();
}
Also used : Description(com.google.errorprone.matchers.Description) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Aggregations

Description (com.google.errorprone.matchers.Description)56 Tree (com.sun.source.tree.Tree)23 VisitorState (com.google.errorprone.VisitorState)22 BugPattern (com.google.errorprone.BugPattern)21 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)20 ASTHelpers (com.google.errorprone.util.ASTHelpers)20 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)17 ExpressionTree (com.sun.source.tree.ExpressionTree)17 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)17 JDK (com.google.errorprone.BugPattern.Category.JDK)16 Symbol (com.sun.tools.javac.code.Symbol)16 ProvidesFix (com.google.errorprone.BugPattern.ProvidesFix)14 Type (com.sun.tools.javac.code.Type)14 DescriptionBasedDiff (com.google.errorprone.apply.DescriptionBasedDiff)11 VariableTree (com.sun.source.tree.VariableTree)11 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)11 NO_MATCH (com.google.errorprone.matchers.Description.NO_MATCH)10 ClassTree (com.sun.source.tree.ClassTree)10 Optional (java.util.Optional)10 MethodTree (com.sun.source.tree.MethodTree)9