mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[workspace model] IJPL-844 Remove WorkspaceEntityData.symbolicId usage from the code
GitOrigin-RevId: 6890e2cbaf8cd93b164e4bbbedb95e96f392a254
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d15d074bc9
commit
eb0b39784d
+3
-2
@@ -5,6 +5,7 @@ import com.google.common.collect.HashBiMap
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.diagnostic.trace
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntity
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId
|
||||
import com.intellij.platform.workspace.storage.impl.exceptions.ApplyChangesFromException
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
import java.util.*
|
||||
@@ -195,7 +196,7 @@ internal class ApplyChangesFromOperation(val target: MutableEntityStorageImpl, v
|
||||
target.indexes.updateIndices(sourceEntityId.id, newTargetEntityData, diff)
|
||||
|
||||
val newEntityId = newTargetEntityData.createEntityId()
|
||||
val oldSymbolicId = target.entityDataById(newEntityId)?.symbolicId()
|
||||
val oldSymbolicId = (target.entityDataById(newEntityId)?.createEntity(target) as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
|
||||
/// Replace entity data. id should not be changed
|
||||
target.entitiesByType.replaceById(newTargetEntityData, sourceEntityId.id.clazz)
|
||||
@@ -414,7 +415,7 @@ internal class ApplyChangesFromOperation(val target: MutableEntityStorageImpl, v
|
||||
}
|
||||
|
||||
private fun checkSymbolicId(entityData: WorkspaceEntityData<out WorkspaceEntity>, newEntityId: EntityId?) {
|
||||
val newSymbolicId = entityData.symbolicId()
|
||||
val newSymbolicId = (entityData.createEntity(diff) as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
if (newSymbolicId != null) {
|
||||
val existingIds = target.indexes.symbolicIdIndex.getIdsByEntry(newSymbolicId)
|
||||
if (existingIds != null) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ public fun EntityStorage.assertConsistency() {
|
||||
internal fun AbstractEntityStorage.assertConsistency() {
|
||||
AbstractEntityStorage.LOG.trace { "Checking consistency of $this" }
|
||||
|
||||
entitiesByType.assertConsistency()
|
||||
entitiesByType.assertConsistency(this)
|
||||
// Rules:
|
||||
// 1) Refs should not have links without a corresponding entity
|
||||
// 1.1) For abstract containers: EntityId has the class of ConnectionId
|
||||
|
||||
+1
-6
@@ -670,9 +670,4 @@ public abstract class WorkspaceEntityData<E : WorkspaceEntity> : Cloneable, Seri
|
||||
public abstract class WithCalculableSymbolicId<E : WorkspaceEntity> : WorkspaceEntityData<E>() {
|
||||
public abstract fun symbolicId(): SymbolicEntityId<*>
|
||||
}
|
||||
}
|
||||
|
||||
internal fun WorkspaceEntityData<*>.symbolicId(): SymbolicEntityId<*>? = when (this) {
|
||||
is WorkspaceEntityData.WithCalculableSymbolicId -> this.symbolicId()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -2,9 +2,12 @@
|
||||
package com.intellij.platform.workspace.storage.impl
|
||||
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.SymbolicEntityId
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntity
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentation
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
|
||||
internal open class ImmutableEntitiesBarrel internal constructor(
|
||||
override val entityFamilies: List<ImmutableEntityFamily<out WorkspaceEntity>?>
|
||||
@@ -117,7 +120,8 @@ internal sealed class EntitiesBarrel {
|
||||
|
||||
fun size() = entityFamilies.size
|
||||
|
||||
fun assertConsistency() {
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
fun assertConsistency(storage: EntityStorageInstrumentation) {
|
||||
val symbolicIds = HashSet<SymbolicEntityId<*>>()
|
||||
entityFamilies.forEachIndexed { i, family ->
|
||||
if (family == null) return@forEachIndexed
|
||||
@@ -135,7 +139,7 @@ internal sealed class EntitiesBarrel {
|
||||
|
||||
// Assert unique of persistent id
|
||||
if (hasSymbolicId) {
|
||||
val symbolicId = entityData.symbolicId()
|
||||
val symbolicId = (entityData.createEntity(storage) as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
assert(symbolicId != null) { "Symbolic id expected for $clazz" }
|
||||
assert(symbolicId !in symbolicIds) { "Duplicated symbolic ids: $symbolicId" }
|
||||
symbolicIds.add(symbolicId!!)
|
||||
|
||||
+18
-16
@@ -270,9 +270,11 @@ internal class MutableEntityStorageImpl(
|
||||
lockWrite()
|
||||
|
||||
val newEntityData = entity.getEntityData()
|
||||
val immutableEntity = newEntityData.createEntity(this)
|
||||
val symbolicId = (immutableEntity as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
|
||||
// Check for persistent id uniqueness
|
||||
assertUniqueSymbolicId(newEntityData)
|
||||
assertUniqueSymbolicId(newEntityData, symbolicId)
|
||||
|
||||
entitiesByType.add(newEntityData, entity.getEntityClass().toClassId())
|
||||
|
||||
@@ -280,24 +282,24 @@ internal class MutableEntityStorageImpl(
|
||||
changeLog.addAddEvent(newEntityData.createEntityId(), newEntityData)
|
||||
|
||||
// Update indexes
|
||||
indexes.entityAdded(newEntityData)
|
||||
indexes.entityAdded(newEntityData, symbolicId)
|
||||
}
|
||||
finally {
|
||||
unlockWrite()
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : WorkspaceEntity> assertUniqueSymbolicId(pEntityData: WorkspaceEntityData<T>) {
|
||||
pEntityData.symbolicId()?.let { symbolicId ->
|
||||
val ids = indexes.symbolicIdIndex.getIdsByEntry(symbolicId)
|
||||
if (ids != null) {
|
||||
// Oh, oh. This symbolic id exists already
|
||||
// Fallback strategy: remove existing entity with all it's references
|
||||
val existingEntityData = entityDataByIdOrDie(ids)
|
||||
val existingEntity = existingEntityData.createEntity(this)
|
||||
removeEntity(existingEntity)
|
||||
LOG.error(
|
||||
"""
|
||||
private fun <T : WorkspaceEntity> assertUniqueSymbolicId(pEntityData: WorkspaceEntityData<T>, symbolicId: SymbolicEntityId<*>?) {
|
||||
if (symbolicId == null) return
|
||||
val ids = indexes.symbolicIdIndex.getIdsByEntry(symbolicId)
|
||||
if (ids != null) {
|
||||
// Oh, oh. This symbolic id exists already
|
||||
// Fallback strategy: remove existing entity with all it's references
|
||||
val existingEntityData = entityDataByIdOrDie(ids)
|
||||
val existingEntity = existingEntityData.createEntity(this)
|
||||
removeEntity(existingEntity)
|
||||
LOG.error(
|
||||
"""
|
||||
addEntity: symbolic id already exists. Replacing entity with the new one.
|
||||
Symbolic id: $symbolicId
|
||||
|
||||
@@ -306,8 +308,7 @@ internal class MutableEntityStorageImpl(
|
||||
|
||||
Broken consistency: $brokenConsistency
|
||||
""".trimIndent(), SymbolicIdAlreadyExistsException(symbolicId)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +340,8 @@ internal class MutableEntityStorageImpl(
|
||||
|
||||
// Check for persistent id uniqueness
|
||||
if (beforeSymbolicId != null) {
|
||||
val newSymbolicId = copiedData.symbolicId()
|
||||
val immutableEntity = modifiableEntity.getEntityData().createEntity(this)
|
||||
val newSymbolicId = if (immutableEntity is WorkspaceEntityWithSymbolicId) immutableEntity.symbolicId else null
|
||||
if (newSymbolicId != null) {
|
||||
val ids = indexes.symbolicIdIndex.getIdsByEntry(newSymbolicId)
|
||||
if (beforeSymbolicId != newSymbolicId && ids != null) {
|
||||
|
||||
+8
-5
@@ -107,18 +107,21 @@ internal open class StorageIndexes(
|
||||
}
|
||||
*/
|
||||
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
private fun assertSymbolicIdIndex(storage: AbstractEntityStorage) {
|
||||
|
||||
var expectedSize = 0
|
||||
storage.entitiesByType.entityFamilies.forEachIndexed { i, family ->
|
||||
if (family == null) return@forEachIndexed
|
||||
if (family.entities.firstOrNull { it != null }?.symbolicId() == null) return@forEachIndexed
|
||||
val entityData = family.entities.firstOrNull { it != null }?.createEntity(storage) as? WorkspaceEntityWithSymbolicId
|
||||
if (entityData?.symbolicId == null) return@forEachIndexed
|
||||
var mutableId = createEntityId(0, i)
|
||||
family.entities.forEach { data ->
|
||||
if (data == null) return@forEach
|
||||
mutableId = mutableId.copy(arrayId = data.id)
|
||||
val expectedSymbolicId = symbolicIdIndex.getEntryById(mutableId)
|
||||
assert(expectedSymbolicId == data.symbolicId()) { "Entity $data isn't found in persistent id index. SymbolicId: ${data.symbolicId()}, Id: $mutableId. Expected entity source: $expectedSymbolicId" }
|
||||
val symbolicId = (data.createEntity(storage) as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
assert(expectedSymbolicId == symbolicId) { "Entity $data isn't found in persistent id index. SymbolicId: $symbolicId, Id: $mutableId. Expected entity source: $expectedSymbolicId" }
|
||||
expectedSize++
|
||||
}
|
||||
}
|
||||
@@ -155,7 +158,7 @@ internal class MutableStorageIndexes(
|
||||
override val externalMappings: MutableMap<ExternalMappingKey<*>, MutableExternalEntityMappingImpl<*>>
|
||||
) : StorageIndexes(softLinks, virtualFileIndex, entitySourceIndex, symbolicIdIndex, externalMappings) {
|
||||
|
||||
fun <T : WorkspaceEntity> entityAdded(entityData: WorkspaceEntityData<T>) {
|
||||
fun <T : WorkspaceEntity> entityAdded(entityData: WorkspaceEntityData<T>, symbolicId: SymbolicEntityId<*>?) {
|
||||
val pid = entityData.createEntityId()
|
||||
|
||||
// Update soft links index
|
||||
@@ -166,7 +169,7 @@ internal class MutableStorageIndexes(
|
||||
val entitySource = entityData.entitySource
|
||||
entitySourceIndex.index(pid, entitySource)
|
||||
|
||||
entityData.symbolicId()?.let { symbolicId ->
|
||||
if (symbolicId != null) {
|
||||
symbolicIdIndex.index(pid, symbolicId)
|
||||
}
|
||||
|
||||
@@ -266,7 +269,7 @@ internal class MutableStorageIndexes(
|
||||
for (entityId in idsWithSoftRef) {
|
||||
val originalEntityData = builder.getOriginalEntityData(entityId) as WorkspaceEntityData<WorkspaceEntity>
|
||||
val entity = builder.entitiesByType.getEntityDataForModification(entityId) as WorkspaceEntityData<WorkspaceEntity>
|
||||
val editingBeforeSymbolicId = entity.symbolicId()
|
||||
val editingBeforeSymbolicId = (entity.createEntity(builder) as? WorkspaceEntityWithSymbolicId)?.symbolicId
|
||||
(entity as SoftLinkable).updateLink(beforeSymbolicId, newSymbolicId)
|
||||
|
||||
// Add an entry to changelog
|
||||
|
||||
+6
-2
@@ -4,6 +4,8 @@ package com.intellij.platform.workspace.storage.impl
|
||||
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.WorkspaceEntityWithSymbolicId
|
||||
import com.intellij.platform.workspace.storage.instrumentation.EntityStorageInstrumentationApi
|
||||
import com.intellij.platform.workspace.storage.instrumentation.Modification
|
||||
|
||||
// Just a wrapper for entity id in THIS store
|
||||
@@ -36,11 +38,12 @@ internal fun loadClassByName(name: String, classLoader: ClassLoader): Class<*> {
|
||||
* This function checks if we try to add an entity as a child to itself.
|
||||
* It can't verify a circular dependency, and it's performed via a third entity
|
||||
*/
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
internal fun checkCircularDependency(connectionId: ConnectionId, childId: Int, parentId: Int, storage: AbstractEntityStorage) {
|
||||
if (connectionId.parentClass == connectionId.childClass && childId == parentId) {
|
||||
val parentEntityId = createEntityId(parentId, connectionId.parentClass)
|
||||
val entityData = storage.entityDataByIdOrDie(parentEntityId)
|
||||
val entityPresentation = entityData.symbolicId()?.toString() ?: entityData.toString()
|
||||
val entityPresentation = (entityData.createEntity(storage) as? WorkspaceEntityWithSymbolicId)?.symbolicId?.toString() ?: entityData.toString()
|
||||
error("""Trying to make a circular dependency in entities by setting an entity as a child of itself.
|
||||
|Entity class: ${connectionId.parentClass.findWorkspaceEntity()}
|
||||
|Entity: $entityPresentation
|
||||
@@ -52,10 +55,11 @@ internal fun checkCircularDependency(connectionId: ConnectionId, childId: Int, p
|
||||
* This function checks if we try to add an entity as a child to itself.
|
||||
* It can't verify a circular dependency, and it's performed via a third entity
|
||||
*/
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
internal fun checkCircularDependency(childId: EntityId, parentId: EntityId, storage: AbstractEntityStorage) {
|
||||
if (childId == parentId) {
|
||||
val entityData = storage.entityDataByIdOrDie(parentId)
|
||||
val entityPresentation = entityData.symbolicId()?.toString() ?: entityData.toString()
|
||||
val entityPresentation = (entityData.createEntity(storage) as? WorkspaceEntityWithSymbolicId)?.symbolicId?.toString() ?: entityData.toString()
|
||||
error("""Trying to make a circular dependency in entities by setting an entity as a child of itself.
|
||||
|Entity class: ${parentId.clazz.findWorkspaceEntity()}
|
||||
|Entity: $entityPresentation
|
||||
|
||||
Reference in New Issue
Block a user