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); }
@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 matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (!ASSERTION.matches(tree, state)) { return NO_MATCH; } JCTry tryStatement = enclosingTry(state); if (tryStatement == null) { return NO_MATCH; } if (!catchesType(tryStatement, state.getSymtab().assertionErrorType, state)) { return NO_MATCH; } Description.Builder description = buildDescription(tree); buildFix(tryStatement, tree, state).ifPresent(description::addFix); return description.build(); }
private static JCTry enclosingTry(VisitorState state) { Tree prev = null; for (Tree parent : state.getPath()) { switch (parent.getKind()) { case METHOD: case LAMBDA_EXPRESSION: return null; case TRY: JCTry tryStatement = (JCTry) parent; return tryStatement.getBlock().equals(prev) ? tryStatement : null; default: // fall out } prev = parent; } return null; }
@Override public void visitTry(JCTry tree) { //skip resources (to prevents same statements to be analyzed twice) scan(tree.getBlock()); scan(tree.getCatches()); scan(tree.getFinallyBlock()); }
private JavacNode buildTry(JCTry tryNode) { if (setAndGetAsHandled(tryNode)) return null; List<JavacNode> childNodes = new ArrayList<JavacNode>(); for (JCTree varDecl : getResourcesForTryNode(tryNode)) { if (varDecl instanceof JCVariableDecl) { addIfNotNull(childNodes, buildLocalVar((JCVariableDecl) varDecl, Kind.LOCAL)); } } addIfNotNull(childNodes, buildStatement(tryNode.body)); for (JCCatch jcc : tryNode.catchers) addIfNotNull(childNodes, buildTree(jcc, Kind.STATEMENT)); addIfNotNull(childNodes, buildStatement(tryNode.finalizer)); return putInMap(new JavacNode(this, tryNode, childNodes, Kind.STATEMENT)); }
private JavacNode buildStatementOrExpression(JCTree statement) { if (statement == null) return null; if (statement instanceof JCAnnotation) return null; if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement); if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL); if (statement instanceof JCTry) return buildTry((JCTry) statement); if (setAndGetAsHandled(statement)) return null; return drill(statement); }
public void visitTry(JCTry that) { try { print("JCTry:"); } catch (Exception e) { } super.visitTry(that); }
@Override public void visitTry(JCTry tree) { printNode(tree); child("body", tree.body); children("catchers", tree.catchers); child("finalizer", tree.finalizer); indent--; }
@Override public void visitTry(JCTry node) { Try t = new Try(); t.rawBody(toTree(node.getBlock())); t.rawFinally(toTree(node.getFinallyBlock())); fillList(node.getCatches(), t.rawCatches()); set(node, t); }
@Override public JCTry inline(Inliner inliner) throws CouldNotResolveImportException { return inliner .maker() .Try( inliner.<JCTree>inlineList(getResources()), getBlock().inline(inliner), inliner.inlineList(getCatches()), inlineFinallyBlock(inliner)); }
private static boolean catchesType( JCTry tryStatement, Type assertionErrorType, VisitorState state) { return tryStatement .getCatches() .stream() .map(catchTree -> ASTHelpers.getType(catchTree.getParameter())) .flatMap( type -> type.isUnion() ? Streams.stream(((UnionClassType) type).getAlternativeTypes()) : Stream.of(type)) .anyMatch(caught -> isSubtype(assertionErrorType, caught, state)); }
public void visitTry(JCTry tree) { try { print("try "); if (tree.resources.nonEmpty()) { print("("); boolean first = true; for (JCTree var : tree.resources) { if (!first) { println(); indent(); } printStat(var); first = false; } print(") "); } printStat(tree.body); for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { printStat(l.head); } if (tree.finalizer != null) { print(" finally "); printStat(tree.finalizer); } } catch (IOException e) { throw new UncheckedIOException(e); } }
public void visitTry(JCTry tree) { try { print("try "); List<?> resources = null; try { Field f = JCTry.class.getField("resources"); resources = (List<?>) f.get(tree); } catch (Exception ignore) { // In JDK6 and down this field does not exist; resources will retain its initializer value which is what we want. } if (resources != null && resources.nonEmpty()) { boolean first = true; print("("); for (Object var0 : resources) { JCTree var = (JCTree) var0; if (!first) { println(); indent(); } printStat(var); first = false; } print(") "); } printStat(tree.body); for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { printStat(l.head); } if (tree.finalizer != null) { print(" finally "); printStat(tree.finalizer); } } catch (IOException e) { throw new UncheckedIOException(e); } }
protected int diffTry(JCTry oldT, JCTry newT, int[] bounds) { int localPointer = bounds[0]; int[] bodyPos = getBounds(oldT.body); if (!listsMatch(oldT.resources, newT.resources)) { if (oldT.resources.nonEmpty() && newT.resources.isEmpty()) { tokenSequence.move(getOldPos(oldT.resources.head)); moveToSrcRelevant(tokenSequence, Direction.BACKWARD); assert tokenSequence.token().id() == JavaTokenId.LPAREN; copyTo(localPointer, tokenSequence.offset()); localPointer = bodyPos[0]; } else { int pos = oldT.resources.isEmpty() ? pos = bodyPos[0] : getOldPos(oldT.resources.head); copyTo(localPointer, pos); boolean parens = oldT.resources.isEmpty() || newT.resources.isEmpty(); int oldPrec = printer.setPrec(TreeInfo.noPrec); if (newT.resources.nonEmpty()) { //Remove all stms from oldTrees to force it to be reprinted by VeryPretty com.sun.tools.javac.util.List<JCTree> l = newT.resources; for (Tree t = l.head; t!= null; l = l.tail, t = l.head) { printer.oldTrees.remove(t); } } localPointer = diffParameterList(oldT.resources, newT.resources, parens ? new JavaTokenId[] { JavaTokenId.LPAREN, JavaTokenId.RPAREN } : null, pos, Measure.ARGUMENT, diffContext.style.spaceBeforeSemi(), diffContext.style.spaceAfterSemi(), false, ";" //NOI18N ); printer.setPrec(oldPrec); if (parens && oldT.resources.isEmpty()) { printer.print(" "); // print the space after type parameter } } } copyTo(localPointer, bodyPos[0]); localPointer = diffTree(oldT.body, newT.body, bodyPos); copyTo(localPointer, localPointer = bodyPos[1]); PositionEstimator est = EstimatorFactory.catches(oldT.getCatches(), newT.getCatches(), oldT.finalizer != null, diffContext); localPointer = diffList(oldT.catchers, newT.catchers, localPointer, est, Measure.DEFAULT, printer); if (oldT.finalizer != null) { int[] finalBounds = getBounds(oldT.finalizer); if (newT.finalizer != null) { copyTo(localPointer, finalBounds[0]); localPointer = diffTree(oldT.finalizer, newT.finalizer, finalBounds); } else { int endetHier = oldT.catchers.isEmpty() ? Math.max(endPos(oldT.body), localPointer) : endPos(oldT.catchers); copyTo(localPointer, endetHier); localPointer = finalBounds[1]; } copyTo(localPointer, bounds[1]); } else { if (newT.finalizer != null) { int catchEnd = oldT.catchers.isEmpty() ? bounds[1] : endPos(oldT.catchers.reverse().head); copyTo(localPointer, localPointer = catchEnd); printer.printFinallyBlock(newT.finalizer); copyTo(localPointer, bounds[1]); } else { copyTo(localPointer, bounds[1]); } } return bounds[1]; }
private boolean matchTry(JCTry t1, JCTry t2) { return treesMatch(t1.finalizer, t2.finalizer) && listsMatch(t1.catchers, t2.catchers) && treesMatch(t1.body, t2.body); }
public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) { return invoke(Try, body, catchers, finalizer); }
public JCTry Try(List<JCTree> resources, JCBlock body, List<JCCatch> catchers, JCBlock finalizer) { return invoke(TryWithResources, resources, body, catchers, finalizer); }
public AJCTry(JCTry ltree) { super(ltree.resources, ltree.body, ltree.catchers, ltree.finalizer); }
public AJCTry(JCTry ltree, String lcomment) { this(ltree); setComment(lcomment); }
private static Optional<Fix> buildFix( JCTry tryStatement, MethodInvocationTree tree, VisitorState state) { if (!ASTHelpers.getSymbol(tree).getSimpleName().contentEquals("fail")) { // ignore non-failure asserts return Optional.empty(); } JCBlock block = tryStatement.getBlock(); if (!expressionStatement((t, s) -> t.equals(tree)) .matches(getLast(block.getStatements()), state)) { // the `fail()` should be the last expression statement in the try block return Optional.empty(); } if (tryStatement.getCatches().size() != 1) { // the fix is less clear for multiple catch clauses return Optional.empty(); } JCCatch catchTree = Iterables.getOnlyElement(tryStatement.getCatches()); if (catchTree.getParameter().getType().getKind() == Kind.UNION_TYPE) { // variables can't have union types return Optional.empty(); } SuggestedFix.Builder fix = SuggestedFix.builder(); boolean expression = block.getStatements().size() == 2 && block.getStatements().get(0).getKind() == Kind.EXPRESSION_STATEMENT; int startPosition; int endPosition; if (expression) { JCExpressionStatement expressionTree = (JCExpressionStatement) block.getStatements().get(0); startPosition = expressionTree.getStartPosition(); endPosition = state.getEndPosition(expressionTree.getExpression()); } else { startPosition = block.getStartPosition(); endPosition = getLast(tryStatement.getBlock().getStatements()).getStartPosition(); } if (catchTree.getBlock().getStatements().isEmpty()) { fix.addStaticImport("org.junit.Assert.assertThrows"); fix.replace( tryStatement.getStartPosition(), startPosition, String.format( "assertThrows(%s.class, () -> ", state.getSourceForNode(catchTree.getParameter().getType()))) .replace(endPosition, state.getEndPosition(catchTree), (expression ? "" : "}") + ");\n"); } else { fix.addStaticImport("org.junit.Assert.expectThrows") .prefixWith(tryStatement, state.getSourceForNode(catchTree.getParameter())) .replace( tryStatement.getStartPosition(), startPosition, String.format( " = expectThrows(%s.class, () -> ", state.getSourceForNode(catchTree.getParameter().getType()))) .replace( /* startPos= */ endPosition, /* endPos= */ catchTree.getBlock().getStatements().get(0).getStartPosition(), (expression ? "" : "}") + ");\n") .replace( state.getEndPosition(getLast(catchTree.getBlock().getStatements())), state.getEndPosition(catchTree), ""); } return Optional.of(fix.build()); }
public void visitTry(JCTry tree) { // Create a new local environment with a local Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup())); boolean isTryWithResource = tree.resources.nonEmpty(); // Create a nested environment for attributing the try block if needed Env<AttrContext> tryEnv = isTryWithResource ? env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) : localEnv; // Attribute resource declarations for (JCTree resource : tree.resources) { if (resource.getTag() == JCTree.VARDEF) { attribStat(resource, tryEnv); chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type"); //check that resource type cannot throw InterruptedException checkAutoCloseable(resource.pos(), localEnv, resource.type); VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource); var.setData(ElementKind.RESOURCE_VARIABLE); } else { attribExpr(resource, tryEnv, syms.autoCloseableType, "try.not.applicable.to.type"); } } // Attribute body attribStat(tree.body, tryEnv); if (isTryWithResource) tryEnv.info.scope.leave(); // Attribute catch clauses for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { JCCatch c = l.head; Env<AttrContext> catchEnv = localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup())); Type ctype = attribStat(c.param, catchEnv); if (TreeInfo.isMultiCatch(c)) { //multi-catch parameter is implicitly marked as final c.param.sym.flags_field |= FINAL | UNION; } if (c.param.sym.kind == Kinds.VAR) { c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER); } chk.checkType(c.param.vartype.pos(), chk.checkClassType(c.param.vartype.pos(), ctype), syms.throwableType); attribStat(c.body, catchEnv); catchEnv.info.scope.leave(); } // Attribute finalizer if (tree.finalizer != null) attribStat(tree.finalizer, localEnv); localEnv.info.scope.leave(); result = null; }