FIR: Copy attributes when copying declaration
Otherwise they share FirDeclarationAttributes instance that might lead to problems when modifying only one of them
This commit is contained in:
@@ -10,6 +10,8 @@ sealed class ArrayMap<T : Any> : Iterable<T> {
|
||||
|
||||
abstract operator fun set(index: Int, value: T)
|
||||
abstract operator fun get(index: Int): T?
|
||||
|
||||
abstract fun copy(): ArrayMap<T>
|
||||
}
|
||||
|
||||
fun ArrayMap<*>.isEmpty(): Boolean = size == 0
|
||||
@@ -27,6 +29,8 @@ internal object EmptyArrayMap : ArrayMap<Nothing>() {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun copy(): ArrayMap<Nothing> = this
|
||||
|
||||
override fun iterator(): Iterator<Nothing> {
|
||||
return object : Iterator<Nothing> {
|
||||
override fun hasNext(): Boolean = false
|
||||
@@ -48,6 +52,8 @@ internal class OneElementArrayMap<T : Any>(val value: T, val index: Int) : Array
|
||||
return if (index == this.index) value else null
|
||||
}
|
||||
|
||||
override fun copy(): ArrayMap<T> = OneElementArrayMap(value, index)
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
return object : Iterator<T> {
|
||||
private var notVisited = true
|
||||
@@ -68,16 +74,20 @@ internal class OneElementArrayMap<T : Any>(val value: T, val index: Int) : Array
|
||||
}
|
||||
}
|
||||
|
||||
internal class ArrayMapImpl<T : Any> : ArrayMap<T>() {
|
||||
internal class ArrayMapImpl<T : Any> private constructor(
|
||||
private var data: Array<Any?>
|
||||
) : ArrayMap<T>() {
|
||||
companion object {
|
||||
private const val DEFAULT_SIZE = 20
|
||||
private const val INCREASE_K = 2
|
||||
}
|
||||
|
||||
constructor() : this(arrayOfNulls<Any>(DEFAULT_SIZE))
|
||||
|
||||
override var size: Int = 0
|
||||
private set
|
||||
|
||||
private var data = arrayOfNulls<Any>(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<T : Any> : ArrayMap<T>() {
|
||||
return data.getOrNull(index) as T?
|
||||
}
|
||||
|
||||
override fun copy(): ArrayMap<T> = ArrayMapImpl(data.copyOf())
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
return object : AbstractIterator<T>() {
|
||||
private var index = -1
|
||||
@@ -128,4 +140,4 @@ internal class ArrayMapImpl<T : Any> : ArrayMap<T>() {
|
||||
}
|
||||
|
||||
data class Entry<T>(override val key: Int, override val value: T) : Map.Entry<Int, T>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,11 +17,15 @@ import kotlin.reflect.KClass
|
||||
* from components in [ComponentArrayOwner]
|
||||
*/
|
||||
@OptIn(Protected::class)
|
||||
abstract class AttributeArrayOwner<K : Any, T : Any> : AbstractArrayMapOwner<K, T>() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
final override var arrayMap: ArrayMap<T> = EmptyArrayMap as ArrayMap<T>
|
||||
abstract class AttributeArrayOwner<K : Any, T : Any> protected constructor(
|
||||
arrayMap: ArrayMap<T>
|
||||
) : AbstractArrayMapOwner<K, T>() {
|
||||
final override var arrayMap: ArrayMap<T> = arrayMap
|
||||
private set
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
constructor() : this(EmptyArrayMap as ArrayMap<T>)
|
||||
|
||||
final override fun registerComponent(tClass: KClass<out K>, value: T) {
|
||||
val id = typeRegistry.getId(tClass)
|
||||
when (arrayMap.size) {
|
||||
@@ -61,4 +65,4 @@ abstract class AttributeArrayOwner<K : Any, T : Any> : AbstractArrayMapOwner<K,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ inline fun buildConstructorCopy(original: FirConstructor, init: FirConstructorBu
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.receiverTypeRef = original.receiverTypeRef
|
||||
copyBuilder.typeParameters.addAll(original.typeParameters)
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ inline fun buildPropertyAccessorCopy(original: FirPropertyAccessor, init: FirPro
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.valueParameters.addAll(original.valueParameters)
|
||||
copyBuilder.body = original.body
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ inline fun buildPropertyCopy(original: FirProperty, init: FirPropertyBuilder.()
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.receiverTypeRef = original.receiverTypeRef
|
||||
copyBuilder.name = original.name
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ inline fun buildSimpleFunctionCopy(original: FirSimpleFunction, init: FirSimpleF
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.receiverTypeRef = original.receiverTypeRef
|
||||
copyBuilder.valueParameters.addAll(original.valueParameters)
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ inline fun buildValueParameterCopy(original: FirValueParameter, init: FirValuePa
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.attributes = original.attributes
|
||||
copyBuilder.attributes = original.attributes.copy()
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.name = original.name
|
||||
copyBuilder.symbol = original.symbol
|
||||
|
||||
+7
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.utils.ArrayMap
|
||||
import org.jetbrains.kotlin.fir.utils.AttributeArrayOwner
|
||||
import org.jetbrains.kotlin.fir.utils.NullableArrayMapAccessor
|
||||
import org.jetbrains.kotlin.fir.utils.TypeRegistry
|
||||
@@ -14,10 +15,13 @@ import kotlin.reflect.KProperty
|
||||
|
||||
abstract class FirDeclarationDataKey
|
||||
|
||||
class FirDeclarationAttributes : AttributeArrayOwner<FirDeclarationDataKey, Any>() {
|
||||
class FirDeclarationAttributes : AttributeArrayOwner<FirDeclarationDataKey, Any> {
|
||||
override val typeRegistry: TypeRegistry<FirDeclarationDataKey, Any>
|
||||
get() = FirDeclarationDataRegistry
|
||||
|
||||
constructor() : super()
|
||||
private constructor(arrayMap: ArrayMap<Any>) : super(arrayMap)
|
||||
|
||||
internal operator fun set(key: KClass<out FirDeclarationDataKey>, value: Any?) {
|
||||
if (value == null) {
|
||||
removeComponent(key)
|
||||
@@ -25,6 +29,8 @@ class FirDeclarationAttributes : AttributeArrayOwner<FirDeclarationDataKey, Any>
|
||||
registerComponent(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun copy(): FirDeclarationAttributes = FirDeclarationAttributes(arrayMap.copy())
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+5
-3
@@ -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("}")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user