Search in sources :

Example 1 with JCTry

use of com.sun.tools.javac.tree.JCTree.JCTry in project lombok by rzwitserloot.

the class HandleNonNull method handle.

@Override
public void handle(AnnotationValues<NonNull> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull");
    if (annotationNode.up().getKind() == Kind.FIELD) {
        try {
            if (isPrimitive(((JCVariableDecl) annotationNode.up().get()).vartype)) {
                annotationNode.addWarning("@NonNull is meaningless on a primitive.");
            }
        } catch (Exception ignore) {
        }
        return;
    }
    if (annotationNode.up().getKind() != Kind.ARGUMENT)
        return;
    JCMethodDecl declaration;
    try {
        declaration = (JCMethodDecl) annotationNode.up().up().get();
    } catch (Exception e) {
        return;
    }
    if (declaration.body == null) {
        // This used to be a warning, but as @NonNull also has a documentary purpose, better to not warn about this. Since 1.16.7
        return;
    }
    // Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter,
    // and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
    // wrap all references to it in the super/this to a call to this method.
    JCStatement nullCheck = recursiveSetGeneratedBy(generateNullCheck(annotationNode.getTreeMaker(), annotationNode.up(), annotationNode), ast, annotationNode.getContext());
    if (nullCheck == null) {
        // @NonNull applied to a primitive. Kinda pointless. Let's generate a warning.
        annotationNode.addWarning("@NonNull is meaningless on a primitive.");
        return;
    }
    List<JCStatement> statements = declaration.body.stats;
    String expectedName = annotationNode.up().getName();
    /* Abort if the null check is already there, delving into try and synchronized statements */
    {
        List<JCStatement> stats = statements;
        int idx = 0;
        while (stats.size() > idx) {
            JCStatement stat = stats.get(idx++);
            if (JavacHandlerUtil.isConstructorCall(stat))
                continue;
            if (stat instanceof JCTry) {
                stats = ((JCTry) stat).body.stats;
                idx = 0;
                continue;
            }
            if (stat instanceof JCSynchronized) {
                stats = ((JCSynchronized) stat).body.stats;
                idx = 0;
                continue;
            }
            String varNameOfNullCheck = returnVarNameIfNullCheck(stat);
            if (varNameOfNullCheck == null)
                break;
            if (varNameOfNullCheck.equals(expectedName))
                return;
        }
    }
    List<JCStatement> tail = statements;
    List<JCStatement> head = List.nil();
    for (JCStatement stat : statements) {
        if (JavacHandlerUtil.isConstructorCall(stat) || (JavacHandlerUtil.isGenerated(stat) && isNullCheck(stat))) {
            tail = tail.tail;
            head = head.prepend(stat);
            continue;
        }
        break;
    }
    List<JCStatement> newList = tail.prepend(nullCheck);
    for (JCStatement stat : head) newList = newList.prepend(stat);
    declaration.body.stats = newList;
    annotationNode.getAst().setChanged();
}
Also used : JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) List(com.sun.tools.javac.util.List) JCSynchronized(com.sun.tools.javac.tree.JCTree.JCSynchronized) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 2 with JCTry

use of com.sun.tools.javac.tree.JCTree.JCTry in project lombok by rzwitserloot.

the class HandleSneakyThrows method buildTryCatchBlock.

public JCStatement buildTryCatchBlock(JavacNode node, List<JCStatement> contents, String exception, JCTree source) {
    JavacTreeMaker maker = node.getTreeMaker();
    Context context = node.getContext();
    JCBlock tryBlock = setGeneratedBy(maker.Block(0, contents), source, context);
    JCExpression varType = chainDots(node, exception.split("\\."));
    JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER), node.toName("$ex"), varType, null);
    JCExpression lombokLombokSneakyThrowNameRef = chainDots(node, "lombok", "Lombok", "sneakyThrow");
    JCBlock catchBody = maker.Block(0, List.<JCStatement>of(maker.Throw(maker.Apply(List.<JCExpression>nil(), lombokLombokSneakyThrowNameRef, List.<JCExpression>of(maker.Ident(node.toName("$ex")))))));
    JCTry tryStatement = maker.Try(tryBlock, List.of(recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source, context)), null);
    if (JavacHandlerUtil.inNetbeansEditor(node)) {
        // set span (start and end position) of the try statement and the main block
        // this allows NetBeans to dive into the statement correctly:
        JCCompilationUnit top = (JCCompilationUnit) node.top().get();
        int startPos = contents.head.pos;
        int endPos = Javac.getEndPosition(contents.last().pos(), top);
        tryBlock.pos = startPos;
        tryStatement.pos = startPos;
        Javac.storeEnd(tryBlock, endPos, top);
        Javac.storeEnd(tryStatement, endPos, top);
    }
    return setGeneratedBy(tryStatement, source, context);
}
Also used : Context(com.sun.tools.javac.util.Context) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 3 with JCTry

use of com.sun.tools.javac.tree.JCTree.JCTry in project error-prone by google.

the class AssertionFailureIgnored method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!ASSERTION.matches(tree, state)) {
        return NO_MATCH;
    }
    JCTry tryStatement = enclosingTry(state);
    if (tryStatement == null) {
        return NO_MATCH;
    }
    Optional<JCCatch> maybeCatchTree = catchesType(tryStatement, state.getSymtab().assertionErrorType, state);
    if (!maybeCatchTree.isPresent()) {
        return NO_MATCH;
    }
    JCCatch catchTree = maybeCatchTree.get();
    VarSymbol parameter = ASTHelpers.getSymbol(catchTree.getParameter());
    boolean rethrows = firstNonNull(new TreeScanner<Boolean, Void>() {

        @Override
        public Boolean visitThrow(ThrowTree tree, Void unused) {
            if (Objects.equals(parameter, ASTHelpers.getSymbol(tree.getExpression()))) {
                return true;
            }
            if (NEW_THROWABLE.matches(tree.getExpression(), state) && ((NewClassTree) tree.getExpression()).getArguments().stream().anyMatch(arg -> Objects.equals(parameter, ASTHelpers.getSymbol(arg)))) {
                return true;
            }
            return super.visitThrow(tree, null);
        }

        @Override
        public Boolean reduce(Boolean a, Boolean b) {
            return firstNonNull(a, false) || firstNonNull(b, false);
        }
    }.scan(catchTree.getBlock(), null), false);
    if (rethrows) {
        return NO_MATCH;
    }
    Description.Builder description = buildDescription(tree);
    buildFix(tryStatement, tree, state).ifPresent(description::addFix);
    return description.build();
}
Also used : Iterables(com.google.common.collect.Iterables) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) TypePredicates(com.google.errorprone.predicates.TypePredicates) 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) NewClassTree(com.sun.source.tree.NewClassTree) LIKELY_ERROR(com.google.errorprone.BugPattern.StandardTags.LIKELY_ERROR) BugPattern(com.google.errorprone.BugPattern) JDK(com.google.errorprone.BugPattern.Category.JDK) Matcher(com.google.errorprone.matchers.Matcher) Fix(com.google.errorprone.fixes.Fix) Tree(com.sun.source.tree.Tree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) MethodInvocationTreeMatcher(com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ExpressionTree(com.sun.source.tree.ExpressionTree) Iterables.getLast(com.google.common.collect.Iterables.getLast) NO_MATCH(com.google.errorprone.matchers.Description.NO_MATCH) Streams(com.google.common.collect.Streams) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch) TreeScanner(com.sun.source.util.TreeScanner) Objects(java.util.Objects) ThrowTree(com.sun.source.tree.ThrowTree) MethodMatchers.staticMethod(com.google.errorprone.matchers.method.MethodMatchers.staticMethod) Stream(java.util.stream.Stream) Description(com.google.errorprone.matchers.Description) MethodMatchers(com.google.errorprone.matchers.method.MethodMatchers) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) Optional(java.util.Optional) MoreObjects.firstNonNull(com.google.common.base.MoreObjects.firstNonNull) WARNING(com.google.errorprone.BugPattern.SeverityLevel.WARNING) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ASTHelpers.isSubtype(com.google.errorprone.util.ASTHelpers.isSubtype) Pattern(java.util.regex.Pattern) ASTHelpers(com.google.errorprone.util.ASTHelpers) Type(com.sun.tools.javac.code.Type) Description(com.google.errorprone.matchers.Description) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) TreeScanner(com.sun.source.util.TreeScanner) ThrowTree(com.sun.source.tree.ThrowTree) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch)

Example 4 with JCTry

use of com.sun.tools.javac.tree.JCTree.JCTry in project ceylon-compiler by ceylon.

the class StatementTransformer method transform.

public JCStatement transform(Tree.TryCatchStatement t) {
    Tree.TryClause tryClause = t.getTryClause();
    at(tryClause);
    JCBlock tryBlock = transform(tryClause.getBlock());
    Tree.ResourceList resList = tryClause.getResourceList();
    if (resList != null) {
        ArrayList<Tree.Resource> resources = new ArrayList<Tree.Resource>(resList.getResources());
        Collections.reverse(resources);
        for (Tree.Resource res : resources) {
            List<JCStatement> stats = List.nil();
            Tree.Expression resExpr;
            String resVarName;
            if (res.getExpression() != null) {
                resExpr = res.getExpression();
                resVarName = naming.newTemp("try");
            } else if (res.getVariable() != null) {
                Tree.Variable var = res.getVariable();
                resExpr = var.getSpecifierExpression().getExpression();
                resVarName = var.getIdentifier().getText();
            } else {
                throw new BugException(res, "missing resource expression");
            }
            boolean isDestroyable = typeFact().getDestroyableType().isSupertypeOf(resExpr.getTypeModel());
            Type resVarType = resExpr.getTypeModel();
            Type resVarExpectedType = isDestroyable ? typeFact().getDestroyableType() : typeFact().getObtainableType();
            // CloseableType $var = resource-expression
            JCExpression expr = expressionGen().transformExpression(resExpr);
            JCExpression javaType = makeJavaType(resVarType);
            JCVariableDecl var = makeVar(FINAL, resVarName, javaType, expr);
            stats = stats.append(var);
            if (!isDestroyable) {
                JCExpression resVar0 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
                JCMethodInvocation openCall = make().Apply(null, makeQualIdent(resVar0, "obtain"), List.<JCExpression>nil());
                stats = stats.append(make().Exec(openCall));
            }
            // Exception $tpmex = null;
            String innerExTmpVarName = naming.newTemp("ex");
            JCExpression innerExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerExTmpVar = makeVar(innerExTmpVarName, innerExType, makeNull());
            stats = stats.append(innerExTmpVar);
            // $tmpex = ex;
            List<JCStatement> innerCatchStats = List.nil();
            Name innerCatchVarName = naming.tempName("ex");
            JCAssign exTmpAssign = make().Assign(makeUnquotedIdent(innerExTmpVarName), make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(make().Exec(exTmpAssign));
            // throw ex;
            JCThrow innerCatchThrow = make().Throw(make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(innerCatchThrow);
            JCBlock innerCatchBlock = make().Block(0, innerCatchStats);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar1 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCMethodInvocation closeCall = make().Apply(null, makeQualIdent(resVar1, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg));
            JCBlock closeTryBlock = make().Block(0, List.<JCStatement>of(make().Exec(closeCall)));
            // try { $var.close() } catch (Exception closex) { $tmpex.addSuppressed(closex); }
            Name closeCatchVarName = naming.tempName("closex");
            JCExpression closeCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl closeCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), closeCatchVarName, closeCatchExType, null);
            JCExpression addarg = make().Ident(closeCatchVarName);
            JCMethodInvocation addSuppressedCall = make().Apply(null, makeQualIdent(makeUnquotedIdent(innerExTmpVarName), "addSuppressed"), List.<JCExpression>of(addarg));
            JCCatch closeCatch = make().Catch(closeCatchVar, make().Block(0, List.<JCStatement>of(make().Exec(addSuppressedCall))));
            JCTry closeTry = at(res).Try(closeTryBlock, List.<JCCatch>of(closeCatch), null);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg2 = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar2 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCMethodInvocation closeCall2 = make().Apply(null, makeQualIdent(resVar2, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg2));
            // if ($tmpex != null) { ... } else { ... }
            JCBinary closeCatchCond = make().Binary(JCTree.NE, makeUnquotedIdent(innerExTmpVarName), makeNull());
            JCIf closeCatchIf = make().If(closeCatchCond, closeTry, make().Exec(closeCall2));
            // try { .... } catch (Exception ex) { $tmpex=ex; throw ex; }
            // finally { try { $var.close() } catch (Exception closex) { } }
            JCExpression innerCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), innerCatchVarName, innerCatchExType, null);
            JCCatch innerCatch = make().Catch(innerCatchVar, innerCatchBlock);
            JCBlock innerFinallyBlock = make().Block(0, List.<JCStatement>of(closeCatchIf));
            JCTry innerTry = at(res).Try(tryBlock, List.<JCCatch>of(innerCatch), innerFinallyBlock);
            stats = stats.append(innerTry);
            tryBlock = at(res).Block(0, stats);
        }
    }
    final List<JCCatch> catches;
    if (usePolymorphicCatches(t.getCatchClauses())) {
        catches = transformCatchesPolymorphic(t.getCatchClauses());
    } else {
        catches = transformCatchesIfElseIf(t.getCatchClauses());
    }
    final JCBlock finallyBlock;
    Tree.FinallyClause finallyClause = t.getFinallyClause();
    if (finallyClause != null) {
        at(finallyClause);
        finallyBlock = transform(finallyClause.getBlock());
    } else {
        finallyBlock = null;
    }
    if (!catches.isEmpty() || finallyBlock != null) {
        return at(t).Try(tryBlock, catches, finallyBlock);
    } else {
        return tryBlock;
    }
}
Also used : Variable(com.redhat.ceylon.compiler.typechecker.tree.Tree.Variable) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ArrayList(java.util.ArrayList) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) CName(com.redhat.ceylon.compiler.java.codegen.Naming.CName) Name(com.sun.tools.javac.util.Name) OptionName(com.sun.tools.javac.main.OptionName) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) JCThrow(com.sun.tools.javac.tree.JCTree.JCThrow) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch)

Example 5 with JCTry

use of com.sun.tools.javac.tree.JCTree.JCTry in project error-prone by google.

the class Template method pretty.

protected static Pretty pretty(Context context, final Writer writer) {
    final JCCompilationUnit unit = context.get(JCCompilationUnit.class);
    try {
        final String unitContents = unit.getSourceFile().getCharContent(false).toString();
        return new Pretty(writer, true) {

            {
                // Work-around for b/22196513
                width = 0;
            }

            @Override
            public void visitAnnotation(JCAnnotation anno) {
                if (anno.getArguments().isEmpty()) {
                    try {
                        print("@");
                        printExpr(anno.annotationType);
                    } catch (IOException e) {
                        // the supertype swallows exceptions too
                        throw new RuntimeException(e);
                    }
                } else {
                    super.visitAnnotation(anno);
                }
            }

            @Override
            public void printExpr(JCTree tree, int prec) throws IOException {
                EndPosTable endPositions = unit.endPositions;
                /*
           * Modifiers, and specifically flags like final, appear to just need weird special
           * handling.
           *
           * Note: we can't use {@code TreeInfo.getEndPos()} or {@code JCTree.getEndPosition()}
           * here, because they will return the end position of an enclosing AST node for trees
           * whose real end positions aren't stored.
           */
                int endPos = endPositions.getEndPos(tree);
                boolean hasRealEndPosition = endPos != Position.NOPOS;
                if (tree.getKind() != Kind.MODIFIERS && hasRealEndPosition) {
                    writer.append(unitContents.substring(tree.getStartPosition(), endPos));
                } else {
                    super.printExpr(tree, prec);
                }
            }

            @Override
            public void visitApply(JCMethodInvocation tree) {
                JCExpression select = tree.getMethodSelect();
                if (select != null && select.toString().equals("Refaster.emitCommentBefore")) {
                    String commentLiteral = (String) ((JCLiteral) tree.getArguments().get(0)).getValue();
                    JCExpression expr = tree.getArguments().get(1);
                    try {
                        print("/* " + commentLiteral + " */ ");
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    expr.accept(this);
                } else {
                    super.visitApply(tree);
                }
            }

            @Override
            public void printStat(JCTree tree) throws IOException {
                if (tree instanceof JCExpressionStatement && ((JCExpressionStatement) tree).getExpression() instanceof JCMethodInvocation) {
                    JCMethodInvocation invocation = (JCMethodInvocation) ((JCExpressionStatement) tree).getExpression();
                    JCExpression select = invocation.getMethodSelect();
                    if (select != null && select.toString().equals("Refaster.emitComment")) {
                        String commentLiteral = (String) ((JCLiteral) invocation.getArguments().get(0)).getValue();
                        print("// " + commentLiteral);
                        return;
                    }
                }
                super.printStat(tree);
            }

            @Override
            public void visitTry(JCTry tree) {
                if (tree.getResources().isEmpty()) {
                    super.visitTry(tree);
                    return;
                }
                try {
                    print("try (");
                    boolean first = true;
                    for (JCTree resource : tree.getResources()) {
                        if (!first) {
                            print(";");
                            println();
                        }
                        printExpr(resource);
                        first = false;
                    }
                    print(")");
                    printStat(tree.body);
                    for (JCCatch catchStmt : tree.getCatches()) {
                        printStat(catchStmt);
                    }
                    if (tree.getFinallyBlock() != null) {
                        print(" finally ");
                        printStat(tree.getFinallyBlock());
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) JCTree(com.sun.tools.javac.tree.JCTree) IOException(java.io.IOException) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) Pretty(com.sun.tools.javac.tree.Pretty) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) EndPosTable(com.sun.tools.javac.tree.EndPosTable)

Aggregations

JCTry (com.sun.tools.javac.tree.JCTree.JCTry)6 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)4 JCCatch (com.sun.tools.javac.tree.JCTree.JCCatch)4 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)3 JCTree (com.sun.tools.javac.tree.JCTree)2 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)2 JCCompilationUnit (com.sun.tools.javac.tree.JCTree.JCCompilationUnit)2 JCExpressionStatement (com.sun.tools.javac.tree.JCTree.JCExpressionStatement)2 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)2 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)2 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)2 Pretty (com.sun.tools.javac.tree.Pretty)2 IOException (java.io.IOException)2 MoreObjects.firstNonNull (com.google.common.base.MoreObjects.firstNonNull)1 Iterables (com.google.common.collect.Iterables)1 Iterables.getLast (com.google.common.collect.Iterables.getLast)1 Streams (com.google.common.collect.Streams)1 BugPattern (com.google.errorprone.BugPattern)1 JDK (com.google.errorprone.BugPattern.Category.JDK)1 WARNING (com.google.errorprone.BugPattern.SeverityLevel.WARNING)1