[Workspace Model] [IJPL-345] Make MutableEntityStorage#hasChanges internal and move it into instrumentation level

GitOrigin-RevId: dc840062e1ba6618176976f78143173347056aa4
This commit is contained in:
Alex Plate
2023-12-27 13:43:07 +00:00
committed by intellij-monorepo-bot
parent fb6bc5da4b
commit 8b83693478
13 changed files with 56 additions and 24 deletions
@@ -203,9 +203,10 @@ class ArtifactModifiableModelBridge(
eventDispatcher.removeListener(listener)
}
@OptIn(EntityStorageInstrumentationApi::class)
override fun isModified(): Boolean {
// TODO: 03.02.2021 May give a wrong result
return diff.hasChanges()
return (diff as MutableEntityStorageInstrumentation).hasChanges()
}
@RequiresWriteLock
@@ -31,6 +31,8 @@ import com.intellij.platform.util.progress.withRawProgressReporter
import com.intellij.platform.workspace.jps.entities.*
import com.intellij.platform.workspace.storage.EntityStorage
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.platform.workspace.storage.toBuilder
import com.intellij.util.containers.ContainerUtil
import kotlinx.coroutines.*
@@ -289,8 +291,9 @@ class RepositoryLibraryUtils(private val project: Project, private val cs: Corou
Notifications.Bus.notify(notification, project)
}
@OptIn(EntityStorageInstrumentationApi::class)
private suspend fun commitBuilderIfModified(workspaceModel: WorkspaceModel, builder: MutableEntityStorage) {
if (!builder.hasChanges()) return
if (!(builder as MutableEntityStorageInstrumentation).hasChanges()) return
withContext(Dispatchers.EDT) {
WriteAction.run<Throwable> {
@@ -18,6 +18,7 @@ import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.platform.backend.workspace.WorkspaceModel;
import com.intellij.platform.workspace.storage.MutableEntityStorage;
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ListUtil;
@@ -77,7 +78,7 @@ public final class RemoteRepositoriesConfigurable implements SearchableConfigura
@Override
public boolean isModified() {
return isServiceListModified() || isRepoListModified() || myMutableEntityStorage.hasChanges();
return isServiceListModified() || isRepoListModified() || ((MutableEntityStorageInstrumentation)myMutableEntityStorage).hasChanges();
}
private boolean isServiceListModified() {
@@ -296,7 +297,7 @@ public final class RemoteRepositoriesConfigurable implements SearchableConfigura
RemoteRepositoriesConfiguration.getInstance(myProject).setRepositories(myReposModel.getItems());
applyMutableEntityStorageChanges();
if (!newUrls.containsAll(oldUrls) || myMutableEntityStorage.hasChanges()) {
if (!newUrls.containsAll(oldUrls) || ((MutableEntityStorageInstrumentation)myMutableEntityStorage).hasChanges()) {
RepositoryLibrariesReloaderKt.reloadAllRepositoryLibraries(myProject);
}
@@ -7,6 +7,8 @@ import com.intellij.openapi.roots.AnnotationOrderRootType
import com.intellij.openapi.roots.OrderRootType
import com.intellij.platform.backend.workspace.workspaceModel
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
@@ -221,6 +223,7 @@ class ExternalAnnotationsRepositoryResolverTest: LibraryTest() {
}
@OptIn(EntityStorageInstrumentationApi::class)
@Test fun `test RootSetChanged should not be triggered resolving same artifact using Workspace API`() {
val resolver = ExternalAnnotationsRepositoryResolver()
val library = createLibrary()
@@ -245,7 +248,7 @@ class ExternalAnnotationsRepositoryResolverTest: LibraryTest() {
modifiableModel.addRoot("file:///fake.source", OrderRootType.SOURCES)
runWriteAction { modifiableModel.commit() } // second write operation
val diff2 = MutableEntityStorage.from(workspaceModel.currentSnapshot)
val diff2 = MutableEntityStorage.from(workspaceModel.currentSnapshot) as MutableEntityStorageInstrumentation
resolver.resolve(myProject, library, AnnotationsLocation("myGroup", "myArtifact", "1.0", myMavenRepoDescription.url), diff2)
assertFalse(diff2.hasChanges())
runWriteAction { workspaceModel.updateProjectModel("applying changes after test") { it.addDiff(diff2)} } // third write operation
@@ -21,6 +21,8 @@ import com.intellij.platform.workspace.storage.EntitySource
import com.intellij.platform.workspace.storage.EntityStorage
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.WorkspaceEntity
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.util.containers.ContainerUtil
import com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.Companion.facetMapping
import com.intellij.workspaceModel.ide.impl.legacyBridge.facet.FacetModelBridge.Companion.mutableFacetMapping
@@ -213,8 +215,9 @@ class ModifiableFacetModelBridgeImpl(private val initialStorage: EntityStorage,
@TestOnly
fun getEntity(facet: Facet<*>): FacetEntity? = diff.facetMapping().getEntities(facet).singleOrNull() as FacetEntity?
@OptIn(EntityStorageInstrumentationApi::class)
override fun isModified(): Boolean {
return diff.hasChanges()
return (diff as MutableEntityStorageInstrumentation).hasChanges()
}
override fun isNewFacet(facet: Facet<*>): Boolean {
@@ -42,6 +42,8 @@ import com.intellij.platform.workspace.storage.DummyParentEntitySource
import com.intellij.platform.workspace.storage.EntitySource
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.VersionedStorageChange
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager
import com.intellij.project.stateStore
import com.intellij.util.PlatformUtils.*
@@ -112,6 +114,7 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
}
}
@OptIn(EntityStorageInstrumentationApi::class)
suspend fun reloadProjectEntities() = reloadProjectEntitiesTimeMs.addMeasuredTimeMillis {
if (StoreReloadManager.getInstance(project).isReloadBlocked()) {
LOG.debug("Skip reloading because it's blocked")
@@ -141,9 +144,9 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
LOG.debugValues("Changed entity sources", reloadingResult.affectedSources)
if (reloadingResult.affectedSources.isEmpty() &&
!reloadingResult.builder.hasChanges() &&
!reloadingResult.unloadedEntityBuilder.hasChanges() &&
!reloadingResult.orphanageBuilder.hasChanges()) {
!(reloadingResult.builder as MutableEntityStorageInstrumentation).hasChanges() &&
!(reloadingResult.unloadedEntityBuilder as MutableEntityStorageInstrumentation).hasChanges() &&
!(reloadingResult.orphanageBuilder as MutableEntityStorageInstrumentation).hasChanges()) {
return@addMeasuredTimeMillis
}
@@ -156,7 +159,7 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
val description = "Reload entities after changes in JPS configuration files"
// Update builder of unloaded entities
if (reloadingResult.unloadedEntityBuilder.hasChanges()) {
if ((reloadingResult.unloadedEntityBuilder as MutableEntityStorageInstrumentation).hasChanges()) {
WorkspaceModel.getInstance(project).updateUnloadedEntities(description) { builder ->
builder.replaceBySource(affectedEntityFilter, reloadingResult.unloadedEntityBuilder.toSnapshot())
}
@@ -171,7 +174,7 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
addUnloadedModuleEntities(unloadedBuilder)
sourcesToSave.removeAll(reloadingResult.affectedSources)
if (reloadingResult.orphanageBuilder.hasChanges()) {
if ((reloadingResult.orphanageBuilder as MutableEntityStorageInstrumentation).hasChanges()) {
EntitiesOrphanage.getInstance(project).update { it.addDiff(reloadingResult.orphanageBuilder) }
}
}
@@ -312,6 +315,7 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
return loadedProjectEntities
}
@OptIn(EntityStorageInstrumentationApi::class)
suspend fun applyLoadedStorage(projectEntities: LoadedProjectEntities?) = applyLoadedStorageTimeMs.addMeasuredTimeMillis {
if (projectEntities == null) {
return@addMeasuredTimeMillis
@@ -325,7 +329,7 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
entitySource is JpsFileEntitySource || entitySource is JpsFileDependentEntitySource || entitySource is CustomModuleEntitySource
|| entitySource is DummyParentEntitySource
}
if (projectEntities.unloadedEntitiesBuilder.hasChanges()) {
if ((projectEntities.unloadedEntitiesBuilder as MutableEntityStorageInstrumentation).hasChanges()) {
WorkspaceModel.getInstance(project).updateUnloadedEntities(description) { updater ->
updater.replaceBySource(sourceFilter, projectEntities.unloadedEntitiesBuilder)
}
@@ -359,8 +363,9 @@ class JpsProjectModelSynchronizer(private val project: Project) : Disposable {
ModuleManagerEx.getInstanceEx(project).unloadNewlyAddedModulesIfPossible(builder, unloadedEntitiesBuilder)
}
@OptIn(EntityStorageInstrumentationApi::class)
private fun addUnloadedModuleEntities(diff: MutableEntityStorage) {
if (diff.hasChanges()) {
if ((diff as MutableEntityStorageInstrumentation).hasChanges()) {
WorkspaceModel.getInstance(project).updateUnloadedEntities("Add new unloaded modules") { updater ->
updater.addDiff(diff)
}
@@ -12,6 +12,8 @@ import com.intellij.platform.workspace.jps.entities.LibraryEntity
import com.intellij.platform.workspace.jps.entities.LibraryTableId
import com.intellij.platform.workspace.jps.serialization.impl.JpsLibraryEntitiesSerializer
import com.intellij.platform.workspace.storage.*
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager
import com.intellij.workspaceModel.ide.getGlobalInstance
import com.intellij.workspaceModel.ide.impl.GlobalWorkspaceModel
@@ -91,6 +93,7 @@ internal class CustomLibraryTableBridgeImpl(private val level: String, private v
}
}
@OptIn(EntityStorageInstrumentationApi::class)
override fun readExternal(libraryTableTag: Element) {
val mutableEntityStorage = MutableEntityStorage.create()
libraryTableTag.getChildren(JpsLibraryTableSerializer.LIBRARY_TAG).forEach { libraryTag ->
@@ -100,7 +103,7 @@ internal class CustomLibraryTableBridgeImpl(private val level: String, private v
mutableEntityStorage.addEntity(libraryEntity)
}
if (!mutableEntityStorage.hasChanges()) return
if (!(mutableEntityStorage as MutableEntityStorageInstrumentation).hasChanges()) return
val runnable: () -> Unit = {
GlobalWorkspaceModel.getInstance().updateModel("Custom library table ${libraryTableId.level} update") { builder ->
@@ -12,6 +12,8 @@ import com.intellij.platform.workspace.jps.entities.LibraryPropertiesEntity
import com.intellij.platform.workspace.jps.entities.LibraryTableId
import com.intellij.platform.workspace.storage.EntitySource
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.workspaceModel.ide.impl.GlobalWorkspaceModel
import com.intellij.workspaceModel.ide.impl.legacyBridge.LegacyBridgeModifiableBase
import com.intellij.workspaceModel.ide.impl.legacyBridge.library.ProjectLibraryTableBridgeImpl.Companion.findLibraryEntity
@@ -94,7 +96,8 @@ internal class GlobalOrCustomModifiableLibraryTableBridgeImpl(private val librar
.toList().toTypedArray()
}
override fun isChanged(): Boolean = diff.hasChanges()
@OptIn(EntityStorageInstrumentationApi::class)
override fun isChanged(): Boolean = (diff as MutableEntityStorageInstrumentation).hasChanges()
override fun dispose() {
modelIsCommittedOrDisposed = true
@@ -16,6 +16,8 @@ import com.intellij.platform.workspace.jps.entities.LibraryTableId
import com.intellij.platform.workspace.storage.CachedValue
import com.intellij.platform.workspace.storage.EntityStorage
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import com.intellij.workspaceModel.ide.impl.LegacyBridgeJpsEntitySourceFactory
import com.intellij.workspaceModel.ide.impl.legacyBridge.LegacyBridgeModifiableBase
import com.intellij.workspaceModel.ide.impl.legacyBridge.library.ProjectLibraryTableBridgeImpl.Companion.findLibraryEntity
@@ -140,7 +142,8 @@ internal class ProjectModifiableLibraryTableBridgeImpl(
librariesArray.forEach { library -> (library as LibraryBridgeImpl).clearTargetBuilder() }
}
override fun isChanged(): Boolean = diff.hasChanges()
@OptIn(EntityStorageInstrumentationApi::class)
override fun isChanged(): Boolean = (diff as MutableEntityStorageInstrumentation).hasChanges()
companion object {
val LOG = logger<ProjectModifiableLibraryTableBridgeImpl>()
@@ -637,8 +637,9 @@ class ModifiableRootModelBridgeImpl(
}
// TODO compare by actual values
@OptIn(EntityStorageInstrumentationApi::class)
override fun isChanged(): Boolean {
if (diff.hasChanges()) return true
if ((diff as MutableEntityStorageInstrumentation).hasChanges()) return true
if (extensionsDelegate.isInitialized() && extensions.any { it.isChanged }) return true
@@ -134,12 +134,6 @@ import org.jetbrains.annotations.NonNls
* This is not a full list of use cases. You can use this operation based on your needs.
*/
public interface MutableEntityStorage : EntityStorage {
/**
* Returns `true` if there are changes recorded in this storage after its creation. Note, that this method may return `true` if these
* changes actually don't modify the resulting set of entities, you may use [hasSameEntities] to perform more sophisticated check.
*/
public fun hasChanges(): Boolean
/**
* Add the given entity to the storage. All children of the entity will also be added.
*
@@ -54,6 +54,15 @@ public interface MutableEntityStorageInstrumentation : MutableEntityStorage, Ent
@ApiStatus.Internal
public fun hasSameEntities(): Boolean
/**
* Returns `true` if there are changes recorded in this storage after its creation. Note, that this method may return `true` if these
* changes actually don't modify the resulting set of entities, you may use [hasSameEntities] to perform more sophisticated check.
*
* This internal API may be removed in the future, so it should not be used to build any functionality with it.
*/
@ApiStatus.Internal
public fun hasChanges(): Boolean
/**
* Return changes in entities recorded in this instance.
*
@@ -24,6 +24,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
import com.intellij.platform.backend.workspace.workspaceModel
import com.intellij.platform.workspace.storage.MutableEntityStorage
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
import com.intellij.platform.workspace.storage.instrumentation.MutableEntityStorageInstrumentation
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import org.jetbrains.plugins.gradle.service.notification.ExternalAnnotationsProgressNotificationManagerImpl
import org.jetbrains.plugins.gradle.service.notification.ExternalAnnotationsTaskId
@@ -124,6 +126,7 @@ fun lookForLocations(project: Project, lib: Library, libData: LibraryData): Pair
}
}
@OptIn(EntityStorageInstrumentationApi::class)
fun resolveProvidedAnnotations(providedAnnotations: Map<Library, Collection<AnnotationsLocation>>,
project: Project, onResolveCompleted: () -> Unit = {}){
val locationsToSkip = mutableSetOf<AnnotationsLocation>()
@@ -147,7 +150,7 @@ fun resolveProvidedAnnotations(providedAnnotations: Map<Library, Collection<Anno
indicator.fraction = index / total
}
}
if (diff.hasChanges()) {
if ((diff as MutableEntityStorageInstrumentation).hasChanges()) {
runInEdt {
runWriteAction { project.workspaceModel.updateProjectModel("Applying resolved annotations") { it.addDiff(diff) } }
}