private static CatchTree getOnlyCatch(TryTree tryTree) { return tryTree.getCatches().get(0); } }
@Override protected MatchResult matchAncestor(Tree tree, Tree prevTree) { if (tree instanceof TryTree) { TryTree tryTree = (TryTree) tree; if (tryTree.getBlock().equals(prevTree) && !tryTree.getCatches().isEmpty()) { // The current ancestor is a try block with associated catch blocks. return MatchResult.NO_MATCH; } } return super.matchAncestor(tree, prevTree); } }
private boolean hasToleratedException(TryTree tree) { for (CatchTree catchTree : tree.getCatches()) { if (catchTree.getParameter().getName().contentEquals("tolerated")) { return true; } } return false; }
private boolean hasExpectedException(TryTree tree) { for (CatchTree catchTree : tree.getCatches()) { if (catchTree.getParameter().getName().contentEquals("expected")) { return true; } } return false; }
private boolean anyCatchBlockMatches(TryTree tree, VisitorState state, Matcher<Tree> matcher) { for (CatchTree catchTree : tree.getCatches()) { if (matcher.matches(catchTree.getBlock(), state)) { return true; } } return false; }
private boolean isInapplicableExceptionType(TryTree tree, VisitorState state) { for (CatchTree catchTree : tree.getCatches()) { if (INAPPLICABLE_EXCEPTION.matches(catchTree.getParameter(), state)) { return true; } } return false; }
/** * Returns a string describing the exception type caught by the given try tree's catch * statement(s), defaulting to {@code "Exception"} if more than one exception type is caught. */ private static String exceptionToString(TryTree tree, VisitorState state) { if (tree.getCatches().size() != 1) { return "Exception"; } Tree exceptionType = tree.getCatches().iterator().next().getParameter().getType(); Type type = ASTHelpers.getType(exceptionType); if (type != null && type.isUnion()) { return "Exception"; } return state.getSourceForNode(exceptionType); }
@Override public Description matchTry(TryTree tree, VisitorState state) { if (tree.getCatches().isEmpty()) { return NO_MATCH; } // Find catch blocks that contain only a call to fail, and that ignore the caught exception. ImmutableList<CatchTree> catchBlocks = tree.getCatches().stream() .filter( c -> c.getBlock().getStatements().size() == 1 && FAIL_METHOD.matches(getOnlyElement(c.getBlock().getStatements()), state)) .filter(c -> !catchVariableIsUsed(c)) .collect(toImmutableList()); if (catchBlocks.isEmpty()) { return NO_MATCH; } Description.Builder description = buildDescription(tree); rethrowFix(catchBlocks, state).ifPresent(description::addFix); deleteFix(tree, catchBlocks, state).ifPresent(description::addFix); return description.build(); }
@Override public Description matchTry(TryTree tree, VisitorState state) { List<? extends StatementTree> body = tree.getBlock().getStatements(); if (body.isEmpty() || tree.getFinallyBlock() != null || tree.getCatches().size() != 1) { // TODO(cushon): support finally // TODO(cushon): support multiple catch blocks return NO_MATCH; } CatchTree catchTree = getOnlyElement(tree.getCatches()); if (catchTree.getParameter().getType().getKind() == UNION_TYPE) { // TODO(cushon): handle multi-catch return NO_MATCH; } if (!FAIL_METHOD.matches(getLast(body), state)) { return NO_MATCH; } // try body statements, excluding the trailing `fail()` List<? extends StatementTree> throwingStatements = tree.getBlock().getStatements().subList(0, tree.getBlock().getStatements().size() - 1); Optional<Fix> fix = AssertThrowsUtils.tryFailToAssertThrows(tree, throwingStatements, state); return fix.isPresent() ? describeMatch(tree, fix) : NO_MATCH; } }
/** Return whether the given try-tree will catch the given exception type. */ private boolean tryCatchesException(TryTree tryTree, Type exceptionToCatch, VisitorState state) { Types types = state.getTypes(); return tryTree.getCatches().stream() .anyMatch( (CatchTree catchClause) -> { Type catchesException = getType(catchClause.getParameter().getType()); // Examine all alternative types of a union type. if (catchesException != null && catchesException.isUnion()) { return Streams.stream(((UnionClassType) catchesException).getAlternativeTypes()) .anyMatch(caught -> types.isSuperType(caught, exceptionToCatch)); } // Simple type, just check superclass. return types.isSuperType(catchesException, exceptionToCatch); }); }
@Override public UTry visitTry(TryTree tree, Void v) { @SuppressWarnings({"unchecked", "rawtypes"}) List<UTree<?>> resources = cast(templateTrees(tree.getResources()), (Class<UTree<?>>) (Class) UTree.class); UBlock block = visitBlock(tree.getBlock(), null); ImmutableList.Builder<UCatch> catchesBuilder = ImmutableList.builder(); for (CatchTree catchTree : tree.getCatches()) { catchesBuilder.add(visitCatch(catchTree, null)); } UBlock finallyBlock = (tree.getFinallyBlock() == null) ? null : visitBlock(tree.getFinallyBlock(), null); return UTry.create(resources, block, catchesBuilder.build(), finallyBlock); }
if (tryTree.getCatches().size() == 0) { if (tryTree.getBlock() != null) { result.addAll(getSafeInitMethods(tryTree.getBlock(), classSymbol, state));
@Override @Nullable public Choice<Unifier> visitTry(TryTree node, @Nullable Unifier unifier) { return unifyList(unifier, getResources(), node.getResources()) .thenChoose(unifications(getBlock(), node.getBlock())) .thenChoose(unifications(getCatches(), node.getCatches())) .thenChoose(unifications(getFinallyBlock(), node.getFinallyBlock())); } }
@Override public Boolean visitTry(TryTree that, Void unused) { boolean completes = scan(that.getBlock()); // assume all catch blocks are reachable; javac has already rejected unreachable // checked exception handlers for (CatchTree catchTree : that.getCatches()) { completes |= scan(catchTree.getBlock()); } if (that.getFinallyBlock() != null && !scan(that.getFinallyBlock())) { completes = false; } return completes; } }
@Override public Result visitTry(TryTree node, BreakContext cxt) { Result result = node.getBlock().accept(this, cxt); for (CatchTree catchTree : node.getCatches()) { result = result.or(catchTree.accept(this, cxt)); } if (node.getFinallyBlock() != null) { result = result.then(node.getFinallyBlock().accept(this, cxt)); } return result; }
@Override public Description matchTry(TryTree tree, VisitorState state) { MatchResult matchResult = tryTreeMatches(tree, state); if (!matchResult.matched()) { return NO_MATCH; } Description.Builder builder = buildDescription(tree.getCatches().get(0).getParameter()); if (matchResult.caughtType == JAVA_LANG_THROWABLE) { builder.addFix(fixByCatchingException(tree)); } if (matchResult.caughtType == SOME_ASSERTION_FAILURE) { builder.addFix(fixByThrowingJavaLangError(matchResult.failStatement, state)); } builder.addFix(fixWithReturnOrBoolean(tree, matchResult.failStatement, state)); return builder.build(); }
@Override public Void visitTry(TryTree tree, HeldLockSet locks) { scan(tree.getResources(), locks); List<? extends Tree> resources = tree.getResources(); scan(resources, locks); // Cheesy try/finally heuristic: assume that all locks released in the finally // are held for the entirety of the try and catch statements. Collection<GuardedByExpression> releasedLocks = ReleasedLockFinder.find(tree.getFinallyBlock(), visitorState); if (resources.isEmpty()) { scan(tree.getBlock(), locks.plusAll(releasedLocks)); } else { // We don't know what to do with the try-with-resources block. // TODO(cushon) - recognize common try-with-resources patterns. Currently there is no // standard implementation of an AutoCloseable lock resource to detect. } scan(tree.getCatches(), locks.plusAll(releasedLocks)); scan(tree.getFinallyBlock(), locks); return null; }
@Override public Choice<State<JCTry>> visitTry(final TryTree node, State<?> state) { return chooseSubtrees( state, s -> unify(node.getResources(), s), s -> unifyStatement(node.getBlock(), s), s -> unify(node.getCatches(), s), s -> unifyStatement(node.getFinallyBlock(), s), (resources, block, catches, finallyBlock) -> maker() .Try( resources, (JCBlock) block, List.convert(JCCatch.class, catches), (JCBlock) finallyBlock)); }
List<? extends CatchTree> catches = tryTree.getCatches(); if (catches.size() != 1) {
for (CatchTree tree : tryTree.getCatches()) { Type typeSym = getType(tree.getParameter().getType()); if (ASTHelpers.isCastable(typeSym, interruptedType, state)) {