Search in sources :

Example 6 with Symbol

use of com.sun.tools.javac.code.Symbol in project error-prone by google.

the class FieldMissingNullable method matchVariable.

@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
    Symbol assigned = ASTHelpers.getSymbol(tree);
    if (assigned == null || assigned.getKind() != ElementKind.FIELD || assigned.type.isPrimitive()) {
        // not a field of nullable type
        return Description.NO_MATCH;
    }
    ExpressionTree expression = tree.getInitializer();
    if (expression == null || ASTHelpers.constValue(expression) != null) {
        // This should include literals such as "true" or a string
        return Description.NO_MATCH;
    }
    if (TrustingNullnessAnalysis.hasNullableAnnotation(assigned)) {
        // field already annotated
        return Description.NO_MATCH;
    }
    // Don't need dataflow to tell us that null is nullable
    if (expression.getKind() == Tree.Kind.NULL_LITERAL) {
        return makeFix(tree, tree, "Initializing field with null literal");
    }
    // OK let's see what dataflow says
    // TODO(kmb): Merge this method with matchAssignment once we unify nullness analysis entry point
    Nullness nullness = TrustingNullnessAnalysis.instance(state.context).getFieldInitializerNullness(state.getPath(), state.context);
    switch(nullness) {
        case BOTTOM:
        case NONNULL:
            return Description.NO_MATCH;
        case NULL:
            return makeFix(tree, tree, "Initializing field with null");
        case NULLABLE:
            return makeFix(tree, tree, "May initialize field with null");
        default:
            throw new AssertionError("Impossible: " + nullness);
    }
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) ExpressionTree(com.sun.source.tree.ExpressionTree) Nullness(com.google.errorprone.dataflow.nullnesspropagation.Nullness)

Example 7 with Symbol

use of com.sun.tools.javac.code.Symbol in project error-prone by google.

the class ParameterNotNullable method matchDereference.

private Description matchDereference(ExpressionTree dereferencedExpression, VisitorState state) {
    Symbol dereferenced = ASTHelpers.getSymbol(dereferencedExpression);
    if (dereferenced == null || dereferenced.getKind() != ElementKind.PARAMETER || dereferenced.type.isPrimitive()) {
        // not a parameter dereference
        return Description.NO_MATCH;
    }
    if (!TrustingNullnessAnalysis.hasNullableAnnotation(dereferenced)) {
        return Description.NO_MATCH;
    }
    Nullness nullness = TrustingNullnessAnalysis.instance(state.context).getNullness(new TreePath(state.getPath(), dereferencedExpression), state.context);
    if (nullness != Nullness.NULLABLE) {
        return Description.NO_MATCH;
    }
    for (AnnotationTree anno : findDeclaration(state, dereferenced).getModifiers().getAnnotations()) {
        if (ASTHelpers.getSymbol(anno).type.toString().endsWith(".Nullable")) {
            return buildDescription(dereferencedExpression).setMessage("Nullable parameter not checked for null").addFix(SuggestedFix.delete(anno)).build();
        }
    }
    // Shouldn't get here
    return Description.NO_MATCH;
}
Also used : TreePath(com.sun.source.util.TreePath) Symbol(com.sun.tools.javac.code.Symbol) AnnotationTree(com.sun.source.tree.AnnotationTree) Nullness(com.google.errorprone.dataflow.nullnesspropagation.Nullness)

Example 8 with Symbol

use of com.sun.tools.javac.code.Symbol in project error-prone by google.

the class StrictFormatStringValidation method validateFormatStringVariable.

/**
   * Helps {@code validate()} validate a format string that is a variable, but not a parameter. This
   * method assumes that the format string variable has already been asserted to be final or
   * effectively final.
   */
private static ValidationResult validateFormatStringVariable(ExpressionTree formatStringTree, final Symbol formatStringSymbol, final List<? extends ExpressionTree> args, final VisitorState state) {
    if (formatStringSymbol.getKind() != ElementKind.LOCAL_VARIABLE) {
        return ValidationResult.create(null, String.format("Variables used as format strings that are not local variables must be compile time" + " consant.\n%s is not a local variable and is not compile time constant.", formatStringTree));
    }
    // Find the Tree for the block in which the variable is defined. If it is not defined in this
    // class (though it may have been in a super class). We require compile time constant values in
    // that case.
    Symbol owner = formatStringSymbol.owner;
    TreePath path = TreePath.getPath(state.getPath(), formatStringTree);
    while (path != null && ASTHelpers.getSymbol(path.getLeaf()) != owner) {
        path = path.getParentPath();
    }
    // impossible.
    if (path == null) {
        throw new IllegalStateException(String.format("Could not find the Tree where local variable %s is declared. " + "This should be impossible.", formatStringTree));
    }
    // Scan down from the scope where the variable was declared
    ValidationResult result = path.getLeaf().accept(new TreeScanner<ValidationResult, Void>() {

        @Override
        public ValidationResult visitVariable(VariableTree node, Void unused) {
            if (ASTHelpers.getSymbol(node) == formatStringSymbol) {
                if (node.getInitializer() == null) {
                    return ValidationResult.create(null, String.format("Variables used as format strings must be initialized when they are" + " declared.\nInvalid declaration: %s", node));
                }
                return validateStringFromAssignment(node, node.getInitializer(), args, state);
            }
            return super.visitVariable(node, unused);
        }

        @Override
        public ValidationResult reduce(ValidationResult r1, ValidationResult r2) {
            if (r1 == null && r2 == null) {
                return null;
            }
            return MoreObjects.firstNonNull(r1, r2);
        }
    }, null);
    return result;
}
Also used : TreePath(com.sun.source.util.TreePath) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) VariableTree(com.sun.source.tree.VariableTree) ValidationResult(com.google.errorprone.bugpatterns.formatstring.FormatStringValidation.ValidationResult)

Example 9 with Symbol

use of com.sun.tools.javac.code.Symbol in project error-prone by google.

the class StrictFormatStringValidation method isFormatStringParameter.

/**
   * Returns whether an input {@link Symbol} is a format string in a {@link FormatMethod}. This is
   * true if the {@link Symbol} is a {@link String} parameter in a {@link FormatMethod} and is
   * either:
   *
   * <ol>
   * <li>Annotated with {@link FormatString}
   * <li>The first {@link String} parameter in the method with no other parameters annotated {@link
   *     FormatString}.
   * </ol>
   */
private static boolean isFormatStringParameter(Symbol formatString, VisitorState state) {
    Type stringType = state.getSymtab().stringType;
    // The input symbol must be a String and a parameter of a @FormatMethod to be a @FormatString.
    if (!ASTHelpers.isSameType(formatString.type, stringType, state) || !(formatString.owner instanceof MethodSymbol) || !ASTHelpers.hasAnnotation(formatString.owner, FormatMethod.class, state)) {
        return false;
    }
    // If the format string is annotated @FormatString in a @FormatMethod, it is a format string.
    if (ASTHelpers.hasAnnotation(formatString, FormatString.class, state)) {
        return true;
    }
    // Check if format string is the first string with no @FormatString params in the @FormatMethod.
    MethodSymbol owner = (MethodSymbol) formatString.owner;
    boolean formatStringFound = false;
    for (Symbol param : owner.getParameters()) {
        if (param == formatString) {
            formatStringFound = true;
        }
        if (ASTHelpers.isSameType(param.type, stringType, state)) {
            // format string since it wasn't annotated @FormatString.
            if (!formatStringFound) {
                return false;
            } else if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) {
                return false;
            }
        }
    }
    return true;
}
Also used : Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) FormatString(com.google.errorprone.annotations.FormatString)

Example 10 with Symbol

use of com.sun.tools.javac.code.Symbol in project error-prone by google.

the class StaticGuardedByInstance method matchSynchronized.

@Override
public Description matchSynchronized(SynchronizedTree tree, VisitorState state) {
    Symbol lock = ASTHelpers.getSymbol(TreeInfo.skipParens((JCTree) tree.getExpression()));
    if (!(lock instanceof VarSymbol)) {
        return Description.NO_MATCH;
    }
    if (lock.isStatic()) {
        return Description.NO_MATCH;
    }
    Multimap<VarSymbol, Tree> writes = WriteVisitor.scan(tree.getBlock());
    for (Entry<VarSymbol, Tree> write : writes.entries()) {
        if (!write.getKey().isStatic()) {
            continue;
        }
        state.reportMatch(buildDescription(write.getValue()).setMessage(String.format(MESSAGE, lock)).build());
    }
    return Description.NO_MATCH;
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) JCTree(com.sun.tools.javac.tree.JCTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) ExpressionTree(com.sun.source.tree.ExpressionTree) UnaryTree(com.sun.source.tree.UnaryTree) JCTree(com.sun.tools.javac.tree.JCTree) AssignmentTree(com.sun.source.tree.AssignmentTree) NewClassTree(com.sun.source.tree.NewClassTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) Tree(com.sun.source.tree.Tree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Aggregations

Symbol (com.sun.tools.javac.code.Symbol)195 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)56 Type (com.sun.tools.javac.code.Type)54 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)53 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)45 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)36 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)29 JCTree (com.sun.tools.javac.tree.JCTree)28 ClassType (com.sun.tools.javac.code.Type.ClassType)18 Tree (com.sun.source.tree.Tree)17 ExpressionTree (com.sun.source.tree.ExpressionTree)15 DynamicMethodSymbol (com.sun.tools.javac.code.Symbol.DynamicMethodSymbol)15 OperatorSymbol (com.sun.tools.javac.code.Symbol.OperatorSymbol)15 ClassTree (com.sun.source.tree.ClassTree)14 MethodTree (com.sun.source.tree.MethodTree)14 Name (com.sun.tools.javac.util.Name)14 IdentifierTree (com.sun.source.tree.IdentifierTree)13 ArrayType (com.sun.tools.javac.code.Type.ArrayType)12 MethodType (com.sun.tools.javac.code.Type.MethodType)12 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)12