From e2689cb6c6698b3ca0ceabeadbb79897d0574917 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 2 Feb 2016 17:58:23 +0300 Subject: [PATCH] reimplement fix 6fb3647 to account for another use case - update of folding placeholder text depending on folded text region --- .../folding/JavaFoldingTest.groovy | 27 +++++++++++++++++++ .../impl/UpdateFoldRegionsOperation.java | 7 ++++- .../injected/editor/FoldingModelWindow.java | 8 ++++++ .../openapi/editor/ex/FoldingModelEx.java | 4 +++ .../openapi/editor/impl/FoldRegionImpl.java | 24 ++++++++++++++++- .../openapi/editor/impl/FoldRegionsTree.java | 10 ++++++- .../openapi/editor/impl/FoldingModelImpl.java | 12 +++++++++ 7 files changed, 89 insertions(+), 3 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 36389acf1e86..c4de6ead161c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -1217,6 +1217,33 @@ class Foo { myFixture.doHighlighting() assertTopLevelFoldRegionsState "[FoldRegion +(24:83), placeholder='{...}']" } + + public void "test placeholder update on refactoring"() { + configure """\ +class Foo { + void method() {} + + Foo foo = new Foo() { + void method() { + System.out.println(); + } + }; +} +""" + assertTopLevelFoldRegionsState "[FoldRegion +(46:84), placeholder='method() → { ', FoldRegion +(105:115), placeholder=' }']" + + // emulate rename refactoring ('method' to 'otherMethod') + def document = myFixture.editor.document + WriteCommandAction.runWriteCommandAction myFixture.project, { + int pos; + while ((pos = document.getText().indexOf("method")) >= 0) { + document.replaceString(pos, pos + "method".length(), "otherMethod") + } + } + + myFixture.doHighlighting() + assertTopLevelFoldRegionsState "[FoldRegion +(51:94), placeholder='otherMethod() → { ', FoldRegion +(115:125), placeholder=' }']" + } private void assertTopLevelFoldRegionsState(String expectedState) { assertEquals(expectedState, myFixture.editor.foldingModel.toString()) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java index 27f5b243c4a7..c5f6f6b32b08 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/UpdateFoldRegionsOperation.java @@ -93,6 +93,8 @@ class UpdateFoldRegionsOperation implements Runnable { List newRegions = addNewRegions(info, foldingModel, elementsToFold, rangeToExpandStatusMap, shouldExpand, groupExpand); applyExpandStatus(newRegions, shouldExpand, groupExpand); + + foldingModel.clearDocumentRangesModificationStatus(); } private static void applyExpandStatus(@NotNull List newRegions, @@ -248,7 +250,10 @@ class UpdateFoldRegionsOperation implements Runnable { } private boolean regionCanBeRemovedWhenCollapsed(FoldRegion region) { - return Boolean.TRUE.equals(region.getUserData(CAN_BE_REMOVED_WHEN_COLLAPSED)) || !region.isValid() || isRegionInCaretLine(region); + return Boolean.TRUE.equals(region.getUserData(CAN_BE_REMOVED_WHEN_COLLAPSED)) || + ((FoldingModelEx)myEditor.getFoldingModel()).hasDocumentRegionChangedFor(region) || + !region.isValid() || + isRegionInCaretLine(region); } private boolean isRegionInCaretLine(FoldRegion region) { diff --git a/platform/lang-impl/src/com/intellij/injected/editor/FoldingModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/FoldingModelWindow.java index 50bd50d4df16..a2a59294efe3 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/FoldingModelWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/FoldingModelWindow.java @@ -200,6 +200,14 @@ class FoldingModelWindow implements FoldingModelEx{ return result; } + @Override + public void clearDocumentRangesModificationStatus() {} + + @Override + public boolean hasDocumentRegionChangedFor(@NotNull FoldRegion region) { + return false; + } + @Override public void clearFoldRegions() { myDelegate.clearFoldRegions(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/FoldingModelEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/FoldingModelEx.java index 47eec67a0631..45bfcf0abd8e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/FoldingModelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/FoldingModelEx.java @@ -64,4 +64,8 @@ public interface FoldingModelEx extends FoldingModel { @NotNull List getGroupedRegions(FoldingGroup group); + + void clearDocumentRangesModificationStatus(); + + boolean hasDocumentRegionChangedFor(@NotNull FoldRegion region); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java index 66ddf67e3f31..f47aeac2352c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.FoldingGroup; +import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.ex.DocumentEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,6 +38,7 @@ class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion { private final String myPlaceholderText; private final FoldingGroup myGroup; private final boolean myShouldNeverExpand; + private boolean myDocumentRegionWasChanged; FoldRegionImpl(@NotNull Editor editor, int startOffset, @@ -119,6 +121,26 @@ class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion { public boolean shouldNeverExpand() { return myShouldNeverExpand; } + + boolean hasDocumentRegionChanged() { + return myDocumentRegionWasChanged; + } + + void resetDocumentRegionChanged() { + myDocumentRegionWasChanged = false; + } + + @Override + protected void changedUpdateImpl(@NotNull DocumentEvent e) { + if (isValid()) { + int oldStart = intervalStart(); + int oldEnd = intervalEnd(); + int changeStart = e.getOffset(); + int changeEnd = e.getOffset() + e.getOldLength(); + if (changeStart < oldEnd && changeEnd > oldStart) myDocumentRegionWasChanged = true; + } + super.changedUpdateImpl(e); + } @Override public String toString() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java index f18b39cf479d..9de2346e741d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldRegionsTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -358,6 +358,14 @@ abstract class FoldRegionsTree { return index < 0 ? null : myRegions.get(index); } + void clearDocumentRangesModificationStatus() { + for (FoldRegion region : myRegions) { + if (region instanceof FoldRegionImpl) { + ((FoldRegionImpl)region).resetDocumentRegionChanged(); + } + } + } + private class CachedData implements Cloneable { private final FoldRegion[] visibleRegions; private final FoldRegion[] topLevelRegions; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java index f083cc233785..3c5ed7c92986 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/FoldingModelImpl.java @@ -87,6 +87,18 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedInternalDocu return (List)myGroups.get(group); } + @Override + public void clearDocumentRangesModificationStatus() { + assertIsDispatchThreadForEditor(); + myFoldTree.clearDocumentRangesModificationStatus(); + } + + @Override + public boolean hasDocumentRegionChangedFor(@NotNull FoldRegion region) { + assertReadAccess(); + return region instanceof FoldRegionImpl && ((FoldRegionImpl)region).hasDocumentRegionChanged(); + } + @NotNull public FoldRegion getFirstRegion(@NotNull FoldingGroup group, FoldRegion child) { final List regions = getGroupedRegions(group);