diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt index 6d2070d5b61..a66f9366b01 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/ArrayMap.kt @@ -10,6 +10,8 @@ sealed class ArrayMap : Iterable { abstract operator fun set(index: Int, value: T) abstract operator fun get(index: Int): T? + + abstract fun copy(): ArrayMap } fun ArrayMap<*>.isEmpty(): Boolean = size == 0 @@ -27,6 +29,8 @@ internal object EmptyArrayMap : ArrayMap() { return null } + override fun copy(): ArrayMap = this + override fun iterator(): Iterator { return object : Iterator { override fun hasNext(): Boolean = false @@ -48,6 +52,8 @@ internal class OneElementArrayMap(val value: T, val index: Int) : Array return if (index == this.index) value else null } + override fun copy(): ArrayMap = OneElementArrayMap(value, index) + override fun iterator(): Iterator { return object : Iterator { private var notVisited = true @@ -68,16 +74,20 @@ internal class OneElementArrayMap(val value: T, val index: Int) : Array } } -internal class ArrayMapImpl : ArrayMap() { +internal class ArrayMapImpl private constructor( + private var data: Array +) : ArrayMap() { companion object { private const val DEFAULT_SIZE = 20 private const val INCREASE_K = 2 } + constructor() : this(arrayOfNulls(DEFAULT_SIZE)) + override var size: Int = 0 private set - private var data = arrayOfNulls(DEFAULT_SIZE) + private fun ensureCapacity(index: Int) { if (data.size <= index) { data = data.copyOf(data.size * INCREASE_K) @@ -97,6 +107,8 @@ internal class ArrayMapImpl : ArrayMap() { return data.getOrNull(index) as T? } + override fun copy(): ArrayMap = ArrayMapImpl(data.copyOf()) + override fun iterator(): Iterator { return object : AbstractIterator() { private var index = -1 @@ -128,4 +140,4 @@ internal class ArrayMapImpl : ArrayMap() { } data class Entry(override val key: Int, override val value: T) : Map.Entry -} \ No newline at end of file +} diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt index 1d5b2360fd8..a7bee7edba9 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/utils/AttributeArrayOwner.kt @@ -17,11 +17,15 @@ import kotlin.reflect.KClass * from components in [ComponentArrayOwner] */ @OptIn(Protected::class) -abstract class AttributeArrayOwner : AbstractArrayMapOwner() { - @Suppress("UNCHECKED_CAST") - final override var arrayMap: ArrayMap = EmptyArrayMap as ArrayMap +abstract class AttributeArrayOwner protected constructor( + arrayMap: ArrayMap +) : AbstractArrayMapOwner() { + final override var arrayMap: ArrayMap = arrayMap private set + @Suppress("UNCHECKED_CAST") + constructor() : this(EmptyArrayMap as ArrayMap) + final override fun registerComponent(tClass: KClass, value: T) { val id = typeRegistry.getId(tClass) when (arrayMap.size) { @@ -61,4 +65,4 @@ abstract class AttributeArrayOwner : AbstractArrayMapOwner() { +class FirDeclarationAttributes : AttributeArrayOwner { override val typeRegistry: TypeRegistry get() = FirDeclarationDataRegistry + constructor() : super() + private constructor(arrayMap: ArrayMap) : super(arrayMap) + internal operator fun set(key: KClass, value: Any?) { if (value == null) { removeComponent(key) @@ -25,6 +29,8 @@ class FirDeclarationAttributes : AttributeArrayOwner registerComponent(key, value) } } + + fun copy(): FirDeclarationAttributes = FirDeclarationAttributes(arrayMap.copy()) } /* diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt index e6050cb2df8..25bd5c33832 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/builder.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.tree.generator.printer +import org.jetbrains.kotlin.fir.tree.generator.declarationAttributesType import org.jetbrains.kotlin.fir.tree.generator.model.* import java.io.File @@ -294,12 +295,13 @@ private fun SmartPrinter.printDslBuildCopyFunction( println("}") println("val copyBuilder = $builderType()") for (field in builder.allFields) { - when (field.origin) { - is FieldList -> println("copyBuilder.${field.name}.addAll(original.${field.name})") + when { + field.origin is FieldList -> println("copyBuilder.${field.name}.addAll(original.${field.name})") + field.type == declarationAttributesType.type -> println("copyBuilder.${field.name} = original.${field.name}.copy()") else -> println("copyBuilder.${field.name} = original.${field.name}") } } println("return copyBuilder.apply(init).build()") } println("}") -} \ No newline at end of file +}