From 6bc46a28cef80369913779cd7720258b80ddf780 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 22 Jun 2017 17:00:43 +0200 Subject: [PATCH] IPP: fix "Move comment to separate line" whitespace issues --- .../MoveCommentToSeparateLineIntention.java | 79 ++++++++++--------- .../comment/separate_line/BigWhitespace.java | 8 ++ .../separate_line/BigWhitespace_after.java | 9 +++ .../comment/separate_line/Simple_after.java | 4 +- .../comment/separate_line/StartOfFile2.java | 3 + .../separate_line/StartOfFile2_after.java | 4 + ...oveCommentToSeparateLineIntentionTest.java | 6 +- 7 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace_after.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2_after.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntention.java index 8a2d62fffe35..85bdc7cbb683 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Dave Griffith + * Copyright 2003-2017 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,14 @@ */ package com.siyeh.ipp.comment; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NotNull; @@ -30,47 +34,48 @@ public class MoveCommentToSeparateLineIntention extends Intention { return new CommentOnLineWithSourcePredicate(); } - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { - final PsiComment selectedComment = (PsiComment)element; - PsiElement elementToCheck = selectedComment; - final PsiWhiteSpace whiteSpace; + public void processIntention(@NotNull PsiElement element) { + final PsiComment comment = (PsiComment)element; + final PsiWhiteSpace whitespace; while (true) { - elementToCheck = PsiTreeUtil.prevLeaf(elementToCheck); - if (elementToCheck == null) { - return; - } - if (isLineBreakWhiteSpace(elementToCheck)) { - whiteSpace = (PsiWhiteSpace)elementToCheck; + final PsiElement prevLeaf = PsiTreeUtil.prevLeaf(element); + if (prevLeaf == null || CommentOnLineWithSourcePredicate.isLineBreakWhiteSpace(prevLeaf)) { + whitespace = (PsiWhiteSpace)prevLeaf; break; } + element = prevLeaf; } - final PsiElement copyWhiteSpace = whiteSpace.copy(); - final PsiElement parent = whiteSpace.getParent(); - assert parent != null; - final PsiManager manager = selectedComment.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final String commentText = selectedComment.getText(); - final PsiComment newComment = - factory.createCommentFromText(commentText, parent); - final PsiElement insertedComment = parent - .addBefore(newComment, whiteSpace); - parent.addBefore(copyWhiteSpace, insertedComment); + final PsiElement anchor = element; - selectedComment.delete(); - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); - codeStyleManager.reformat(insertedComment); + final Project project = comment.getProject(); + final Document document = PsiDocumentManager.getInstance(project).getDocument(comment.getContainingFile()); + if (document == null) { + return; + } + final String newline; + if (whitespace == null) { + newline = "\n"; + } + else { + final String text = whitespace.getText(); + newline = text.substring(text.lastIndexOf('\n')); + } + final PsiElement prev = PsiTreeUtil.prevLeaf(comment); + final int deleteOffset = prev instanceof PsiWhiteSpace ? prev.getTextOffset() : comment.getTextOffset(); + document.deleteString(deleteOffset, comment.getTextOffset() + comment.getTextLength()); + + final int offset = anchor.getTextOffset(); + document.insertString(offset, newline); + document.insertString(offset, comment.getText()); + scrollToVisible(project, offset); } - private static boolean isLineBreakWhiteSpace(PsiElement element) { - if (!(element instanceof PsiWhiteSpace)) { - return false; + private static void scrollToVisible(Project project, int offset) { + final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) { + return; } - final String text = element.getText(); - return containsLineBreak(text); - } - - private static boolean containsLineBreak(String text) { - return text.indexOf((int)'\n') >= 0 || text.indexOf((int)'\r') >= 0; + final LogicalPosition position = editor.offsetToLogicalPosition(offset); + editor.getScrollingModel().scrollTo(position, ScrollType.MAKE_VISIBLE); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace.java new file mode 100644 index 000000000000..7483a16cbe96 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace.java @@ -0,0 +1,8 @@ +class A { + + + + + + String a; // not b +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace_after.java new file mode 100644 index 000000000000..390399a76576 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/BigWhitespace_after.java @@ -0,0 +1,9 @@ +class A { + + + + + + // not b + String a; +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/Simple_after.java index 5f4a766a6494..2de89c4f4830 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/Simple_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/Simple_after.java @@ -1,7 +1,7 @@ class X { void m() { - // covfafa - System.out.println(); + // covfafa + System.out.println(); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2.java new file mode 100644 index 000000000000..97b17168f66a --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2.java @@ -0,0 +1,3 @@ +package s; // factory food + +class A {} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2_after.java new file mode 100644 index 000000000000..e98a01ec0e6b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/comment/separate_line/StartOfFile2_after.java @@ -0,0 +1,4 @@ +// factory food +package s; + +class A {} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntentionTest.java index f8b4e02f0bb9..7baab46489e1 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/comment/MoveCommentToSeparateLineIntentionTest.java @@ -22,9 +22,9 @@ import com.siyeh.ipp.IPPTestCase; */ public class MoveCommentToSeparateLineIntentionTest extends IPPTestCase { - public void testSimple() { - doTest(); - } + public void testSimple() { doTest(); } + public void testBigWhitespace() { doTest(); } + public void testStartOfFile2() { doTest(); } public void testStartOfFile() { assertIntentionNotAvailable();