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) {
|
internal class KonanIr(context: Context, irModule: IrModuleFragment): Ir<Context>(context, irModule) {
|
||||||
|
|
||||||
val propertiesWithBackingFields = mutableSetOf<PropertyDescriptor>()
|
val propertiesWithBackingFields = mutableSetOf<PropertyDescriptor>()
|
||||||
|
val classesDelegatedBackingFields = mutableMapOf<ClassDescriptor, MutableList<PropertyDescriptor>>()
|
||||||
|
|
||||||
val originalModuleIndex = ModuleIndex(irModule)
|
val originalModuleIndex = ModuleIndex(irModule)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ val IrProperty.konanBackingField: IrField?
|
|||||||
this.endOffset,
|
this.endOffset,
|
||||||
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
|
||||||
backingFieldDescriptor,
|
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 {
|
).also {
|
||||||
it.parent = this.parent
|
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 {
|
private fun ContextUtils.createClassBodyType(name: String, fields: List<IrField>): LLVMTypeRef {
|
||||||
val fieldTypes = fields.map {
|
val fieldTypes = fields.map { getLLVMType(it.type) }
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
getLLVMType(if (it.isDelegate) context.irBuiltIns.anyNType else it.type)
|
|
||||||
}
|
|
||||||
|
|
||||||
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!!
|
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), name)!!
|
||||||
|
|
||||||
|
|||||||
+20
-3
@@ -17,8 +17,13 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.serialization
|
package org.jetbrains.kotlin.backend.konan.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
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.declarations.IrProperty
|
||||||
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
|
||||||
@@ -29,12 +34,24 @@ internal class BackingFieldVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitProperty(declaration: IrProperty) {
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
if (declaration.backingField == null) return
|
if (declaration.isDelegated) {
|
||||||
assert(declaration.backingField!!.descriptor
|
val irClass = declaration.parent as? IrClass
|
||||||
== declaration.descriptor || declaration.isDelegated)
|
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)
|
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) {
|
internal fun markBackingFields(context: Context) {
|
||||||
|
|||||||
+15
-8
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.serialization
|
package org.jetbrains.kotlin.serialization
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.onlyIf
|
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.descriptors.needsSerializedIr
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.IrAwareExtension
|
import org.jetbrains.kotlin.backend.konan.serialization.IrAwareExtension
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanStringTable
|
import org.jetbrains.kotlin.backend.konan.serialization.KonanStringTable
|
||||||
@@ -54,6 +55,7 @@ import java.io.ByteArrayOutputStream
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KonanDescriptorSerializer private constructor(
|
class KonanDescriptorSerializer private constructor(
|
||||||
|
private val context: Context,
|
||||||
private val containingDeclaration: DeclarationDescriptor?,
|
private val containingDeclaration: DeclarationDescriptor?,
|
||||||
private val typeParameters: Interner<TypeParameterDescriptor>,
|
private val typeParameters: Interner<TypeParameterDescriptor>,
|
||||||
private val extension: SerializerExtension,
|
private val extension: SerializerExtension,
|
||||||
@@ -64,7 +66,7 @@ class KonanDescriptorSerializer private constructor(
|
|||||||
private val contractSerializer = ContractSerializer()
|
private val contractSerializer = ContractSerializer()
|
||||||
|
|
||||||
fun createChildSerializer(descriptor: DeclarationDescriptor): KonanDescriptorSerializer =
|
fun createChildSerializer(descriptor: DeclarationDescriptor): KonanDescriptorSerializer =
|
||||||
KonanDescriptorSerializer(descriptor, Interner(typeParameters), extension, typeTable, versionRequirementTable,
|
KonanDescriptorSerializer(context, descriptor, Interner(typeParameters), extension, typeTable, versionRequirementTable,
|
||||||
serializeTypeTableToFunction = false)
|
serializeTypeTableToFunction = false)
|
||||||
|
|
||||||
val stringTable: DescriptorAwareStringTable
|
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))
|
val nestedClassifiers = sort(DescriptorUtils.getAllDescriptors(classDescriptor.unsubstitutedInnerClassesScope))
|
||||||
for (descriptor in nestedClassifiers) {
|
for (descriptor in nestedClassifiers) {
|
||||||
if (descriptor is TypeAliasDescriptor) {
|
if (descriptor is TypeAliasDescriptor) {
|
||||||
@@ -735,29 +741,30 @@ class KonanDescriptorSerializer private constructor(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createTopLevel(extension: SerializerExtension): KonanDescriptorSerializer {
|
internal fun createTopLevel(context: Context, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||||
return KonanDescriptorSerializer(null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
return KonanDescriptorSerializer(context, null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||||
serializeTypeTableToFunction = false)
|
serializeTypeTableToFunction = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun createForLambda(extension: SerializerExtension): KonanDescriptorSerializer {
|
internal fun createForLambda(context: Context, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||||
return KonanDescriptorSerializer(null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
return KonanDescriptorSerializer(context, null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
|
||||||
serializeTypeTableToFunction = true)
|
serializeTypeTableToFunction = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun create(descriptor: ClassDescriptor, extension: SerializerExtension): KonanDescriptorSerializer {
|
internal fun create(context: Context, descriptor: ClassDescriptor, extension: SerializerExtension): KonanDescriptorSerializer {
|
||||||
val container = descriptor.containingDeclaration
|
val container = descriptor.containingDeclaration
|
||||||
val parentSerializer = if (container is ClassDescriptor)
|
val parentSerializer = if (container is ClassDescriptor)
|
||||||
create(container, extension)
|
create(context, container, extension)
|
||||||
else
|
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
|
// 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.
|
// serializing outer classes before nested classes.
|
||||||
// Otherwise our interner can get wrong ids because we may serialize classes in any order.
|
// Otherwise our interner can get wrong ids because we may serialize classes in any order.
|
||||||
val serializer = KonanDescriptorSerializer(
|
val serializer = KonanDescriptorSerializer(
|
||||||
|
context,
|
||||||
descriptor,
|
descriptor,
|
||||||
Interner(parentSerializer.typeParameters),
|
Interner(parentSerializer.typeParameters),
|
||||||
parentSerializer.extension,
|
parentSerializer.extension,
|
||||||
|
|||||||
+2
-2
@@ -144,7 +144,7 @@ internal fun deserializeModule(languageVersionSettings: LanguageVersionSettings,
|
|||||||
internal class KonanSerializationUtil(val context: Context, metadataVersion: BinaryVersion) {
|
internal class KonanSerializationUtil(val context: Context, metadataVersion: BinaryVersion) {
|
||||||
|
|
||||||
val serializerExtension = KonanSerializerExtension(context, metadataVersion)
|
val serializerExtension = KonanSerializerExtension(context, metadataVersion)
|
||||||
val topSerializer = KonanDescriptorSerializer.createTopLevel(serializerExtension)
|
val topSerializer = KonanDescriptorSerializer.createTopLevel(context, serializerExtension)
|
||||||
var classSerializer: KonanDescriptorSerializer = topSerializer
|
var classSerializer: KonanDescriptorSerializer = topSerializer
|
||||||
|
|
||||||
fun serializeClass(packageName: FqName,
|
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.
|
// TODO: this is to filter out object{}. Change me.
|
||||||
if (classDescriptor.isExported())
|
if (classDescriptor.isExported())
|
||||||
classSerializer = KonanDescriptorSerializer.create(classDescriptor, serializerExtension)
|
classSerializer = KonanDescriptorSerializer.create(context, classDescriptor, serializerExtension)
|
||||||
|
|
||||||
val classProto = classSerializer.classProto(classDescriptor).build()
|
val classProto = classSerializer.classProto(classDescriptor).build()
|
||||||
?: error("Class not serialized: $classDescriptor")
|
?: error("Class not serialized: $classDescriptor")
|
||||||
|
|||||||
Reference in New Issue
Block a user