IJPL-339 [psi] send property-change events on write access update

GitOrigin-RevId: c0f70a5a5cf747492a3c64816ae9b3d791ef8bf8
This commit is contained in:
Max Medvedev
2025-11-14 23:26:52 +00:00
committed by intellij-monorepo-bot
parent f52a7fb785
commit d8d02f0191
2 changed files with 57 additions and 17 deletions
@@ -247,15 +247,19 @@ private class PsiVFSListener(private val project: Project) {
}
}
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
treeEvent.newValue = event.newValue
manager.beforePropertyChange(treeEvent)
val psiFiles = fileManager.getCachedPsiFilesInner(vFile).ifEmpty {
return@externalChangeAction
}
for (psiFile in psiFiles) {
val treeEvent = PsiTreeChangeEventImpl(manager)
treeEvent.parent = parentDir
treeEvent.element = psiFile
treeEvent.propertyName = PsiTreeChangeEvent.PROP_WRITABLE
treeEvent.oldValue = event.oldValue
treeEvent.newValue = event.newValue
manager.beforePropertyChange(treeEvent)
}
}
})
}
@@ -408,13 +412,15 @@ private class PsiVFSListener(private val project: Project) {
return@externalChangeAction
}
val treeEvent = PsiTreeChangeEventImpl(manager)
treeEvent.parent = parentDir
treeEvent.element = oldPsiFiles.first() // todo IJPL-339 update me
treeEvent.propertyName = PsiTreeChangeEvent.PROP_WRITABLE
treeEvent.oldValue = event.oldValue
treeEvent.newValue = event.newValue
manager.propertyChanged(treeEvent)
for (oldPsiFile in oldPsiFiles) {
val treeEvent = PsiTreeChangeEventImpl(manager)
treeEvent.parent = parentDir
treeEvent.element = oldPsiFile
treeEvent.propertyName = PsiTreeChangeEvent.PROP_WRITABLE
treeEvent.oldValue = event.oldValue
treeEvent.newValue = event.newValue
manager.propertyChanged(treeEvent)
}
}
VirtualFile.PROP_ENCODING -> {
if (oldPsiFiles.isEmpty()) {
@@ -151,10 +151,44 @@ internal class MultiversePsiEventTest {
expectedEventNumber = 1
)
@Test
fun `test we receive 2 writeable event on changing writable status of a file with 2 psi files`() = doChangeTest(
listenerFactory = { counter ->
object : PsiTreeChangeAdapter() {
override fun propertyChanged(event: PsiTreeChangeEvent) {
if (event.propertyName == PsiTreeChangeEvent.PROP_WRITABLE) {
counter.incrementAndGet()
}
}
}
},
updateBlock = { file ->
file.isWritable = false
},
expectedEventNumber = 2
)
@Test
fun `test we receive 2 before-writeable event on changing writable status of a file with 2 psi files`() = doChangeTest(
listenerFactory = { counter ->
object : PsiTreeChangeAdapter() {
override fun beforePropertyChange(event: PsiTreeChangeEvent) {
if (event.propertyName == PsiTreeChangeEvent.PROP_WRITABLE) {
counter.incrementAndGet()
}
}
}
},
updateBlock = { file ->
file.isWritable = false
},
expectedEventNumber = 2
)
private fun doChangeTest(
listenerFactory: (AtomicInteger) -> PsiTreeChangeListener,
updateBlock: (file: VirtualFile) -> Unit,
@Suppress("SameParameterValue") expectedEventNumber: Int
@Suppress("SameParameterValue") expectedEventNumber: Int,
) = runTest {
val counter = AtomicInteger(0)
val listener = listenerFactory(counter)