@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)); }
protected int diffCatch(JCCatch oldT, JCCatch newT, int[] bounds) { int localPointer = bounds[0]; // param int[] paramBounds = getBounds(oldT.param); copyTo(localPointer, paramBounds[0]); localPointer = diffTree(oldT.param, newT.param, paramBounds); // body int[] bodyBounds = getBounds(oldT.body); copyTo(localPointer, bodyBounds[0]); localPointer = diffTree(oldT.body, newT.body, bodyBounds); copyTo(localPointer, bounds[1]); return bounds[1]; }
@Override @DefinedBy(Api.COMPILER_TREE) public TypeMirror getLub(CatchTree tree) { JCCatch ct = (JCCatch) tree; JCVariableDecl v = ct.param; if (v.type != null && v.type.getKind() == TypeKind.UNION) { UnionClassType ut = (UnionClassType) v.type; return ut.getLub(); } else { return v.type; } }
private void printCatch(JCCatch catchBlock) { print(" catch ("); printVarDefInline(catchBlock.param); // ExprType1 | ExprType2 handled via JCTypeUnion. println(") {"); indent++; for (JCStatement stat : catchBlock.body.stats) print(stat); indent--; aPrint("}"); }
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)); }
/** For javac, both JCExpression and JCStatement are considered as valid children types. */ @Override protected Collection<Class<? extends JCTree>> getStatementTypes() { Collection<Class<? extends JCTree>> collection = new ArrayList<Class<? extends JCTree>>(3); collection.add(JCStatement.class); collection.add(JCExpression.class); collection.add(JCCatch.class); return collection; }
public void visitCatch(JCCatch that) { try { print("JCCatch:"); } catch (Exception e) { } super.visitCatch(that); }
public void visitCatch(JCCatch tree) { try { print(" catch ("); printExpr(tree.param); print(") "); printStat(tree.body); } catch (IOException e) { throw new UncheckedIOException(e); } }
@Override public Choice<State<JCCatch>> visitCatch(final CatchTree node, State<?> state) { return chooseSubtrees( state, s -> unifyStatement(node.getBlock(), s), block -> maker().Catch((JCVariableDecl) node.getParameter(), (JCBlock) block)); }
/** CatchClause = CATCH "(" FormalParameter ")" Block */ protected JCCatch catchClause() { int pos = S.pos(); accept(CATCH); accept(LPAREN); JCModifiers mods = optFinal(Flags.PARAMETER); List<JCExpression> catchTypes = catchTypes(); JCExpression paramType = catchTypes.size() > 1 ? toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) : catchTypes.head; JCVariableDecl formal = variableDeclaratorId(mods, paramType); accept(RPAREN); JCBlock body = block(); return F.at(pos).Catch(formal, body); }
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); } }
@Override public void visit(TryWrapper tryWrapper) { TreeMaker maker = builder.getTreeMaker(); JCBlock block = (JCBlock) generate(tryWrapper.getBlock()); JCBlock finalizer = (JCBlock) generate(tryWrapper.getFinalizer()); ListBuffer<JCCatch> catches = new ListBuffer<JCCatch>(); for (CatchWrapper cw : tryWrapper.getCatchers()) { catches.append(generate(cw, JCCatch.class)); } result = maker.Try(block, catches.toList(), finalizer); }
private boolean matchCatch(JCCatch t1, JCCatch t2) { return treesMatch(t1.param, t2.param) && 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 JCCatch Catch(JCVariableDecl param, JCBlock body) { return invoke(Catch, param, body); }
@Override public void visitCatch(JCCatch tree) { print(" catch ("); print(tree.param); print(") "); print(tree.body); }
public AJCCatch(JCCatch ltree) { super(ltree.param, ltree.body); }
public AJCCatch(JCCatch ltree, String lcomment) { this(ltree); setComment(lcomment); }
@Override public boolean visitTry(Try node) { List<JCCatch> catches = toList(JCCatch.class, node.astCatches()); return posSet(node, treeMaker.Try((JCBlock) toTree(node.astBody()), catches, (JCBlock) toTree(node.astFinally()))); }
@Override public void visitCatch(JCCatch tree) { printNode(tree); child("param", tree.param); child("body", tree.body); indent--; }
@Override public void visitCatch(JCCatch node) { set(node, new Catch() .rawExceptionDeclaration(toTree(node.getParameter(), FlagKey.VARDEF_IS_DEFINITION)) .rawBody(toTree(node.getBlock()))); }
@Override public JCCatch inline(Inliner inliner) throws CouldNotResolveImportException { return inliner.maker().Catch(getParameter().inline(inliner), getBlock().inline(inliner)); }
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; }
@Override public void handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, JavacNode annotationNode) { if (inNetbeansEditor(annotationNode)) return; deleteAnnotationIfNeccessary(annotationNode, Cleanup.class); String cleanupName = annotation.getInstance().value(); if (cleanupName.length() == 0) { annotationNode.addError("cleanupName cannot be the empty string."); return; } if (annotationNode.up().getKind() != Kind.LOCAL) { annotationNode.addError("@Cleanup is legal only on local variable declarations."); return; } JCVariableDecl decl = (JCVariableDecl)annotationNode.up().get(); if (decl.init == null) { annotationNode.addError("@Cleanup variable declarations need to be initialized."); return; } JavacNode ancestor = annotationNode.up().directUp(); JCTree blockNode = ancestor.get(); final List<JCStatement> statements; if (blockNode instanceof JCBlock) { statements = ((JCBlock)blockNode).stats; } else if (blockNode instanceof JCCase) { statements = ((JCCase)blockNode).stats; } else if (blockNode instanceof JCMethodDecl) { statements = ((JCMethodDecl)blockNode).body.stats; } else { annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block."); return; } boolean seenDeclaration = false; ListBuffer<JCStatement> newStatements = ListBuffer.lb(); ListBuffer<JCStatement> tryBlock = ListBuffer.lb(); for (JCStatement statement : statements) { if (!seenDeclaration) { if (statement == decl) seenDeclaration = true; newStatements.append(statement); } else { tryBlock.append(statement); } } if (!seenDeclaration) { annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent."); return; } doAssignmentCheck(annotationNode, tryBlock.toList(), decl.name); TreeMaker maker = annotationNode.getTreeMaker(); JCFieldAccess cleanupMethod = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName)); List<JCStatement> cleanupCall = List.<JCStatement>of(maker.Exec( maker.Apply(List.<JCExpression>nil(), cleanupMethod, List.<JCExpression>nil()))); JCMethodInvocation preventNullAnalysis = preventNullAnalysis(maker, annotationNode, maker.Ident(decl.name)); JCBinary isNull = maker.Binary(CTC_NOT_EQUAL, preventNullAnalysis, maker.Literal(CTC_BOT, null)); JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null); JCBlock finalizer = recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), ast); newStatements.append(setGeneratedBy(maker.Try(setGeneratedBy(maker.Block(0, tryBlock.toList()), ast), List.<JCCatch>nil(), finalizer), ast)); if (blockNode instanceof JCBlock) { ((JCBlock)blockNode).stats = newStatements.toList(); } else if (blockNode instanceof JCCase) { ((JCCase)blockNode).stats = newStatements.toList(); } else if (blockNode instanceof JCMethodDecl) { ((JCMethodDecl)blockNode).body.stats = newStatements.toList(); } else throw new AssertionError("Should not get here"); ancestor.rebuild(); }