preserve folding model consistency on document change - remove fold regions which become equal

This commit is contained in:
Dmitry Batrak
2014-12-24 14:42:38 +03:00
parent 56f2123663
commit 4da8d8a4a4
2 changed files with 43 additions and 1 deletions
@@ -19,6 +19,8 @@ import com.intellij.openapi.editor.*;
import com.intellij.openapi.util.Key;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,6 +49,18 @@ abstract class FoldRegionsTree {
};
private static final Comparator<? super FoldRegion> BY_END_OFFSET_REVERSE = Collections.reverseOrder(BY_END_OFFSET);
private static final TObjectHashingStrategy<FoldRegion> OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy<FoldRegion>() {
@Override
public int computeHashCode(FoldRegion o) {
return o.getStartOffset() * 31 + o.getEndOffset();
}
@Override
public boolean equals(FoldRegion o1, FoldRegion o2) {
return o1.getStartOffset() == o2.getStartOffset() && o1.getEndOffset() == o2.getEndOffset();
}
};
void clear() {
clearCachedValues();
@@ -67,11 +81,16 @@ abstract class FoldRegionsTree {
List<FoldRegion> topLevels = new ArrayList<FoldRegion>(myRegions.size() / 2);
List<FoldRegion> visible = new ArrayList<FoldRegion>(myRegions.size());
List<FoldRegion> allValid = new ArrayList<FoldRegion>(myRegions.size());
Set<FoldRegion> distinctRegions = new THashSet<FoldRegion>(myRegions.size(), OFFSET_BASED_HASHING_STRATEGY);
FoldRegion currentCollapsed = null;
for (FoldRegion region : myRegions) {
if (!region.isValid()) {
continue;
}
if (!distinctRegions.add(region)) {
region.dispose();
continue;
}
allValid.add(region);
}
@@ -134,9 +153,11 @@ abstract class FoldRegionsTree {
rebuild();
return;
}
Set<FoldRegion> distinctRegions = new THashSet<FoldRegion>(visibleRegions.length, OFFSET_BASED_HASHING_STRATEGY);
for (FoldRegion foldRegion : visibleRegions) {
if (!foldRegion.isValid()) {
if (!foldRegion.isValid() || !distinctRegions.add(foldRegion)) {
rebuild();
return;
}
@@ -22,6 +22,7 @@ import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.TestFileType;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
/**
* @author max
@@ -195,4 +196,24 @@ public class FoldingTest extends AbstractEditorTest {
assertTrue(myModel.isOffsetCollapsed(5));
}
public void testIdenticalRegionsAreRemoved() {
addFoldRegion(0, 5, "...");
addFoldRegion(0, 4, "...");
assertNumberOfValidFoldRegions(2);
myEditor.getDocument().deleteString(4, 5);
assertNumberOfValidFoldRegions(1);
}
private void assertNumberOfValidFoldRegions(int expectedValue) {
int actualValue = 0;
for (FoldRegion region : myModel.getAllFoldRegions()) {
if (region.isValid()) {
actualValue++;
}
}
assertEquals(expectedValue, actualValue);
}
}