[Kotlin] KTIJ-35916 Register KotlinForwardDeclarationsModelChangeService as WorkspaceModelChangeListener directly

GitOrigin-RevId: 69e2b779c868b97d8b7515cc4d3664c58106b34d
This commit is contained in:
Ilya Korennoy
2025-10-15 11:25:56 +00:00
committed by intellij-monorepo-bot
parent dd1719669c
commit d161e67b72
2 changed files with 28 additions and 39 deletions
@@ -1,16 +1,12 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.base.projectStructure.forwardDeclarations
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.startup.ProjectActivity
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.platform.backend.workspace.WorkspaceModel
import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener
import com.intellij.platform.backend.workspace.WorkspaceModelTopics
import com.intellij.platform.workspace.jps.entities.LibraryEntity
import com.intellij.platform.workspace.jps.entities.modifyLibraryEntity
import com.intellij.platform.workspace.storage.EntityChange
@@ -30,44 +26,44 @@ import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
import java.io.File
/**
* Service for background generation of K/N forward declaration files on workspace model updates.
* Listener for background generation of K/N forward declaration files on workspace model updates.
* Detected updates in relevant KLIB libraries trigger regeneration of synthetic Kotlin files.
* Generated roots are stored inside a child [KotlinForwardDeclarationsWorkspaceEntity] of the affected library.
*
* @see [KotlinForwardDeclarationsFileGenerator]
*/
@Service(Service.Level.PROJECT)
internal class KotlinForwardDeclarationsModelChangeService(private val project: Project, cs: CoroutineScope) {
init {
val busConnection = project.messageBus.connect()
busConnection.subscribe(WorkspaceModelTopics.CHANGED, object : WorkspaceModelChangeListener {
override fun changed(event: VersionedStorageChange) {
val fwdDeclarationChanges = event.getChanges<KotlinForwardDeclarationsWorkspaceEntity>()
cleanUp(fwdDeclarationChanges)
internal class KotlinForwardDeclarationsModelChangeService(
private val project: Project,
private val cs: CoroutineScope,
) : WorkspaceModelChangeListener {
val libraryChanges = event.getChanges<LibraryEntity>().ifEmpty { return }
override fun changed(event: VersionedStorageChange) {
cs.launch {
val fwdDeclarationChanges = event.getChanges<KotlinForwardDeclarationsWorkspaceEntity>()
cleanUp(fwdDeclarationChanges)
val nativeKlibs: Map<LibraryEntity, KLibRoot> =
libraryChanges.toNativeKLibs(event.storageAfter).ifEmpty { return }
val workspaceModel = WorkspaceModel.getInstance(project)
val createEntityStorageChanges = createEntityStorageChanges(workspaceModel, nativeKlibs)
val libraryChanges = event.getChanges<LibraryEntity>().ifEmpty { return@launch }
cs.launch {
workspaceModel.update("Kotlin Forward Declarations workspace model update") { storage ->
createEntityStorageChanges.forEach { (libraryEntity, builder) ->
val nativeKlibs: Map<LibraryEntity, KLibRoot> =
libraryChanges.toNativeKLibs(event.storageAfter).ifEmpty { return@launch }
val workspaceModel = WorkspaceModel.getInstance(project)
val createEntityStorageChanges = createEntityStorageChanges(workspaceModel, nativeKlibs)
// a hack to bypass workspace model issues; without the extra check entity updates lead to recursion
if (libraryEntity.kotlinForwardDeclarationsWorkspaceEntity == null) {
storage.modifyLibraryEntity(libraryEntity) {
this.kotlinForwardDeclarationsWorkspaceEntity = builder
}
storage.addEntity(builder)
cs.launch {
workspaceModel.update("Kotlin Forward Declarations workspace model update") { storage ->
createEntityStorageChanges.forEach { (libraryEntity, builder) ->
// a hack to bypass workspace model issues; without the extra check entity updates lead to recursion
if (libraryEntity.kotlinForwardDeclarationsWorkspaceEntity == null) {
storage.modifyLibraryEntity(libraryEntity) {
this.kotlinForwardDeclarationsWorkspaceEntity = builder
}
storage.addEntity(builder)
}
}
}
}
})
}
}
private fun cleanUp(fwdDeclarationChanges: List<EntityChange<KotlinForwardDeclarationsWorkspaceEntity>>) {
@@ -120,13 +116,4 @@ internal class KotlinForwardDeclarationsModelChangeService(private val project:
it.isKlibLibraryRootForPlatform(NativeIdePlatformKind.defaultPlatform)
}
}
}
/**
* Request [KotlinForwardDeclarationsModelChangeService] on startup to start receiving workspace model update events.
*/
internal class KotlinForwardDeclarationsStartupActivity : ProjectActivity {
override suspend fun execute(project: Project) {
project.service<KotlinForwardDeclarationsModelChangeService>()
}
}
@@ -1,11 +1,13 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity
implementation="org.jetbrains.kotlin.idea.base.projectStructure.forwardDeclarations.KotlinForwardDeclarationsStartupActivity"/>
<workspaceModel.fileIndexContributor
implementation="org.jetbrains.kotlin.idea.base.projectStructure.forwardDeclarations.KotlinForwardDeclarationsWorkspaceFileIndexContributor"/>
<virtualFileSystem implementationClass="org.jetbrains.kotlin.idea.base.projectStructure.forwardDeclarations.KotlinForwardDeclarationsFileSystemImpl"
key="fwd" physical="false"/>
</extensions>
<projectListeners>
<listener class="org.jetbrains.kotlin.idea.base.projectStructure.forwardDeclarations.KotlinForwardDeclarationsModelChangeService"
topic="com.intellij.platform.backend.workspace.WorkspaceModelChangeListener"/>
</projectListeners>
</idea-plugin>