[FIR] Try to load properties in order according to kotlinx.serialization metadata extension

Move metadata extension with property order from kotlinx.serialization to core

After fix of KT-54792 properties will be deserialized in declaration order
  if corresponding class was compiled with modern compiler. But this order
  is needed for kotlinx.serialization for binaries compiled with any
  kotlin compiler >= 1.4. Since we don't plan to add any extension points
  into (de)serialization into FIR, we need to take into account existing
  metadata extension from kotlinx.serialization in compiler itself

^KT-57769 Fixed
This commit is contained in:
Dmitriy Novozhilov
2022-11-02 13:59:32 +02:00
committed by Space Team
parent 7685284cb7
commit 94f77add49
15 changed files with 142 additions and 13 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.toLookupTag
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.SerializationPluginMetadataExtensions
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.name.*
@@ -139,7 +140,7 @@ fun deserializeClassToSymbol(
)
addDeclarations(
classProto.propertyList.map {
classProto.propertiesInOrder(context).map {
classDeserializer.loadProperty(it, classProto, symbol)
}
)
@@ -314,10 +315,23 @@ abstract class DeserializedClassConfigurator(val session: FirSession) : FirSessi
open fun FirRegularClass.configure(classId: ClassId) {}
}
class JvmDeserializedClassConfigurator(session: FirSession): DeserializedClassConfigurator(session) {
class JvmDeserializedClassConfigurator(session: FirSession) : DeserializedClassConfigurator(session) {
override fun FirRegularClassBuilder.configure(classId: ClassId) {
addSerializableIfNeeded(classId)
}
}
private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(context: FirDeserializationContext): List<ProtoBuf.Property> {
val properties = propertyList
val versionRequirements = VersionRequirement.create(this, context.nameResolver, context.versionRequirementTable)
if (versionRequirements.any { it.version.major >= 2 }) return properties
val order = getExtension(SerializationPluginMetadataExtensions.propertiesNamesInProgramOrder)
.takeIf { it.isNotEmpty() }
?: return properties
val propertiesByName = properties.groupBy { it.name }
return order.flatMap { propertiesByName[it] ?: emptyList() }.also {
assert(it.size == properties.size)
}
}
val FirSession.deserializedClassConfigurator: DeserializedClassConfigurator? by FirSession.nullableSessionComponentAccessor()