private static boolean tryStatementsAreEquivalent( @NotNull PsiTryStatement statement1, @NotNull PsiTryStatement statement2) { final PsiCodeBlock tryBlock1 = statement1.getTryBlock(); final PsiCodeBlock tryBlock2 = statement2.getTryBlock(); if (!codeBlocksAreEquivalent(tryBlock1, tryBlock2)) { return false; } final PsiCodeBlock finallyBlock1 = statement1.getFinallyBlock(); final PsiCodeBlock finallyBlock2 = statement2.getFinallyBlock(); if (!codeBlocksAreEquivalent(finallyBlock1, finallyBlock2)) { return false; } final PsiCodeBlock[] catchBlocks1 = statement1.getCatchBlocks(); final PsiCodeBlock[] catchBlocks2 = statement2.getCatchBlocks(); if (catchBlocks1.length != catchBlocks2.length) { return false; } for (int i = 0; i < catchBlocks2.length; i++) { if (!codeBlocksAreEquivalent(catchBlocks1[i], catchBlocks2[i])) { return false; } } final PsiParameter[] catchParameters1 = statement1.getCatchBlockParameters(); final PsiParameter[] catchParameters2 = statement2.getCatchBlockParameters(); if (catchParameters1.length != catchParameters2.length) { return false; } for (int i = 0; i < catchParameters2.length; i++) { if (!parametersAreEquivalent(catchParameters2[i], catchParameters1[i])) { return false; } } return true; }
private static boolean tryStatementsAreEquivalent( @NotNull PsiTryStatement statement1, @NotNull PsiTryStatement statement2) { final PsiCodeBlock tryBlock1 = statement1.getTryBlock(); final PsiCodeBlock tryBlock2 = statement2.getTryBlock(); if (!codeBlocksAreEquivalent(tryBlock1, tryBlock2)) { return false; } final PsiCodeBlock finallyBlock1 = statement1.getFinallyBlock(); final PsiCodeBlock finallyBlock2 = statement2.getFinallyBlock(); if (!codeBlocksAreEquivalent(finallyBlock1, finallyBlock2)) { return false; } final PsiCodeBlock[] catchBlocks1 = statement1.getCatchBlocks(); final PsiCodeBlock[] catchBlocks2 = statement2.getCatchBlocks(); if (catchBlocks1.length != catchBlocks2.length) { return false; } for (int i = 0; i < catchBlocks2.length; i++) { if (!codeBlocksAreEquivalent(catchBlocks1[i], catchBlocks2[i])) { return false; } } final PsiResourceList resourceList1 = statement1.getResourceList(); final PsiResourceList resourceList2 = statement2.getResourceList(); if (resourceList1 != null) { if (resourceList2 == null) { return false; } if (resourceList1.getResourceVariablesCount() != resourceList2.getResourceVariablesCount()) { return false; } final List<PsiResourceVariable> resourceVariables1 = resourceList1.getResourceVariables(); final List<PsiResourceVariable> resourceVariables2 = resourceList2.getResourceVariables(); for (int i1 = 0, size = resourceVariables1.size(); i1 < size; i1++) { final PsiResourceVariable variable1 = resourceVariables1.get(i1); final PsiResourceVariable variable2 = resourceVariables2.get(i1); if (!localVariablesAreEquivalent(variable1, variable2)) { return false; } } } else if (resourceList2 != null) { return false; } final PsiParameter[] catchParameters1 = statement1.getCatchBlockParameters(); final PsiParameter[] catchParameters2 = statement2.getCatchBlockParameters(); if (catchParameters1.length != catchParameters2.length) { return false; } for (int i = 0; i < catchParameters2.length; i++) { if (!parametersAreEquivalent(catchParameters2[i], catchParameters1[i])) { return false; } } return true; }
private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions newExceptions = filterCheckedExceptions(newExceptions); PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); if (context instanceof PsiTryStatement) { PsiTryStatement tryStatement = (PsiTryStatement) context; PsiCodeBlock tryBlock = tryStatement.getTryBlock(); // Remove unused catches Collection<PsiClassType> classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); for (PsiParameter parameter : catchParameters) { final PsiType caughtType = parameter.getType(); if (!(caughtType instanceof PsiClassType)) continue; if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue; if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue; parameter.getParent().delete(); // delete catch section } PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); addExceptions(exceptionsToAdd, tryStatement); adjustPossibleEmptyTryStatement(tryStatement); } else { newExceptions = filterUnhandledExceptions(newExceptions, ref); if (newExceptions.length > 0) { // Add new try statement PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject()); PsiTryStatement tryStatement = (PsiTryStatement) elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); LOG.assertTrue(anchor != null); tryStatement.getTryBlock().add(anchor); tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor); addExceptions(newExceptions, tryStatement); anchor.delete(); tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section } } }
private static void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement) throws IncorrectOperationException { PsiCodeBlock tryBlock = tryStatement.getTryBlock(); if (tryBlock != null) { if (tryStatement.getCatchSections().length == 0 && tryStatement.getFinallyBlock() == null) { PsiElement firstBodyElement = tryBlock.getFirstBodyElement(); if (firstBodyElement != null) { tryStatement .getParent() .addRangeAfter(firstBodyElement, tryBlock.getLastBodyElement(), tryStatement); } tryStatement.delete(); } } }
@Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { final PsiType thrownType = myThrown.getType(); if (thrownType == null) { return; } final PsiElement typeElement = descriptor.getPsiElement(); if (typeElement == null) { return; } final PsiElement catchParameter = typeElement.getParent(); if (!(catchParameter instanceof PsiParameter)) { return; } final PsiElement catchBlock = ((PsiParameter) catchParameter).getDeclarationScope(); if (!(catchBlock instanceof PsiCatchSection)) { return; } final PsiCatchSection myBeforeCatchSection = (PsiCatchSection) catchBlock; final PsiTryStatement myTryStatement = myBeforeCatchSection.getTryStatement(); final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); final String name = codeStyleManager.suggestUniqueVariableName("e", myTryStatement.getTryBlock(), false); final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); final PsiCatchSection section = factory.createCatchSection(thrownType, name, myTryStatement); final PsiCatchSection element = (PsiCatchSection) myTryStatement.addBefore(section, myBeforeCatchSection); codeStyleManager.shortenClassReferences(element); if (isOnTheFly()) { final PsiCodeBlock newBlock = element.getCatchBlock(); assert newBlock != null; final TextRange range = SurroundWithUtil.getRangeToSelect(newBlock); final PsiFile file = element.getContainingFile(); final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); if (editor == null) { return; } final Document document = PsiDocumentManager.getInstance(project).getDocument(file); if (editor.getDocument() != document) { return; } editor.getCaretModel().moveToOffset(range.getStartOffset()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); } }
@Override public TextRange surroundStatements( Project project, Editor editor, PsiElement container, PsiElement[] statements) throws IncorrectOperationException { PsiManager manager = PsiManager.getInstance(project); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); statements = SurroundWithUtil.moveDeclarationsOut(container, statements, false); if (statements.length == 0) { return null; } @NonNls String text = "try{\n}finally{\n\n}"; PsiTryStatement tryStatement = (PsiTryStatement) factory.createStatementFromText(text, null); tryStatement = (PsiTryStatement) codeStyleManager.reformat(tryStatement); tryStatement = (PsiTryStatement) container.addAfter(tryStatement, statements[statements.length - 1]); PsiCodeBlock tryBlock = tryStatement.getTryBlock(); if (tryBlock == null) { return null; } SurroundWithUtil.indentCommentIfNecessary(tryBlock, statements); tryBlock.addRange(statements[0], statements[statements.length - 1]); container.deleteChildRange(statements[0], statements[statements.length - 1]); PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); if (finallyBlock == null) { return null; } int offset = finallyBlock.getTextRange().getStartOffset() + 2; editor.getCaretModel().moveToOffset(offset); final Document document = editor.getDocument(); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document); editor.getSelectionModel().removeSelection(); final PsiStatement firstTryStmt = tryBlock.getStatements()[0]; final int indent = firstTryStmt.getTextOffset() - document.getLineStartOffset(document.getLineNumber(firstTryStmt.getTextOffset())); EditorModificationUtil.insertStringAtCaret(editor, StringUtil.repeat(" ", indent), false, true); return new TextRange(editor.getCaretModel().getOffset(), editor.getCaretModel().getOffset()); }