Search in sources :

Example 41 with Description

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

the class CollectionIncompatibleType method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    MatchResult directResult = firstNonNullMatchResult(DIRECT_MATCHERS, tree, state);
    MatchResult typeArgResult = null;
    if (directResult == null) {
        typeArgResult = firstNonNullMatchResult(TYPE_ARG_MATCHERS, tree, state);
    }
    if (directResult == null && typeArgResult == null) {
        return Description.NO_MATCH;
    }
    Verify.verify(directResult == null ^ typeArgResult == null);
    MatchResult result = MoreObjects.firstNonNull(directResult, typeArgResult);
    Types types = state.getTypes();
    TypeCompatibilityReport compatibilityReport = EqualsIncompatibleType.compatibilityOfTypes(result.targetType(), result.sourceType(), state);
    if (compatibilityReport.compatible()) {
        return Description.NO_MATCH;
    }
    // For error message, use simple names instead of fully qualified names unless they are
    // identical.
    String sourceTreeType = Signatures.prettyType(ASTHelpers.getType(result.sourceTree()));
    String sourceType = Signatures.prettyType(result.sourceType());
    String targetType = Signatures.prettyType(result.targetType());
    if (sourceType.equals(targetType)) {
        sourceType = result.sourceType().toString();
        targetType = result.targetType().toString();
    }
    Description.Builder description = buildDescription(tree);
    if (typeArgResult != null) {
        description.setMessage(String.format("Argument '%s' should not be passed to this method; its type %s has a type argument " + "%s that is not compatible with its collection's type argument %s", result.sourceTree(), sourceTreeType, sourceType, targetType));
    } else {
        description.setMessage(String.format("Argument '%s' should not be passed to this method; its type %s is not compatible " + "with its collection's type argument %s", result.sourceTree(), sourceType, targetType));
    }
    switch(fixType) {
        case PRINT_TYPES_AS_COMMENT:
            description.addFix(SuggestedFix.prefixWith(tree, String.format("/* expected: %s, actual: %s */", ASTHelpers.getUpperBound(result.targetType(), types), result.sourceType())));
            break;
        case CAST:
            Fix fix;
            if (typeArgResult != null) {
                TypeArgOfMethodArgMatcher matcher = (TypeArgOfMethodArgMatcher) typeArgResult.matcher();
                String fullyQualifiedType = matcher.getMethodArgTypeName();
                String simpleType = Iterables.getLast(Splitter.on('.').split(fullyQualifiedType));
                fix = SuggestedFix.builder().prefixWith(result.sourceTree(), String.format("(%s<?>) ", simpleType)).addImport(fullyQualifiedType).build();
            } else {
                fix = SuggestedFix.prefixWith(result.sourceTree(), "(Object) ");
            }
            description.addFix(fix);
            break;
        case SUPPRESS_WARNINGS:
            SuggestedFix.Builder builder = SuggestedFix.builder();
            builder.prefixWith(result.sourceTree(), String.format("/* expected: %s, actual: %s */ ", targetType, sourceType));
            addSuppressWarnings(builder, state, "CollectionIncompatibleType");
            description.addFix(builder.build());
            break;
        case NONE:
            break;
    }
    return description.build();
}
Also used : Types(com.sun.tools.javac.code.Types) Description(com.google.errorprone.matchers.Description) Fix(com.google.errorprone.fixes.Fix) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MatchResult(com.google.errorprone.bugpatterns.collectionincompatibletype.AbstractCollectionIncompatibleTypeMatcher.MatchResult) TypeCompatibilityReport(com.google.errorprone.bugpatterns.EqualsIncompatibleType.TypeCompatibilityReport)

Example 42 with Description

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

the class DoubleCheckedLocking method handleField.

/**
 * Report a {@link Description} if a field used in double-checked locking is not volatile.
 *
 * <p>If the AST node for the field declaration can be located in the current compilation unit,
 * suggest adding the volatile modifier.
 */
private Description handleField(IfTree outerIf, VarSymbol sym, VisitorState state) {
    if (sym.getModifiers().contains(Modifier.VOLATILE)) {
        return Description.NO_MATCH;
    }
    if (isImmutable(sym.type, state)) {
        return Description.NO_MATCH;
    }
    Description.Builder builder = buildDescription(outerIf);
    JCTree fieldDecl = findFieldDeclaration(state.getPath(), sym);
    if (fieldDecl != null) {
        builder.addFix(SuggestedFixes.addModifiers(fieldDecl, state, Modifier.VOLATILE));
    }
    return builder.build();
}
Also used : Description(com.google.errorprone.matchers.Description) JCTree(com.sun.tools.javac.tree.JCTree)

Example 43 with Description

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

the class InconsistentOverloads method processGroupMethods.

private void processGroupMethods(List<MethodTree> groupMethodTrees, VisitorState state) {
    Preconditions.checkArgument(!groupMethodTrees.isEmpty());
    for (ParameterOrderingViolation violation : getViolations(groupMethodTrees)) {
        MethodSymbol methodSymbol = getSymbol(violation.methodTree());
        if (ASTHelpers.findSuperMethods(methodSymbol, state.getTypes()).isEmpty()) {
            Description.Builder description = buildDescription(violation.methodTree());
            description.setMessage(violation.getDescription());
            state.reportMatch(description.build());
        }
    }
}
Also used : Description(com.google.errorprone.matchers.Description) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol)

Example 44 with Description

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

the class ConstantField method matchVariable.

@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
    Symbol.VarSymbol sym = ASTHelpers.getSymbol(tree);
    if (sym == null || sym.getKind() != ElementKind.FIELD) {
        return Description.NO_MATCH;
    }
    String name = sym.getSimpleName().toString();
    if (sym.isStatic() && sym.getModifiers().contains(Modifier.FINAL)) {
        return checkImmutable(tree, state, sym, name);
    }
    if (!name.equals(name.toUpperCase())) {
        return Description.NO_MATCH;
    }
    Description.Builder fixBuilder = buildDescription(tree);
    if (canBecomeStaticMember(sym)) {
        fixBuilder.addFix(SuggestedFixes.addModifiers(tree, state, Modifier.FINAL, Modifier.STATIC));
    }
    return fixBuilder.addFix(SuggestedFixes.renameVariable(tree, CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name), state)).build();
}
Also used : Description(com.google.errorprone.matchers.Description) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Symbol(com.sun.tools.javac.code.Symbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 45 with Description

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

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