Search in sources :

Example 26 with ClassTree

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

the class NullnessPropagationTransfer method fieldInitializerNullnessIfAvailable.

@Nullable
private Nullness fieldInitializerNullnessIfAvailable(ClassAndField accessed) {
    if (!traversed.add(accessed.symbol)) {
        // TODO(kmb): Try to recognize problems with initialization order
        return NULL;
    }
    try {
        JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
        TreePath fieldDeclPath = Trees.instance(javacEnv).getPath(accessed.symbol);
        // missing types.
        if (fieldDeclPath == null || fieldDeclPath.getCompilationUnit() != compilationUnit || !(fieldDeclPath.getLeaf() instanceof VariableTree)) {
            return null;
        }
        ExpressionTree initializer = ((VariableTree) fieldDeclPath.getLeaf()).getInitializer();
        if (initializer == null) {
            return null;
        }
        ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
        // Run flow analysis on field initializer.  This is inefficient compared to just walking
        // the initializer expression tree but it avoids duplicating the logic from this transfer
        // function into a method that operates on Javac Nodes.
        TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
        UnderlyingAST ast = new UnderlyingAST.CFGStatement(initializerPath.getLeaf(), classTree);
        ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
        false, /* assumeAssertionsDisabled */
        false);
        Analysis<Nullness, LocalStore<Nullness>, NullnessPropagationTransfer> analysis = new Analysis<>(javacEnv, this);
        analysis.performAnalysis(cfg);
        return analysis.getValue(initializerPath.getLeaf());
    } finally {
        traversed.remove(accessed.symbol);
    }
}
Also used : VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) LocalStore(com.google.errorprone.dataflow.LocalStore) TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) ExpressionTree(com.sun.source.tree.ExpressionTree) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Nullable(javax.annotation.Nullable)

Example 27 with ClassTree

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

the class TrustingNullnessAnalysis method getFieldInitializerNullness.

/**
 * Returns {@link Nullness} of the initializer of the {@link VariableTree} at the leaf of the
 * given {@code fieldDeclPath}. Returns {@link Nullness#NULL} should there be no initializer.
 */
// TODO(kmb): Fold this functionality into Dataflow.expressionDataflow
public Nullness getFieldInitializerNullness(TreePath fieldDeclPath, Context context) {
    Tree decl = fieldDeclPath.getLeaf();
    checkArgument(decl instanceof VariableTree && ((JCVariableDecl) decl).sym.getKind() == ElementKind.FIELD, "Leaf of fieldDeclPath must be a field declaration: %s", decl);
    ExpressionTree initializer = ((VariableTree) decl).getInitializer();
    if (initializer == null) {
        // An uninitialized field is null or 0 to start :)
        return ((JCVariableDecl) decl).type.isPrimitive() ? Nullness.NONNULL : Nullness.NULL;
    }
    TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
    ClassTree classTree = (ClassTree) fieldDeclPath.getParentPath().getLeaf();
    JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
    UnderlyingAST ast = new UnderlyingAST.CFGStatement(decl, classTree);
    ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
    false, /* assumeAssertionsDisabled */
    false);
    try {
        nullnessPropagation.setContext(context).setCompilationUnit(fieldDeclPath.getCompilationUnit());
        Analysis<Nullness, LocalStore<Nullness>, TrustingNullnessPropagation> analysis = new Analysis<>(javacEnv, nullnessPropagation);
        analysis.performAnalysis(cfg);
        return analysis.getValue(initializer);
    } finally {
        nullnessPropagation.setContext(null).setCompilationUnit(null);
    }
}
Also used : VariableTree(com.sun.source.tree.VariableTree) ClassTree(com.sun.source.tree.ClassTree) LocalStore(com.google.errorprone.dataflow.LocalStore) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) ExpressionTree(com.sun.source.tree.ExpressionTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Example 28 with ClassTree

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

the class DataFlow method findEnclosingMethodOrLambdaOrInitializer.

// TODO(user), remove once we merge jdk8 specific's with core
private static <T> TreePath findEnclosingMethodOrLambdaOrInitializer(TreePath path) {
    while (path != null) {
        if (path.getLeaf() instanceof MethodTree) {
            return path;
        }
        TreePath parent = path.getParentPath();
        if (parent != null) {
            if (parent.getLeaf() instanceof ClassTree) {
                if (path.getLeaf() instanceof BlockTree) {
                    // this is a class or instance initializer block
                    return path;
                }
                if (path.getLeaf() instanceof VariableTree && ((VariableTree) path.getLeaf()).getInitializer() != null) {
                    // this is a field with an inline initializer
                    return path;
                }
            }
            if (parent.getLeaf() instanceof LambdaExpressionTree) {
                return parent;
            }
        }
        path = parent;
    }
    return null;
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree) BlockTree(com.sun.source.tree.BlockTree)

Example 29 with ClassTree

use of com.sun.source.tree.ClassTree 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)

Example 30 with ClassTree

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

the class DoubleBraceInitialization method matchNewClass.

@Override
public Description matchNewClass(NewClassTree tree, VisitorState state) {
    ClassTree body = tree.getClassBody();
    if (body == null) {
        return NO_MATCH;
    }
    ImmutableList<? extends Tree> members = body.getMembers().stream().filter(m -> !(m instanceof MethodTree && ASTHelpers.isGeneratedConstructor((MethodTree) m))).collect(toImmutableList());
    if (members.size() != 1) {
        return NO_MATCH;
    }
    Tree member = Iterables.getOnlyElement(members);
    if (!(member instanceof BlockTree)) {
        return NO_MATCH;
    }
    BlockTree block = (BlockTree) member;
    Optional<CollectionTypes> collectionType = Stream.of(CollectionTypes.values()).filter(type -> type.constructorMatcher.matches(tree, state)).findFirst();
    if (!collectionType.isPresent()) {
        return NO_MATCH;
    }
    Description.Builder description = buildDescription(tree);
    collectionType.get().maybeFix(tree, state, block).ifPresent(description::addFix);
    return description.build();
}
Also used : Iterables(com.google.common.collect.Iterables) MethodTree(com.sun.source.tree.MethodTree) Modifier(javax.lang.model.element.Modifier) MethodMatchers.instanceMethod(com.google.errorprone.matchers.method.MethodMatchers.instanceMethod) VariableTree(com.sun.source.tree.VariableTree) NewClassTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.NewClassTreeMatcher) TypePredicates.isDescendantOf(com.google.errorprone.predicates.TypePredicates.isDescendantOf) ArrayList(java.util.ArrayList) MethodMatchers.constructor(com.google.errorprone.matchers.method.MethodMatchers.constructor) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Matchers.expressionStatement(com.google.errorprone.matchers.Matchers.expressionStatement) Kind(com.sun.source.tree.Tree.Kind) ImmutableList(com.google.common.collect.ImmutableList) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) BugPattern(com.google.errorprone.BugPattern) Matcher(com.google.errorprone.matchers.Matcher) Fix(com.google.errorprone.fixes.Fix) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ElementKind(javax.lang.model.element.ElementKind) ExpressionTree(com.sun.source.tree.ExpressionTree) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Collection(java.util.Collection) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) Collectors.joining(java.util.stream.Collectors.joining) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) List(java.util.List) Stream(java.util.stream.Stream) Matchers(com.google.errorprone.matchers.Matchers) Description(com.google.errorprone.matchers.Description) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) MethodMatchers(com.google.errorprone.matchers.method.MethodMatchers) Optional(java.util.Optional) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ASTHelpers(com.google.errorprone.util.ASTHelpers) Description(com.google.errorprone.matchers.Description) MethodTree(com.sun.source.tree.MethodTree) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) BlockTree(com.sun.source.tree.BlockTree)

Aggregations

ClassTree (com.sun.source.tree.ClassTree)119 Tree (com.sun.source.tree.Tree)76 MethodTree (com.sun.source.tree.MethodTree)66 VariableTree (com.sun.source.tree.VariableTree)59 NewClassTree (com.sun.source.tree.NewClassTree)48 ExpressionTree (com.sun.source.tree.ExpressionTree)45 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)40 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)31 AnnotationTree (com.sun.source.tree.AnnotationTree)29 BlockTree (com.sun.source.tree.BlockTree)28 IdentifierTree (com.sun.source.tree.IdentifierTree)27 NewArrayTree (com.sun.source.tree.NewArrayTree)26 AssignmentTree (com.sun.source.tree.AssignmentTree)25 MemberSelectTree (com.sun.source.tree.MemberSelectTree)25 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)24 TypeElement (javax.lang.model.element.TypeElement)24 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)23 ArrayList (java.util.ArrayList)23 ReturnTree (com.sun.source.tree.ReturnTree)22 TreePath (com.sun.source.util.TreePath)22