From dab50daf56e70ad5232a6eddd6b5503310976ec2 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 4 Jan 2023 11:14:15 +0100 Subject: [PATCH] K2: Add ability identify DI components by string key instead of KClass It allows having several the same typed-component in the container --- .../org/jetbrains/kotlin/fir/FirSession.kt | 9 ++++++ .../jetbrains/kotlin/util/ArrayMapOwner.kt | 32 ++++++++++++------- .../kotlin/util/AttributeArrayOwner.kt | 4 +-- .../kotlin/util/ComponentArrayOwner.kt | 10 +++--- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt index b0b64a14d1c..4244bacb09f 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt @@ -24,6 +24,10 @@ abstract class FirSession @PrivateSessionConstructor constructor( return generateAccessor(T::class) } + inline fun sessionComponentAccessor(id: String): ArrayMapAccessor { + return generateAccessor(id) + } + inline fun nullableSessionComponentAccessor(): NullableArrayMapAccessor { return generateNullableAccessor(T::class) } @@ -38,6 +42,11 @@ abstract class FirSession @PrivateSessionConstructor constructor( registerComponent(tClass, value) } + @SessionConfiguration + fun register(keyQualifiedName: String, value: FirSessionComponent) { + registerComponent(keyQualifiedName, value) + } + override fun toString(): String { val moduleData = nullableModuleData ?: return "Libraries session" return "Source session for module ${moduleData.name}" diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/ArrayMapOwner.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/ArrayMapOwner.kt index 1b0dfef625a..4b778f2509a 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/ArrayMapOwner.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/ArrayMapOwner.kt @@ -19,7 +19,6 @@ abstract class AbstractArrayMapOwner : Iterable { protected abstract val typeRegistry: TypeRegistry abstract class AbstractArrayMapAccessor( - protected val key: KClass, protected val id: Int ) { protected fun extractValue(thisRef: AbstractArrayMapOwner): T? { @@ -28,7 +27,11 @@ abstract class AbstractArrayMapOwner : Iterable { } } - protected abstract fun registerComponent(tClass: KClass, value: V) + protected abstract fun registerComponent(keyQualifiedName: String, value: V) + + protected fun registerComponent(tClass: KClass, value: V) { + registerComponent(tClass.qualifiedName!!, value) + } final override fun iterator(): Iterator = arrayMap.iterator() @@ -40,21 +43,20 @@ abstract class AbstractArrayMapOwner : Iterable { } class ArrayMapAccessor( - key: KClass, + private val keyQualifiedName: String, id: Int, val default: T? = null -) : AbstractArrayMapOwner.AbstractArrayMapAccessor(key, id), ReadOnlyProperty, V> { +) : AbstractArrayMapOwner.AbstractArrayMapAccessor(id), ReadOnlyProperty, V> { override fun getValue(thisRef: AbstractArrayMapOwner, property: KProperty<*>): T { return extractValue(thisRef) ?: default - ?: error("No '$key'($id) in array owner: $thisRef") + ?: error("No '$keyQualifiedName'($id) in array owner: $thisRef") } } class NullableArrayMapAccessor( - key: KClass, id: Int -) : AbstractArrayMapOwner.AbstractArrayMapAccessor(key, id), ReadOnlyProperty, V?> { +) : AbstractArrayMapOwner.AbstractArrayMapAccessor(id), ReadOnlyProperty, V?> { override fun getValue(thisRef: AbstractArrayMapOwner, property: KProperty<*>): T? { return extractValue(thisRef) } @@ -65,19 +67,27 @@ abstract class TypeRegistry { private val idCounter = AtomicInteger(0) fun generateAccessor(kClass: KClass, default: T? = null): ArrayMapAccessor { - return ArrayMapAccessor(kClass, getId(kClass), default) + return ArrayMapAccessor(kClass.qualifiedName!!, getId(kClass), default) + } + + fun generateAccessor(keyQualifiedName: String, default: T? = null): ArrayMapAccessor { + return ArrayMapAccessor(keyQualifiedName, getId(keyQualifiedName), default) } fun generateNullableAccessor(kClass: KClass): NullableArrayMapAccessor { - return NullableArrayMapAccessor(kClass, getId(kClass)) + return NullableArrayMapAccessor(getId(kClass)) } fun generateAnyNullableAccessor(kClass: KClass): NullableArrayMapAccessor { - return NullableArrayMapAccessor(kClass, getId(kClass)) + return NullableArrayMapAccessor(getId(kClass)) } fun getId(kClass: KClass): Int { - return idPerType.customComputeIfAbsent(kClass.qualifiedName!!) { idCounter.getAndIncrement() } + return getId(kClass.qualifiedName!!) + } + + fun getId(keyQualifiedName: String): Int { + return idPerType.customComputeIfAbsent(keyQualifiedName) { idCounter.getAndIncrement() } } /* diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/AttributeArrayOwner.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/AttributeArrayOwner.kt index 0df3596e0b0..2d65c2d031d 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/AttributeArrayOwner.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/AttributeArrayOwner.kt @@ -25,8 +25,8 @@ abstract class AttributeArrayOwner protected constructor( @Suppress("UNCHECKED_CAST") constructor() : this(EmptyArrayMap as ArrayMap) - final override fun registerComponent(tClass: KClass, value: T) { - val id = typeRegistry.getId(tClass) + final override fun registerComponent(keyQualifiedName: String, value: T) { + val id = typeRegistry.getId(keyQualifiedName) when (arrayMap.size) { 0 -> { arrayMap = OneElementArrayMap(value, id) diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/ComponentArrayOwner.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/ComponentArrayOwner.kt index d8b81281c68..67cab26709e 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/ComponentArrayOwner.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/ComponentArrayOwner.kt @@ -15,12 +15,12 @@ abstract class ComponentArrayOwner : AbstractArrayMapOwner = ArrayMapImpl() - final override fun registerComponent(tClass: KClass, value: V) { - val id = typeRegistry.getId(tClass) + final override fun registerComponent(keyQualifiedName: String, value: V) { + val id = typeRegistry.getId(keyQualifiedName) try { arrayMap[id] = value } catch (e: Exception) { - throw RuntimeException(createDiagnosticMessage(id, tClass), e) + throw RuntimeException(createDiagnosticMessage(id, keyQualifiedName), e) } } @@ -29,10 +29,10 @@ abstract class ComponentArrayOwner : AbstractArrayMapOwner): String = buildString { + private fun createDiagnosticMessage(id: Int, keyQualifiedName: String): String = buildString { appendLine("Error occurred during registration of component in array") appendLine("Currently registered") - appendLine(" $id: $tClass") + appendLine(" $id: $keyQualifiedName") appendLine("Registrar:") for ((kClass, x) in typeRegistry.allValuesThreadUnsafeForRendering()) { appendLine(" $x: $kClass")