From 22d73991e70a32155f992d3718177a9c1818469e Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Tue, 21 Jan 2014 10:26:46 +0400 Subject: [PATCH] IDEA-95410 Arrangement: Preserve fold regions on arrangement --- .../JavaRearrangerFoldingTest.groovy | 198 +++++++++++++----- .../actions/ReformatCodeAction.java | 2 +- .../arrangement/engine/ArrangementEngine.java | 19 +- .../RestoreFoldArrangementCallback.java | 46 ++-- 4 files changed, 195 insertions(+), 70 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy index 9166eaf5d4ae..dfee35bb83c6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerFoldingTest.groovy @@ -15,6 +15,9 @@ */ package com.intellij.psi.codeStyle.arrangement +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PRIVATE +import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.PUBLIC + /** * @author Denis Zhdanov * @since 11/20/12 3:34 PM @@ -24,51 +27,152 @@ class JavaRearrangerFoldingTest extends AbstractJavaRearrangerTest { void "test dummy"() { } - // This should be uncommented as soon as cdr pushed fixes for range markers processing. -// void "test that doc comment folding is preserved"() { -// commonSettings.BLANK_LINES_AROUND_METHOD = 1 -// doTest( -// initial: '''\ -//import java.util.List; -//import java.util.Set; -// -///** -// * Class comment -// */ -//class Test { -// -// /** -// * Another method comment -// */ -// public void test(Set s) {} -//}''', -// -// rules: [rule(PUBLIC), rule(PRIVATE)], -// -// expected: '''\ -//import java.util.List; -//import java.util.Set; -// -///** -// * Class comment -// */ -//class Test { -// -// /** -// * Method comment -// */ -// private void test(List l) {} -//}''' -// ) -// } + void "test that doc comment folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +import java.util.List; +import java.util.Set; + +/** +* Class comment +*/ +class Test { + + /** + * Another method comment + */ + public void test(Set s) {} +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +import java.util.List; +import java.util.Set; + +/** +* Class comment +*/ +class Test { + + /** + * Method comment + */ + private void test(List l) {} +}''' + ) + } + + void "test that doc comment and method folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +import java.util.List; +import java.util.Set; + +class MyTest { + /** + * comment 1 + * + * @param s + */ + private void test(String s) { + } + + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + } +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +import java.util.List; +import java.util.Set; + +class MyTest { + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + } + + /** + * comment 1 + * + * @param s + */ + private void test(String s) { + } +}''' + ) + } + + void "test that single doc comment folding is preserved"() { + commonSettings.BLANK_LINES_AROUND_METHOD = 1 + doTest( + initial: '''\ +package a.b; + +class MyTest { + /** + * private comment + * + * @param s + */ + private void test(String s) { + } + + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + System.out.println(1); + } +}''', + + rules: [rule(PUBLIC), rule(PRIVATE)], + + expected: '''\ +package a.b; + +class MyTest { + /** + * comment 2 + * + * @param i + */ + public void test(int i) { + System.out.println(1); + } + + /** + * private comment + * + * @param s + */ + private void test(String s) { + } +}''' + ) + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java index 0dc880d92a53..215e9a56ec40 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java @@ -194,7 +194,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - engine.arrange(finalFile, Collections.singleton(rangeToUse)); + engine.arrange(editor, finalFile, Collections.singleton(rangeToUse)); } }, getTemplatePresentation().getText(), null); } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java index 53907d7c4d02..4f54fa7b56aa 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/ArrangementEngine.java @@ -53,12 +53,25 @@ import java.util.*; */ public class ArrangementEngine { + /** + * Arranges given PSI root contents that belong to the given ranges. + * Note: After arrangement editor foldings we'll be preserved. + * + * @param editor + * @param file target PSI root + * @param ranges target ranges to use within the given root + */ public void arrange(@NotNull final Editor editor, @NotNull PsiFile file, Collection ranges) { - arrange(file, ranges, null); - // This should be uncommented as soon as cdr pushed fixes for range markers processing. - //arrange(file, ranges, new RestoreFoldArrangementCallback(editor)); + arrange(file, ranges, new RestoreFoldArrangementCallback(editor)); } + /** + * Arranges given PSI root contents that belong to the given ranges. + * Note: Editor foldings are not expected to be preserved. + * + * @param file target PSI root + * @param ranges target ranges to use within the given root + */ public void arrange(@NotNull PsiFile file, @NotNull Collection ranges) { arrange(file, ranges, null); } diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java index 8f93afe4cc50..b23b79c8c88b 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/arrangement/engine/RestoreFoldArrangementCallback.java @@ -18,16 +18,10 @@ package com.intellij.psi.codeStyle.arrangement.engine; import com.intellij.codeInsight.folding.CodeFoldingManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; -import com.intellij.openapi.fileEditor.impl.text.CodeFoldingState; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.ContainerUtilRt; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.Comparator; +import java.util.ArrayList; import java.util.List; /** @@ -37,34 +31,48 @@ import java.util.List; public class RestoreFoldArrangementCallback implements ArrangementCallback { @NotNull private final Editor myEditor; - @Nullable private final CodeFoldingState myCodeFoldingState; public RestoreFoldArrangementCallback(@NotNull Editor editor) { myEditor = editor; - - Project project = editor.getProject(); - if (project == null) { - myCodeFoldingState = null; - } - else { - final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(editor.getProject()); - myCodeFoldingState = foldingManager.saveFoldingState(editor); - } } @Override public void afterArrangement(@NotNull final List moveInfos) { // Restore state for the PSI elements not affected by arrangement. Project project = myEditor.getProject(); - if (myCodeFoldingState != null && project != null) { + if (project != null) { + final FoldRegion[] regions = myEditor.getFoldingModel().getAllFoldRegions(); + final List foldRegionsInfo = new ArrayList(); + for (FoldRegion region : regions) { + final FoldRegionInfo info = new FoldRegionInfo(region.getStartOffset(), region.getEndOffset(), region.isExpanded()); + foldRegionsInfo.add(info); + } + final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(project); foldingManager.updateFoldRegions(myEditor); myEditor.getFoldingModel().runBatchFoldingOperation(new Runnable() { @Override public void run() { - foldingManager.restoreFoldingState(myEditor, myCodeFoldingState); + for (FoldRegionInfo info : foldRegionsInfo) { + final FoldRegion foldRegion = foldingManager.findFoldRegion(myEditor, info.myStart, info.myEnd); + if (foldRegion != null) { + foldRegion.setExpanded(info.myIsExpanded); + } + } } }); } } + + private static class FoldRegionInfo { + private int myStart; + private int myEnd; + private boolean myIsExpanded; + + private FoldRegionInfo(int start, int end, boolean expanded) { + myStart = start; + myEnd = end; + myIsExpanded = expanded; + } + } }