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 302791f03a1c..84a67a68f2e9 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 @@ -176,8 +176,6 @@ private class PsiVFSListener(private val project: Project) { } ApplicationManager.getApplication().runWriteAction(ExternalChangeActionUtil.externalChangeAction { - val treeEvent = PsiTreeChangeEventImpl(manager) - treeEvent.parent = parentDir if (propertyName == VirtualFile.PROP_NAME) { if (parentDir == null) { return@externalChangeAction @@ -188,6 +186,8 @@ private class PsiVFSListener(private val project: Project) { val psiDir = fileManager.findDirectory(vFile) if (psiDir != null) { if (!FileTypeManager.getInstance().isFileIgnored(newName)) { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir treeEvent.child = psiDir treeEvent.propertyName = PsiTreeChangeEvent.PROP_DIRECTORY_NAME treeEvent.oldValue = vFile.name @@ -195,45 +195,62 @@ private class PsiVFSListener(private val project: Project) { manager.beforePropertyChange(treeEvent) } else { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir treeEvent.child = psiDir manager.beforeChildRemoval(treeEvent) } } else { if ((!Registry.`is`("ide.hide.excluded.files") || !isExcludeRoot(vFile)) && !FileTypeManager.getInstance().isFileIgnored(newName)) { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir manager.beforeChildAddition(treeEvent) } } } else { - val psiFile = fileManager.findViewProvider(vFile).getPsi(fileManager.findViewProvider(vFile).baseLanguage) - val psiFile1 = createFileCopyWithNewName(vFile, newName) + val viewProviders = fileManager.findCachedViewProviders(vFile).ifEmpty { listOf(fileManager.findViewProvider(vFile)) } + for (viewProvider in viewProviders) { + val psiFile = viewProvider.getPsi(fileManager.findViewProvider(vFile).baseLanguage) + val psiFile1 = createFileCopyWithNewName(vFile, newName) - if (psiFile != null) { - if (psiFile1 == null) { - treeEvent.child = psiFile - manager.beforeChildRemoval(treeEvent) + if (psiFile != null) { + if (psiFile1 == null) { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir + treeEvent.child = psiFile + manager.beforeChildRemoval(treeEvent) + } + else if (psiFile1.javaClass != psiFile.javaClass) { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir + treeEvent.oldChild = psiFile + manager.beforeChildReplacement(treeEvent) + } + else { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir + treeEvent.child = psiFile + treeEvent.propertyName = PsiTreeChangeEvent.PROP_FILE_NAME + treeEvent.oldValue = vFile.name + treeEvent.newValue = newName + manager.beforePropertyChange(treeEvent) + } } - else if (psiFile1.javaClass != psiFile.javaClass) { - treeEvent.oldChild = psiFile - manager.beforeChildReplacement(treeEvent) + else if (psiFile1 != null) { + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir + manager.beforeChildAddition(treeEvent) } - else { - treeEvent.child = psiFile - treeEvent.propertyName = PsiTreeChangeEvent.PROP_FILE_NAME - treeEvent.oldValue = vFile.name - treeEvent.newValue = newName - manager.beforePropertyChange(treeEvent) - } - } - else if (psiFile1 != null) { - manager.beforeChildAddition(treeEvent) } } } else if (propertyName == VirtualFile.PROP_WRITABLE) { // todo IJPL-339 implement proper event for multiple files val psiFile = fileManager.getCachedPsiFileInner(vFile, anyContext()) ?: return@externalChangeAction + val treeEvent = PsiTreeChangeEventImpl(manager) + treeEvent.parent = parentDir treeEvent.element = psiFile treeEvent.propertyName = PsiTreeChangeEvent.PROP_WRITABLE treeEvent.oldValue = event.oldValue 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 3737d4e4c1b6..9e343c92fee6 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 @@ -82,6 +82,32 @@ internal class MultiversePsiEventTest { expectedEventNumber = 2 ) + @Test + fun `test we receive 2 before-property-change rename events on renaming file with 2 psi files`() = doChangeTest( + listenerFactory = { counter -> + object : PsiTreeChangeAdapter() { + override fun beforePropertyChange(event: PsiTreeChangeEvent) { + counter.incrementAndGet() + } + } + }, + updateBlock = { file -> file.rename(this, "B.java") }, + expectedEventNumber = 2 + ) + + @Test + fun `test we receive 2 property-change rename events on renaming file with 2 psi files`() = doChangeTest( + listenerFactory = { counter -> + object : PsiTreeChangeAdapter() { + override fun propertyChanged(event: PsiTreeChangeEvent) { + counter.incrementAndGet() + } + } + }, + updateBlock = { file -> file.rename(this, "B.java") }, + expectedEventNumber = 2 + ) + private fun doChangeTest( listenerFactory: (AtomicInteger) -> PsiTreeChangeListener, updateBlock: (file: VirtualFile) -> Unit,