From 8dd82d71fd9fc4c1964713a77b8883ba67cc7d11 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 31 Jan 2019 13:13:38 +0100 Subject: [PATCH] handle moving catch sections up/down better when using selection (IDEA-36496) --- .../moveUpDown/CatchBlockMover.java | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/CatchBlockMover.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/CatchBlockMover.java index e42c814e0a8c..e9cad92b82ec 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/CatchBlockMover.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/CatchBlockMover.java @@ -3,6 +3,7 @@ package com.intellij.codeInsight.editorActions.moveUpDown; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @@ -18,38 +19,40 @@ public class CatchBlockMover extends LineMover { if (!super.checkAvailable(editor, file, info, down)) return false; final Document document = editor.getDocument(); - int startOffset = document.getLineStartOffset(info.toMove.startLine); - int endOffset = document.getLineEndOffset(info.toMove.endLine); - PsiElement element = file.findElementAt(startOffset); - if (element == null) return false; - PsiKeyword keyword = null; - while (element != null && element.getTextOffset() < endOffset) { - if (element instanceof PsiKeyword) { - keyword = (PsiKeyword)element; - if (keyword.getTokenType() != JavaTokenType.CATCH_KEYWORD) { - return false; - } - break; - } - element = PsiTreeUtil.nextLeaf(element); + final SelectionModel selectionModel = editor.getSelectionModel(); + final int startOffset; + final int endOffset; + if (selectionModel.hasSelection()) { + startOffset = selectionModel.getSelectionStart(); + endOffset = selectionModel.getSelectionEnd(); } - if (keyword == null) return false; - final PsiElement parent = keyword.getParent(); - if (!(parent instanceof PsiCatchSection)) return false; - final PsiCatchSection firstToMove = (PsiCatchSection)parent; - + else { + startOffset = document.getLineStartOffset(info.toMove.startLine); + endOffset = document.getLineStartOffset(info.toMove.endLine); + } + final PsiElement element = file.findElementAt(startOffset); + if (element == null) return false; + final PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(element, PsiTryStatement.class, true, PsiMember.class); + if (tryStatement == null) return false; + PsiCatchSection firstToMove = null; + PsiCatchSection lastToMove = null; + for (PsiCatchSection catchSection : tryStatement.getCatchSections()) { + final int offset = catchSection.getTextOffset(); + if (offset >= startOffset && offset < endOffset || catchSection.getFirstChild().getTextRange().contains(startOffset)) { + if (firstToMove == null) firstToMove = catchSection; + lastToMove = catchSection; + } + } + if (firstToMove == null) return false; if (!sanityCheck(firstToMove)) { return info.prohibitMove(); } - - PsiCatchSection lastToMove = firstToMove; - while (true) { - final PsiCatchSection next = PsiTreeUtil.getNextSiblingOfType(lastToMove, PsiCatchSection.class); - if (next == null || next.getTextRange().getStartOffset() >= endOffset) { - break; - } - lastToMove = next; + if (element instanceof PsiWhiteSpace && element.getNextSibling() instanceof PsiStatement + || PsiTreeUtil.getParentOfType(element, PsiStatement.class, true, PsiMember.class) != tryStatement) { + // nonsensical selection + return info.prohibitMove(); } + final PsiCatchSection sibling = down ? PsiTreeUtil.getNextSiblingOfType(lastToMove, PsiCatchSection.class) : PsiTreeUtil.getPrevSiblingOfType(firstToMove, PsiCatchSection.class);