FIR IDE: do not consider OOBM in non-physical file as OOBM
This commit is contained in:
+12
-3
@@ -18,6 +18,7 @@ import com.intellij.pom.event.PomModelEvent
|
|||||||
import com.intellij.pom.event.PomModelListener
|
import com.intellij.pom.event.PomModelListener
|
||||||
import com.intellij.pom.tree.TreeAspect
|
import com.intellij.pom.tree.TreeAspect
|
||||||
import com.intellij.pom.tree.events.TreeChangeEvent
|
import com.intellij.pom.tree.events.TreeChangeEvent
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.impl.source.tree.FileElement
|
import com.intellij.psi.impl.source.tree.FileElement
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
@@ -68,16 +69,24 @@ internal class KotlinFirModificationTrackerService(project: Project) : Disposabl
|
|||||||
|
|
||||||
override fun modelChanged(event: PomModelEvent) {
|
override fun modelChanged(event: PomModelEvent) {
|
||||||
val changeSet = event.getChangeSet(treeAspect) as TreeChangeEvent? ?: return
|
val changeSet = event.getChangeSet(treeAspect) as TreeChangeEvent? ?: return
|
||||||
if (changeSet.rootElement.psi.language != KotlinLanguage.INSTANCE) return
|
val psi = changeSet.rootElement.psi
|
||||||
|
if (psi.language != KotlinLanguage.INSTANCE) return
|
||||||
val changedElements = changeSet.changedElements
|
val changedElements = changeSet.changedElements
|
||||||
|
|
||||||
handleChangedElementsInAllModules(changedElements, changeSet)
|
handleChangedElementsInAllModules(changedElements, changeSet, psi)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangedElementsInAllModules(
|
private fun handleChangedElementsInAllModules(
|
||||||
changedElements: Array<out ASTNode>,
|
changedElements: Array<out ASTNode>,
|
||||||
changeSet: TreeChangeEvent
|
changeSet: TreeChangeEvent,
|
||||||
|
changeSetRootElementPsi: PsiElement
|
||||||
) {
|
) {
|
||||||
|
if (!changeSetRootElementPsi.isPhysical) {
|
||||||
|
/**
|
||||||
|
* Element which do not belong to a project should not cause OOBM
|
||||||
|
*/
|
||||||
|
return
|
||||||
|
}
|
||||||
if (changedElements.isEmpty()) {
|
if (changedElements.isEmpty()) {
|
||||||
incrementModificationCountForFileChange(changeSet)
|
incrementModificationCountForFileChange(changeSet)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+50
-6
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.trackers
|
|||||||
|
|
||||||
import com.intellij.openapi.command.WriteCommandAction
|
import com.intellij.openapi.command.WriteCommandAction
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
import com.intellij.openapi.vfs.LocalFileSystem
|
import com.intellij.openapi.vfs.LocalFileSystem
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
@@ -15,11 +17,14 @@ import com.intellij.testFramework.PsiTestUtil
|
|||||||
import junit.framework.Assert
|
import junit.framework.Assert
|
||||||
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
|
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.idea.util.rootManager
|
|
||||||
import org.jetbrains.kotlin.idea.util.sourceRoots
|
import org.jetbrains.kotlin.idea.util.sourceRoots
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
|
import org.jetbrains.kotlin.trackers.KotlinOutOfBlockModificationTrackerFactory
|
||||||
import org.jetbrains.kotlin.trackers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
import org.jetbrains.kotlin.trackers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
||||||
|
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import kotlin.io.path.ExperimentalPathApi
|
import kotlin.io.path.ExperimentalPathApi
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
@@ -84,6 +89,40 @@ class KotlinModuleOutOfBlockTrackerTest : AbstractMultiModuleTest() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testThatNonPhysicalFileChangeNotCausingBOOM() {
|
||||||
|
val moduleA = createModuleWithModificationTracker("a") {
|
||||||
|
listOf(
|
||||||
|
FileWithText("main.kt", "fun main() {}")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val moduleB = createModuleWithModificationTracker("b")
|
||||||
|
|
||||||
|
val moduleAWithTracker = ModuleWithModificationTracker(moduleA)
|
||||||
|
val moduleBWithTracker = ModuleWithModificationTracker(moduleB)
|
||||||
|
|
||||||
|
|
||||||
|
val projectWithModificationTracker = ProjectWithModificationTracker(project)
|
||||||
|
|
||||||
|
runWriteAction {
|
||||||
|
val nonPhysicalPsi = KtPsiFactory(moduleA.project).createFile("nonPhysical", "val a = c")
|
||||||
|
nonPhysicalPsi.add(KtPsiFactory(moduleA.project).createFunction("fun x(){}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
"Out of block modification count for module A should not change after non physical file change, modification count is ${moduleAWithTracker.modificationCount}",
|
||||||
|
moduleAWithTracker.changed()
|
||||||
|
)
|
||||||
|
Assert.assertFalse(
|
||||||
|
"Out of block modification count for module B should not change after non physical file change, modification count is ${moduleBWithTracker.modificationCount}",
|
||||||
|
moduleBWithTracker.changed()
|
||||||
|
)
|
||||||
|
|
||||||
|
Assert.assertFalse(
|
||||||
|
"Out of block modification count for project should not change after non physical file change, modification count is ${projectWithModificationTracker.modificationCount}",
|
||||||
|
projectWithModificationTracker.changed()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun Module.typeInFunctionBody(fileName: String, textAfterTyping: String) {
|
private fun Module.typeInFunctionBody(fileName: String, textAfterTyping: String) {
|
||||||
val file = "${sourceRoots.first().url}/$fileName"
|
val file = "${sourceRoots.first().url}/$fileName"
|
||||||
val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!!
|
val virtualFile = VirtualFileManager.getInstance().findFileByUrl(file)!!
|
||||||
@@ -119,14 +158,19 @@ class KotlinModuleOutOfBlockTrackerTest : AbstractMultiModuleTest() {
|
|||||||
|
|
||||||
private data class FileWithText(val name: String, val text: String)
|
private data class FileWithText(val name: String, val text: String)
|
||||||
|
|
||||||
private class ModuleWithModificationTracker(module: Module) {
|
abstract class WithModificationTracker(protected val modificationTracker: ModificationTracker) {
|
||||||
private val modificationTracker = module.createModuleWithoutDependenciesOutOfBlockModificationTracker()
|
|
||||||
private val initialModificationCount = modificationTracker.modificationCount
|
private val initialModificationCount = modificationTracker.modificationCount
|
||||||
|
val modificationCount: Long get() = modificationTracker.modificationCount
|
||||||
val modificationCount: Long
|
|
||||||
get() = modificationTracker.modificationCount
|
|
||||||
|
|
||||||
fun changed(): Boolean =
|
fun changed(): Boolean =
|
||||||
modificationTracker.modificationCount != initialModificationCount
|
modificationTracker.modificationCount != initialModificationCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ModuleWithModificationTracker(module: Module) : WithModificationTracker(
|
||||||
|
module.createModuleWithoutDependenciesOutOfBlockModificationTracker()
|
||||||
|
)
|
||||||
|
|
||||||
|
private class ProjectWithModificationTracker(project: Project) : WithModificationTracker(
|
||||||
|
project.createProjectWideOutOfBlockModificationTracker()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user