Supported synthetic fields in serialization
This commit is contained in:
+1
@@ -58,6 +58,7 @@ import kotlin.properties.Delegates
|
||||
internal class KonanIr(context: Context, irModule: IrModuleFragment): Ir<Context>(context, irModule) {
|
||||
|
||||
val propertiesWithBackingFields = mutableSetOf<PropertyDescriptor>()
|
||||
val classesDelegatedBackingFields = mutableMapOf<ClassDescriptor, MutableList<PropertyDescriptor>>()
|
||||
|
||||
val originalModuleIndex = ModuleIndex(irModule)
|
||||
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ val IrProperty.konanBackingField: IrField?
|
||||
this.endOffset,
|
||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||
backingFieldDescriptor,
|
||||
this.getter!!.returnType // TODO: this copies the behaviour found in backing field descriptor creation, but both are incorrect for property delegation.
|
||||
this.getter!!.returnType
|
||||
).also {
|
||||
it.parent = this.parent
|
||||
}
|
||||
|
||||
+1
-4
@@ -139,10 +139,7 @@ private fun Context.getDeclaredFields(classDescriptor: ClassDescriptor): List<Ir
|
||||
}
|
||||
|
||||
private fun ContextUtils.createClassBodyType(name: String, fields: List<IrField>): LLVMTypeRef {
|
||||
val fieldTypes = fields.map {
|
||||
@Suppress("DEPRECATION")
|
||||
getLLVMType(if (it.isDelegate) context.irBuiltIns.anyNType else it.type)
|
||||
}
|
||||
val fieldTypes = fields.map { getLLVMType(it.type) }
|
||||
|
||||
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!!
|
||||
|
||||
|
||||
+20
-3
@@ -17,8 +17,13 @@
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
|
||||
@@ -29,12 +34,24 @@ internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty) {
|
||||
if (declaration.backingField == null) return
|
||||
assert(declaration.backingField!!.descriptor
|
||||
== declaration.descriptor || declaration.isDelegated)
|
||||
if (declaration.isDelegated) {
|
||||
val irClass = declaration.parent as? IrClass
|
||||
val list = irClass?.let { context.ir.classesDelegatedBackingFields.getOrPut(irClass.descriptor) { mutableListOf() } }
|
||||
list?.add(declaration.backingField!!.descriptor)
|
||||
}
|
||||
if (declaration.backingField == null || declaration.isDelegated) return
|
||||
assert(declaration.backingField!!.descriptor == declaration.descriptor)
|
||||
|
||||
context.ir.propertiesWithBackingFields.add(declaration.descriptor)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
declaration.declarations.filterIsInstance<IrField>().forEach {
|
||||
val list = context.ir.classesDelegatedBackingFields.getOrPut(declaration.descriptor) { mutableListOf() }
|
||||
list.add(it.descriptor)
|
||||
}
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun markBackingFields(context: Context) {
|
||||
|
||||
+15
-8
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.onlyIf
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.needsSerializedIr
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.IrAwareExtension
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanStringTable
|
||||
@@ -54,6 +55,7 @@ import java.io.ByteArrayOutputStream
|
||||
import java.util.*
|
||||
|
||||
class KonanDescriptorSerializer private constructor(
|
||||
private val context: Context,
|
||||
private val containingDeclaration: DeclarationDescriptor?,
|
||||
private val typeParameters: Interner<TypeParameterDescriptor>,
|
||||
private val extension: SerializerExtension,
|
||||
@@ -64,7 +66,7 @@ class KonanDescriptorSerializer private constructor(
|
||||
private val contractSerializer = ContractSerializer()
|
||||
|
||||
fun createChildSerializer(descriptor: DeclarationDescriptor): KonanDescriptorSerializer =
|
||||
KonanDescriptorSerializer(descriptor, Interner(typeParameters), extension, typeTable, versionRequirementTable,
|
||||
KonanDescriptorSerializer(context, descriptor, Interner(typeParameters), extension, typeTable, versionRequirementTable,
|
||||
serializeTypeTableToFunction = false)
|
||||
|
||||
val stringTable: DescriptorAwareStringTable
|
||||
@@ -124,6 +126,10 @@ class KonanDescriptorSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
context.ir.classesDelegatedBackingFields[classDescriptor]?.forEach {
|
||||
builder.addProperty(propertyProto(it))
|
||||
}
|
||||
|
||||
val nestedClassifiers = sort(DescriptorUtils.getAllDescriptors(classDescriptor.unsubstitutedInnerClassesScope))
|
||||
for (descriptor in nestedClassifiers) {
|
||||
if (descriptor is TypeAliasDescriptor) {
|
||||
@@ -735,29 +741,30 @@ class KonanDescriptorSerializer private constructor(
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createTopLevel(extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
return KonanDescriptorSerializer(null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||
internal fun createTopLevel(context: Context, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
return KonanDescriptorSerializer(context, null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||
serializeTypeTableToFunction = false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createForLambda(extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
return KonanDescriptorSerializer(null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||
internal fun createForLambda(context: Context, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
return KonanDescriptorSerializer(context, null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||
serializeTypeTableToFunction = true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun create(descriptor: ClassDescriptor, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
internal fun create(context: Context, descriptor: ClassDescriptor, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||
val container = descriptor.containingDeclaration
|
||||
val parentSerializer = if (container is ClassDescriptor)
|
||||
create(container, extension)
|
||||
create(context, container, extension)
|
||||
else
|
||||
createTopLevel(extension)
|
||||
createTopLevel(context, extension)
|
||||
|
||||
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
|
||||
// serializing outer classes before nested classes.
|
||||
// Otherwise our interner can get wrong ids because we may serialize classes in any order.
|
||||
val serializer = KonanDescriptorSerializer(
|
||||
context,
|
||||
descriptor,
|
||||
Interner(parentSerializer.typeParameters),
|
||||
parentSerializer.extension,
|
||||
|
||||
+2
-2
@@ -144,7 +144,7 @@ internal fun deserializeModule(languageVersionSettings: LanguageVersionSettings,
|
||||
internal class KonanSerializationUtil(val context: Context, metadataVersion: BinaryVersion) {
|
||||
|
||||
val serializerExtension = KonanSerializerExtension(context, metadataVersion)
|
||||
val topSerializer = KonanDescriptorSerializer.createTopLevel(serializerExtension)
|
||||
val topSerializer = KonanDescriptorSerializer.createTopLevel(context, serializerExtension)
|
||||
var classSerializer: KonanDescriptorSerializer = topSerializer
|
||||
|
||||
fun serializeClass(packageName: FqName,
|
||||
@@ -155,7 +155,7 @@ internal class KonanSerializationUtil(val context: Context, metadataVersion: Bin
|
||||
|
||||
// TODO: this is to filter out object{}. Change me.
|
||||
if (classDescriptor.isExported())
|
||||
classSerializer = KonanDescriptorSerializer.create(classDescriptor, serializerExtension)
|
||||
classSerializer = KonanDescriptorSerializer.create(context, classDescriptor, serializerExtension)
|
||||
|
||||
val classProto = classSerializer.classProto(classDescriptor).build()
|
||||
?: error("Class not serialized: $classDescriptor")
|
||||
|
||||
Reference in New Issue
Block a user