private static PsiElement fixCatchBlock(GrTryCatchStatement tryCatch, PsiClassType[] exceptions) { if (exceptions.length == 0) return tryCatch; final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(tryCatch.getProject()); final GrCatchClause[] clauses = tryCatch.getCatchClauses(); List<String> restricted = ContainerUtil.map( clauses, new Function<GrCatchClause, String>() { @Override @Nullable public String fun(GrCatchClause grCatchClause) { final GrParameter grParameter = grCatchClause.getParameter(); return grParameter != null ? grParameter.getName() : null; } }); restricted = ContainerUtil.skipNulls(restricted); final DefaultGroovyVariableNameValidator nameValidator = new DefaultGroovyVariableNameValidator(tryCatch, restricted); GrCatchClause anchor = clauses.length == 0 ? null : clauses[clauses.length - 1]; for (PsiClassType type : exceptions) { final String[] names = GroovyNameSuggestionUtil.suggestVariableNameByType(type, nameValidator); final GrCatchClause catchClause = factory.createCatchClause(type, names[0]); final GrStatement printStackTrace = factory.createStatementFromText(names[0] + ".printStackTrace()"); catchClause.getBody().addStatementBefore(printStackTrace, null); anchor = tryCatch.addCatchClause(catchClause, anchor); JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor); } return tryCatch; }
@Override public void visitTryStatement(GrTryCatchStatement tryCatchStatement) { final GrOpenBlock tryBlock = tryCatchStatement.getTryBlock(); final GrCatchClause[] catchClauses = tryCatchStatement.getCatchClauses(); final GrFinallyClause finallyClause = tryCatchStatement.getFinallyClause(); builder.append("try"); tryBlock.accept(this); for (GrCatchClause catchClause : catchClauses) { catchClause.accept(this); } if (finallyClause != null) { finallyClause.accept(this); } }
private static PsiElement generateTryCatch(PsiElement element, PsiClassType[] exceptions) { if (exceptions.length == 0) return element; GrTryCatchStatement tryCatch = (GrTryCatchStatement) GroovyPsiElementFactory.getInstance(element.getProject()) .createStatementFromText("try{} catch (Exception e){}"); final GrStatement statement = PsiTreeUtil.getParentOfType(element, GrStatement.class); assert statement != null; tryCatch.getTryBlock().addStatementBefore(statement, null); tryCatch = (GrTryCatchStatement) statement.replace(tryCatch); tryCatch.getCatchClauses()[0].delete(); fixCatchBlock(tryCatch, exceptions); return tryCatch; }
public void visitTryStatement(GrTryCatchStatement tryCatchStatement) { final GrOpenBlock tryBlock = tryCatchStatement.getTryBlock(); final GrCatchClause[] catchClauses = tryCatchStatement.getCatchClauses(); final GrFinallyClause finallyClause = tryCatchStatement.getFinallyClause(); for (int i = catchClauses.length - 1; i >= 0; i--) { myCaughtExceptionInfos.push(new ExceptionInfo(catchClauses[i])); } if (finallyClause != null) myFinallyCount++; List<Pair<InstructionImpl, GroovyPsiElement>> oldPending = null; if (finallyClause != null) { oldPending = myPending; myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(); } InstructionImpl tryBegin = startNode(tryBlock); tryBlock.accept(this); InstructionImpl tryEnd = myHead; finishNode(tryBegin); Set<Pair<InstructionImpl, GroovyPsiElement>> pendingAfterTry = new LinkedHashSet<Pair<InstructionImpl, GroovyPsiElement>>(myPending); @SuppressWarnings("unchecked") List<InstructionImpl>[] throwers = new List[catchClauses.length]; for (int i = 0; i < catchClauses.length; i++) { throwers[i] = myCaughtExceptionInfos.pop().myThrowers; } InstructionImpl[] catches = new InstructionImpl[catchClauses.length]; for (int i = 0; i < catchClauses.length; i++) { interruptFlow(); final InstructionImpl catchBeg = startNode(catchClauses[i]); for (InstructionImpl thrower : throwers[i]) { addEdge(thrower, catchBeg); } final GrParameter parameter = catchClauses[i].getParameter(); if (parameter != null && myPolicy.isVariableInitialized(parameter)) { addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE)); } catchClauses[i].accept(this); catches[i] = myHead; finishNode(catchBeg); } pendingAfterTry.addAll(myPending); myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(pendingAfterTry); if (finallyClause != null) { myFinallyCount--; interruptFlow(); final InstructionImpl finallyInstruction = startNode(finallyClause, false); Set<AfterCallInstruction> postCalls = new LinkedHashSet<AfterCallInstruction>(); final List<Pair<InstructionImpl, GroovyPsiElement>> copy = myPending; myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(); for (Pair<InstructionImpl, GroovyPsiElement> pair : copy) { postCalls.add(addCallNode(finallyInstruction, pair.getSecond(), pair.getFirst())); } if (tryEnd != null) { postCalls.add(addCallNode(finallyInstruction, tryCatchStatement, tryEnd)); } for (InstructionImpl catchEnd : catches) { if (catchEnd != null) { postCalls.add(addCallNode(finallyInstruction, tryCatchStatement, catchEnd)); } } // save added postcalls into separate list because we don't want returnInstruction grabbed // their pending edges List<Pair<InstructionImpl, GroovyPsiElement>> pendingPostCalls = myPending; myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(); myHead = finallyInstruction; finallyClause.accept(this); final ReturnInstruction returnInstruction = new ReturnInstruction(finallyClause); for (AfterCallInstruction postCall : postCalls) { postCall.setReturnInstruction(returnInstruction); addEdge(returnInstruction, postCall); } addNodeAndCheckPending(returnInstruction); interruptFlow(); finishNode(finallyInstruction); if (oldPending == null) { error(); } oldPending.addAll(pendingPostCalls); myPending = oldPending; } else { if (tryEnd != null) { addPendingEdge(tryCatchStatement, tryEnd); } for (InstructionImpl catchEnd : catches) { addPendingEdge(tryBlock, catchEnd); } } }