mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
one more correction for a folding model fix (IDEA-177458)
also make EditorStressTest validate folding model's internal state
This commit is contained in:
@@ -37,7 +37,7 @@ abstract class FoldRegionsTree {
|
||||
private static final Comparator<FoldRegion> BY_END_OFFSET = Comparator.comparingInt(RangeMarker::getEndOffset);
|
||||
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>() {
|
||||
static final TObjectHashingStrategy<FoldRegion> OFFSET_BASED_HASHING_STRATEGY = new TObjectHashingStrategy<FoldRegion>() {
|
||||
@Override
|
||||
public int computeHashCode(FoldRegion o) {
|
||||
return o.getStartOffset() * 31 + o.getEndOffset();
|
||||
@@ -77,13 +77,14 @@ abstract class FoldRegionsTree {
|
||||
public boolean process(int offset, @NotNull FoldRegionImpl region, boolean atStart, @NotNull Collection<FoldRegionImpl> overlapping) {
|
||||
if (atStart) {
|
||||
if (sameRange(region, lastRegion)) {
|
||||
if (region.getUserData(VISIBLE) == null) {
|
||||
if (region.getUserData(VISIBLE) == null || lastRegion.getUserData(VISIBLE) != null && region.isExpanded()) {
|
||||
duplicatesToKill.add(region);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
duplicatesToKill.add(lastRegion);
|
||||
if (!visible.isEmpty() && lastRegion == visible.get(visible.size() - 1)) removeFromVisible(visible.size() - 1);
|
||||
if (lastRegion == lastCollapsedRegion) lastCollapsedRegion = null;
|
||||
}
|
||||
}
|
||||
lastRegion = region;
|
||||
|
||||
@@ -34,12 +34,13 @@ import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@@ -622,10 +623,57 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedInternalDocu
|
||||
|
||||
@TestOnly
|
||||
void validateState() {
|
||||
for (FoldRegion region : getAllFoldRegions()) {
|
||||
LOG.assertTrue (!region.isValid() ||
|
||||
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getStartOffset()) &&
|
||||
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), region.getEndOffset()));
|
||||
if (myEditor.getDocument().isInBulkUpdate()) return;
|
||||
|
||||
FoldRegion[] allFoldRegions = getAllFoldRegions();
|
||||
boolean[] invisibleRegions = new boolean[allFoldRegions.length];
|
||||
for (int i = 0; i < allFoldRegions.length; i++) {
|
||||
FoldRegion r1 = allFoldRegions[i];
|
||||
LOG.assertTrue(r1.isValid() &&
|
||||
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getStartOffset()) &&
|
||||
!DocumentUtil.isInsideSurrogatePair(myEditor.getDocument(), r1.getEndOffset()),
|
||||
"Invalid region");
|
||||
for (int j = i + 1; j < allFoldRegions.length; j++) {
|
||||
FoldRegion r2 = allFoldRegions[j];
|
||||
int r1s = r1.getStartOffset();
|
||||
int r1e = r1.getEndOffset();
|
||||
int r2s = r2.getStartOffset();
|
||||
int r2e = r2.getEndOffset();
|
||||
LOG.assertTrue(r1s < r2s && (r1e <= r2s || r1e >= r2e) ||
|
||||
r1s == r2s && r1e != r2e ||
|
||||
r1s > r2s && r1s < r2e && r1e <= r2e ||
|
||||
r1s >= r2e,
|
||||
"Disallowed relative position of regions");
|
||||
if (!r1.isExpanded() && r1s <= r2s && r1e >= r2e) invisibleRegions[j] = true;
|
||||
if (!r2.isExpanded() && r2s <= r1s && r2e >= r1e) invisibleRegions[i] = true;
|
||||
}
|
||||
}
|
||||
Set<FoldRegion> visibleRegions = new THashSet<>(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY);
|
||||
List<FoldRegion> topLevelRegions = new ArrayList<>();
|
||||
for (int i = 0; i < allFoldRegions.length; i++) {
|
||||
if (!invisibleRegions[i]) {
|
||||
FoldRegion region = allFoldRegions[i];
|
||||
LOG.assertTrue(visibleRegions.add(region), "Duplicate visible regions");
|
||||
if (!region.isExpanded()) topLevelRegions.add(region);
|
||||
}
|
||||
}
|
||||
Collections.sort(topLevelRegions, Comparator.comparingInt(r -> r.getStartOffset()));
|
||||
|
||||
FoldRegion[] actualVisibles = fetchVisible();
|
||||
if (actualVisibles != null) {
|
||||
for (FoldRegion r : actualVisibles) {
|
||||
LOG.assertTrue(visibleRegions.remove(r), "Unexpected visible region");
|
||||
}
|
||||
LOG.assertTrue(visibleRegions.isEmpty(), "Missing visible region");
|
||||
}
|
||||
|
||||
FoldRegion[] actualTopLevels = fetchTopLevel();
|
||||
if (actualTopLevels != null) {
|
||||
LOG.assertTrue(actualTopLevels.length == topLevelRegions.size(), "Wrong number of top-level regions");
|
||||
for (int i = 0; i < actualTopLevels.length; i++) {
|
||||
LOG.assertTrue(FoldRegionsTree.OFFSET_BASED_HASHING_STRATEGY.equals(actualTopLevels[i], topLevelRegions.get(i)),
|
||||
"Unexpected top-level region");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -350,4 +350,11 @@ public class FoldingTest extends AbstractEditorTest {
|
||||
addCollapsedFoldRegion(11, 12, "innermost");
|
||||
Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel());
|
||||
}
|
||||
|
||||
public void testIdenticalRegionsOtherCase() {
|
||||
FoldRegion inner = addCollapsedFoldRegion(10, 15, "inner");
|
||||
addFoldRegion(10, 20, "outer");
|
||||
WriteCommandAction.runWriteCommandAction(ourProject, () -> myEditor.getDocument().deleteString(15, 20));
|
||||
Assert.assertArrayEquals(new FoldRegion[]{inner}, myModel.fetchTopLevel());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user