diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java index 8848884bec49..1b888bcacdbd 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java @@ -27,7 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Supplier; @ApiStatus.Internal -public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree { +public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree { static final Logger LOG = Logger.getInstance(IntervalTreeImpl.class); static final boolean DEBUG = LOG.isDebugEnabled() || ApplicationManager.getApplication() != null && ApplicationManager.getApplication().isUnitTestMode(); private int keySize; // number of all intervals, counting all duplicates, some of them maybe gced @@ -38,7 +38,7 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int private int deadReferenceCount; @ApiStatus.Internal - protected static class IntervalNode extends Node implements MutableInterval { + protected static class IntervalNode extends Node implements MutableInterval { private volatile long myRange; private static final byte ATTACHED_TO_TREE_FLAG = COLOR_MASK <<1; // true if the node is inserted to the tree protected final List> intervals; @@ -367,7 +367,7 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int E runUnderWriteLock(@NotNull Supplier runnable) { if (l.getReadHoldCount() > 0) { - throw new IllegalStateException("Must not perform modifications while holding read lock or iterating"); + throw new IllegalStateException("Must not perform modifications while holding read lock/iterating"); } l.writeLock().lock(); try { @@ -904,8 +904,8 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int if (t == null) continue; liveInterval = t; checkBelongsToTheTree(t, false); - if (((RangeMarkerImpl)t).isValid()) { - long id = ((RangeMarkerImpl)t).getId(); + if (t.isValid()) { + long id = t.getId(); boolean added = ids.add(id); assert added : t +"\nids:"+ids+"; id="+id+"\n; root.intervals="+root.intervals; } @@ -991,28 +991,34 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int @Override public boolean removeInterval(@NotNull T interval) { - if (!((RangeMarkerEx)interval).isValid()) { + if (!interval.isValid()) { return false; } try { return runUnderWriteLock(() -> { - incModCount(); - if (!((RangeMarkerEx)interval).isValid()) return false; - checkBelongsToTheTree(interval, true); - checkMax(true); - processReferenceQueue(); + try { + incModCount(); + boolean ret = false; + if (interval.isValid()) { + checkBelongsToTheTree(interval, true); + checkMax(true); + processReferenceQueue(); - IntervalNode node = lookupNode(interval); - if (node == null) return false; - - beforeRemove(interval, node); - - node.removeInterval(interval); - return true; + IntervalNode node = lookupNode(interval); + if (node != null) { + beforeRemove(interval, node); + node.removeInterval(interval); + ret = true; + } + } + return ret; + } + finally { + setNode(interval, null); + } }); } finally { - setNode(interval, null); fireAfterRemoved(interval); } } @@ -1376,9 +1382,9 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int } } - private static class IntervalTreeGuide implements WalkingState.TreeGuide> { + private static class IntervalTreeGuide implements WalkingState.TreeGuide> { private static final IntervalTreeGuide INSTANCE = new IntervalTreeGuide<>(); - private static @NotNull WalkingState.TreeGuide> getGuide() { + private static @NotNull WalkingState.TreeGuide> getGuide() { //noinspection unchecked,rawtypes return (WalkingState.TreeGuide)INSTANCE; } @@ -1418,7 +1424,7 @@ public abstract class IntervalTreeImpl extends RedBlackTree implements Int // combines iterators for two trees in one using the specified comparator @ApiStatus.Internal - protected static @NotNull MarkupIterator mergingOverlappingIterator( + protected static @NotNull MarkupIterator mergingOverlappingIterator( @NotNull IntervalTreeImpl tree1, @NotNull TextRange tree1Range, @NotNull IntervalTreeImpl tree2, diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java index b2f323b181e5..d5fba0768a4f 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerImpl.java @@ -27,7 +27,7 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx private final @NotNull Object myDocumentOrFile; // either VirtualFile (if any) or DocumentEx if no file associated @ApiStatus.Internal - protected RangeMarkerTree.RMNode myNode; + protected volatile RangeMarkerTree.RMNode myNode; private volatile long myId; private static final StripedIDGenerator counter = new StripedIDGenerator(); diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java index 9f0071770c6c..70924ca8300e 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java @@ -110,7 +110,8 @@ public class RangeMarkerTree extends IntervalTreeImpl intervalNode) { + protected void setNode(@NotNull T key, IntervalNode intervalNode) { + assertUnderWriteLock(); //noinspection unchecked ((RangeMarkerImpl)key).myNode = (RMNode)intervalNode; } @@ -304,9 +305,9 @@ public class RangeMarkerTree extends IntervalTreeImpl root, - int start, int end, int lengthDelta, - @NotNull List> affected) { + protected void collectAffectedMarkersAndShiftSubtrees(@Nullable IntervalNode root, + int start, int end, int lengthDelta, + @NotNull List> affected) { if (root == null) return; pushDelta(root); 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 b7126ed7573d..7f28f9d454a9 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 @@ -881,7 +881,7 @@ public final class FoldingModelImpl extends InlayModel.SimpleAdapter @ApiStatus.Internal @Override - public void collectAffectedMarkersAndShiftSubtrees( + protected void collectAffectedMarkersAndShiftSubtrees( @Nullable IntervalNode root, int start, int end,