[workspace model] IDEA-298714 Initialize facets only if loaded from cache

GitOrigin-RevId: 0aae96135290d9c0546fec0ce4190ea58f080e0a
This commit is contained in:
Mikhail Mazurkevich
2022-09-08 20:27:31 +00:00
committed by intellij-monorepo-bot
parent 26e7978aa8
commit 91f1bfac48
8 changed files with 37 additions and 29 deletions
@@ -31,7 +31,7 @@ class FacetEntityChangeListener(private val project: Project): Disposable {
init {
if (!project.isDefault) {
val busConnection = project.messageBus.connect(this)
WorkspaceModelTopics.getInstance(project).subscribeModuleBridgeInitializer(busConnection, object : WorkspaceModelChangeListener {
WorkspaceModelTopics.getInstance(project).subscribeAfterModuleLoading(busConnection, object : WorkspaceModelChangeListener {
override fun beforeChanged(event: VersionedStorageChange) {
WorkspaceFacetContributor.EP_NAME.extensions.forEach { facetBridgeContributor ->
processBeforeChangeEvents(event, facetBridgeContributor)
@@ -54,7 +54,9 @@ class FacetEntityChangeListener(private val project: Project): Disposable {
val existingFacetBridge = event.storageAfter.facetMapping().getDataByEntity(change.entity)
val facetBridge = if (existingFacetBridge == null) {
val workspaceModel = WorkspaceModel.getInstance(project)
val newFacetBridge = workspaceFacetContributor.createFacetFromEntity(change.newEntity, project)
val moduleEntity = workspaceFacetContributor.getRelatedModuleEntity(change.newEntity)
val module = ModuleManager.getInstance(project).findModuleByName(moduleEntity.name) ?: error("Module bridge should be available")
val newFacetBridge = workspaceFacetContributor.createFacetFromEntity(change.newEntity, module)
workspaceModel.updateProjectModelSilent {
it.mutableFacetMapping().addMapping(change.newEntity, newFacetBridge)
}
@@ -85,7 +87,9 @@ class FacetEntityChangeListener(private val project: Project): Disposable {
val existingFacetBridge = event.storageAfter.facetMapping().getDataByEntity(change.entity)
val facet = if (existingFacetBridge == null) {
val workspaceModel = WorkspaceModel.getInstance(project)
val newFacetBridge = workspaceFacetContributor.createFacetFromEntity(change.newEntity, project)
val moduleEntity = workspaceFacetContributor.getRelatedModuleEntity(change.newEntity)
val module = ModuleManager.getInstance(project).findModuleByName(moduleEntity.name) ?: error("Module bridge should be available")
val newFacetBridge = workspaceFacetContributor.createFacetFromEntity(change.newEntity, module)
workspaceModel.updateProjectModelSilent {
it.mutableFacetMapping().addMapping(change.newEntity, newFacetBridge)
}
@@ -3,8 +3,7 @@ package com.intellij.workspaceModel.ide.impl.legacyBridge.facet
import com.intellij.facet.Facet
import com.intellij.facet.FacetManager
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.module.Module
import com.intellij.workspaceModel.ide.legacyBridge.WorkspaceFacetContributor
import com.intellij.workspaceModel.storage.bridgeEntities.api.FacetEntity
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
@@ -15,8 +14,7 @@ class FacetEntityContributor: WorkspaceFacetContributor<FacetEntity> {
override fun getRootEntityByModuleEntity(moduleEntity: ModuleEntity): FacetEntity = error("Unsupported operation")
override fun createFacetFromEntity(entity: FacetEntity, project: Project): Facet<*> {
val module = ModuleManager.getInstance(project).findModuleByName(entity.module.name) ?: error("Module bridge should be available")
override fun createFacetFromEntity(entity: FacetEntity, module: Module): Facet<*> {
val facetManagerBridge = FacetManager.getInstance(module) as FacetManagerBridge
return facetManagerBridge.model.createFacet(entity)
}
@@ -129,19 +129,15 @@ open class FacetModelBridge(private val moduleBridge: ModuleBridge) : FacetModel
init {
// Initialize facet bridges after loading from cache
fun createFacetBridgeIfNeeded(entity: WorkspaceEntity, facetContributor: WorkspaceFacetContributor<WorkspaceEntity>, project: Project) {
updateDiffOrStorage{ this.getOrPutDataByEntity(entity) { facetContributor.createFacetFromEntity(entity, project) } }
}
moduleBridge.project
val moduleEntity = moduleBridge.entityStorage.current.resolve(moduleBridge.moduleEntityId)
?: error("Module entity should be available")
WorkspaceFacetContributor.EP_NAME.extensions.forEach { facetContributor ->
if (facetContributor.rootEntityType != FacetEntity::class.java) {
facetContributor.getRootEntityByModuleEntity(moduleEntity)?.let {
createFacetBridgeIfNeeded(it, facetContributor, moduleBridge.project)
updateDiffOrStorage{ this.getOrPutDataByEntity(it) { facetContributor.createFacetFromEntity(it, moduleBridge) }}
}
} else {
moduleEntity.facets.forEach { createFacetBridgeIfNeeded(it, facetContributor, moduleBridge.project) }
moduleEntity.facets.forEach { getOrCreateFacet(it) }
}
}
}
@@ -31,7 +31,7 @@ private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedList
private val LOG = logger<ModuleBridgeLoaderService>()
}
private suspend fun loadModules(project: Project, activity: Activity?) {
private suspend fun loadModules(project: Project, activity: Activity?, loadedFromCache: Boolean) {
val componentManager = project as ComponentManagerEx
val childActivity = activity?.startChild("modules instantiation")
@@ -40,7 +40,7 @@ private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedList
val moduleManager = componentManager.getServiceAsync(ModuleManager::class.java).await() as ModuleManagerComponentBridge
val entities = moduleManager.entityStore.current.entities(ModuleEntity::class.java)
moduleManager.loadModules(entities)
moduleManager.loadModules(entities, loadedFromCache)
childActivity?.setDescription("modules count: ${moduleManager.modules.size}")
childActivity?.end()
@@ -62,7 +62,7 @@ private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedList
workspaceModel.ignoreCache() // sets `WorkspaceModelImpl#loadedFromCache` to `false`
project.putUserData(PROJECT_LOADED_FROM_CACHE_BUT_HAS_NO_MODULES, true)
}
loadModules(project, activity)
loadModules(project, activity, workspaceModel.loadedFromCache)
}
else {
LOG.info("Workspace model loaded without cache. Loading real project state into workspace model. ${Thread.currentThread()}")
@@ -71,7 +71,7 @@ private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedList
projectModelSynchronizer.applyLoadedStorage(storeToEntitySources)
project.messageBus.syncPublisher(JpsProjectLoadedListener.LOADED).loaded()
loadModules(project, activity)
loadModules(project, activity, workspaceModel.loadedFromCache)
}
runActivity("tracked libraries setup") {
@@ -2,7 +2,7 @@ package com.intellij.workspaceModel.ide.legacyBridge
import com.intellij.facet.Facet
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import com.intellij.openapi.module.Module
import com.intellij.workspaceModel.storage.WorkspaceEntity
import com.intellij.workspaceModel.storage.bridgeEntities.api.ModuleEntity
import org.jetbrains.annotations.ApiStatus
@@ -51,7 +51,7 @@ interface WorkspaceFacetContributor<T: WorkspaceEntity> {
/**
* Method for creating [com.intellij.facet.Facet] from the given entity of root type
*/
fun createFacetFromEntity(entity: T, project: Project): Facet<*>
fun createFacetFromEntity(entity: T, module: Module): Facet<*>
/**
* This field should be overridden if root entity can have children which changes can affect e.g. facet configuration
@@ -38,7 +38,10 @@ open class WorkspaceModelImpl(private val project: Project) : WorkspaceModel, Di
val initialContent = WorkspaceModelInitialTestContent.pop()
val cache = WorkspaceModelCache.getInstance(project)
val projectEntities: MutableEntityStorage = when {
initialContent != null -> initialContent.toBuilder()
initialContent != null -> {
loadedFromCache = initialContent !== EntityStorageSnapshot.empty()
initialContent.toBuilder()
}
cache != null -> {
val activity = startActivity("cache loading")
val previousStorage: MutableEntityStorage?
@@ -2,6 +2,7 @@
package com.intellij.workspaceModel.ide.impl
import com.intellij.openapi.application.ApplicationManager
import com.intellij.util.PlatformUtils
import com.intellij.workspaceModel.storage.EntityStorageSnapshot
import org.jetbrains.annotations.TestOnly
import java.util.concurrent.atomic.AtomicReference
@@ -26,12 +27,19 @@ object WorkspaceModelInitialTestContent {
error("Initial content was already registered")
}
val previousPropertyValue = System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY)
if (storage !== EntityStorageSnapshot.empty()) {
System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, PlatformUtils.IDEA_CE_PREFIX)
}
hasInitialContent = true
try {
return block()
}
finally {
hasInitialContent = false
if (storage !== EntityStorageSnapshot.empty()) {
System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, previousPropertyValue)
}
if (initialContent.getAndSet(null) != null) {
error("Initial content was not used")
}
@@ -78,7 +78,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
val entityStore = WorkspaceModel.getInstance(project).entityStorage
suspend fun loadModules(entities: Sequence<ModuleEntity>) {
suspend fun loadModules(entities: Sequence<ModuleEntity>, initializeFacets: Boolean) {
val plugins = PluginManagerCore.getPluginSet().getEnabledModules()
val corePlugin = plugins.firstOrNull { it.pluginId == PluginManagerCore.CORE_ID }
val result = coroutineScope {
@@ -130,13 +130,12 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
// Facets that are loaded from the cache do not generate "EntityAdded" event and aren't initialized
// We initialize the facets manually here (after modules loading).
//
// Possible issue - if we'll initialize facets here and after that we'll get "EntityAdded" event, the facet will be initialized twice
// But 1. That seems impossible as we don't create facets before the modules are loaded 2. I hope that facets initialization is idempotent
blockingContext {
invokeLater {
for (module in modules) {
module.initFacets()
if (initializeFacets) {
blockingContext {
invokeLater {
for (module in modules) {
module.initFacets()
}
}
}
}
@@ -301,7 +300,7 @@ abstract class ModuleManagerBridgeImpl(private val project: Project) : ModuleMan
}
// todo why we load modules in a write action
runBlocking {
loadModules(moduleEntitiesToLoad.asSequence())
loadModules(moduleEntitiesToLoad.asSequence(), true)
}
}
}