mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Workspace Model] EntityData should calculate PersistentId if TypedEntity has it
GitOrigin-RevId: d0b3d356ce71b194e34c1c2bc22175c80e96f1f7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c0af13dcab
commit
e57ddfb4e3
+4
-2
@@ -8,12 +8,14 @@ import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
internal class PNamedSampleEntityData : PEntityData<PNamedSampleEntity>() {
|
||||
internal class PNamedSampleEntityData : PEntityData.WithCalculatablePersistentId<PNamedSampleEntity>() {
|
||||
lateinit var name: String
|
||||
lateinit var next: PSampleEntityId
|
||||
override fun createEntity(snapshot: TypedEntityStorage): PNamedSampleEntity {
|
||||
return PNamedSampleEntity(name, next).also { addMetaData(it, snapshot) }
|
||||
}
|
||||
|
||||
override fun persistentId(): PSampleEntityId = PSampleEntityId(name)
|
||||
}
|
||||
|
||||
internal class PNamedSampleEntity(
|
||||
@@ -42,7 +44,7 @@ internal data class PChildEntityId(val childName: String,
|
||||
get() = childName
|
||||
}
|
||||
|
||||
internal class PChildWithPersistentIdEntityData : PEntityData<PChildWithPersistentIdEntity>() {
|
||||
internal class PChildWithPersistentIdEntityData : PEntityData.WithPersistentId<PChildWithPersistentIdEntity>() {
|
||||
lateinit var parent: PNamedSampleEntity
|
||||
lateinit var childName: String
|
||||
override fun createEntity(snapshot: TypedEntityStorage): PChildWithPersistentIdEntity {
|
||||
|
||||
+7
-2
@@ -1,15 +1,20 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.workspace.api.pstorage
|
||||
|
||||
import com.intellij.workspace.api.*
|
||||
import com.intellij.workspace.api.EntitySource
|
||||
import com.intellij.workspace.api.TypedEntityStorage
|
||||
import com.intellij.workspace.api.TypedEntityStorageBuilder
|
||||
import com.intellij.workspace.api.TypedEntityWithPersistentId
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
internal class PPersistentIdEntityData : PEntityData<PPersistentIdEntity>() {
|
||||
internal class PPersistentIdEntityData : PEntityData.WithCalculatablePersistentId<PPersistentIdEntity>() {
|
||||
lateinit var data: String
|
||||
override fun createEntity(snapshot: TypedEntityStorage): PPersistentIdEntity {
|
||||
return PPersistentIdEntity(data).also { addMetaData(it, snapshot) }
|
||||
}
|
||||
|
||||
override fun persistentId(): PSampleEntityId = PSampleEntityId(data)
|
||||
}
|
||||
|
||||
internal class PPersistentIdEntity(val data: String) : TypedEntityWithPersistentId, PTypedEntity() {
|
||||
|
||||
+3
-1
@@ -19,11 +19,13 @@ internal data class NameId(private val name: String) : PersistentEntityId<NamedE
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
internal class NamedEntityData : PEntityData<NamedEntity>() {
|
||||
internal class NamedEntityData : PEntityData.WithCalculatablePersistentId<NamedEntity>() {
|
||||
lateinit var name: String
|
||||
override fun createEntity(snapshot: TypedEntityStorage): NamedEntity {
|
||||
return NamedEntity(name).also { addMetaData(it, snapshot) }
|
||||
}
|
||||
|
||||
override fun persistentId(): PersistentEntityId<*> = NameId(name)
|
||||
}
|
||||
|
||||
internal class NamedEntity(
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.io.Serializable
|
||||
*/
|
||||
|
||||
@Suppress("unused")
|
||||
class ModuleEntityData : PEntityData<ModuleEntity>(), PSoftLinkable {
|
||||
class ModuleEntityData : PEntityData.WithCalculatablePersistentId<ModuleEntity>(), PSoftLinkable {
|
||||
lateinit var name: String
|
||||
var type: String? = null
|
||||
lateinit var dependencies: List<ModuleDependencyItem>
|
||||
@@ -65,6 +65,8 @@ class ModuleEntityData : PEntityData<ModuleEntity>(), PSoftLinkable {
|
||||
override fun createEntity(snapshot: TypedEntityStorage): ModuleEntity = ModuleEntity(name, type, dependencies.toList()).also {
|
||||
addMetaData(it, snapshot)
|
||||
}
|
||||
|
||||
override fun persistentId(): ModuleId = ModuleId(name)
|
||||
}
|
||||
|
||||
class ModuleEntity(
|
||||
@@ -325,7 +327,7 @@ sealed class LibraryTableId : Serializable {
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
class LibraryEntityData : PEntityData<LibraryEntity>(), PSoftLinkable {
|
||||
class LibraryEntityData : PEntityData.WithCalculatablePersistentId<LibraryEntity>(), PSoftLinkable {
|
||||
lateinit var tableId: LibraryTableId
|
||||
lateinit var name: String
|
||||
lateinit var roots: List<LibraryRoot>
|
||||
@@ -350,6 +352,8 @@ class LibraryEntityData : PEntityData<LibraryEntity>(), PSoftLinkable {
|
||||
override fun createEntity(snapshot: TypedEntityStorage): LibraryEntity {
|
||||
return LibraryEntity(tableId, name, roots.toList(), excludedRoots.toList()).also { addMetaData(it, snapshot) }
|
||||
}
|
||||
|
||||
override fun persistentId(): LibraryId = LibraryId(name, tableId)
|
||||
}
|
||||
|
||||
open class LibraryEntity(
|
||||
@@ -450,7 +454,7 @@ val ModuleEntity.externalSystemOptions: ExternalSystemModuleOptionsEntity?
|
||||
get() = referrers(ExternalSystemModuleOptionsEntity::module).firstOrNull()
|
||||
|
||||
@Suppress("unused")
|
||||
class FacetEntityData : PEntityData<FacetEntity>() {
|
||||
class FacetEntityData : PEntityData.WithPersistentId<FacetEntity>() {
|
||||
lateinit var name: String
|
||||
lateinit var facetType: String
|
||||
var configurationXmlTag: String? = null
|
||||
@@ -490,7 +494,7 @@ data class ArtifactId(val name: String) : PersistentEntityId<ArtifactEntity>() {
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
class ArtifactEntityData : PEntityData<ArtifactEntity>() {
|
||||
class ArtifactEntityData : PEntityData.WithCalculatablePersistentId<ArtifactEntity>() {
|
||||
lateinit var name: String
|
||||
lateinit var artifactType: String
|
||||
var includeInProjectBuild: Boolean = false
|
||||
@@ -499,6 +503,8 @@ class ArtifactEntityData : PEntityData<ArtifactEntity>() {
|
||||
override fun createEntity(snapshot: TypedEntityStorage): ArtifactEntity {
|
||||
return ArtifactEntity(name, artifactType, includeInProjectBuild, outputUrl).also { addMetaData(it, snapshot) }
|
||||
}
|
||||
|
||||
override fun persistentId(): ArtifactId = ArtifactId(name)
|
||||
}
|
||||
|
||||
class ArtifactEntity(
|
||||
|
||||
@@ -6,7 +6,6 @@ import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
abstract class PTypedEntity : ReferableTypedEntity, Any() {
|
||||
@@ -150,6 +149,24 @@ abstract class PEntityData<E : TypedEntity>: Cloneable {
|
||||
.mapNotNull { it.get(this)?.hashCode() }
|
||||
.fold(31) { acc, i -> acc * 17 + i }
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporally solution.
|
||||
* Get persistent Id without creating of TypedEntity. Should be in sync with TypedEntityWithPersistentId.
|
||||
* But it doesn't everywhere. E.g. FacetEntity where we should resolve module before creating persistent id.
|
||||
*/
|
||||
abstract class WithCalculatablePersistentId<E : TypedEntity> : PEntityData<E>() {
|
||||
abstract fun persistentId(): PersistentEntityId<*>
|
||||
}
|
||||
|
||||
abstract class WithPersistentId<E : TypedEntity> : PEntityData<E>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun PEntityData<*>.persistentId(snapshot: TypedEntityStorage): PersistentEntityId<*>? = when (this) {
|
||||
is PEntityData.WithCalculatablePersistentId -> this.persistentId()
|
||||
is PEntityData.WithPersistentId -> (this.createEntity(snapshot) as TypedEntityWithPersistentId).persistentId()
|
||||
else -> null
|
||||
}
|
||||
|
||||
class EntityDataDelegation<A : PModifiableTypedEntity<*>, B> : ReadWriteProperty<A, B> {
|
||||
|
||||
@@ -158,7 +158,7 @@ internal class PEntityStorageBuilder(
|
||||
// Restore links to soft references
|
||||
if (cloned is PSoftLinkable) {
|
||||
for (link in cloned.getLinks()) {
|
||||
softLinks.put(link, cloned.createPid())
|
||||
softLinks.put(link, replaceToPid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +205,7 @@ internal class PEntityStorageBuilder(
|
||||
|
||||
val id = newEntity.createPid()
|
||||
val existingEntityData = entityDataById(id)
|
||||
val existingEntity = existingEntityData?.createEntity(this)
|
||||
val beforePersistentId = if (existingEntity is TypedEntityWithPersistentId) existingEntity.persistentId() else null
|
||||
val beforePersistentId = existingEntityData?.persistentId(this)
|
||||
val beforeSoftLinks = if (existingEntityData is PSoftLinkable) existingEntityData.getLinks() else null
|
||||
|
||||
/// Replace entity data. id should not be changed
|
||||
@@ -257,10 +256,9 @@ internal class PEntityStorageBuilder(
|
||||
private fun <T : TypedEntity> updateSoftReferences(beforePersistentId: PersistentEntityId<*>?,
|
||||
beforeSoftLinks: List<PersistentEntityId<*>>?,
|
||||
copiedData: PEntityData<T>) {
|
||||
val updatedEntity = copiedData.createEntity(this)
|
||||
val pid = (updatedEntity as PTypedEntity).id
|
||||
val pid = copiedData.createPid()
|
||||
if (beforePersistentId != null) {
|
||||
val afterPersistentId = (updatedEntity as TypedEntityWithPersistentId).persistentId()
|
||||
val afterPersistentId = copiedData.persistentId(this) ?: error("Persistent id expected")
|
||||
if (beforePersistentId != afterPersistentId) {
|
||||
val updatedIds = mutableListOf(beforePersistentId to afterPersistentId)
|
||||
while (updatedIds.isNotEmpty()) {
|
||||
@@ -415,23 +413,15 @@ internal class PEntityStorageBuilder(
|
||||
}
|
||||
|
||||
private fun PEntityData<*>.identificator(storage: AbstractPEntityStorage): Any {
|
||||
val entity = this.createEntity(storage)
|
||||
return if (entity is TypedEntityWithPersistentId) {
|
||||
entity.persistentId()
|
||||
}
|
||||
else {
|
||||
this.hashCode()
|
||||
}
|
||||
return this.persistentId(storage) ?: this.hashCode()
|
||||
}
|
||||
|
||||
private fun ArrayListMultimap<Any, PEntityData<out TypedEntity>>.find(entity: PEntityData<out TypedEntity>,
|
||||
storage: AbstractPEntityStorage): PEntityData<out TypedEntity>? {
|
||||
val possibleValues = this[entity.identificator(storage)]
|
||||
return if (entity.hasPersistentId()) {
|
||||
possibleValues.find {
|
||||
(it.createEntity(this@PEntityStorageBuilder) as TypedEntityWithPersistentId).persistentId() ==
|
||||
(entity.createEntity(this@PEntityStorageBuilder) as TypedEntityWithPersistentId).persistentId()
|
||||
}
|
||||
val persistentId = entity.persistentId(storage)
|
||||
return if (persistentId != null) {
|
||||
possibleValues.find { it.persistentId(this@PEntityStorageBuilder) == persistentId }
|
||||
}
|
||||
else {
|
||||
possibleValues.find { it == entity }
|
||||
@@ -753,7 +743,9 @@ internal class PEntityStorageBuilder(
|
||||
// TODO: 27.03.2020 Here should be consistency check
|
||||
val res = HashMap<TypedEntity, TypedEntity>()
|
||||
replaceMap.forEach { (oldId, newId) ->
|
||||
res[diff.entityDataByIdOrDie(oldId).createEntity(diff)] = this.entityDataByIdOrDie(newId).createEntity(this)
|
||||
if (oldId != newId) {
|
||||
res[diff.entityDataByIdOrDie(oldId).createEntity(diff)] = this.entityDataByIdOrDie(newId).createEntity(this)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user