Search in sources :

Example 16 with VisitorState

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

the class RefasterRuleBuilderScanner method visitMethod.

@Override
public Void visitMethod(MethodTree tree, Void v) {
    try {
        VisitorState state = new VisitorState(context);
        logger.log(FINE, "Discovered method with name {0}", tree.getName());
        if (ASTHelpers.hasAnnotation(tree, Placeholder.class, state)) {
            checkArgument(tree.getModifiers().getFlags().contains(Modifier.ABSTRACT), "@Placeholder methods are expected to be abstract");
            UTemplater templater = new UTemplater(context);
            ImmutableMap.Builder<UVariableDecl, ImmutableClassToInstanceMap<Annotation>> params = ImmutableMap.builder();
            for (VariableTree param : tree.getParameters()) {
                params.put(templater.visitVariable(param, null), UTemplater.annotationMap(ASTHelpers.getSymbol(param)));
            }
            MethodSymbol sym = ASTHelpers.getSymbol(tree);
            placeholderMethods.put(sym, PlaceholderMethod.create(tree.getName(), templater.template(sym.getReturnType()), params.build(), UTemplater.annotationMap(sym)));
        } else if (ASTHelpers.hasAnnotation(tree, BeforeTemplate.class, state)) {
            checkState(afterTemplates.isEmpty(), "BeforeTemplate must come before AfterTemplate");
            Template<?> template = UTemplater.createTemplate(context, tree);
            beforeTemplates.add(template);
            if (template instanceof BlockTemplate) {
                context.put(UTemplater.REQUIRE_BLOCK_KEY, true);
            }
        } else if (ASTHelpers.hasAnnotation(tree, AfterTemplate.class, state)) {
            afterTemplates.add(UTemplater.createTemplate(context, tree));
        } else if (tree.getModifiers().getFlags().contains(Modifier.ABSTRACT)) {
            throw new IllegalArgumentException("Placeholder methods must have @Placeholder, but abstract method does not: " + tree);
        }
        return null;
    } catch (Throwable t) {
        throw new RuntimeException("Error analysing: " + tree.getName(), t);
    }
}
Also used : BeforeTemplate(com.google.errorprone.refaster.annotation.BeforeTemplate) ImmutableClassToInstanceMap(com.google.common.collect.ImmutableClassToInstanceMap) VariableTree(com.sun.source.tree.VariableTree) ImmutableMap(com.google.common.collect.ImmutableMap) BeforeTemplate(com.google.errorprone.refaster.annotation.BeforeTemplate) AfterTemplate(com.google.errorprone.refaster.annotation.AfterTemplate) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) VisitorState(com.google.errorprone.VisitorState)

Example 17 with VisitorState

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

the class UMatches method makeVisitorState.

static VisitorState makeVisitorState(Tree target, Unifier unifier) {
    Context context = unifier.getContext();
    TreePath path = TreePath.getPath(context.get(JCCompilationUnit.class), target);
    return new VisitorState(context).withPath(path);
}
Also used : Context(com.sun.tools.javac.util.Context) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) TreePath(com.sun.source.util.TreePath) VisitorState(com.google.errorprone.VisitorState)

Example 18 with VisitorState

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

the class FindIdentifiers method findAllIdents.

/**
   * Finds the set of all bare variable identifiers in scope at the current location. Identifiers
   * are ordered by ascending distance/scope count from the current location to match shadowing
   * rules. That is, if two variables with the same simple names appear in the set, the one that
   * appears first in iteration order is the one you get if you use the bare name in the source
   * code.
   *
   * <p>We do not report variables that would require a qualfied access. We also do not handle
   * wildcard imports.
   */
public static LinkedHashSet<VarSymbol> findAllIdents(VisitorState state) {
    ImmutableSet.Builder<VarSymbol> result = new ImmutableSet.Builder<>();
    Tree prev = state.getPath().getLeaf();
    for (Tree curr : state.getPath().getParentPath()) {
        switch(curr.getKind()) {
            case BLOCK:
                for (StatementTree stmt : ((BlockTree) curr).getStatements()) {
                    if (stmt.equals(prev)) {
                        break;
                    }
                    addIfVariable(stmt, result);
                }
                break;
            case METHOD:
                for (VariableTree param : ((MethodTree) curr).getParameters()) {
                    result.add(ASTHelpers.getSymbol(param));
                }
                break;
            case CATCH:
                result.add(ASTHelpers.getSymbol(((CatchTree) curr).getParameter()));
                break;
            case CLASS:
            case INTERFACE:
            case ENUM:
            case ANNOTATION_TYPE:
                // field is referred to by qualified name, but we don't support that.
                for (Tree member : ((ClassTree) curr).getMembers()) {
                    if (member.equals(prev)) {
                        break;
                    }
                    addIfVariable(member, result);
                }
                // Collect inherited fields.
                Type classType = ASTHelpers.getType(curr);
                com.sun.tools.javac.util.List<Type> superTypes = state.getTypes().closure(classType).tail;
                for (Type type : superTypes) {
                    Scope scope = type.tsym.members();
                    ImmutableList.Builder<VarSymbol> varsList = new ImmutableList.Builder<VarSymbol>();
                    for (Symbol var : scope.getSymbols(VarSymbol.class::isInstance)) {
                        varsList.add((VarSymbol) var);
                    }
                    result.addAll(varsList.build().reverse());
                }
                break;
            case FOR_LOOP:
                addAllIfVariable(((ForLoopTree) curr).getInitializer(), result);
                break;
            case ENHANCED_FOR_LOOP:
                result.add(ASTHelpers.getSymbol(((EnhancedForLoopTree) curr).getVariable()));
                break;
            case TRY:
                TryTree tryTree = (TryTree) curr;
                boolean inResources = false;
                for (Tree resource : tryTree.getResources()) {
                    if (resource.equals(prev)) {
                        inResources = true;
                        break;
                    }
                }
                if (inResources) {
                    // Case 1: we're in one of the resource declarations
                    for (Tree resource : tryTree.getResources()) {
                        if (resource.equals(prev)) {
                            break;
                        }
                        addIfVariable(resource, result);
                    }
                } else if (tryTree.getBlock().equals(prev)) {
                    // Case 2: We're in the block (not a catch or finally)
                    addAllIfVariable(tryTree.getResources(), result);
                }
                break;
            case COMPILATION_UNIT:
                for (ImportTree importTree : ((CompilationUnitTree) curr).getImports()) {
                    if (importTree.isStatic() && importTree.getQualifiedIdentifier().getKind() == Kind.MEMBER_SELECT) {
                        MemberSelectTree memberSelectTree = (MemberSelectTree) importTree.getQualifiedIdentifier();
                        Scope scope = state.getTypes().membersClosure(ASTHelpers.getType(memberSelectTree.getExpression()), /*skipInterface*/
                        false);
                        for (Symbol var : scope.getSymbols(sym -> sym instanceof VarSymbol && sym.getSimpleName().equals(memberSelectTree.getIdentifier()))) {
                            result.add((VarSymbol) var);
                        }
                    }
                }
                break;
            default:
                // other node types don't introduce variables
                break;
        }
        prev = curr;
    }
    // TODO(eaftan): switch out collector for ImmutableSet.toImmutableSet()
    return result.build().stream().filter(var -> isVisible(var, state.getPath())).collect(Collectors.toCollection(LinkedHashSet::new));
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Modifier(javax.lang.model.element.Modifier) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) Method(java.lang.reflect.Method) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TreePath(com.sun.source.util.TreePath) ImmutableSet(com.google.common.collect.ImmutableSet) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) MemberSelectTree(com.sun.source.tree.MemberSelectTree) Env(com.sun.tools.javac.comp.Env) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) List(java.util.List) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) Flags(com.sun.tools.javac.code.Flags) Name(com.sun.tools.javac.util.Name) Scope(com.sun.tools.javac.code.Scope) Type(com.sun.tools.javac.code.Type) MethodTree(com.sun.source.tree.MethodTree) MemberEnter(com.sun.tools.javac.comp.MemberEnter) VariableTree(com.sun.source.tree.VariableTree) AttrContext(com.sun.tools.javac.comp.AttrContext) ArrayList(java.util.ArrayList) VisitorState(com.google.errorprone.VisitorState) BiPredicate(java.util.function.BiPredicate) Kind(com.sun.source.tree.Tree.Kind) ImmutableList(com.google.common.collect.ImmutableList) NewClassTree(com.sun.source.tree.NewClassTree) StreamSupport(java.util.stream.StreamSupport) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Enter(com.sun.tools.javac.comp.Enter) ElementKind(javax.lang.model.element.ElementKind) KindSelector(com.sun.tools.javac.code.Kinds.KindSelector) TryTree(com.sun.source.tree.TryTree) Resolve(com.sun.tools.javac.comp.Resolve) MethodTree(com.sun.source.tree.MethodTree) CatchTree(com.sun.source.tree.CatchTree) ImmutableList(com.google.common.collect.ImmutableList) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) MemberSelectTree(com.sun.source.tree.MemberSelectTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) StatementTree(com.sun.source.tree.StatementTree) ImmutableSet(com.google.common.collect.ImmutableSet) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) ForLoopTree(com.sun.source.tree.ForLoopTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TryTree(com.sun.source.tree.TryTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) Type(com.sun.tools.javac.code.Type) WriteableScope(com.sun.tools.javac.code.Scope.WriteableScope) Scope(com.sun.tools.javac.code.Scope) TryTree(com.sun.source.tree.TryTree) ImportTree(com.sun.source.tree.ImportTree)

Example 19 with VisitorState

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

the class Matchers method inLoop.

/**
   * Matches if the given tree is inside a loop.
   */
public static <T extends Tree> Matcher<T> inLoop() {
    return new Matcher<T>() {

        @Override
        public boolean matches(Tree tree, VisitorState state) {
            TreePath path = state.getPath().getParentPath();
            Tree node = path.getLeaf();
            while (path != null) {
                switch(node.getKind()) {
                    case METHOD:
                    case CLASS:
                        return false;
                    case WHILE_LOOP:
                    case FOR_LOOP:
                    case ENHANCED_FOR_LOOP:
                    case DO_WHILE_LOOP:
                        return true;
                    default:
                        path = path.getParentPath();
                        node = path.getLeaf();
                        break;
                }
            }
            return false;
        }
    };
}
Also used : TreePath(com.sun.source.util.TreePath) InstanceMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.InstanceMethodMatcher) AnyMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.AnyMethodMatcher) StaticMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.StaticMethodMatcher) ConstructorMatcher(com.google.errorprone.matchers.method.MethodMatchers.ConstructorMatcher) VisitorState(com.google.errorprone.VisitorState) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ContinueTree(com.sun.source.tree.ContinueTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 20 with VisitorState

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

the class Matchers method inSynchronized.

/**
   * Matches if this Tree is enclosed by either a synchronized block or a synchronized method.
   */
public static final <T extends Tree> Matcher<T> inSynchronized() {
    return new Matcher<T>() {

        @Override
        public boolean matches(T tree, VisitorState state) {
            SynchronizedTree synchronizedTree = ASTHelpers.findEnclosingNode(state.getPath(), SynchronizedTree.class);
            if (synchronizedTree != null) {
                return true;
            }
            MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
            return methodTree != null && methodTree.getModifiers().getFlags().contains(Modifier.SYNCHRONIZED);
        }
    };
}
Also used : SynchronizedTree(com.sun.source.tree.SynchronizedTree) InstanceMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.InstanceMethodMatcher) AnyMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.AnyMethodMatcher) StaticMethodMatcher(com.google.errorprone.matchers.method.MethodMatchers.StaticMethodMatcher) ConstructorMatcher(com.google.errorprone.matchers.method.MethodMatchers.ConstructorMatcher) VisitorState(com.google.errorprone.VisitorState) MethodTree(com.sun.source.tree.MethodTree)

Aggregations

VisitorState (com.google.errorprone.VisitorState)29 MethodTree (com.sun.source.tree.MethodTree)13 Tree (com.sun.source.tree.Tree)13 ExpressionTree (com.sun.source.tree.ExpressionTree)12 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)11 ClassTree (com.sun.source.tree.ClassTree)10 Symbol (com.sun.tools.javac.code.Symbol)9 Type (com.sun.tools.javac.code.Type)9 Description (com.google.errorprone.matchers.Description)8 IdentifierTree (com.sun.source.tree.IdentifierTree)8 VariableTree (com.sun.source.tree.VariableTree)8 JCTree (com.sun.tools.javac.tree.JCTree)8 List (java.util.List)8 BugPattern (com.google.errorprone.BugPattern)7 ASTHelpers (com.google.errorprone.util.ASTHelpers)7 TreePath (com.sun.source.util.TreePath)7 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)7 ArrayList (java.util.ArrayList)7 JDK (com.google.errorprone.BugPattern.Category.JDK)6 MemberSelectTree (com.sun.source.tree.MemberSelectTree)6