[LL FIR] allow recursive access to the same FirThreadSafeCache

^KT-56721 fixed
This commit is contained in:
Ilya Kirillov
2023-02-16 14:10:26 +01:00
committed by Space Team
parent d670e5a695
commit c60fd38e05
4 changed files with 11 additions and 10 deletions
@@ -13,17 +13,9 @@ internal class FirThreadSafeCache<K : Any, V, CONTEXT>(
private val createValue: (K, CONTEXT) -> V
) : FirCache<K, V, CONTEXT>() {
private val updating: ThreadLocal<Boolean> = ThreadLocal.withInitial { false }
override fun getValue(key: K, context: CONTEXT): V =
map.getOrPutWithNullableValue(key) {
if (updating.get()) error("Recursive update")
try {
updating.set(true)
createValue(it, context)
} finally {
updating.set(false)
}
createValue(it, context)
}
override fun getValueIfComputed(key: K): V? =
@@ -19,6 +19,6 @@ internal inline fun <KEY : Any, RESULT> ConcurrentMap<KEY, Any>.getOrPutWithNull
key: KEY,
crossinline compute: (KEY) -> Any?
): RESULT {
val value = computeIfAbsent(key) { compute(key) ?: NullValue }
val value = getOrPut(key) { compute(key) ?: NullValue }
return value.nullValueToNull()
}
@@ -23,6 +23,12 @@ import kotlin.reflect.KClass
* TODO:
* - check that annotations or meta-annotations is not empty
*/
/**
* All `generate*` members have the contract that the computation should be side-effect-free.
* That means that all `generate*` function implementations should not modify any state or leak the generated `FirElement` or `FirBasedSymbol` (e.g., by putting it to some cache).
* This restriction is imposed by the corresponding IDE cache implementation, which might retry the computation several times.
*/
abstract class FirDeclarationGenerationExtension(session: FirSession) : FirExtension(session) {
companion object {
val NAME = FirExtensionPointName("ExistingClassModification")
@@ -15,6 +15,9 @@ abstract class FirCachesFactory : FirSessionComponent {
*
* [FirCache.getValue] should not be called inside [createValue]
*
* Note, that [createValue] might be called multiple times for the same value,
* but all threads will always get the same value
*
* Where:
* [CONTEXT] -- type of value which be used to create value by [createValue]
*/