From ad09eb5416d5d4dbc2e7125487daeb96812530e7 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 7 May 2020 17:42:16 +0300 Subject: [PATCH] [FIR] Add ability to rewrite attributes in FirDeclarationAttributes --- .../declarations/FirDeclarationAttributes.kt | 12 ++++++----- .../jetbrains/kotlin/fir/utils/ArrayMap.kt | 21 ++++++++++++++++--- .../kotlin/fir/utils/AttributeArrayOwner.kt | 20 ++++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationAttributes.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationAttributes.kt index 96bb8fb475a..b477cdfef51 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationAttributes.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationAttributes.kt @@ -18,8 +18,12 @@ class FirDeclarationAttributes : AttributeArrayOwner override val typeRegistry: TypeRegistry get() = FirDeclarationDataRegistry - internal operator fun set(key: KClass, value: Any) { - registerComponent(key, value) + internal operator fun set(key: KClass, value: Any?) { + if (value == null) { + removeComponent(key) + } else { + registerComponent(key, value) + } } } @@ -44,9 +48,7 @@ object FirDeclarationDataRegistry : TypeRegistry() { } override fun setValue(thisRef: FirDeclaration, property: KProperty<*>, value: V?) { - if (value != null) { - thisRef.attributes[key] = value - } + thisRef.attributes[key] = value } } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt index 01f4fc63701..5e4488fef84 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt @@ -38,7 +38,7 @@ internal class OneElementArrayMap(val value: T, val index: Int) : Array } } -internal class ArrayMapImpl : ArrayMap() { +internal class ArrayMapImpl : ArrayMap() { companion object { private const val DEFAULT_SIZE = 20 private const val INCREASE_K = 2 @@ -56,13 +56,28 @@ internal class ArrayMapImpl : ArrayMap() { override operator fun set(index: Int, value: T) { ensureCapacity(index) + if (data[index] == null) { + size++ + } data[index] = value - - size++ } override operator fun get(index: Int): T? { @Suppress("UNCHECKED_CAST") return data.getOrNull(index) as T? } + + fun remove(index: Int) { + if (data[index] != null) { + size-- + } + data[index] = null + } + + fun entries(): List> { + @Suppress("UNCHECKED_CAST") + return data.mapIndexedNotNull { index, value -> if (value != null) Entry(index, value as T) else null } + } + + data class Entry(override val key: Int, override val value: T) : Map.Entry } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt index 32930a3f9dc..0d73688dbc5 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt @@ -12,6 +12,9 @@ import kotlin.reflect.KClass * depending on array map fullness * [AttributeArrayOwner] can be used in classes with many instances, * like user data for Fir elements or attributes for cone types + * + * Note that you can remove attributes from [AttributeArrayOwner] despite + * from components in [ComponentArrayOwner] */ abstract class AttributeArrayOwner : AbstractArrayMapOwner() { @Suppress("UNCHECKED_CAST") @@ -36,4 +39,21 @@ abstract class AttributeArrayOwner : AbstractArrayMapOwner) { + val id = typeRegistry.getId(tClass) + if (arrayMap[id] == null) return + @Suppress("UNCHECKED_CAST") + when (arrayMap.size) { + 1 -> arrayMap = EmptyArrayMap as ArrayMap + else -> { + val map = arrayMap as ArrayMapImpl + map.remove(id) + if (map.size == 1) { + val (index, value) = map.entries().first() + arrayMap = OneElementArrayMap(value, index) + } + } + } + } } \ No newline at end of file