diff --git a/java/java-tests/testSrc/com/intellij/java/psi/TreeIsCorrectAfterDiffReparseTest.java b/java/java-tests/testSrc/com/intellij/java/psi/TreeIsCorrectAfterDiffReparseTest.java index b4e896df8e77..4c98c18bcf7d 100644 --- a/java/java-tests/testSrc/com/intellij/java/psi/TreeIsCorrectAfterDiffReparseTest.java +++ b/java/java-tests/testSrc/com/intellij/java/psi/TreeIsCorrectAfterDiffReparseTest.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NonNls; public class TreeIsCorrectAfterDiffReparseTest extends LightJavaCodeInsightTestCase { - public void testIDEADEV41862() { + public void testIDEADEV41862() throws Throwable { @NonNls String part1 = """ package com.test; @@ -1106,14 +1106,8 @@ public class TreeIsCorrectAfterDiffReparseTest extends LightJavaCodeInsightTestC final Document doc = docManager.getDocument(getFile()); WriteCommandAction.runWriteCommandAction(getProject(), () -> doc.insertString(part1.length(), "/**")); - - boolean old = DebugUtil.CHECK; - DebugUtil.CHECK = true; - try { + DebugUtil.runWithCheckInternalInvariantsEnabled(() -> { docManager.commitAllDocuments(); - } - finally { - DebugUtil.CHECK = old; - } + }); } } diff --git a/platform/core-impl/api-dump-unreviewed.txt b/platform/core-impl/api-dump-unreviewed.txt index c06079c720aa..8fbcf7aaade2 100644 --- a/platform/core-impl/api-dump-unreviewed.txt +++ b/platform/core-impl/api-dump-unreviewed.txt @@ -1581,6 +1581,7 @@ c:com.intellij.openapi.editor.impl.RangeMarkerImpl - p:onReTarget(com.intellij.openapi.editor.event.DocumentEvent):V - p:persistentHighlighterUpdate(com.intellij.openapi.editor.event.DocumentEvent,Z):V - p:registerInTree(I,I,Z,Z,I):V +- s:runAssertingInternalInvariants(com.intellij.util.ThrowableRunnable):V - setGreedyToLeft(Z):V - setGreedyToRight(Z):V - setStickingToRight(Z):V @@ -1588,7 +1589,6 @@ c:com.intellij.openapi.editor.impl.RangeMarkerImpl - p:unregisterInTree():V a:com.intellij.openapi.editor.impl.RedBlackTree - java.util.concurrent.atomic.AtomicInteger -- s:VERIFY:Z - p:root:com.intellij.openapi.editor.impl.RedBlackTree$Node - clear():V - p:deleteNode(com.intellij.openapi.editor.impl.RedBlackTree$Node):V @@ -2442,7 +2442,6 @@ f:com.intellij.psi.impl.CheckUtil - s:checkDelete(com.intellij.openapi.vfs.VirtualFile):V - s:checkWritable(com.intellij.psi.PsiElement):V f:com.intellij.psi.impl.DebugUtil -- s:CHECK:Z - sf:CHECK_INSIDE_ATOMIC_ACTION_ENABLED:Z - sf:DO_EXPENSIVE_CHECKS:Z - ():V @@ -2470,6 +2469,8 @@ f:com.intellij.psi.impl.DebugUtil - s:psiToStringIgnoringNonCode(com.intellij.psi.PsiElement):java.lang.String - s:psiTreeToString(com.intellij.psi.PsiElement,Z):java.lang.String - s:revalidateNode(com.intellij.lang.ASTNode):V +- s:runWithCheckInternalInvariantsDisabled(com.intellij.util.ThrowableRunnable):V +- s:runWithCheckInternalInvariantsEnabled(com.intellij.util.ThrowableRunnable):V - s:sleep(J):V - s:startPsiModification(java.lang.String):V - s:stubTreeToBuffer(com.intellij.psi.stubs.Stub,java.lang.Appendable,I):V 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 ad731a124796..9f87d56f33e1 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 @@ -18,10 +18,12 @@ import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.DocumentUtil; import com.intellij.util.ObjectUtils; +import com.intellij.util.ThrowableRunnable; import com.intellij.util.diff.FilesTooBigForDiffException; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx { private static final Logger LOG = Logger.getInstance(RangeMarkerImpl.class); @@ -467,4 +469,15 @@ public class RangeMarkerImpl extends UserDataHolderBase implements RangeMarkerEx // piggyback myId to store offsets, to conserve memory myId = TextRangeScalarUtil.toScalarRange(startOffset, endOffset); // avoid invalid range } + + @TestOnly + public static void runAssertingInternalInvariants(@NotNull ThrowableRunnable runnable) throws Throwable { + RedBlackTree.VERIFY = true; + try { + runnable.run(); + } + finally { + RedBlackTree.VERIFY = false; + } + } } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java index 5ae1521948e3..e96e4ae09579 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RedBlackTree.java @@ -14,7 +14,7 @@ public abstract class RedBlackTree extends AtomicInteger { // this "extends AtomicInteger" thing is for supporting modCounter. // I couldn't make it "volatile int" field because Unsafe.getAndAddInt is since jdk8 only, and "final AtomicInteger" field would be too many indirections - public static boolean VERIFY; + static boolean VERIFY; private static final int INDENT_STEP = 4; private int nodeSize; // number of nodes protected Node root; diff --git a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java index 05726b8bf833..10bfb3b4cfb6 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java @@ -28,6 +28,7 @@ import com.intellij.util.graph.OutboundSemiGraph; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import java.io.IOException; import java.util.HashSet; @@ -37,8 +38,7 @@ import java.util.Set; public final class DebugUtil { private static final Logger LOG = Logger.getInstance(DebugUtil.class); - - @SuppressWarnings("StaticNonFinalField") public static boolean CHECK; + @SuppressWarnings("StaticNonFinalField") private static boolean CHECK; public static final boolean DO_EXPENSIVE_CHECKS; static { @@ -691,6 +691,29 @@ public final class DebugUtil { .replace(".lang.", ".l."); } + @TestOnly + public static void runWithCheckInternalInvariantsEnabled(@NotNull ThrowableRunnable runnable) throws Throwable { + boolean oldDebugUtilCheck = DebugUtil.CHECK; + DebugUtil.CHECK = true; + try { + runnable.run(); + } + finally { + DebugUtil.CHECK = oldDebugUtilCheck; + } + } + @TestOnly + public static void runWithCheckInternalInvariantsDisabled(@NotNull ThrowableRunnable runnable) throws Throwable { + boolean oldDebugUtilCheck = DebugUtil.CHECK; + DebugUtil.CHECK = false; + try { + runnable.run(); + } + finally { + DebugUtil.CHECK = oldDebugUtilCheck; + } + } + // /** @deprecated use {@link #performPsiModification} instead */