Added support for inline class members.
Inline constructors in particular.
This commit is contained in:
committed by
alexander-gorshenev
parent
2a246a9a3a
commit
d4c34b29c1
+14
@@ -296,6 +296,20 @@ internal fun FunctionDescriptor.bridgeDirectionsTo(overriddenDescriptor: Functio
|
||||
return ourDirections
|
||||
}
|
||||
|
||||
internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
|
||||
return if (this is PackageFragmentDescriptor) this
|
||||
else this.containingDeclaration!!.findPackage()
|
||||
}
|
||||
|
||||
internal fun DeclarationDescriptor.allContainingDeclarations(): List<DeclarationDescriptor> {
|
||||
var list = mutableListOf<DeclarationDescriptor>()
|
||||
var current = this.containingDeclaration
|
||||
while (current != null) {
|
||||
list.add(current)
|
||||
current = current.containingDeclaration
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
internal fun DeclarationDescriptor.getMemberScope(): MemberScope {
|
||||
val containingScope = when (this) {
|
||||
|
||||
+24
-28
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.KonanIrDeserializationException
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.contributedMethods
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.isExported
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.serialization.KonanIr.KotlinDescriptor
|
||||
import org.jetbrains.kotlin.serialization.KonanIr.DeclarationDescriptor.DescriptorCase.*
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
@@ -36,18 +38,12 @@ import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
|
||||
return if (this is PackageFragmentDescriptor) this
|
||||
else this.containingDeclaration!!.findPackage()
|
||||
}
|
||||
|
||||
internal fun DeserializedMemberDescriptor.nameTable(): ProtoBuf.QualifiedNameTable {
|
||||
val pkg = this.findPackage()
|
||||
assert(pkg is KonanPackageFragment)
|
||||
return (pkg as KonanPackageFragment).proto.getNameTable()
|
||||
}
|
||||
|
||||
|
||||
internal fun DeserializedMemberDescriptor.nameResolver(): NameResolver {
|
||||
val pkg = this.findPackage() as KonanPackageFragment
|
||||
return NameResolverImpl(pkg.proto.getStringTable(), pkg.proto.getNameTable())
|
||||
@@ -68,9 +64,10 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
fun deserializeKotlinType(proto: KonanIr.KotlinType): KotlinType {
|
||||
val index = proto.getIndex()
|
||||
val text = proto.getDebugText()
|
||||
val typeProto = localDeserializer.typeTable[index]
|
||||
val typeProto = localDeserializer.parentTypeTable[index]
|
||||
val type = localDeserializer.deserializeInlineType(typeProto)
|
||||
if (type.isError) throw KonanIrDeserializationException("Could not deserialize KotlinType: $text $type")
|
||||
if (type.isError)
|
||||
throw KonanIrDeserializationException("Could not deserialize KotlinType: $text $type")
|
||||
|
||||
val realType = if (proto.isCaptured) {
|
||||
unpackCapturedType(type)
|
||||
@@ -80,26 +77,24 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
context.log{"### deserialized Kotlin Type index=$index, text=$text:\t$realType"}
|
||||
return realType
|
||||
}
|
||||
|
||||
fun deserializeLocalDeclaration(irProto: KonanIr.KotlinDescriptor): DeclarationDescriptor {
|
||||
val localDeclarationProto = irProto.irLocalDeclaration.descriptor
|
||||
when {
|
||||
localDeclarationProto.hasFunction() -> {
|
||||
val index = irProto.index
|
||||
val descriptor = localDeserializer.deserializeFunction(irProto)
|
||||
descriptorIndex.put(index, descriptor)
|
||||
return descriptor
|
||||
}
|
||||
|
||||
localDeclarationProto.hasProperty() -> {
|
||||
val index = irProto.index
|
||||
val descriptor = localDeserializer.deserializeProperty(irProto)
|
||||
descriptorIndex.put(index, descriptor)
|
||||
return descriptor
|
||||
}
|
||||
// TODO
|
||||
// localDclarationProto.hasClazz() ->
|
||||
val index = irProto.index
|
||||
//val localDeserializer = LocalDeclarationDeserializer(parent)
|
||||
val descriptor: DeclarationDescriptor = when(localDeclarationProto.descriptorCase) {
|
||||
FUNCTION ->
|
||||
localDeserializer.deserializeFunction(irProto)
|
||||
PROPERTY ->
|
||||
localDeserializer.deserializeProperty(irProto)
|
||||
CLAZZ ->
|
||||
localDeserializer.deserializeClass(irProto)
|
||||
CONSTRUCTOR ->
|
||||
localDeserializer.deserializeConstructor(irProto)
|
||||
else -> TODO("Unexpected descriptor kind")
|
||||
}
|
||||
descriptorIndex.put(index, descriptor)
|
||||
return descriptor
|
||||
}
|
||||
|
||||
// Either (a substitution of) a public descriptor
|
||||
@@ -113,6 +108,10 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
KonanIr.KotlinDescriptor.Kind.VALUE_PARAMETER,
|
||||
KonanIr.KotlinDescriptor.Kind.TYPE_PARAMETER,
|
||||
KonanIr.KotlinDescriptor.Kind.RECEIVER,
|
||||
// Properties can only be found in local
|
||||
// classes, so no need to look for them
|
||||
// in the public descriptor tree.
|
||||
KonanIr.KotlinDescriptor.Kind.PROPERTY,
|
||||
KonanIr.KotlinDescriptor.Kind.VARIABLE ->
|
||||
descriptorIndex[index]!!
|
||||
|
||||
@@ -133,7 +132,6 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
fun deserializeDescriptor(proto: KonanIr.KotlinDescriptor): DeclarationDescriptor {
|
||||
|
||||
context.log{"### deserializeDescriptor ${proto.kind} ${proto.index}"}
|
||||
|
||||
val descriptor = if (proto.hasIrLocalDeclaration()) {
|
||||
deserializeLocalDeclaration(proto)
|
||||
} else
|
||||
@@ -146,7 +144,7 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
// Now there are several descriptors that automatically
|
||||
// recreated in addition to this one. Register them
|
||||
// all too.
|
||||
|
||||
|
||||
if (descriptor is FunctionDescriptor) {
|
||||
registerParameterDescriptors(proto, descriptor)
|
||||
}
|
||||
@@ -307,7 +305,6 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
fun matchNameInParentScope(proto: KonanIr.KotlinDescriptor): Collection<DeclarationDescriptor> {
|
||||
val classOrPackage = proto.classOrPackage
|
||||
val name = proto.name
|
||||
|
||||
when (proto.kind) {
|
||||
KotlinDescriptor.Kind.CLASS -> {
|
||||
val parentScope =
|
||||
@@ -362,7 +359,6 @@ internal class IrDescriptorDeserializer(val context: Context,
|
||||
constructors: Collection<DeclarationDescriptor>,
|
||||
descriptorProto: KonanIr.KotlinDescriptor):
|
||||
DeserializedClassConstructorDescriptor {
|
||||
|
||||
val originalIndex = descriptorProto.originalIndex
|
||||
return constructors.single {
|
||||
it.uniqId == originalIndex
|
||||
|
||||
+9
-5
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan.serialization
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -38,7 +39,7 @@ internal class IrDescriptorSerializer(
|
||||
val context: Context,
|
||||
val descriptorTable: DescriptorTable,
|
||||
val stringTable: KonanStringTable,
|
||||
var typeSerializer: ((KotlinType)->Int),
|
||||
val localDeclarationSerializer: LocalDeclarationSerializer,
|
||||
var rootFunction: FunctionDescriptor) {
|
||||
|
||||
fun serializeKotlinType(type: KotlinType): KonanIr.KotlinType {
|
||||
@@ -48,7 +49,7 @@ internal class IrDescriptorSerializer(
|
||||
} else {
|
||||
type
|
||||
}
|
||||
val index = typeSerializer(typeToSerialize)
|
||||
val index = localDeclarationSerializer.typeSerializer(typeToSerialize)
|
||||
val proto = KonanIr.KotlinType.newBuilder()
|
||||
.setIndex(index)
|
||||
.setDebugText(type.toString())
|
||||
@@ -76,7 +77,9 @@ internal class IrDescriptorSerializer(
|
||||
-> KonanIr.KotlinDescriptor.Kind.TYPE_PARAMETER
|
||||
is ReceiverParameterDescriptor
|
||||
-> KonanIr.KotlinDescriptor.Kind.RECEIVER
|
||||
else -> TODO("Unexpected local descriptor.")
|
||||
is PropertyDescriptor
|
||||
-> KonanIr.KotlinDescriptor.Kind.PROPERTY
|
||||
else -> TODO("Unexpected local descriptor: $descriptor")
|
||||
}
|
||||
|
||||
fun functionDescriptorSpecifics(descriptor: FunctionDescriptor, proto: KonanIr.KotlinDescriptor.Builder) {
|
||||
@@ -89,7 +92,7 @@ internal class IrDescriptorSerializer(
|
||||
// natural order of declaration. Otherwise
|
||||
// they appear in the order of appearence in the
|
||||
// body of the function, and get wrong indices.
|
||||
typeSerializer(it.defaultType)
|
||||
localDeclarationSerializer.typeSerializer(it.defaultType)
|
||||
}
|
||||
|
||||
descriptor.valueParameters.forEach {
|
||||
@@ -120,6 +123,7 @@ internal class IrDescriptorSerializer(
|
||||
|
||||
fun variableDescriptorSpecifics(descriptor: VariableDescriptor, proto: KonanIr.KotlinDescriptor.Builder) {
|
||||
proto.setType(serializeKotlinType(descriptor.type))
|
||||
|
||||
}
|
||||
|
||||
fun serializeDescriptor(descriptor: DeclarationDescriptor): KonanIr.KotlinDescriptor {
|
||||
@@ -145,7 +149,7 @@ internal class IrDescriptorSerializer(
|
||||
context.log{"originalIndex = $originalIndex"}
|
||||
context.log{""}
|
||||
|
||||
val proto = KonanIr.KotlinDescriptor.newBuilder()
|
||||
val proto = KonanIr.KotlinDescriptor.newBuilder()
|
||||
.setName(descriptor.name.asString())
|
||||
.setKind(kotlinDescriptorKind(descriptor))
|
||||
.setIndex(index)
|
||||
|
||||
+17
-8
@@ -54,7 +54,7 @@ class KonanDescriptorSerializer private constructor(
|
||||
}.toByteArray()
|
||||
}
|
||||
|
||||
private fun createChildSerializer(descriptor: DeclarationDescriptor): KonanDescriptorSerializer =
|
||||
fun createChildSerializer(descriptor: DeclarationDescriptor): KonanDescriptorSerializer =
|
||||
KonanDescriptorSerializer(descriptor, Interner(typeParameters), extension, typeTable, sinceKotlinInfoTable,
|
||||
serializeTypeTableToFunction = false)
|
||||
|
||||
@@ -230,11 +230,11 @@ class KonanDescriptorSerializer private constructor(
|
||||
if (extension is IrAwareExtension) {
|
||||
descriptor.getter?.onlyIf({needsSerializedIr}) {
|
||||
extension.addGetterIR(builder,
|
||||
extension.serializeInlineBody(it, {it -> typeId(it)}))
|
||||
extension.serializeInlineBody(it, local))
|
||||
}
|
||||
descriptor.setter?.onlyIf({needsSerializedIr}) {
|
||||
extension.addSetterIR(builder,
|
||||
extension.serializeInlineBody(it, {it -> typeId(it)}))
|
||||
extension.serializeInlineBody(it, local))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,10 +295,10 @@ class KonanDescriptorSerializer private constructor(
|
||||
|
||||
extension.serializeFunction(descriptor, builder)
|
||||
|
||||
if (extension is IrAwareExtension
|
||||
&& descriptor.needsSerializedIr) {
|
||||
extension.addFunctionIR(builder,
|
||||
extension.serializeInlineBody(descriptor, {it -> typeId(it)}))
|
||||
if (extension is IrAwareExtension
|
||||
&& descriptor.needsSerializedIr) {
|
||||
extension.addFunctionIR(builder,
|
||||
extension.serializeInlineBody(descriptor, local))
|
||||
}
|
||||
|
||||
return builder
|
||||
@@ -324,6 +324,12 @@ class KonanDescriptorSerializer private constructor(
|
||||
|
||||
extension.serializeConstructor(descriptor, builder)
|
||||
|
||||
if (extension is IrAwareExtension
|
||||
&& descriptor.needsSerializedIr) {
|
||||
extension.addConstructorIR(builder,
|
||||
extension.serializeInlineBody(descriptor, local))
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
@@ -447,7 +453,10 @@ class KonanDescriptorSerializer private constructor(
|
||||
return builder
|
||||
}
|
||||
|
||||
public fun typeId(type: KotlinType): Int = typeTable[type(type)]
|
||||
public fun typeId(type: KotlinType): Int {
|
||||
val result = typeTable[type(type)]
|
||||
return result
|
||||
}
|
||||
|
||||
private fun type(type: KotlinType): ProtoBuf.Type.Builder {
|
||||
val builder = ProtoBuf.Type.newBuilder()
|
||||
|
||||
+43
-14
@@ -19,6 +19,7 @@ message KotlinDescriptor {
|
||||
TYPE_PARAMETER = 6;
|
||||
RECEIVER = 7;
|
||||
ACCESSOR = 8;
|
||||
PROPERTY = 9;
|
||||
}
|
||||
// TODO: Use the string table index.
|
||||
optional string name = 1;
|
||||
@@ -150,6 +151,16 @@ message IrGetEnumValue {
|
||||
required KotlinDescriptor descriptor = 2;
|
||||
}
|
||||
|
||||
message FieldAccessCommon {
|
||||
required KotlinDescriptor descriptor = 1;
|
||||
optional KotlinDescriptor super = 2;
|
||||
required IrExpression reciever = 3;
|
||||
}
|
||||
|
||||
message IrGetField {
|
||||
required FieldAccessCommon field_access = 1;
|
||||
}
|
||||
|
||||
message IrGetValue {
|
||||
required KotlinDescriptor descriptor = 1;
|
||||
}
|
||||
@@ -167,6 +178,11 @@ message IrReturn {
|
||||
required IrExpression value = 2;
|
||||
}
|
||||
|
||||
message IrSetField {
|
||||
required FieldAccessCommon field_access = 1;
|
||||
required IrExpression value = 2;
|
||||
}
|
||||
|
||||
message IrSetVariable {
|
||||
required KotlinDescriptor descriptor = 1;
|
||||
required IrExpression value = 2;
|
||||
@@ -220,18 +236,20 @@ message IrOperation {
|
||||
IrDelegatingConstructorCall delegating_constructor_call = 7;
|
||||
IrEnumConstructorCall enum_constructor_call = 8;
|
||||
IrGetEnumValue get_enum_value = 9;
|
||||
IrGetValue get_value = 10;
|
||||
IrGetObject get_object = 11;
|
||||
IrInstanceInitializerCall instance_initializer_call = 12;
|
||||
IrReturn return = 13;
|
||||
IrSetVariable set_variable = 14;
|
||||
IrStringConcat string_concat = 15;
|
||||
IrThrow throw = 16;
|
||||
IrTry try = 17;
|
||||
IrTypeOp type_op = 18;
|
||||
IrVararg vararg = 19;
|
||||
IrWhen when = 20;
|
||||
IrWhile while = 21;
|
||||
IrGetField get_field = 10;
|
||||
IrGetValue get_value = 11;
|
||||
IrGetObject get_object = 12;
|
||||
IrInstanceInitializerCall instance_initializer_call = 13;
|
||||
IrReturn return = 14;
|
||||
IrSetField set_field = 15;
|
||||
IrSetVariable set_variable = 16;
|
||||
IrStringConcat string_concat = 17;
|
||||
IrThrow throw = 18;
|
||||
IrTry try = 19;
|
||||
IrTypeOp type_op = 20;
|
||||
IrVararg vararg = 21;
|
||||
IrWhen when = 22;
|
||||
IrWhile while = 23;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +272,7 @@ message IrExpression {
|
||||
|
||||
/* ------ Declarations --------------------------------------------- */
|
||||
|
||||
message IrFunc {
|
||||
message IrFunction {
|
||||
message DefaultArgument {
|
||||
required int32 position = 1;
|
||||
required IrExpression value = 2;
|
||||
@@ -263,6 +281,16 @@ message IrFunc {
|
||||
repeated DefaultArgument default_argument = 2;
|
||||
}
|
||||
|
||||
message IrProperty {
|
||||
message IrField {
|
||||
required IrExpression initializer = 1;
|
||||
}
|
||||
required bool is_delegated = 1;
|
||||
optional IrField backing_field = 2;
|
||||
optional IrFunction getter = 3;
|
||||
optional IrFunction setter = 4;
|
||||
}
|
||||
|
||||
message IrVar {
|
||||
optional IrExpression initializer = 1;
|
||||
}
|
||||
@@ -281,9 +309,10 @@ message IrEnumEntry {
|
||||
message IrDeclarator {
|
||||
oneof symbol {
|
||||
IrVar variable = 1;
|
||||
IrFunc function = 2;
|
||||
IrFunction function = 2;
|
||||
IrClass ir_class = 3;
|
||||
IrEnumEntry ir_enum_entry = 4;
|
||||
IrProperty ir_property = 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ extend Class {
|
||||
|
||||
extend Constructor {
|
||||
repeated Annotation constructor_annotation = 170;
|
||||
optional InlineIrBody inline_constructor_ir_body = 171;
|
||||
}
|
||||
|
||||
extend Function {
|
||||
|
||||
+26
-77
@@ -21,14 +21,10 @@ import org.jetbrains.kotlin.backend.konan.LinkData
|
||||
import org.jetbrains.kotlin.backend.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.isExported
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||
import org.jetbrains.kotlin.descriptors.Modality.FINAL
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.INTERNAL
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations.Companion.EMPTY
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
@@ -41,7 +37,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
@@ -55,6 +50,17 @@ import java.io.InputStream
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
/*
|
||||
* This is Konan specific part of public descriptor
|
||||
* tree serialization and deserialization.
|
||||
*
|
||||
* It takes care of module and package fragment serializations.
|
||||
* The lower level (classes and members) serializations are delegated
|
||||
* to the KonanDescriptorSerializer class.
|
||||
* The lower level deserializations are performed by the frontend
|
||||
* with MemberDeserializer class.
|
||||
*/
|
||||
|
||||
typealias Base64 = String
|
||||
|
||||
fun byteArrayToBase64(byteArray: ByteArray): Base64 {
|
||||
@@ -150,25 +156,32 @@ internal fun deserializeModule(configuration: CompilerConfiguration,
|
||||
|
||||
internal class KonanSerializationUtil(val context: Context) {
|
||||
|
||||
val serializerExtension = KonanSerializerExtension(context, this)
|
||||
val serializer = KonanDescriptorSerializer.createTopLevel(serializerExtension)
|
||||
val typeSerializer: (KotlinType)->Int = { it -> serializer.typeId(it) }
|
||||
val serializerExtension = KonanSerializerExtension(context)
|
||||
val topSerializer = KonanDescriptorSerializer.createTopLevel(serializerExtension)
|
||||
var classSerializer: KonanDescriptorSerializer = topSerializer
|
||||
|
||||
fun serializeClass(packageName: FqName,
|
||||
builder: KonanLinkData.Classes.Builder,
|
||||
classDescriptor: ClassDescriptor) {
|
||||
|
||||
val localSerializer = KonanDescriptorSerializer.create(classDescriptor, serializerExtension)
|
||||
val classProto = localSerializer.classProto(classDescriptor).build()
|
||||
val previousSerializer = classSerializer
|
||||
|
||||
// TODO: this is to filter out object{}. Change me.
|
||||
if (classDescriptor.isExported())
|
||||
classSerializer = KonanDescriptorSerializer.create(classDescriptor, serializerExtension)
|
||||
|
||||
val classProto = classSerializer.classProto(classDescriptor).build()
|
||||
?: error("Class not serialized: $classDescriptor")
|
||||
|
||||
builder.addClasses(classProto)
|
||||
val index = localSerializer.stringTable.getFqNameIndex(classDescriptor)
|
||||
val index = classSerializer.stringTable.getFqNameIndex(classDescriptor)
|
||||
builder.addClassName(index)
|
||||
|
||||
serializeClasses(packageName, builder,
|
||||
classDescriptor.unsubstitutedInnerClassesScope
|
||||
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))
|
||||
|
||||
classSerializer = previousSerializer
|
||||
}
|
||||
|
||||
fun serializeClasses(packageName: FqName,
|
||||
@@ -208,7 +221,7 @@ internal class KonanSerializationUtil(val context: Context) {
|
||||
serializeClasses(fqName, classesBuilder, classifierDescriptors)
|
||||
val classesProto = classesBuilder.build()
|
||||
|
||||
val packageProto = serializer.packagePartProto(fqName, members).build()
|
||||
val packageProto = topSerializer.packagePartProto(fqName, members).build()
|
||||
?: error("Package fragments not serialized: $fragments")
|
||||
|
||||
val strings = serializerExtension.stringTable
|
||||
@@ -263,69 +276,5 @@ internal class KonanSerializationUtil(val context: Context) {
|
||||
val library = byteArrayToBase64(libraryAsByteArray)
|
||||
return LinkData(library, fragments, fragmentNames)
|
||||
}
|
||||
|
||||
/* The section below is specific for IR serialization */
|
||||
|
||||
// TODO: We utilize DescriptorSerializer's property
|
||||
// serialization to serialize variables for now.
|
||||
// Need to negotiate the ability to deserialize
|
||||
// variables with the big kotlin somehow.
|
||||
fun variableAsProperty(variable: VariableDescriptor): PropertyDescriptor {
|
||||
|
||||
val isDelegated = when (variable) {
|
||||
is LocalVariableDescriptor -> variable.isDelegated
|
||||
is IrTemporaryVariableDescriptor -> false
|
||||
else -> error("Unexpected variable descriptor.")
|
||||
}
|
||||
|
||||
val property = PropertyDescriptorImpl.create(
|
||||
variable.containingDeclaration,
|
||||
EMPTY,
|
||||
FINAL,
|
||||
INTERNAL,
|
||||
variable.isVar(),
|
||||
variable.name,
|
||||
DECLARATION,
|
||||
NO_SOURCE,
|
||||
false, false, false, false, false,
|
||||
isDelegated)
|
||||
|
||||
property.setType(variable.type, listOf(), null, null as KotlinType?)
|
||||
|
||||
// TODO: transform the getter and the setter too.
|
||||
property.initialize(null, null)
|
||||
return property
|
||||
}
|
||||
|
||||
fun serializeLocalDeclaration(descriptor: DeclarationDescriptor): KonanIr.DeclarationDescriptor {
|
||||
|
||||
val proto = KonanIr.DeclarationDescriptor.newBuilder()
|
||||
|
||||
context.log{"### serializeLocalDeclaration: $descriptor"}
|
||||
|
||||
when (descriptor) {
|
||||
is FunctionDescriptor ->
|
||||
proto.setFunction(serializer.functionProto(descriptor))
|
||||
|
||||
is PropertyDescriptor ->
|
||||
proto.setProperty(serializer.propertyProto(descriptor))
|
||||
|
||||
is ClassDescriptor ->
|
||||
proto.setClazz(serializer.classProto(descriptor))
|
||||
|
||||
is VariableDescriptor -> {
|
||||
val property = variableAsProperty(descriptor)
|
||||
serializerExtension.originalVariables.put(property, descriptor)
|
||||
proto.setProperty(serializer.propertyProto(property))
|
||||
}
|
||||
|
||||
else -> error("Unexpected descriptor kind: $descriptor")
|
||||
}
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -24,12 +24,10 @@ import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
||||
import org.jetbrains.kotlin.serialization.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
internal class KonanSerializerExtension(val context: Context, val util: KonanSerializationUtil) :
|
||||
internal class KonanSerializerExtension(val context: Context) :
|
||||
KotlinSerializerExtensionBase(KonanSerializerProtocol), IrAwareExtension {
|
||||
|
||||
val inlineDescriptorTable = DescriptorTable(context.irBuiltIns)
|
||||
val originalVariables = mutableMapOf<PropertyDescriptor, VariableDescriptor>()
|
||||
override val stringTable = KonanStringTable()
|
||||
override fun shouldUseTypeTable(): Boolean = true
|
||||
|
||||
@@ -85,17 +83,19 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
|
||||
override fun addFunctionIR(proto: ProtoBuf.Function.Builder, serializedIR: String)
|
||||
= proto.setInlineIr(inlineBody(serializedIR))
|
||||
|
||||
override fun addConstructorIR(proto: ProtoBuf.Constructor.Builder, serializedIR: String)
|
||||
= proto.setConstructorIr(inlineBody(serializedIR))
|
||||
|
||||
override fun addGetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String)
|
||||
= proto.setGetterIr(inlineBody(serializedIR))
|
||||
|
||||
override fun addSetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String)
|
||||
= proto.setSetterIr(inlineBody(serializedIR))
|
||||
|
||||
override fun serializeInlineBody(descriptor: FunctionDescriptor, typeSerializer: ((KotlinType)->Int)): String {
|
||||
override fun serializeInlineBody(descriptor: FunctionDescriptor, serializer: KonanDescriptorSerializer): String {
|
||||
|
||||
return IrSerializer(
|
||||
context, inlineDescriptorTable, stringTable, util,
|
||||
typeSerializer, descriptor).serializeInlineBody()
|
||||
context, inlineDescriptorTable, stringTable, serializer, descriptor).serializeInlineBody()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,10 +117,12 @@ object KonanSerializerProtocol : SerializerExtensionProtocol(
|
||||
|
||||
internal interface IrAwareExtension {
|
||||
|
||||
fun serializeInlineBody(descriptor: FunctionDescriptor, typeSerializer: ((KotlinType)->Int)): String
|
||||
fun serializeInlineBody(descriptor: FunctionDescriptor, serializer: KonanDescriptorSerializer): String
|
||||
|
||||
fun addFunctionIR(proto: ProtoBuf.Function.Builder, serializedIR: String): ProtoBuf.Function.Builder
|
||||
|
||||
fun addConstructorIR(proto: ProtoBuf.Constructor.Builder, serializedIR: String): ProtoBuf.Constructor.Builder
|
||||
|
||||
fun addSetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String): ProtoBuf.Property.Builder
|
||||
|
||||
fun addGetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String): ProtoBuf.Property.Builder
|
||||
|
||||
+68
-60
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.allContainingDeclarations
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
@@ -23,96 +24,103 @@ import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
|
||||
import org.jetbrains.kotlin.serialization.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
|
||||
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.backend.common.peek
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
|
||||
// This class knows how to construct contexts for
|
||||
// MemberDeserializer to deserialize descriptors declared in IR.
|
||||
// Consider merging it all to the very MemberDesereializer itself eventually.
|
||||
// Eventually, these descriptors shall be reconstructed from IR declarations,
|
||||
// or may be just go away completely.
|
||||
|
||||
class LocalDeclarationDeserializer(val rootDescriptor: DeserializedCallableMemberDescriptor, val module: ModuleDescriptor) {
|
||||
|
||||
val pkg = rootDescriptor.getContainingDeclaration() as KonanPackageFragment
|
||||
class LocalDeclarationDeserializer(val rootDescriptor: DeclarationDescriptor) {
|
||||
|
||||
val tower: List<DeclarationDescriptor> =
|
||||
(listOf(rootDescriptor) + rootDescriptor.allContainingDeclarations()).reversed()
|
||||
init {
|
||||
assert(pkg is KonanPackageFragment)
|
||||
assert(tower.first() is ModuleDescriptor)
|
||||
}
|
||||
val parents = tower.drop(1)
|
||||
|
||||
val pkg = parents.first() as KonanPackageFragment
|
||||
val components = pkg.components
|
||||
val nameResolver = NameResolverImpl(pkg.proto.getStringTable(), pkg.proto.getNameTable())
|
||||
val nameTable = pkg.proto.getNameTable()
|
||||
val typeTable = TypeTable(pkg.proto.getPackage().getTypeTable())
|
||||
val context = components.createContext(
|
||||
pkg, nameResolver, typeTable, SinceKotlinInfoTable.EMPTY, null)
|
||||
val nameTable = pkg.proto.nameTable
|
||||
val nameResolver = NameResolverImpl(pkg.proto.stringTable, nameTable)
|
||||
|
||||
val contextStack = mutableListOf<Pair<DeserializationContext, MemberDeserializer>>()
|
||||
|
||||
val typeParameterProtos = when (rootDescriptor) {
|
||||
// These are two different typeParameterLists not
|
||||
// having a common ancestor.
|
||||
is DeserializedSimpleFunctionDescriptor
|
||||
-> rootDescriptor.proto.typeParameterList
|
||||
is DeserializedPropertyDescriptor
|
||||
-> rootDescriptor.proto.typeParameterList
|
||||
else -> error("Unexpected descriptor kind")
|
||||
init {
|
||||
parents.forEach{
|
||||
pushContext(it)
|
||||
}
|
||||
}
|
||||
|
||||
val childContext = context.childContext(rootDescriptor, typeParameterProtos, nameResolver, typeTable)
|
||||
val typeDeserializer = childContext.typeDeserializer
|
||||
val parentContext: DeserializationContext
|
||||
get() = contextStack.peek()!!.first
|
||||
|
||||
val memberDeserializer = MemberDeserializer(childContext)
|
||||
val parentTypeTable: TypeTable
|
||||
get() = parentContext.typeTable
|
||||
|
||||
val typeDeserializer: TypeDeserializer
|
||||
get() = parentContext.typeDeserializer
|
||||
|
||||
val memberDeserializer: MemberDeserializer
|
||||
get() = contextStack.peek()!!.second
|
||||
|
||||
fun newContext(descriptor: DeclarationDescriptor): DeserializationContext {
|
||||
if (descriptor is KonanPackageFragment) {
|
||||
val packageTypeTable = TypeTable(pkg.proto.getPackage().typeTable)
|
||||
return components.createContext(
|
||||
pkg, nameResolver, packageTypeTable, SinceKotlinInfoTable.EMPTY, null)
|
||||
}
|
||||
|
||||
// Only packages and classes have their type tables.
|
||||
val typeTable = if (descriptor is DeserializedClassDescriptor) {
|
||||
TypeTable(descriptor.classProto.typeTable)
|
||||
} else {
|
||||
parentTypeTable
|
||||
}
|
||||
|
||||
|
||||
val oldContext = contextStack.peek()!!.first
|
||||
|
||||
return oldContext.childContext(descriptor,
|
||||
descriptor.typeParameterProtos, nameResolver, typeTable)
|
||||
}
|
||||
|
||||
fun pushContext(descriptor: DeclarationDescriptor) {
|
||||
val newContext = newContext(descriptor)
|
||||
contextStack.push(Pair(newContext, MemberDeserializer(newContext)))
|
||||
}
|
||||
|
||||
fun popContext(descriptor: DeclarationDescriptor) {
|
||||
assert(contextStack.peek()!!.first.containingDeclaration == descriptor)
|
||||
contextStack.pop()
|
||||
}
|
||||
|
||||
fun deserializeInlineType(type: ProtoBuf.Type): KotlinType {
|
||||
|
||||
val result = typeDeserializer.type(type)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun getDescriptorByFqNameIndex(module: ModuleDescriptor, fqNameIndex: Int): DeclarationDescriptor {
|
||||
fun deserializeClass(irProto: KonanIr.KotlinDescriptor): ClassDescriptor {
|
||||
return DeserializedClassDescriptor(parentContext, irProto.irLocalDeclaration.descriptor.clazz, nameResolver, SourceElement.NO_SOURCE)
|
||||
|
||||
val packageName = nameResolver.getPackageFqName(fqNameIndex)
|
||||
// Here we using internals of NameresolverImpl.
|
||||
val proto = nameTable.getQualifiedName(fqNameIndex)
|
||||
when (proto.kind) {
|
||||
QualifiedName.Kind.CLASS,
|
||||
QualifiedName.Kind.LOCAL ->
|
||||
return module.findClassAcrossModuleDependencies(nameResolver.getClassId(fqNameIndex))!!
|
||||
QualifiedName.Kind.PACKAGE ->
|
||||
return module.getPackage(packageName)
|
||||
else -> TODO("Unexpected descriptor kind.")
|
||||
}
|
||||
}
|
||||
|
||||
fun memberDeserializerByParentFqNameIndex(fqNameIndex: Int): MemberDeserializer {
|
||||
|
||||
val parent = getDescriptorByFqNameIndex(module, fqNameIndex)
|
||||
val typeParameters = if (parent is DeserializedClassDescriptor) {
|
||||
parent.classProto.typeParameterList
|
||||
} else listOf<ProtoBuf.TypeParameter>()
|
||||
|
||||
val childContext = context.childContext(parent, typeParameters, nameResolver, typeTable)
|
||||
return MemberDeserializer(childContext)
|
||||
|
||||
}
|
||||
|
||||
private fun memberDeserializer(irProto: KonanIr.KotlinDescriptor): MemberDeserializer {
|
||||
return if (irProto.hasClassOrPackage()) {
|
||||
memberDeserializerByParentFqNameIndex(irProto.classOrPackage)
|
||||
} else {
|
||||
// TODO: learn to take the containing IR declaration
|
||||
this.memberDeserializer
|
||||
}
|
||||
}
|
||||
|
||||
fun deserializeFunction(irProto: KonanIr.KotlinDescriptor): FunctionDescriptor =
|
||||
memberDeserializer(irProto).loadFunction(irProto.irLocalDeclaration.descriptor.function)
|
||||
memberDeserializer.loadFunction(irProto.irLocalDeclaration.descriptor.function)
|
||||
|
||||
fun deserializeConstructor(irProto: KonanIr.KotlinDescriptor): ConstructorDescriptor {
|
||||
|
||||
val proto = irProto.irLocalDeclaration.descriptor.constructor
|
||||
val memberDeserializer = memberDeserializerByParentFqNameIndex(irProto.classOrPackage)
|
||||
val isPrimary = !Flags.IS_SECONDARY.get(proto.flags)
|
||||
val constructor = memberDeserializer.loadConstructor(proto, isPrimary)
|
||||
|
||||
@@ -122,7 +130,7 @@ class LocalDeclarationDeserializer(val rootDescriptor: DeserializedCallableMembe
|
||||
fun deserializeProperty(irProto: KonanIr.KotlinDescriptor): VariableDescriptor {
|
||||
|
||||
val proto = irProto.irLocalDeclaration.descriptor.property
|
||||
val property = memberDeserializer(irProto).loadProperty(proto)
|
||||
val property = memberDeserializer.loadProperty(proto)
|
||||
|
||||
return if (proto.getExtension(KonanLinkData.usedAsVariable)) {
|
||||
propertyToVariable(property)
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.peek
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||
import org.jetbrains.kotlin.descriptors.Modality.FINAL
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities.INTERNAL
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations.Companion.EMPTY
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/*
|
||||
* This class knows how to create KonanDescriptorSerializer
|
||||
* invocations to serialize function local declaration descriptors.
|
||||
* Those descriptors are not part of the public descriptor tree.
|
||||
*
|
||||
* We maintain the stack of the serializers because this class
|
||||
* provides type serialization facility for all the types in IR.
|
||||
* And class serialization is context specific.
|
||||
*/
|
||||
|
||||
internal class LocalDeclarationSerializer(val context: Context, val rootFunctionSerializer: KonanDescriptorSerializer) {
|
||||
|
||||
private val contextStack = mutableListOf<KonanDescriptorSerializer>(rootFunctionSerializer)
|
||||
|
||||
fun pushContext(descriptor: DeclarationDescriptor) {
|
||||
val previousContext = contextStack.peek()!!
|
||||
val newSerializer = previousContext.createChildSerializer(descriptor)
|
||||
contextStack.push(newSerializer)
|
||||
}
|
||||
|
||||
fun popContext(descriptor: DeclarationDescriptor) {
|
||||
contextStack.pop()
|
||||
}
|
||||
|
||||
val localSerializer
|
||||
get() = contextStack.peek()!!
|
||||
|
||||
val typeSerializer: ((KotlinType)->Int)
|
||||
get() = {it -> localSerializer.typeId(it)}
|
||||
|
||||
fun serializeLocalDeclaration(descriptor: DeclarationDescriptor): KonanIr.DeclarationDescriptor {
|
||||
|
||||
val proto = KonanIr.DeclarationDescriptor.newBuilder()
|
||||
|
||||
context.log{"### serializeLocalDeclaration: $descriptor"}
|
||||
|
||||
val parent = descriptor.classOrPackage
|
||||
|
||||
|
||||
when (descriptor) {
|
||||
is ClassConstructorDescriptor ->
|
||||
proto.setConstructor(localSerializer.constructorProto(descriptor))
|
||||
|
||||
is FunctionDescriptor ->
|
||||
proto.setFunction(localSerializer.functionProto(descriptor))
|
||||
|
||||
is PropertyDescriptor ->
|
||||
proto.setProperty(localSerializer.propertyProto(descriptor))
|
||||
|
||||
is ClassDescriptor ->
|
||||
proto.setClazz(localSerializer.classProto(descriptor))
|
||||
|
||||
is VariableDescriptor -> {
|
||||
val property = variableAsProperty(descriptor)
|
||||
originalVariables.put(property, descriptor)
|
||||
proto.setProperty(localSerializer.propertyProto(property))
|
||||
}
|
||||
|
||||
else -> error("Unexpected descriptor kind: $descriptor")
|
||||
}
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
// TODO: We utilize DescriptorSerializer's property
|
||||
// serialization to serialize variables for now.
|
||||
// Need to introduce an extension protobuf message
|
||||
// and serialize variables directly.
|
||||
fun variableAsProperty(variable: VariableDescriptor): PropertyDescriptor {
|
||||
|
||||
val isDelegated = when (variable) {
|
||||
is LocalVariableDescriptor -> variable.isDelegated
|
||||
is IrTemporaryVariableDescriptor -> false
|
||||
else -> error("Unexpected variable descriptor.")
|
||||
}
|
||||
|
||||
val property = PropertyDescriptorImpl.create(
|
||||
variable.containingDeclaration,
|
||||
EMPTY,
|
||||
FINAL,
|
||||
INTERNAL,
|
||||
variable.isVar(),
|
||||
variable.name,
|
||||
DECLARATION,
|
||||
NO_SOURCE,
|
||||
false, false, false, false, false,
|
||||
isDelegated)
|
||||
|
||||
property.setType(variable.type, listOf(), null, null as KotlinType?)
|
||||
|
||||
// TODO: transform the getter and the setter too.
|
||||
property.initialize(null, null)
|
||||
return property
|
||||
}
|
||||
}
|
||||
|
||||
val originalVariables = mutableMapOf<PropertyDescriptor, VariableDescriptor>()
|
||||
|
||||
+27
@@ -1,5 +1,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData.*
|
||||
@@ -48,6 +50,12 @@ val ProtoBuf.Property.setterIr: InlineIrBody
|
||||
fun ProtoBuf.Property.Builder.setSetterIr(body: InlineIrBody): ProtoBuf.Property.Builder =
|
||||
this.setExtension(inlineSetterIrBody, body)
|
||||
|
||||
val ProtoBuf.Constructor.constructorIr: InlineIrBody
|
||||
get() = this.getExtension(inlineConstructorIrBody)
|
||||
|
||||
fun ProtoBuf.Constructor.Builder.setConstructorIr(body: InlineIrBody): ProtoBuf.Constructor.Builder =
|
||||
this.setExtension(inlineConstructorIrBody, body)
|
||||
|
||||
val ProtoBuf.Function.inlineIr: InlineIrBody
|
||||
get() = this.getExtension(inlineIrBody)
|
||||
|
||||
@@ -74,4 +82,23 @@ internal fun printTypeTable(proto: ProtoBuf.TypeTable) {
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
internal val DeclarationDescriptor.typeParameterProtos: List<ProtoBuf.TypeParameter>
|
||||
get() = when (this) {
|
||||
// These are different typeParameterLists not
|
||||
// having a common ancestor.
|
||||
is DeserializedSimpleFunctionDescriptor
|
||||
-> this.proto.typeParameterList
|
||||
is DeserializedPropertyDescriptor
|
||||
-> this.proto.typeParameterList
|
||||
is DeserializedClassDescriptor
|
||||
-> this.classProto.typeParameterList
|
||||
is DeserializedTypeAliasDescriptor
|
||||
-> this.proto.typeParameterList
|
||||
is DeserializedClassConstructorDescriptor
|
||||
-> listOf()
|
||||
else -> error("Unexpected descriptor kind: $this")
|
||||
}
|
||||
|
||||
|
||||
|
||||
+128
-42
@@ -18,10 +18,9 @@ package org.jetbrains.kotlin.backend.konan.serialization
|
||||
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeepCopyIrTreeWithDescriptors
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.KonanIrDeserializationException
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.deserializedPropertyIfAccessor
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isDeserializableCallable
|
||||
import org.jetbrains.kotlin.backend.konan.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.konan.ir.ir2stringWhole
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
|
||||
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.DEFINED
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
|
||||
@@ -40,11 +38,14 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
|
||||
import org.jetbrains.kotlin.serialization.KonanIr
|
||||
import org.jetbrains.kotlin.serialization.KonanIr.IrConst.ValueCase.*
|
||||
import org.jetbrains.kotlin.serialization.KonanIr.IrOperation.OperationCase.*
|
||||
import org.jetbrains.kotlin.serialization.KonanLinkData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
@@ -53,14 +54,16 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
internal class IrSerializer(val context: Context,
|
||||
val descriptorTable: DescriptorTable,
|
||||
val stringTable: KonanStringTable,
|
||||
val util: KonanSerializationUtil,
|
||||
val typeSerializer: ((KotlinType)->Int),
|
||||
val rootFunctionSerializer: KonanDescriptorSerializer,
|
||||
var rootFunction: FunctionDescriptor) {
|
||||
|
||||
val loopIndex = mutableMapOf<IrLoop, Int>()
|
||||
var currentLoopIndex = 0
|
||||
val irDescriptorSerializer = IrDescriptorSerializer(context,
|
||||
descriptorTable, stringTable, typeSerializer, rootFunction)
|
||||
val localDeclarationSerializer
|
||||
= LocalDeclarationSerializer(context, rootFunctionSerializer)
|
||||
val irDescriptorSerializer
|
||||
= IrDescriptorSerializer(context, descriptorTable,
|
||||
stringTable, localDeclarationSerializer, rootFunction)
|
||||
|
||||
fun serializeInlineBody(): String {
|
||||
val declaration = context.ir.originalModuleIndex.functions[rootFunction]!!
|
||||
@@ -259,6 +262,24 @@ internal class IrSerializer(val context: Context,
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeFieldAccessCommon(expression: IrFieldAccessExpression): KonanIr.FieldAccessCommon {
|
||||
val proto = KonanIr.FieldAccessCommon.newBuilder()
|
||||
.setDescriptor(serializeDescriptor(expression.descriptor))
|
||||
val superQualifier = expression.superQualifier
|
||||
if (superQualifier != null)
|
||||
proto.setSuper(serializeDescriptor(superQualifier))
|
||||
val receiver = expression.receiver
|
||||
if (receiver != null)
|
||||
proto.setReciever(serializeExpression(receiver))
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeGetField(expression: IrGetField): KonanIr.IrGetField {
|
||||
val proto = KonanIr.IrGetField.newBuilder()
|
||||
.setFieldAccess(serializeFieldAccessCommon(expression))
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeGetValue(expression: IrGetValue): KonanIr.IrGetValue {
|
||||
val proto = KonanIr.IrGetValue.newBuilder()
|
||||
.setDescriptor(serializeDescriptor(expression.descriptor))
|
||||
@@ -286,6 +307,13 @@ internal class IrSerializer(val context: Context,
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeSetField(expression: IrSetField): KonanIr.IrSetField {
|
||||
val proto = KonanIr.IrSetField.newBuilder()
|
||||
.setFieldAccess(serializeFieldAccessCommon(expression))
|
||||
.setValue(serializeExpression(expression.value))
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeSetVariable(expression: IrSetVariable): KonanIr.IrSetVariable {
|
||||
val proto = KonanIr.IrSetVariable.newBuilder()
|
||||
.setDescriptor(serializeDescriptor(expression.descriptor))
|
||||
@@ -420,6 +448,7 @@ internal class IrSerializer(val context: Context,
|
||||
is IrContinue -> operationProto.setContinue(serializeContinue(expression))
|
||||
is IrDelegatingConstructorCall
|
||||
-> operationProto.setDelegatingConstructorCall(serializeDelegatingConstructorCall(expression))
|
||||
is IrGetField -> operationProto.setGetField(serializeGetField(expression))
|
||||
is IrGetValue -> operationProto.setGetValue(serializeGetValue(expression))
|
||||
is IrGetEnumValue
|
||||
-> operationProto.setGetEnumValue(serializeGetEnumValue(expression))
|
||||
@@ -428,6 +457,7 @@ internal class IrSerializer(val context: Context,
|
||||
is IrInstanceInitializerCall
|
||||
-> operationProto.setInstanceInitializerCall(serializeInstanceInitializerCall(expression))
|
||||
is IrReturn -> operationProto.setReturn(serializeReturn(expression))
|
||||
is IrSetField -> operationProto.setSetField(serializeSetField(expression))
|
||||
is IrSetVariable -> operationProto.setSetVariable(serializeSetVariable(expression))
|
||||
is IrStringConcatenation
|
||||
-> operationProto.setStringConcat(serializeStringConcat(expression))
|
||||
@@ -467,15 +497,15 @@ internal class IrSerializer(val context: Context,
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeFunction(function: IrFunction): KonanIr.IrFunc {
|
||||
val proto = KonanIr.IrFunc.newBuilder()
|
||||
fun serializeIrFunction(function: IrFunction): KonanIr.IrFunction {
|
||||
val proto = KonanIr.IrFunction.newBuilder()
|
||||
val body = function.body
|
||||
if (body != null) proto.setBody(serializeStatement(body))
|
||||
|
||||
function.descriptor.valueParameters.forEachIndexed { index, it ->
|
||||
val default = function.getDefault(it)
|
||||
if (default != null) {
|
||||
val pair = KonanIr.IrFunc.DefaultArgument.newBuilder()
|
||||
val pair = KonanIr.IrFunction.DefaultArgument.newBuilder()
|
||||
pair.position = index
|
||||
pair.value = serializeExpression(default.expression)
|
||||
proto.addDefaultArgument(pair)
|
||||
@@ -485,7 +515,33 @@ internal class IrSerializer(val context: Context,
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeVariable(variable: IrVariable): KonanIr.IrVar {
|
||||
fun serializeIrProperty(property: IrProperty): KonanIr.IrProperty {
|
||||
val proto = KonanIr.IrProperty.newBuilder()
|
||||
.setIsDelegated(property.isDelegated)
|
||||
val backingField = property.backingField
|
||||
val getter = property.getter
|
||||
val setter = property.setter
|
||||
if (backingField != null)
|
||||
proto.setBackingField(serializeIrField(backingField))
|
||||
if (getter != null)
|
||||
proto.setGetter(serializeIrFunction(getter))
|
||||
if (setter != null)
|
||||
proto.setSetter(serializeIrFunction(setter))
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeIrField(field: IrField): KonanIr.IrProperty.IrField {
|
||||
val proto = KonanIr.IrProperty.IrField.newBuilder()
|
||||
val field = field.initializer?.expression
|
||||
if (field != null) {
|
||||
proto.setInitializer(
|
||||
serializeExpression(field))
|
||||
}
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
fun serializeIrVariable(variable: IrVariable): KonanIr.IrVar {
|
||||
val proto = KonanIr.IrVar.newBuilder()
|
||||
val initializer = variable.initializer
|
||||
if (initializer != null) {
|
||||
@@ -496,6 +552,12 @@ internal class IrSerializer(val context: Context,
|
||||
|
||||
fun serializeIrClass(clazz: IrClass): KonanIr.IrClass {
|
||||
val proto = KonanIr.IrClass.newBuilder()
|
||||
|
||||
// TODO: As of now we get here only for anonymous local objects.
|
||||
// There is still some work needed to support them.
|
||||
// Until it is done, let's pretend all IrClasses are empty.
|
||||
// So that we don't have to deal with their type tables.
|
||||
/*
|
||||
val declarations = clazz.declarations
|
||||
declarations.forEach {
|
||||
val descriptor = it.descriptor
|
||||
@@ -503,6 +565,7 @@ internal class IrSerializer(val context: Context,
|
||||
proto.addMember(serializeDeclaration(it))
|
||||
}
|
||||
}
|
||||
*/
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
@@ -521,20 +584,49 @@ internal class IrSerializer(val context: Context,
|
||||
context.log{"### serializing Declaration: ${ir2string(declaration)}"}
|
||||
|
||||
val descriptor = declaration.descriptor
|
||||
|
||||
if (descriptor != rootFunction &&
|
||||
!(declaration is IrVariable)) {
|
||||
localDeclarationSerializer.pushContext(descriptor)
|
||||
}
|
||||
|
||||
var kotlinDescriptor = serializeDescriptor(descriptor)
|
||||
var realDescriptor: KonanIr.DeclarationDescriptor? = null
|
||||
if (descriptor != rootFunction) {
|
||||
realDescriptor = localDeclarationSerializer.serializeLocalDeclaration(descriptor)
|
||||
}
|
||||
val declarator = KonanIr.IrDeclarator.newBuilder()
|
||||
|
||||
when (declaration) {
|
||||
is IrFunction
|
||||
-> declarator.setFunction(serializeIrFunction(declaration))
|
||||
is IrVariable
|
||||
-> declarator.setVariable(serializeIrVariable(declaration))
|
||||
is IrClass
|
||||
-> declarator.setIrClass(serializeIrClass(declaration))
|
||||
is IrEnumEntry
|
||||
-> declarator.setIrEnumEntry(serializeIrEnumEntry(declaration))
|
||||
is IrProperty
|
||||
-> declarator.setIrProperty(serializeIrProperty(declaration))
|
||||
else
|
||||
-> {
|
||||
TODO("Declaration serialization not supported yet: $declaration")
|
||||
}
|
||||
}
|
||||
|
||||
if (!(declaration is IrVariable)) {
|
||||
localDeclarationSerializer.popContext(descriptor)
|
||||
}
|
||||
|
||||
if (descriptor != rootFunction) {
|
||||
val realDescriptor = util.serializeLocalDeclaration(descriptor)
|
||||
val localDeclaration = KonanIr.LocalDeclaration
|
||||
.newBuilder()
|
||||
.setDescriptor(realDescriptor)
|
||||
.setDescriptor(realDescriptor!!)
|
||||
.build()
|
||||
kotlinDescriptor = kotlinDescriptor
|
||||
.toBuilder()
|
||||
.setIrLocalDeclaration(localDeclaration)
|
||||
.build()
|
||||
} else if (descriptor is ClassDescriptor) {
|
||||
// TODO
|
||||
context.log{"Can't serialize local class declarations in inline functions yet"}
|
||||
}
|
||||
|
||||
val coordinates = serializeCoordinates(declaration.startOffset, declaration.endOffset)
|
||||
@@ -543,22 +635,6 @@ internal class IrSerializer(val context: Context,
|
||||
.setDescriptor(kotlinDescriptor)
|
||||
.setCoordinates(coordinates)
|
||||
|
||||
val declarator = KonanIr.IrDeclarator.newBuilder()
|
||||
|
||||
when (declaration) {
|
||||
is IrFunction
|
||||
-> declarator.setFunction(serializeFunction(declaration))
|
||||
is IrVariable
|
||||
-> declarator.setVariable(serializeVariable(declaration))
|
||||
is IrClass
|
||||
-> declarator.setIrClass(serializeIrClass(declaration))
|
||||
is IrEnumEntry
|
||||
-> declarator.setIrEnumEntry(serializeIrEnumEntry(declaration))
|
||||
else
|
||||
-> {
|
||||
TODO("Declaration serialization not supported yet.")
|
||||
}
|
||||
}
|
||||
|
||||
proto.setDeclarator(declarator)
|
||||
|
||||
@@ -583,7 +659,7 @@ internal class IrDeserializer(val context: Context,
|
||||
val loopIndex = mutableMapOf<Int, IrLoop>()
|
||||
|
||||
val rootMember = rootFunction.deserializedPropertyIfAccessor
|
||||
val localDeserializer = LocalDeclarationDeserializer(rootMember, context.moduleDescriptor)
|
||||
val localDeserializer = LocalDeclarationDeserializer(rootMember)
|
||||
|
||||
val descriptorDeserializer = IrDescriptorDeserializer(
|
||||
context, rootMember, localDeserializer)
|
||||
@@ -656,7 +732,7 @@ internal class IrDeserializer(val context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
context.log{"Deserialized statement: ${ir2string(element)}"}
|
||||
context.log{"### Deserialized statement: ${ir2string(element)}"}
|
||||
|
||||
return element
|
||||
}
|
||||
@@ -967,7 +1043,7 @@ internal class IrDeserializer(val context: Context,
|
||||
val operation = proto.getOperation()
|
||||
val expression = deserializeOperation(operation, start, end, type)
|
||||
|
||||
context.log{"Deserialized expression: ${ir2string(expression)}"}
|
||||
context.log{"### Deserialized expression: ${ir2string(expression)}"}
|
||||
return expression
|
||||
}
|
||||
|
||||
@@ -986,7 +1062,7 @@ internal class IrDeserializer(val context: Context,
|
||||
|
||||
}
|
||||
|
||||
fun deserializeIrFunction(proto: KonanIr.IrFunc, descriptor: FunctionDescriptor,
|
||||
fun deserializeIrFunction(proto: KonanIr.IrFunction, descriptor: FunctionDescriptor,
|
||||
start: Int, end: Int, origin: IrDeclarationOrigin): IrFunction {
|
||||
|
||||
val body = deserializeStatement(proto.getBody())
|
||||
@@ -1031,6 +1107,9 @@ internal class IrDeserializer(val context: Context,
|
||||
|
||||
val descriptor = deserializeDescriptor(proto.descriptor)
|
||||
|
||||
if (!(descriptor is VariableDescriptor) && descriptor != rootFunction)
|
||||
localDeserializer.pushContext(descriptor)
|
||||
|
||||
val start = proto.getCoordinates().getStartOffset()
|
||||
val end = proto.getCoordinates().getEndOffset()
|
||||
val origin = DEFINED // TODO: retore the real origins
|
||||
@@ -1053,7 +1132,10 @@ internal class IrDeserializer(val context: Context,
|
||||
TODO("Declaration deserialization not implemented")
|
||||
}
|
||||
}
|
||||
context.log{"Deserialized declaration: ${ir2string(declaration)}"}
|
||||
|
||||
if (!(descriptor is VariableDescriptor) && descriptor != rootFunction)
|
||||
localDeserializer.popContext(descriptor)
|
||||
context.log{"### Deserialized declaration: ${ir2string(declaration)}"}
|
||||
return declaration
|
||||
}
|
||||
|
||||
@@ -1068,8 +1150,9 @@ internal class IrDeserializer(val context: Context,
|
||||
// I tried to copy over TypeDeserializaer, MemberDeserializer,
|
||||
// and the rest of what's needed, but it didn't work out.
|
||||
fun adaptDeserializedTypeParameters(declaration: IrDeclaration): IrDeclaration {
|
||||
|
||||
val rootFunctionTypeParameters =
|
||||
descriptorDeserializer.localDeserializer.childContext.typeDeserializer.ownTypeParameters
|
||||
localDeserializer.typeDeserializer.ownTypeParameters
|
||||
|
||||
val realTypeParameters =
|
||||
rootFunction.deserializedPropertyIfAccessor.typeParameters
|
||||
@@ -1094,13 +1177,16 @@ internal class IrDeserializer(val context: Context,
|
||||
is DeserializedSimpleFunctionDescriptor -> {
|
||||
rootFunction.proto.inlineIr
|
||||
}
|
||||
is DeserializedClassConstructorDescriptor -> {
|
||||
rootFunction.proto.constructorIr
|
||||
}
|
||||
is PropertyGetterDescriptor -> {
|
||||
(rootMember as DeserializedPropertyDescriptor).proto.getterIr
|
||||
}
|
||||
is PropertySetterDescriptor -> {
|
||||
(rootMember as DeserializedPropertyDescriptor).proto.setterIr
|
||||
}
|
||||
else -> error("Unexpected descriptor: rootFunction")
|
||||
else -> error("Unexpected descriptor: $rootFunction")
|
||||
}
|
||||
|
||||
fun decodeDeclaration(): IrDeclaration {
|
||||
@@ -1110,7 +1196,7 @@ internal class IrDeserializer(val context: Context,
|
||||
val base64 = inlineProto.encodedIr
|
||||
val byteArray = base64Decode(base64)
|
||||
val irProto = KonanIr.IrDeclaration.parseFrom(byteArray, KonanSerializerProtocol.extensionRegistry)
|
||||
val declaration = deserializeDeclaration(irProto)
|
||||
val declaration = deserializeDeclaration(irProto)
|
||||
|
||||
val copyFunctionDeclaration = adaptDeserializedTypeParameters(declaration)
|
||||
|
||||
|
||||
+1
-1
@@ -32,8 +32,8 @@ internal fun NameResolverImpl.getDescriptorByFqNameIndex(
|
||||
nameTable: ProtoBuf.QualifiedNameTable,
|
||||
fqNameIndex: Int): DeclarationDescriptor {
|
||||
|
||||
if (fqNameIndex == -1) return module.getPackage(FqName.ROOT)
|
||||
val packageName = this.getPackageFqName(fqNameIndex)
|
||||
if (packageName.isRoot) return module.getPackage(FqName.ROOT)
|
||||
// TODO: Here we are using internals of NameresolverImpl.
|
||||
// Consider extending NameResolver.
|
||||
val proto = nameTable.getQualifiedName(fqNameIndex)
|
||||
|
||||
Reference in New Issue
Block a user