public Boolean visitTry(TryTree node, TreePath p) { if (p == null) { super.visitTry(node, p); return false; } TryTree at = (TryTree) p.getLeaf(); if (!checkLists(node.getResources(), at.getResources(), p)) { return false; } if (!scan(node.getBlock(), at.getBlock(), p)) { return false; } if (!checkLists(node.getCatches(), at.getCatches(), p)) { return false; } return scan(node.getFinallyBlock(), at.getFinallyBlock(), p); }
@Override public Void visitTry(TryTree node, Collection<TreePath> trees) { Set<TypeMirror> caught = new HashSet<TypeMirror>(); for (CatchTree ct : node.getCatches()) { TypeMirror t = info.getTrees().getTypeMirror(new TreePath(new TreePath(getCurrentPath(), ct), ct.getParameter())); if (t != null) { caught.add(t); } } caughtExceptions.push(caught); try { scan(node.getBlock(), trees); } finally { caughtExceptions.pop(); } scan(node.getFinallyBlock(), trees); return null; }
@Override protected void performRewrite(TransformationContext ctx) throws Exception { Tree t = ctx.getPath().getLeaf(); if (t.getKind() != Tree.Kind.CATCH) { // remove a clause from the multi-catch removeAlternativeFromMultiCatch(ctx); return; } CatchTree toRemove = (CatchTree)t; TryTree parent = (TryTree) ctx.getPath().getParentPath().getLeaf(); TreeMaker make = ctx.getWorkingCopy().getTreeMaker(); if (parent.getResources().isEmpty() && parent.getCatches().size() == 1) { List<StatementTree> repl = new ArrayList<>(); repl.addAll(parent.getBlock().getStatements()); if (parent.getFinallyBlock() != null) { repl.addAll(parent.getFinallyBlock().getStatements()); } Utilities.replaceStatement(ctx.getWorkingCopy(), ctx.getPath().getParentPath(), repl); } else { ctx.getWorkingCopy().rewrite(parent, make.removeTryCatch(parent, toRemove)); } }
static TreePath enclosingTry(TreePath from) { TreePath tryPath = from; while (tryPath != null && tryPath.getLeaf().getKind() != Kind.TRY && !TreeUtilities.CLASS_TREE_KINDS.contains(tryPath.getLeaf().getKind()) && tryPath.getLeaf().getKind() != Kind.CATCH && tryPath.getLeaf().getKind() != Kind.LAMBDA_EXPRESSION) tryPath = tryPath.getParentPath(); if (tryPath.getLeaf().getKind() == Kind.TRY) { TryTree tt = (TryTree) tryPath.getLeaf(); //#104085: if the statement to be wrapped is inside a finally block of the try-catch, //do not attempt to extend existing catches...: for (Tree t : from) { if (tt.getFinallyBlock() == t) { return null; } } return tryPath; } return null; }
@Override public Boolean visitTry(TryTree node, Void p) { Set<TypeMirror> caught = new HashSet<TypeMirror>(); for (CatchTree ct : node.getCatches()) { TypeMirror t = info.getTrees().getTypeMirror(new TreePath(new TreePath(getCurrentPath(), ct), ct.getParameter())); if (t != null) { caught.add(t); } } caughtExceptions.push(Pair.of(caught, node)); try { return scan(node.getBlock(), p) == Boolean.TRUE || scan(node.getFinallyBlock(), p) == Boolean.TRUE; } finally { caughtExceptions.pop(); } }
@Override public Void visitTry(TryTree tryTree, List<ReformatOption> optionsToReformat) { addLeftBraceToList(optionsToReformat, tryTree.getBlock(), PreferencesFormatOptions.BRACES_IN_OTHER_DECLARATION); BlockTree finalBlock = tryTree.getFinallyBlock(); List<? extends CatchTree> catches = tryTree.getCatches(); if (finalBlock instanceof CompoundTree) { addLeftBraceToList(optionsToReformat, finalBlock, PreferencesFormatOptions.BRACES_IN_OTHER_DECLARATION); addRightBraceToList(optionsToReformat, (CompoundTree) finalBlock, PreferencesFormatOptions.AFTER_OTHER_DECLARATION); } else if (!catches.isEmpty()) { BlockTree catchBlock = catches.get(catches.size() - 1).getBlock(); addRightBraceToList(optionsToReformat, (CompoundTree) catchBlock, PreferencesFormatOptions.AFTER_OTHER_DECLARATION); } else { addRightBraceToList(optionsToReformat, (CompoundTree) tryTree.getBlock(), PreferencesFormatOptions.AFTER_OTHER_DECLARATION); } return null; }
@Test public void testVisitTry() throws ParseException, BadLocationException, IOException { List<ReformatOption> optionsToReformat = new ArrayList<>(); CompilationUnitTree unit = getCompilationUnitTree(INPUT_FILE); MethodTree methodTree = TreeNavigationUtils.findMethodTreeByName("doSomething", unit).get(0); TryTree tryTree = (TryTree) getStatementTreeByClassName(TryTree.class, methodTree); if (tryTree == null) { fail(ERROR_MESSAGE); } ReformatTreeVisitor reformatTreeVisitor = getReformatTreeVisitor(INPUT_FILE); reformatTreeVisitor.visitTry(tryTree, optionsToReformat); assertEquals(optionsToReformat.size(), 3); }
@Test public void testVisitTryNotReformat() throws ParseException, BadLocationException, IOException { List<ReformatOption> optionsToReformat = new ArrayList<>(); CompilationUnitTree unit = getCompilationUnitTree(INPUT_FILE); MethodTree methodTree = TreeNavigationUtils.findMethodTreeByName("doSomething", unit).get(0); TryTree tryTree = (TryTree) getStatementTreeByClassName(TryTree.class, methodTree); if (tryTree == null) { fail(ERROR_MESSAGE); } ReformatTreeVisitor reformatTreeVisitor = getReformatTreeVisitor(INPUT_FILE, 5, 10); reformatTreeVisitor.visitTry(tryTree, optionsToReformat); assertTrue(optionsToReformat.isEmpty()); }
@Test public void testVisitCatch() throws ParseException, BadLocationException, IOException { List<ReformatOption> optionsToReformat = new ArrayList<>(); CompilationUnitTree unit = getCompilationUnitTree(INPUT_FILE); MethodTree methodTree = TreeNavigationUtils.findMethodTreeByName("doSomething", unit).get(0); TryTree tryTree = (TryTree) getStatementTreeByClassName(TryTree.class, methodTree); if (tryTree == null) { fail(ERROR_MESSAGE); } CatchTree catchTree = tryTree.getCatches().get(0); ReformatTreeVisitor reformatTreeVisitor = getReformatTreeVisitor(INPUT_FILE); reformatTreeVisitor.visitCatch(catchTree, optionsToReformat); assertFalse(optionsToReformat.isEmpty()); }
@Test public void testVisitCatchNotReformat() throws ParseException, BadLocationException, IOException { List<ReformatOption> optionsToReformat = new ArrayList<>(); CompilationUnitTree unit = getCompilationUnitTree(INPUT_FILE); MethodTree methodTree = TreeNavigationUtils.findMethodTreeByName("doSomething", unit).get(0); TryTree tryTree = (TryTree) getStatementTreeByClassName(TryTree.class, methodTree); if (tryTree == null) { fail(ERROR_MESSAGE); } CatchTree catchTree = tryTree.getCatches().get(0); ReformatTreeVisitor reformatTreeVisitor = getReformatTreeVisitor(INPUT_FILE, 10, 20); reformatTreeVisitor.visitCatch(catchTree, optionsToReformat); assertTrue(optionsToReformat.isEmpty()); }
@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)); }
@Override public Description matchTry(TryTree tree, VisitorState state) { if (tryTreeMatches(tree, state)) { List<? extends StatementTree> tryStatements = tree.getBlock().getStatements(); StatementTree lastTryStatement = tryStatements.get(tryStatements.size() - 1); String failCall = String.format("\nfail(\"Expected %s\");", exceptionToString(tree)); SuggestedFix.Builder fixBuilder = SuggestedFix.builder().postfixWith(lastTryStatement, failCall); // Make sure that when the fail import is added it doesn't conflict with existing ones. fixBuilder.removeStaticImport("junit.framework.Assert.fail"); fixBuilder.removeStaticImport("junit.framework.TestCase.fail"); fixBuilder.addStaticImport("org.junit.Assert.fail"); return describeMatch(lastTryStatement, fixBuilder.build()); } else { return Description.NO_MATCH; } }
@Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (!FENCE_MATCHER.matches(tree, state)) { return NO_MATCH; } Tree previous = null; OUTER: for (Tree enclosing : state.getPath().getParentPath()) { switch (enclosing.getKind()) { case TRY: if (((TryTree) enclosing).getFinallyBlock().equals(previous)) { return NO_MATCH; } break; case CLASS: case METHOD: case LAMBDA_EXPRESSION: break OUTER; default: // fall out } previous = enclosing; } return describeMatch(tree); }
@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 matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { // Match on calls to any override of WakeLock.release(). if (!RELEASE.matches(tree, state)) { return NO_MATCH; } // Ok if surrounded in try/catch block that catches RuntimeException. TryTree enclosingTry = findEnclosingNode(state.getPath(), TryTree.class); if (enclosingTry != null && tryCatchesException(enclosingTry, state.getSymtab().runtimeExceptionType, state)) { return NO_MATCH; } // Ok if WakeLock not in danger of unexpected exception. // Also, can't perform analysis if WakeLock symbol not found. Symbol wakelockSymbol = getSymbol(getReceiver(tree)); if (wakelockSymbol == null || !wakelockMayThrow(wakelockSymbol, state)) { return NO_MATCH; } Tree releaseStatement = state.getPath().getParentPath().getLeaf(); return describeMatch(releaseStatement, getFix(releaseStatement, wakelockSymbol, state)); }
/** 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 Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (!RESTORE_IDENTITY_METHOD.matches(tree, state)) { return NO_MATCH; } // This is a simple implementation that doesn't have 100% accuracy - e.g. it would accept it // if both Binder.clearCallingIdentity() and Binder.restoreCallingIdentity() were in the same // finally {} block. But in practice it should work well for the large majority of existing // code. // TODO: Also detect when a clearCallingIdentity() call is not followed by // restoreCallingIdentity(). TryTree enclosingTry = findEnclosingNode(state.getPath(), TryTree.class); if (enclosingTry == null) { return describeMatch(tree); } return NO_MATCH; }
@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 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 Description matchTry (TryTree tree, VisitorState state) { List<? extends CatchTree> catchList = tree.getCatches(); if (catchList == null || catchList.size() == 0) { // TODO: this try block does not have a catch, we should further check the // finally block! return Description.NO_MATCH; } CatchTree lastCatch = catchList.get(tree.getCatches().size() - 1); if (overcatch(lastCatch, state)) { if (abortInCatch(lastCatch, state)) { LineMap lineMap = state.getPath().getCompilationUnit().getLineMap(); /* System.out.println("****** warning starts **************"); System.out.println("WARNING: abort in overcatch: " + state.getPath().getCompilationUnit().getSourceFile().getName() + ":" + lineMap.getLineNumber(TreeInfo.getStartPos((JCTree) lastCatch))); System.out.println(state.getPath().getLeaf()); System.out.println("****** warning ends **************"); System.out.println(); */ return describeMatch(lastCatch, NO_FIX); } } return Description.NO_MATCH; }
@Override public Description matchTry (TryTree tree, VisitorState state) { if (badEmptyCatchBlock(tree, state)) { // If it has finally block, assume it's OK BlockTree bt = tree.getFinallyBlock(); if (bt == null || bt.getStatements().size() == 0) { CatchTree lastCatch = tree.getCatches().get(tree.getCatches().size() - 1); LineMap lineMap = state.getPath().getCompilationUnit().getLineMap(); /* System.out.println("****** warning starts **************"); System.out.println("WARNING: empty catch: " + state.getPath().getCompilationUnit().getSourceFile().getName() // + ":" + state.getEndPosition((JCTree) tree) + ":" + lineMap.getLineNumber(TreeInfo.getStartPos((JCTree) lastCatch))); System.out.println(state.getPath().getLeaf()); System.out.println(); System.out.println("****** warning ends **************"); */ return describeMatch(lastCatch, NO_FIX); } } return Description.NO_MATCH; }
private boolean alreadyInCatch(TryTree tryTree, VisitorState state) { TreePath enclosing = state.getPath().getParentPath(); Kind kind = enclosing.getLeaf().getKind(); while (kind == BLOCK || kind == IF || kind == WHILE_LOOP || kind == SWITCH || kind == FOR_LOOP || kind == DO_WHILE_LOOP || kind == ENHANCED_FOR_LOOP) { enclosing = enclosing.getParentPath(); kind = enclosing.getLeaf().getKind(); } if (kind == CATCH) { // OK, we are already in a catch block return true; } /* We should also ignore the empty catch block in a finally block. However, * there is no com.sun.source.tree.Tree.Kind.FINALLY kind, and the finally * block has a kind = TRY, therefore, we will simply ignore the empty catch * blocks from try as well! */ if (kind == TRY) { // System.out.println("DEBUG: The parent of the try tree is TRY or FINALLY, will ignore!"); return true; } // System.out.println("DEBUG: parent of the try tree, kind: " + kind); return false; }
private boolean handledByControlflow (TryTree tryTree, VisitorState state) { List<? extends StatementTree> statements = tryTree.getBlock().getStatements(); if (statements.isEmpty()) { return false; } Kind lastTrystmtKind = statements.get(statements.size() - 1).getKind(); // System.out.println("DEBUG: control flow check; last stmt in try: " + lastTrystmtKind); if (lastTrystmtKind == RETURN || lastTrystmtKind == CONTINUE || lastTrystmtKind == BREAK) { return true; // it is handled by control flow! /* TODO: to be more accurate, we should further check if the basic block * after this try is not empty. */ } return false; }
@Override public Wrapper visitTry(TryTree arg0, Void arg1) { // Signal that the next BlockTree is a finally block. blockIsFinally = true; FinallyWrapper finallyWrapper; try { finallyWrapper = visit(arg0.getFinallyBlock(), FinallyWrapper.class); } finally { blockIsFinally = false; } return new TryWrapper(arg0, // visitList(builder.getJavacUtils().getResources(arg0), Wrapper.class), visit(arg0.getBlock(), BlockWrapper.class), // visitList(arg0.getCatches(), CatchWrapper.class), // finallyWrapper); }
@Override public Tree visitTry(TryTree tree, Void p) { TryTree n = make.Try(tree.getResources(), tree.getBlock(), tree.getCatches(), tree.getFinallyBlock()); model.setType(n, model.getType(tree)); comments.copyComments(tree, n); model.setPos(n, model.getPos(tree)); return n; }
@Override public Number visitTry(TryTree node, Void p) { List<? extends Tree> resources = (List<? extends Tree>) resolveMultiParameters(node.getResources()); List<? extends CatchTree> catches = (List<? extends CatchTree>) resolveMultiParameters(node.getCatches()); TryTree nue = make.Try(resources, node.getBlock(), catches, node.getFinallyBlock()); rewrite(node, nue); return super.visitTry(node, p); }
@Override public Object visitTry(TryTree node, Object p) { depth++; Object o = super.visitTry(node, p); depth--; return o; }
@Override public Void visitTry(TryTree tree, List<Node> d) { List<Node> below = new ArrayList<Node>(); addCorrespondingType(below); addCorrespondingComments(below); super.visitTry(tree, below); d.add(new TreeNode(info, getCurrentPath(), below)); return null; }
private static TryTree findNestedARM( final Collection<? extends StatementTree> stms, final StatementTree var) { int state = var != null ? 0 : 1; for (StatementTree stm : stms) { if (stm == var) { state = 1; } if (state == 1) { if (stm.getKind() == Kind.TRY) { final TryTree tryTree = (TryTree)stm; if (tryTree.getResources() != null && !tryTree.getResources().isEmpty()) { return tryTree; } else { final Iterator<? extends StatementTree> blkStms = tryTree.getBlock().getStatements().iterator(); if (blkStms.hasNext()) { StatementTree bstm = blkStms.next(); if (bstm.getKind() == Kind.TRY) { return (TryTree)bstm; } if (bstm.getKind() == Kind.EXPRESSION_STATEMENT && blkStms.hasNext()) { bstm = blkStms.next(); if (bstm.getKind() == Kind.TRY) { return (TryTree)bstm; } } } } } if (stm != var) { break; } } } return null; }
@Override protected void performRewrite(TransformationContext ctx) { WorkingCopy wc = ctx.getWorkingCopy(); TreePath tp = ctx.getPath(); List<Tree> disjointTypes = new LinkedList<Tree>(); TryTree tt = (TryTree) tp.getLeaf(); int first = duplicates.get(0); List<Integer> remainingDuplicates = duplicates.subList(1, duplicates.size()); addDisjointType(disjointTypes, tt.getCatches().get(first).getParameter().getType()); for (Integer d : remainingDuplicates) { addDisjointType(disjointTypes, tt.getCatches().get((int) d).getParameter().getType()); } List<CatchTree> newCatches = new LinkedList<CatchTree>(); int c = 0; for (CatchTree ct : tt.getCatches()) { if (c == first) { wc.rewrite(ct.getParameter().getType(), wc.getTreeMaker().UnionType(disjointTypes)); } if (remainingDuplicates.contains(c++)) continue; newCatches.add(ct); } TryTree nue = wc.getTreeMaker().Try(tt.getResources(), tt.getBlock(), newCatches, tt.getFinallyBlock()); wc.rewrite(tt, nue); }
@Override protected void performRewrite(JavaFix.TransformationContext ctx) throws Exception { CatchTree oldTree = (CatchTree)ctx.getPath().getLeaf(); TryTree oldTry = (TryTree)ctx.getPath().getParentPath().getLeaf(); WorkingCopy wcopy = ctx.getWorkingCopy(); GeneratorUtilities gen = GeneratorUtilities.get(wcopy); TreeMaker mk = wcopy.getTreeMaker(); int index = oldTry.getCatches().indexOf(oldTree); TryTree result = mk.removeTryCatch(oldTry, index); for (TypeMirrorHandle h : newTypes) { TypeMirror m = h.resolve(wcopy); if (m == null || m.getKind() != TypeKind.DECLARED) { continue; } CatchTree branch = mk.Catch( mk.Variable( oldTree.getParameter().getModifiers(), oldTree.getParameter().getName(), mk.Type(m), oldTree.getParameter().getInitializer()), oldTree.getBlock()); gen.copyComments(oldTree, branch, true); result = mk.insertTryCatch(result, index++, branch); } wcopy.rewrite(oldTry, result); }
@Hint( displayName = "#DN_BroadCatch", description = "#DESC_BroadCatch", category = "rules15", customizerProvider = CF.class, suppressWarnings = { "BroadCatchBlock", "TooBroadCatch" }, enabled = false ) @TriggerPatterns({ @TriggerPattern("try { $statements$; } catch $catches$"), @TriggerPattern("try { $statements$; } catch $catches$ finally { $handler$; }") }) public static List<ErrorDescription> broadCatch(HintContext ctx) { if (ctx.getPath().getLeaf().getKind() != Tree.Kind.TRY) { return null; } TryTree tt = (TryTree)ctx.getPath().getLeaf(); Set<TypeMirror> realExceptions = ctx.getInfo().getTreeUtilities().getUncaughtExceptions( new TreePath(ctx.getPath(), tt.getBlock())); CatchClauseProcessor processor = new CatchClauseProcessor(ctx.getInfo(), ctx, realExceptions); if (ctx.getPreferences().getBoolean(OPTION_EXCLUDE_COMMON, DEFAULT_EXCLUDE_COMMON)) { processor.excludeCommons(); } if (ctx.getPreferences().getBoolean(OPTION_EXCLUDE_UMBRELLA, DEFAULT_EXCLUDE_UMBRELLA)) { processor.suppressUmbrellas(ctx.getPreferences().get(OPTION_UMBRELLA_LIST, DEFAULT_UMBRELLA_LIST)); } processor.process(ctx.getMultiVariables().get("$catches$")); return processor.errors; }
@Override protected void performRewrite(TransformationContext ctx) { WorkingCopy wc = ctx.getWorkingCopy(); final TreeMaker tm = wc.getTreeMaker(); TreePath tp = ctx.getPath(); final BlockTree oldBody = ((MethodTree)tp.getLeaf()).getBody(); if (oldBody == null) { return; } final List<StatementTree> newStatements = new ArrayList<StatementTree>(2); BlockTree superFinalize = tm.Block( Collections.singletonList( tm.ExpressionStatement( tm.MethodInvocation(Collections.<ExpressionTree>emptyList(), tm.MemberSelect( tm.Identifier(SUPER), FINALIZE), Collections.<ExpressionTree>emptyList()))), false); if (oldBody.getStatements().isEmpty()) { wc.rewrite(oldBody, superFinalize); } else { TryTree soleTry = soleTryWithoutFinally(oldBody); if (soleTry != null) { wc.rewrite(soleTry, tm.Try(soleTry.getBlock(), soleTry.getCatches(), superFinalize)); } else { wc.rewrite(oldBody, tm.Block(Collections.singletonList(tm.Try(oldBody, Collections.<CatchTree>emptyList(), superFinalize)), false)); } } }
private TryTree soleTryWithoutFinally(BlockTree block) { if (block.getStatements().size() != 1) return null; StatementTree first = block.getStatements().get(0); if (first.getKind() != Kind.TRY) return null; TryTree tt = (TryTree) first; if (tt.getFinallyBlock() != null) return null; return tt; }
@Override protected void performRewrite(TransformationContext ctx) throws Exception { TreeMaker make = ctx.getWorkingCopy().getTreeMaker(); TryTree tt = (TryTree) ctx.getPath().getLeaf(); List<CatchTree> catches = new ArrayList<CatchTree>(); catches.addAll(tt.getCatches()); catches.addAll(MagicSurroundWithTryCatchFix.createCatches(ctx.getWorkingCopy(), make, thandles, ctx.getPath())); ctx.getWorkingCopy().rewrite(tt, make.Try(tt.getResources(), tt.getBlock(), catches, tt.getFinallyBlock())); }
protected void doModification(ResultIterator resultIterator) throws Exception { WorkingCopy copy = WorkingCopy.get(resultIterator.getParserResult()); copy.toPhase(Phase.RESOLVED); CompilationUnitTree cut = copy.getCompilationUnit(); ClassTree ct = (ClassTree) cut.getTypeDecls().get(0); MethodTree mt = (MethodTree) ct.getMembers().get(1); TreeMaker treeMaker = copy.getTreeMaker(); BlockTree bt = mt.getBody(); StatementTree stmt = treeMaker.Variable(treeMaker.Modifiers(EnumSet.noneOf(Modifier.class)), "is", treeMaker.QualIdent("java.io.InputStream"), treeMaker.Literal(null)); //NOI18N bt = treeMaker.addBlockStatement(bt, stmt); BlockTree tryBlock = treeMaker.Block(Collections.<StatementTree>emptyList(), false); ExpressionTree et = treeMaker.NewClass(null, Collections.<ExpressionTree>emptyList(), treeMaker.QualIdent("java.io.File"), Collections.singletonList(treeMaker.Literal("test.txt")), null); //NOI18N stmt = treeMaker.Variable(treeMaker.Modifiers(EnumSet.noneOf(Modifier.class)), "f", treeMaker.QualIdent("java.io.File"), et); //NOI18N tryBlock = treeMaker.addBlockStatement(tryBlock, stmt); et = treeMaker.NewClass(null, Collections.<ExpressionTree>emptyList(), treeMaker.QualIdent("java.io.FileInputStream"), Collections.singletonList(treeMaker.Identifier("f")), null); //NOI18N et = treeMaker.Assignment(treeMaker.Identifier("is"), et); //NOI18N tryBlock = treeMaker.addBlockStatement(tryBlock, treeMaker.ExpressionStatement(et)); et = treeMaker.MemberSelect(treeMaker.Identifier("is"), "read"); //NOI18N et = treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), et, Collections.<ExpressionTree>emptyList()); stmt = treeMaker.Try(treeMaker.Block(Collections.singletonList(treeMaker.ExpressionStatement(et)), false), Collections.<CatchTree>emptyList(), null); et = treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), treeMaker.MemberSelect(treeMaker.QualIdent("java.util.logging.Logger"), "getLogger"), Collections.<ExpressionTree>emptyList()); //NOI18N et = treeMaker.addMethodInvocationArgument((MethodInvocationTree) et, treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), treeMaker.MemberSelect(treeMaker.MemberSelect(treeMaker.QualIdent("org.netbeans.samples.ClassA"), "class"), "getName"), Collections.<ExpressionTree>emptyList())); //NOI18N et = treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), treeMaker.MemberSelect(et, "log"), Collections.<ExpressionTree>emptyList()); //NOI18N et = treeMaker.addMethodInvocationArgument((MethodInvocationTree) et, treeMaker.MemberSelect(treeMaker.QualIdent("java.util.logging.Logger"), "SEVERE")); //NOI18N et = treeMaker.addMethodInvocationArgument((MethodInvocationTree) et, treeMaker.Literal(null)); et = treeMaker.addMethodInvocationArgument((MethodInvocationTree) et, treeMaker.Identifier("ex")); //NOI18N BlockTree catchBlock = treeMaker.Block(Collections.singletonList(treeMaker.ExpressionStatement(et)), false); stmt = treeMaker.addTryCatch((TryTree) stmt, treeMaker.Catch(treeMaker.Variable(treeMaker.Modifiers(EnumSet.noneOf(Modifier.class)), "ex", treeMaker.QualIdent("java.io.IOException"), null), catchBlock)); //NOI18N tryBlock = treeMaker.addBlockStatement(tryBlock, stmt); et = treeMaker.MemberSelect(treeMaker.Identifier("is"), "close"); //NOI18N et = treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), et, Collections.<ExpressionTree>emptyList()); stmt = treeMaker.Try(treeMaker.Block(Collections.singletonList(treeMaker.ExpressionStatement(et)), false), Collections.<CatchTree>emptyList(), null); stmt = treeMaker.addTryCatch((TryTree) stmt, treeMaker.Catch(treeMaker.Variable(treeMaker.Modifiers(EnumSet.noneOf(Modifier.class)), "ex", treeMaker.QualIdent("java.io.IOException"), null), catchBlock)); //NOI18N stmt = treeMaker.Try(tryBlock, Collections.<CatchTree>emptyList(), treeMaker.Block(Collections.singletonList(stmt), false)); stmt = treeMaker.addTryCatch((TryTree) stmt, treeMaker.Catch(treeMaker.Variable(treeMaker.Modifiers(EnumSet.noneOf(Modifier.class)), "ex", treeMaker.QualIdent("java.io.FileNotFoundException"), null), catchBlock)); //NOI18N bt = treeMaker.addBlockStatement(bt, stmt); copy.rewrite(mt.getBody(), bt); }
@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 Void visitTry(TryTree tree, VisitorState visitorState) { VisitorState state = visitorState.withPath(getCurrentPath()); for (TryTreeMatcher matcher : tryMatchers) { if (!isSuppressed(matcher, state)) { try { reportMatch(matcher.matchTry(tree, state), tree, state); } catch (Throwable t) { handleError(matcher, t); } } } return super.visitTry(tree, state); }
@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); }
@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())); }