Captured type constructor support in serializer.
This commit is contained in:
committed by
alexander-gorshenev
parent
1544045643
commit
e2bf81d7d8
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.name.*
|
||||||
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||||
|
|
||||||
|
private val konanInternalPackageName = FqName("konan.internal")
|
||||||
|
private val fakeCapturedTypeClassName = Name.identifier("FAKE_CAPTURED_TYPE_CLASS")
|
||||||
|
|
||||||
|
internal fun createFakeClass(packageName: FqName, className: Name)
|
||||||
|
= MutableClassDescriptor(
|
||||||
|
EmptyPackageFragmentDescriptor(
|
||||||
|
ErrorUtils.getErrorModule(),
|
||||||
|
packageName
|
||||||
|
),
|
||||||
|
ClassKind.INTERFACE,
|
||||||
|
/* isInner = */ false,
|
||||||
|
/* isExternal = */ false,
|
||||||
|
className,
|
||||||
|
SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
|
||||||
|
// We do the trick similar to FAKE_CONTINUATION_CLASS_DESCRIPTOR.
|
||||||
|
// To pack a captured type constructor as a type parameter
|
||||||
|
// of a fake class. We need it because type serialization
|
||||||
|
// protobuf is not expressive enough.
|
||||||
|
private val FAKE_CAPTURED_TYPE_CLASS_DESCRIPTOR
|
||||||
|
= createFakeClass(konanInternalPackageName, fakeCapturedTypeClassName)
|
||||||
|
.apply {
|
||||||
|
modality = Modality.ABSTRACT
|
||||||
|
visibility = Visibilities.PUBLIC
|
||||||
|
setTypeParameterDescriptors(
|
||||||
|
TypeParameterDescriptorImpl
|
||||||
|
.createWithDefaultBound(
|
||||||
|
this, Annotations.EMPTY,
|
||||||
|
false, Variance.IN_VARIANCE,
|
||||||
|
Name.identifier("Projection"),
|
||||||
|
/* index = */ 0
|
||||||
|
).let(::listOf)
|
||||||
|
)
|
||||||
|
createTypeConstructor()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun packCapturedType(type: CapturedType): SimpleType =
|
||||||
|
KotlinTypeFactory.simpleType(
|
||||||
|
Annotations.EMPTY,
|
||||||
|
FAKE_CAPTURED_TYPE_CLASS_DESCRIPTOR.typeConstructor,
|
||||||
|
listOf(type.typeProjection),
|
||||||
|
nullable = false
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun unpackCapturedType(type: KotlinType)
|
||||||
|
= createCapturedType(type.arguments.single())
|
||||||
+9
-6
@@ -17,16 +17,15 @@
|
|||||||
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.backend.konan.KonanIrDeserializationException
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.contributedMethods
|
import org.jetbrains.kotlin.backend.konan.descriptors.contributedMethods
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanIrDeserializationException
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.symbolName
|
import org.jetbrains.kotlin.backend.konan.llvm.symbolName
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.serialization.KonanIr
|
import org.jetbrains.kotlin.serialization.KonanIr
|
||||||
import org.jetbrains.kotlin.serialization.KonanIr.KotlinDescriptor
|
import org.jetbrains.kotlin.serialization.KonanIr.KotlinDescriptor
|
||||||
@@ -130,15 +129,19 @@ internal class IrDescriptorDeserializer(val context: Context,
|
|||||||
val descriptorIndex = IrDeserializationDescriptorIndex(context.irBuiltIns).map
|
val descriptorIndex = IrDeserializationDescriptorIndex(context.irBuiltIns).map
|
||||||
|
|
||||||
fun deserializeKotlinType(proto: KonanIr.KotlinType): KotlinType {
|
fun deserializeKotlinType(proto: KonanIr.KotlinType): KotlinType {
|
||||||
|
|
||||||
val index = proto.getIndex()
|
val index = proto.getIndex()
|
||||||
val text = proto.getDebugText()
|
val text = proto.getDebugText()
|
||||||
val typeProto = localDeserializer.typeTable[index]
|
val typeProto = localDeserializer.typeTable[index]
|
||||||
val type = localDeserializer.deserializeInlineType(typeProto)
|
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")
|
||||||
context.log("### deserialized Kotlin Type index=$index, text=$text:\t$type")
|
|
||||||
|
|
||||||
return type
|
val realType = if (proto.isCaptured) {
|
||||||
|
unpackCapturedType(type)
|
||||||
|
} else
|
||||||
|
type
|
||||||
|
|
||||||
|
context.log("### deserialized Kotlin Type index=$index, text=$text:\t$realType")
|
||||||
|
return realType
|
||||||
}
|
}
|
||||||
fun deserializeLocalDeclaration(proto: KonanLinkData.Descriptor): DeclarationDescriptor {
|
fun deserializeLocalDeclaration(proto: KonanLinkData.Descriptor): DeclarationDescriptor {
|
||||||
when {
|
when {
|
||||||
|
|||||||
+11
-3
@@ -21,7 +21,8 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.isCaptured
|
||||||
import org.jetbrains.kotlin.serialization.KonanIr
|
import org.jetbrains.kotlin.serialization.KonanIr
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -40,10 +41,17 @@ internal class IrDescriptorSerializer(
|
|||||||
var rootFunction: FunctionDescriptor) {
|
var rootFunction: FunctionDescriptor) {
|
||||||
|
|
||||||
fun serializeKotlinType(type: KotlinType): KonanIr.KotlinType {
|
fun serializeKotlinType(type: KotlinType): KonanIr.KotlinType {
|
||||||
val index = this.typeSerializer(type)
|
val isCaptured = type.isCaptured()
|
||||||
val proto = KonanIr.KotlinType.newBuilder()
|
val typeToSerialize = if (isCaptured) {
|
||||||
|
packCapturedType(type as CapturedType)
|
||||||
|
} else {
|
||||||
|
type
|
||||||
|
}
|
||||||
|
val index = typeSerializer(typeToSerialize)
|
||||||
|
val proto = KonanIr.KotlinType.newBuilder()
|
||||||
.setIndex(index)
|
.setIndex(index)
|
||||||
.setDebugText(type.toString())
|
.setDebugText(type.toString())
|
||||||
|
.setIsCaptured(isCaptured)
|
||||||
.build()
|
.build()
|
||||||
return proto
|
return proto
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -44,7 +44,8 @@ message LocalDeclaration {
|
|||||||
|
|
||||||
message KotlinType {
|
message KotlinType {
|
||||||
required int32 index = 1;
|
required int32 index = 1;
|
||||||
optional string debug_text = 2; // TODO: remove me
|
required bool isCaptured = 2; // TODO: make it a flag set?
|
||||||
|
optional string debug_text = 3; // TODO: remove me
|
||||||
}
|
}
|
||||||
|
|
||||||
message Coordinates {
|
message Coordinates {
|
||||||
@@ -190,6 +191,8 @@ message IrWhile {
|
|||||||
optional IrExpression body = 4;
|
optional IrExpression body = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: we need an extension mechanism to accomodate new
|
||||||
|
// IR operators in upcoming releases.
|
||||||
message IrOperation {
|
message IrOperation {
|
||||||
oneof operation {
|
oneof operation {
|
||||||
IrBlock block = 1;
|
IrBlock block = 1;
|
||||||
@@ -257,6 +260,8 @@ message IrEnumEntry {
|
|||||||
optional IrDeclaration corresponding_class = 2;
|
optional IrDeclaration corresponding_class = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: we need an extension mechanism to accomodate new
|
||||||
|
// IR operators in upcoming releases.
|
||||||
message IrDeclarator {
|
message IrDeclarator {
|
||||||
oneof symbol {
|
oneof symbol {
|
||||||
IrVar variable = 1;
|
IrVar variable = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user