Search in sources :

Example 36 with VariableTree

use of com.sun.source.tree.VariableTree 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) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Symbol(com.sun.tools.javac.code.Symbol) VariableTree(com.sun.source.tree.VariableTree) ValidationResult(com.google.errorprone.bugpatterns.formatstring.FormatStringValidation.ValidationResult)

Example 37 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class VarChecker method forLoopVariable.

boolean forLoopVariable(VariableTree tree, TreePath path) {
    Tree parent = path.getParentPath().getLeaf();
    if (!(parent instanceof ForLoopTree)) {
        return false;
    }
    ForLoopTree forLoop = (ForLoopTree) parent;
    return forLoop.getInitializer().contains(tree);
}
Also used : ForLoopTree(com.sun.source.tree.ForLoopTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ForLoopTree(com.sun.source.tree.ForLoopTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 38 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class FieldMissingNullable method matchAssignment.

@Override
public Description matchAssignment(AssignmentTree tree, VisitorState state) {
    Symbol assigned = ASTHelpers.getSymbol(tree.getVariable());
    if (assigned == null || assigned.getKind() != ElementKind.FIELD || assigned.type.isPrimitive()) {
        // not a field of nullable type
        return Description.NO_MATCH;
    }
    // Best-effort try to avoid running the dataflow analysis
    // TODO(kmb): bail on more non-null expressions, such as "this", arithmethic, logical, and &&/||
    ExpressionTree expression = tree.getExpression();
    if (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;
    }
    VariableTree fieldDecl = findDeclaration(state, assigned);
    if (fieldDecl == null) {
        // skip fields declared elsewhere for simplicity
        return Description.NO_MATCH;
    }
    // Don't need dataflow to tell us that null is nullable
    if (expression.getKind() == Tree.Kind.NULL_LITERAL) {
        return makeFix(state, fieldDecl, tree, "Assigning null literal to field");
    }
    // OK let's see what dataflow says
    Nullness nullness = TrustingNullnessAnalysis.instance(state.context).getNullness(new TreePath(state.getPath(), expression), state.context);
    if (nullness == null) {
        // TODO(b/69154806): Make dataflow work for that case.
        return Description.NO_MATCH;
    }
    switch(nullness) {
        case BOTTOM:
        case NONNULL:
            return Description.NO_MATCH;
        case NULL:
            return makeFix(state, fieldDecl, tree, "Assigning null to field");
        case NULLABLE:
            return makeFix(state, fieldDecl, tree, "May assign null to field");
        default:
            throw new AssertionError("Impossible: " + nullness);
    }
}
Also used : TreePath(com.sun.source.util.TreePath) Symbol(com.sun.tools.javac.code.Symbol) VariableTree(com.sun.source.tree.VariableTree) ExpressionTree(com.sun.source.tree.ExpressionTree) Nullness(com.google.errorprone.dataflow.nullnesspropagation.Nullness)

Example 39 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class ParameterTree method create.

public static ParameterTree create(VariableTree variableTree) {
    Preconditions.checkArgument(isValidParameterTree(variableTree));
    Name name = variableTree.getName();
    Tree type = variableTree.getType();
    boolean isVarargs = isVariableTreeVarArgs(variableTree);
    return new AutoValue_ParameterTree(name, type, isVarargs);
}
Also used : VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) Name(javax.lang.model.element.Name)

Example 40 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class InconsistentCapitalization method matchClass.

@Override
public Description matchClass(ClassTree tree, VisitorState state) {
    ImmutableSet<Symbol> fields = FieldScanner.findFields(tree);
    if (fields.isEmpty()) {
        return Description.NO_MATCH;
    }
    ImmutableMap<String, Symbol> fieldNamesMap = fields.stream().collect(toImmutableMap(symbol -> symbol.toString().toLowerCase(), identity()));
    ImmutableMap<TreePath, Symbol> matchedParameters = MatchingParametersScanner.findMatchingParameters(fieldNamesMap, state.getPath());
    if (matchedParameters.isEmpty()) {
        return Description.NO_MATCH;
    }
    for (Entry<TreePath, Symbol> entry : matchedParameters.entrySet()) {
        TreePath parameterPath = entry.getKey();
        Symbol field = entry.getValue();
        String fieldName = field.getSimpleName().toString();
        VariableTree parameterTree = (VariableTree) parameterPath.getLeaf();
        SuggestedFix.Builder fix = SuggestedFix.builder().merge(SuggestedFixes.renameVariable(parameterTree, fieldName, state));
        if (parameterPath.getParentPath() != null) {
            String qualifiedName = getExplicitQualification(parameterPath, tree, state) + field.getSimpleName();
            // If the field was accessed in a non-qualified way, by renaming the parameter this may
            // cause clashes with it. Thus, it is required to qualify all uses of the field within the
            // parameter's scope just in case.
            parameterPath.getParentPath().getLeaf().accept(new TreeScanner<Void, Void>() {

                @Override
                public Void visitIdentifier(IdentifierTree tree, Void unused) {
                    if (field.equals(ASTHelpers.getSymbol(tree))) {
                        fix.replace(tree, qualifiedName);
                    }
                    return null;
                }
            }, null);
        }
        state.reportMatch(buildDescription(parameterPath.getLeaf()).setMessage(String.format("Found the field '%s' with the same name as the parameter '%s' but with " + "different capitalization.", fieldName, ((VariableTree) parameterPath.getLeaf()).getName())).addFix(fix.build()).build());
    }
    return Description.NO_MATCH;
}
Also used : SuggestedFixes(com.google.errorprone.fixes.SuggestedFixes) TreePath(com.sun.source.util.TreePath) ImmutableSet(com.google.common.collect.ImmutableSet) ElementKind(javax.lang.model.element.ElementKind) ImmutableMap(com.google.common.collect.ImmutableMap) ClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher) Symbol(com.sun.tools.javac.code.Symbol) VariableTree(com.sun.source.tree.VariableTree) TreeScanner(com.sun.source.util.TreeScanner) VisitorState(com.google.errorprone.VisitorState) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Description(com.google.errorprone.matchers.Description) IdentifierTree(com.sun.source.tree.IdentifierTree) Function.identity(java.util.function.Function.identity) Entry(java.util.Map.Entry) BugPattern(com.google.errorprone.BugPattern) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) ProvidesFix(com.google.errorprone.BugPattern.ProvidesFix) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) JDK(com.google.errorprone.BugPattern.Category.JDK) TreePathScanner(com.sun.source.util.TreePathScanner) Tree(com.sun.source.tree.Tree) ASTHelpers(com.google.errorprone.util.ASTHelpers) ClassTree(com.sun.source.tree.ClassTree) Symbol(com.sun.tools.javac.code.Symbol) VariableTree(com.sun.source.tree.VariableTree) IdentifierTree(com.sun.source.tree.IdentifierTree) TreePath(com.sun.source.util.TreePath) SuggestedFix(com.google.errorprone.fixes.SuggestedFix)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)86 Tree (com.sun.source.tree.Tree)43 ClassTree (com.sun.source.tree.ClassTree)37 MethodTree (com.sun.source.tree.MethodTree)37 ExpressionTree (com.sun.source.tree.ExpressionTree)34 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)25 NewClassTree (com.sun.source.tree.NewClassTree)23 TreePath (com.sun.source.util.TreePath)23 IdentifierTree (com.sun.source.tree.IdentifierTree)22 JCTree (com.sun.tools.javac.tree.JCTree)21 MemberSelectTree (com.sun.source.tree.MemberSelectTree)19 AssignmentTree (com.sun.source.tree.AssignmentTree)17 ArrayList (java.util.ArrayList)17 BlockTree (com.sun.source.tree.BlockTree)16 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)13 Type (com.sun.tools.javac.code.Type)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 ReturnTree (com.sun.source.tree.ReturnTree)12 StatementTree (com.sun.source.tree.StatementTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)12