[PSI] new: added collecting uncommited documents traces when they become uncommited

This collection process is disabled by default. It is enabled by the `ide.activity.tracking.enable.debug` registry key.

GitOrigin-RevId: 9f9959f33cab6922869b57204f478f24ef82c198
This commit is contained in:
Sergei Vorobyov
2024-09-20 18:42:38 +02:00
committed by intellij-monorepo-bot
parent 3c633516d1
commit fa1bf0583e
2 changed files with 32 additions and 0 deletions

View File

@@ -6,7 +6,10 @@ import com.intellij.diagnostic.dumpCoroutines
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.registry.Registry
import com.intellij.platform.backend.observation.Observation
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.impl.PsiDocumentManagerBase
import com.intellij.testFramework.concurrency.waitForPromiseAndPumpEdt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.TimeoutCancellationException
@@ -42,6 +45,7 @@ object TestObservation {
}
catch (_: TimeoutCancellationException) {
val activityDump = Observation.dumpAwaitedActivitiesToString()
val uncommitedDocuments = dumpUncommitedDocumentsWithTracesToString(project)
val coroutineDump = dumpCoroutines()
val threadDump = dumpThreadsToString()
@@ -50,6 +54,9 @@ object TestObservation {
|------ Operation log begin ------
|$operationLog
|------- Operation log end -------
|--- Uncommited documents begin --
|$uncommitedDocuments
|---- Uncommited documents end ---
|------ Activity dump begin ------
|$activityDump
|------- Activity dump end -------
@@ -64,6 +71,17 @@ object TestObservation {
}
}
private fun dumpUncommitedDocumentsWithTracesToString(project: Project): String {
if (!Registry.`is`("ide.activity.tracking.enable.debug")) {
return "Enable 'ide.activity.tracking.enable.debug' registry option to collect uncommited document traces"
}
val psiDocumentManager = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
return psiDocumentManager.uncommitedDocumentsWithTraces.entries
.joinToString("\n") {
it.key.toString() + ": " + it.value.stackTraceToString()
}
}
@Service(Service.Level.PROJECT)
private class CoroutineScopeService(private val coroutineScope: CoroutineScope) {
companion object {

View File

@@ -28,6 +28,7 @@ import com.intellij.openapi.progress.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -66,6 +67,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
private final DocumentCommitProcessor myDocumentCommitProcessor;
final Set<Document> myUncommittedDocuments = Collections.newSetFromMap(CollectionFactory.createConcurrentWeakMap());
private final Map<Document, Throwable> myUncommittedDocumentTraces = CollectionFactory.createConcurrentWeakMap();
private final Map<Document, UncommittedInfo> myUncommittedInfos = new ConcurrentHashMap<>();
private /*non-static*/ final Key<UncommittedInfo> FREE_THREADED_UNCOMMITTED_INFO = Key.create("FREE_THREADED_UNCOMMITTED_INFO");
@@ -440,6 +442,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
finally {
if (success.get()) {
myUncommittedDocuments.remove(document);
myUncommittedDocumentTraces.remove(document);
}
}
});
@@ -508,6 +511,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
PsiFile psiFile = getPsiFile(document);
if (psiFile == null) {
myUncommittedDocuments.remove(document);
myUncommittedDocumentTraces.remove(document);
runAfterCommitActions(document);
return true; // the project must be closing or file deleted
}
@@ -865,6 +869,11 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
return ArrayUtil.stripTrailingNulls(documents);
}
@ApiStatus.Internal
public @NotNull Map<Document, Throwable> getUncommitedDocumentsWithTraces() {
return Collections.unmodifiableMap(myUncommittedDocumentTraces);
}
boolean isInUncommittedSet(@NotNull Document document) {
return myUncommittedDocuments.contains(getTopLevelDocument(document));
}
@@ -973,6 +982,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
if (commitNecessary) {
assert !(document instanceof DocumentWindow);
myUncommittedDocuments.add(document);
if (Registry.is("ide.activity.tracking.enable.debug")) {
myUncommittedDocumentTraces.put(document, new Throwable());
}
if (forceCommit) {
commitDocument(document);
}
@@ -1029,6 +1041,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
myUncommittedDocuments.remove(document);
myUncommittedDocumentTraces.remove(document);
if (!myProject.isInitialized() || myProject.isDisposed() || myProject.isDefault()) {
return;
@@ -1138,6 +1151,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
public void clearUncommittedDocuments() {
myUncommittedInfos.clear();
myUncommittedDocuments.clear();
myUncommittedDocumentTraces.clear();
mySynchronizer.cleanupForNextTest();
}