From e3c9f2890969cf33e027e4422a6fa309692e33a1 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Tue, 5 Apr 2016 15:12:57 +0300 Subject: [PATCH] PY-18522 Detection of empty parent block takes comments into account --- .../editor/PythonCopyPasteProcessor.java | 24 ++++++++++++------- ...EmptyParentBlockWithCommentInside.after.py | 6 +++++ .../EmptyParentBlockWithCommentInside.dst.py | 6 +++++ .../EmptyParentBlockWithCommentInside.src.py | 1 + .../com/jetbrains/python/PyCopyPasteTest.java | 5 ++++ 5 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py create mode 100644 python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py create mode 100644 python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py diff --git a/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java b/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java index dfb1294427da..d4e90b69ade3 100644 --- a/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java +++ b/python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java @@ -23,10 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.CharFilter; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.tree.IElementType; @@ -184,11 +181,11 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor { } @Nullable - private static PyStatementList findEmptyStatementListNearby(@NotNull PsiElement ws) { - PyStatementList statementList = ObjectUtils.chooseNotNull(as(ws.getNextSibling(), PyStatementList.class), - as(ws.getPrevSibling(), PyStatementList.class)); + private static PyStatementList findEmptyStatementListNearby(@NotNull PsiElement whitespace) { + PyStatementList statementList = ObjectUtils.chooseNotNull(as(whitespace.getNextSibling(), PyStatementList.class), + as(whitespace.getPrevSibling(), PyStatementList.class)); if (statementList == null) { - final PsiElement prevLeaf = PsiTreeUtil.prevLeaf(ws, false); + final PsiElement prevLeaf = getPrevNonCommentLeaf(whitespace); if (prevLeaf instanceof PsiErrorElement) { statementList = as(prevLeaf.getParent(), PyStatementList.class); } @@ -198,7 +195,7 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor { @Nullable private static PyStatementListContainer getDeepestPossibleParentBlock(@NotNull PsiElement whitespace) { - final PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(whitespace); + final PsiElement prevLeaf = getPrevNonCommentLeaf(whitespace); return PsiTreeUtil.getParentOfType(prevLeaf, PyStatementListContainer.class); } @@ -214,6 +211,15 @@ public class PythonCopyPasteProcessor implements CopyPastePreProcessor { return false; } + @Nullable + private static PsiElement getPrevNonCommentLeaf(@NotNull PsiElement element) { + PsiElement anchor = PsiTreeUtil.prevLeaf(element); + while (anchor instanceof PsiComment || anchor instanceof PsiWhiteSpace) { + anchor = PsiTreeUtil.prevLeaf(anchor, false); + } + return anchor; + } + private static boolean inStatementList(@NotNull final PsiFile file, int caretOffset) { final PsiElement element = file.findElementAt(caretOffset); return PsiTreeUtil.getParentOfType(element, PyStatementListContainer.class) != null; diff --git a/python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py new file mode 100644 index 000000000000..8885c5ee26bd --- /dev/null +++ b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py @@ -0,0 +1,6 @@ +def func(): + try: + pass + except: + # comment + x = 42 \ No newline at end of file diff --git a/python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py new file mode 100644 index 000000000000..a0250b345a45 --- /dev/null +++ b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py @@ -0,0 +1,6 @@ +def func(): + try: + pass + except: + # comment + \ No newline at end of file diff --git a/python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py new file mode 100644 index 000000000000..69bdd7794d02 --- /dev/null +++ b/python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py @@ -0,0 +1 @@ +x = 42 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java b/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java index 3f3231bde634..61a1976f0172 100644 --- a/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java +++ b/python/testSrc/com/jetbrains/python/PyCopyPasteTest.java @@ -402,6 +402,11 @@ public class PyCopyPasteTest extends PyTestCase { doTest(); } + // PY-18522 + public void testEmptyParentBlockWithCommentInside() { + doTest(); + } + // PY-19064 public void testAmbiguousParentBlockSmallestIndent() { doTest();