Simplified IR awareness of KonanDescriptorSerializer.

This commit is contained in:
Alexander Gorshenev
2017-04-24 14:51:38 +03:00
committed by alexander-gorshenev
parent 39f2c3d7fb
commit 5b4eb47235
4 changed files with 63 additions and 70 deletions
@@ -16,6 +16,9 @@
package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.serialization.IrAwareExtension
import org.jetbrains.kotlin.backend.konan.util.onlyIf
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
@@ -36,13 +39,6 @@ import org.jetbrains.kotlin.utils.Interner
import java.io.ByteArrayOutputStream
import java.util.*
import org.jetbrains.kotlin.backend.konan.serialization.KonanSerializerExtension
// This is an almost exact copy of DescriptorSerializer
// from the big Kotlin.
// The only difference for now is typeId is public now.
// Consider bringing the new functionaity upstream.
class KonanDescriptorSerializer private constructor(
private val containingDeclaration: DeclarationDescriptor?,
private val typeParameters: Interner<TypeParameterDescriptor>,
@@ -229,12 +225,18 @@ class KonanDescriptorSerializer private constructor(
builder.sinceKotlinInfo = writeSinceKotlinInfo(LanguageFeature.Coroutines)
}
if (extension is KonanSerializerExtension) {
extension.serializePropertyWithIR(descriptor, builder, {it -> typeId(it)})
} else {
extension.serializeProperty(descriptor, builder)
}
extension.serializeProperty(descriptor, builder)
if (extension is IrAwareExtension) {
descriptor.getter?.onlyIf({needsInlining}) {
extension.addGetterIR(builder,
extension.serializeInlineBody(it, {it -> typeId(it)}))
}
descriptor.setter?.onlyIf({needsInlining}) {
extension.addSetterIR(builder,
extension.serializeInlineBody(it, {it -> typeId(it)}))
}
}
return builder
}
@@ -291,10 +293,12 @@ class KonanDescriptorSerializer private constructor(
builder.sinceKotlinInfo = writeSinceKotlinInfo(LanguageFeature.Coroutines)
}
if (extension is KonanSerializerExtension) {
extension.serializeFunctionWithIR(descriptor, builder, {it -> typeId(it)})
} else {
extension.serializeFunction(descriptor, builder)
extension.serializeFunction(descriptor, builder)
if (extension is IrAwareExtension
&& descriptor.needsInlining) {
extension.addFunctionIR(builder,
extension.serializeInlineBody(descriptor, {it -> typeId(it)}))
}
return builder
@@ -18,33 +18,15 @@ package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalClass
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.util.only
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.serialization.*
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.KonanLinkData
import org.jetbrains.kotlin.serialization.KonanLinkData.InlineIrBody
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.*
import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.StringTableImpl
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.types.FlexibleType
import org.jetbrains.kotlin.types.KotlinType
internal class KonanSerializerExtension(val context: Context, val util: KonanSerializationUtil) :
KotlinSerializerExtensionBase(KonanSerializerProtocol) {
KotlinSerializerExtensionBase(KonanSerializerProtocol), IrAwareExtension {
val inlineDescriptorTable = DescriptorTable(context.irBuiltIns)
val originalVariables = mutableMapOf<PropertyDescriptor, VariableDescriptor>()
@@ -99,31 +81,12 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
super.serializeClass(descriptor, proto)
}
private fun serializeInlineBody(descriptor: FunctionDescriptor, typeSerializer: ((KotlinType)->Int)): KonanLinkData.InlineIrBody {
val encodedIR = IrSerializer(
context, inlineDescriptorTable, stringTable, util,
typeSerializer, descriptor).serializeInlineBody()
return KonanLinkData.InlineIrBody
.newBuilder()
.setEncodedIr(encodedIR)
.build()
}
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) = serializeFunctionWithIR(descriptor, proto, null)
fun serializeFunctionWithIR(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder, typeSerializer: ((KotlinType)->Int)?) {
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
proto.setFunctionIndex(
inlineDescriptorTable.indexByValue(descriptor))
val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.functionParent, parentIndex)
if (descriptor.needsInlining) {
proto.setInlineIr(
serializeInlineBody(descriptor, typeSerializer!!))
}
super.serializeFunction(descriptor, proto)
}
@@ -133,9 +96,7 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
private val backingFieldAnnotation = AnnotationDescriptorImpl(
backingFieldClass, emptyMap(), SourceElement.NO_SOURCE)
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) = serializePropertyWithIR(descriptor, proto, null)
fun serializePropertyWithIR(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder, typeSerializer: ((KotlinType)->Int)?) {
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.propertyParent, parentIndex)
val variable = originalVariables[descriptor]
@@ -149,16 +110,6 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
inlineDescriptorTable.indexByValue(descriptor))
}
descriptor.getter?.only({needsInlining}) {
proto.setGetterIr(
serializeInlineBody(it, typeSerializer!!))
}
descriptor.setter?.only({needsInlining}) {
proto.setSetterIr(
serializeInlineBody(it, typeSerializer!!))
}
super.serializeProperty(descriptor, proto)
if (context.ir.propertiesWithBackingFields.contains(descriptor)) {
@@ -168,6 +119,22 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
proto.flags = proto.flags or Flags.HAS_ANNOTATIONS.toFlags(true)
}
}
override fun addFunctionIR(proto: ProtoBuf.Function.Builder, serializedIR: String)
= proto.setInlineIr(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 {
return IrSerializer(
context, inlineDescriptorTable, stringTable, util,
typeSerializer, descriptor).serializeInlineBody()
}
}
object KonanSerializerProtocol : SerializerExtensionProtocol(
@@ -185,3 +152,15 @@ object KonanSerializerProtocol : SerializerExtensionProtocol(
KonanLinkData.typeAnnotation,
KonanLinkData.typeParameterAnnotation
)
internal interface IrAwareExtension {
fun serializeInlineBody(descriptor: FunctionDescriptor, typeSerializer: ((KotlinType)->Int)): String
fun addFunctionIR(proto: ProtoBuf.Function.Builder, serializedIR: String): ProtoBuf.Function.Builder
fun addSetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String): ProtoBuf.Property.Builder
fun addGetterIR(proto: ProtoBuf.Property.Builder, serializedIR: String): ProtoBuf.Property.Builder
}
@@ -76,6 +76,16 @@ val ProtoBuf.Function.inlineIr: InlineIrBody
fun ProtoBuf.Function.Builder.setInlineIr(body: InlineIrBody): ProtoBuf.Function.Builder =
this.setExtension(inlineIrBody, body)
// -----------------------------------------------------------
fun inlineBody(encodedIR: String)
= KonanLinkData.InlineIrBody
.newBuilder()
.setEncodedIr(encodedIR)
.build()
// -----------------------------------------------------------
internal fun printType(proto: ProtoBuf.Type) {
println("debug text: " + proto.getExtension(KonanLinkData.typeText))
}
@@ -46,7 +46,7 @@ fun <T> Collection<T>.atMostOne(): T? {
inline fun <T> Iterable<T>.atMostOne(predicate: (T) -> Boolean): T? = this.filter(predicate).atMostOne()
fun <T: Any> T.only(condition: T.()->Boolean, then: (T)->Unit): T {
fun <T: Any> T.onlyIf(condition: T.()->Boolean, then: (T)->Unit): T {
if (this.condition()) then(this)
return this
}