From 00ececf543b9ef6f9f3b02bbcf6a6bef1435f125 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 14 Nov 2025 12:39:38 +0100 Subject: [PATCH] IJPL-218636 [psi] send children-change events on changing content of file without document GitOrigin-RevId: 25c4213e205307f3d1c921f45a1603c18667ad9e --- .../psi/impl/file/impl/PsiVFSListener.kt | 8 +++-- .../impl/file/impl/MultiversePsiEventTest.kt | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.kt b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.kt index cf520b3e3c5d..954250d963df 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.kt +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.kt @@ -784,8 +784,8 @@ private class MyFileDocumentManagerListener(private val project: Project) : File private val fileManager = PsiManagerEx.getInstanceEx(project).fileManager as FileManagerEx override fun fileWithNoDocumentChanged(file: VirtualFile) { - val viewProvider = fileManager.findCachedViewProvider(file) - if (viewProvider == null) { + val viewProviders = fileManager.findCachedViewProviders(file) + if (viewProviders.isEmpty()) { project.service().handleVfsChangeWithoutPsi(file) } else { @@ -794,7 +794,9 @@ private class MyFileDocumentManagerListener(private val project: Project) : File fileManager.forceReload(file) } else { - fileManager.reloadPsiAfterTextChange(viewProvider, file) + for (viewProvider in viewProviders) { + fileManager.reloadPsiAfterTextChange(viewProvider, file) + } } }) } diff --git a/platform/lang-impl/testSources/com/intellij/psi/impl/file/impl/MultiversePsiEventTest.kt b/platform/lang-impl/testSources/com/intellij/psi/impl/file/impl/MultiversePsiEventTest.kt index 92f1b12444f4..2c6d06d84b95 100644 --- a/platform/lang-impl/testSources/com/intellij/psi/impl/file/impl/MultiversePsiEventTest.kt +++ b/platform/lang-impl/testSources/com/intellij/psi/impl/file/impl/MultiversePsiEventTest.kt @@ -16,6 +16,7 @@ import com.intellij.psi.PsiTreeChangeAdapter import com.intellij.psi.PsiTreeChangeEvent import com.intellij.psi.PsiTreeChangeListener import com.intellij.psi.impl.PsiManagerEx +import com.intellij.psi.impl.PsiTreeChangeEventImpl import com.intellij.testFramework.IndexingTestUtil import com.intellij.testFramework.common.timeoutRunBlocking import com.intellij.testFramework.junit5.TestApplication @@ -231,6 +232,40 @@ internal class MultiversePsiEventTest { ) } + @Test + fun `test we receive 2 before children changed events on updating content of a file with 2 psi files and WITHOT a document `() = doChangeTest( + listenerFactory = { counter -> + object : PsiTreeChangeAdapter() { + override fun beforeChildrenChange(event: PsiTreeChangeEvent) { + if (!(event as PsiTreeChangeEventImpl).isGenericChange) { + counter.incrementAndGet() + } + } + } + }, + updateBlock = { file -> + file.setBinaryContent("class Baz {}".toByteArray()) + }, + expectedEventNumber = 2 + ) + + @Test + fun `test we receive 2 children changed events on updating content of a file with 2 psi files and WITHOT a document `() = doChangeTest( + listenerFactory = { counter -> + object : PsiTreeChangeAdapter() { + override fun childrenChanged(event: PsiTreeChangeEvent) { + if (!(event as PsiTreeChangeEventImpl).isGenericChange) { + counter.incrementAndGet() + } + } + } + }, + updateBlock = { file -> + file.setBinaryContent("class Baz {}".toByteArray()) + }, + expectedEventNumber = 2 + ) + private fun doChangeTest( listenerFactory: (AtomicInteger) -> PsiTreeChangeListener, updateBlock: (file: VirtualFile) -> Unit,