Search in sources :

Example 1 with ValidationResult

use of com.google.errorprone.bugpatterns.formatstring.FormatStringValidation.ValidationResult 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)

Aggregations

ValidationResult (com.google.errorprone.bugpatterns.formatstring.FormatStringValidation.ValidationResult)1 VariableTree (com.sun.source.tree.VariableTree)1 TreePath (com.sun.source.util.TreePath)1 Symbol (com.sun.tools.javac.code.Symbol)1 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)1 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)1