PY-18522 Detection of empty parent block takes comments into account
authorMikhail Golubev <mikhail.golubev@jetbrains.com>
Tue, 5 Apr 2016 12:12:57 +0000 (15:12 +0300)
committerMikhail Golubev <mikhail.golubev@jetbrains.com>
Tue, 5 Apr 2016 14:04:19 +0000 (17:04 +0300)
python/src/com/jetbrains/python/editor/PythonCopyPasteProcessor.java
python/testData/copyPaste/EmptyParentBlockWithCommentInside.after.py [new file with mode: 0644]
python/testData/copyPaste/EmptyParentBlockWithCommentInside.dst.py [new file with mode: 0644]
python/testData/copyPaste/EmptyParentBlockWithCommentInside.src.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/PyCopyPasteTest.java

index dfb1294427da51dae574807b14f59f75fd9ba785..d4e90b69ade3e7fddcd34245b391dd91d3b4de22 100644 (file)
@@ -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 (file)
index 0000000..8885c5e
--- /dev/null
@@ -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 (file)
index 0000000..a0250b3
--- /dev/null
@@ -0,0 +1,6 @@
+def func():
+    try:
+        pass
+    except:
+        # comment
+<caret>        
\ 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 (file)
index 0000000..69bdd77
--- /dev/null
@@ -0,0 +1 @@
+<selection>x = 42</selection>
\ No newline at end of file
index 3f3231bde6348a39cc8d34b92f819ee30ca7b6f7..61a1976f01726c16e1cf9443e68e9599d45c4208 100644 (file)
@@ -402,6 +402,11 @@ public class PyCopyPasteTest extends PyTestCase {
     doTest();
   }
 
+  // PY-18522
+  public void testEmptyParentBlockWithCommentInside() {
+    doTest();
+  }
+
   // PY-19064
   public void testAmbiguousParentBlockSmallestIndent() {
     doTest();