Captured type constructor support in serializer.

This commit is contained in:
Alexander Gorshenev
2017-04-15 03:41:01 +03:00
committed by alexander-gorshenev
parent 1544045643
commit e2bf81d7d8
4 changed files with 82 additions and 10 deletions
@@ -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())
@@ -17,16 +17,15 @@
package org.jetbrains.kotlin.backend.konan.serialization
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.KonanIrDeserializationException
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
import org.jetbrains.kotlin.backend.konan.llvm.symbolName
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.expressions.IrLoop
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.serialization.KonanIr
import org.jetbrains.kotlin.serialization.KonanIr.KotlinDescriptor
@@ -130,15 +129,19 @@ internal class IrDescriptorDeserializer(val context: Context,
val descriptorIndex = IrDeserializationDescriptorIndex(context.irBuiltIns).map
fun deserializeKotlinType(proto: KonanIr.KotlinType): KotlinType {
val index = proto.getIndex()
val text = proto.getDebugText()
val typeProto = localDeserializer.typeTable[index]
val type = localDeserializer.deserializeInlineType(typeProto)
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 {
when {
@@ -21,7 +21,8 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
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.types.KotlinType
@@ -40,10 +41,17 @@ internal class IrDescriptorSerializer(
var rootFunction: FunctionDescriptor) {
fun serializeKotlinType(type: KotlinType): KonanIr.KotlinType {
val index = this.typeSerializer(type)
val proto = KonanIr.KotlinType.newBuilder()
val isCaptured = type.isCaptured()
val typeToSerialize = if (isCaptured) {
packCapturedType(type as CapturedType)
} else {
type
}
val index = typeSerializer(typeToSerialize)
val proto = KonanIr.KotlinType.newBuilder()
.setIndex(index)
.setDebugText(type.toString())
.setIsCaptured(isCaptured)
.build()
return proto
}
@@ -44,7 +44,8 @@ message LocalDeclaration {
message KotlinType {
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 {
@@ -190,6 +191,8 @@ message IrWhile {
optional IrExpression body = 4;
}
// TODO: we need an extension mechanism to accomodate new
// IR operators in upcoming releases.
message IrOperation {
oneof operation {
IrBlock block = 1;
@@ -257,6 +260,8 @@ message IrEnumEntry {
optional IrDeclaration corresponding_class = 2;
}
// TODO: we need an extension mechanism to accomodate new
// IR operators in upcoming releases.
message IrDeclarator {
oneof symbol {
IrVar variable = 1;