Added support of inline properties.

This commit is contained in:
Alexander Gorshenev
2017-04-21 18:38:06 +03:00
committed by alexander-gorshenev
parent 92964e1eae
commit 39f2c3d7fb
11 changed files with 210 additions and 122 deletions
@@ -16,9 +16,8 @@
package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.FqName
@@ -58,4 +57,24 @@ fun DeclarationDescriptor.deepPrint() {
internal val String.synthesizedName get() = Name.identifier(this.synthesizedString)
internal val String.synthesizedString get() = "\$$this"
internal val String.synthesizedString get() = "\$$this"
internal val DeclarationDescriptor.propertyIfAccessor
get() = if (this is PropertyAccessorDescriptor)
this.correspondingProperty
else this
internal val FunctionDescriptor.deserializedPropertyIfAccessor: DeserializedCallableMemberDescriptor
get() {
val member = this.propertyIfAccessor
if (member is DeserializedCallableMemberDescriptor)
return member
else
error("Unexpected deserializable callable descriptor")
}
internal val DeclarationDescriptor.isDeserializableCallable
get () = (this.propertyIfAccessor is DeserializedCallableMemberDescriptor)
@@ -20,7 +20,6 @@ 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.llvm.symbolName
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.expressions.IrLoop
@@ -33,99 +32,36 @@ import org.jetbrains.kotlin.serialization.KonanLinkData
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
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.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.types.KotlinType
fun newUniqId(index: Long): KonanLinkData.UniqId =
KonanLinkData.UniqId.newBuilder().setIndex(index).build()
val ProtoBuf.Function.functionIndex: Long
get() = this.getExtension(KonanLinkData.functionIndex).index
val ProtoBuf.Constructor.constructorIndex: Long
get() = this.getExtension(KonanLinkData.constructorIndex).index
val ProtoBuf.Property.propertyIndex: Long
get() = this.getExtension(KonanLinkData.propertyIndex).index
fun ProtoBuf.Function.Builder.setFunctionIndex(index: Long)
= this.setExtension(KonanLinkData.functionIndex, newUniqId(index))
fun ProtoBuf.Constructor.Builder.setConstructorIndex(index: Long)
= this.setExtension(KonanLinkData.constructorIndex, newUniqId(index))
fun ProtoBuf.Property.Builder.setPropertyIndex(index: Long)
= this.setExtension(KonanLinkData.propertyIndex, newUniqId(index))
fun ProtoBuf.Class.Builder.setClassIndex(index: Long)
= this.setExtension(KonanLinkData.classIndex, newUniqId(index))
val KonanIr.KotlinDescriptor.index: Long
get() = this.uniqId.index
fun KonanIr.KotlinDescriptor.Builder.setIndex(index: Long)
= this.setUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.originalIndex: Long
get() = this.originalUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setOriginalIndex(index: Long)
= this.setOriginalUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.dispatchReceiverIndex: Long
get() = this.dispatchReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setDispatchReceiverIndex(index: Long)
= this.setDispatchReceiverUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.extensionReceiverIndex: Long
get() = this.extensionReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setExtensionReceiverIndex(index: Long)
= this.setExtensionReceiverUniqId(newUniqId(index))
internal fun printType(proto: ProtoBuf.Type) {
println("debug text: " + proto.getExtension(KonanLinkData.typeText))
}
internal fun printTypeTable(proto: ProtoBuf.TypeTable) {
proto.getTypeList().forEach {
printType(it)
}
}
internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
return if (this is PackageFragmentDescriptor) this
else this.containingDeclaration!!.findPackage()
}
internal fun DeserializedSimpleFunctionDescriptor.nameTable(): ProtoBuf.QualifiedNameTable {
internal fun DeserializedMemberDescriptor.nameTable(): ProtoBuf.QualifiedNameTable {
val pkg = this.findPackage()
assert(pkg is KonanPackageFragment)
return (pkg as KonanPackageFragment).proto.getNameTable()
}
internal fun DeserializedSimpleFunctionDescriptor.nameResolver(): NameResolver {
internal fun DeserializedMemberDescriptor.nameResolver(): NameResolver {
val pkg = this.findPackage() as KonanPackageFragment
return NameResolverImpl(pkg.proto.getStringTable(), pkg.proto.getNameTable())
}
// This is the class that knowns how to deserialize
// Kotlin descriptors and types for IR.
internal class IrDescriptorDeserializer(val context: Context,
val rootFunction: DeserializedSimpleFunctionDescriptor,
val rootDescriptor: DeserializedCallableMemberDescriptor,
val localDeserializer: LocalDeclarationDeserializer) {
val loopIndex = mutableMapOf<Int, IrLoop>()
val nameResolver = rootFunction.nameResolver() as NameResolverImpl
val nameTable = rootFunction.nameTable()
val nameResolver = rootDescriptor.nameResolver() as NameResolverImpl
val nameTable = rootDescriptor.nameTable()
val descriptorIndex = IrDeserializationDescriptorIndex(context.irBuiltIns).map
fun deserializeKotlinType(proto: KonanIr.KotlinType): KotlinType {
@@ -483,8 +419,8 @@ internal class IrDescriptorDeserializer(val context: Context,
// copies for public descriptors if we know the substituted
// descriptor is going to be the same.
// But that's not a trivial thing to find out.
if (originalDescriptor == rootFunction)
return rootFunction
if (originalDescriptor == rootDescriptor)
return rootDescriptor
return when (originalDescriptor) {
is SimpleFunctionDescriptor ->
@@ -229,7 +229,12 @@ class KonanDescriptorSerializer private constructor(
builder.sinceKotlinInfo = writeSinceKotlinInfo(LanguageFeature.Coroutines)
}
extension.serializeProperty(descriptor, builder)
if (extension is KonanSerializerExtension) {
extension.serializePropertyWithIR(descriptor, builder, {it -> typeId(it)})
} else {
extension.serializeProperty(descriptor, builder)
}
return builder
}
@@ -20,7 +20,7 @@ message KotlinDescriptor {
RECEIVER = 7;
ACCESSOR = 8;
}
// TODO: Use the string table?
// TODO: Use the string table index.
optional string name = 1;
required Kind kind = 2;
required UniqId uniq_id = 3;
@@ -47,6 +47,8 @@ extend Property {
optional int32 property_parent = 172;
optional bool used_as_variable = 173;
optional Annotation.Argument.Value compile_time_value = 174;
optional InlineIrBody inline_getter_ir_body = 175;
optional InlineIrBody inline_setter_ir_body = 176;
}
extend EnumEntry {
@@ -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.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.annotations.AnnotationDescriptorImpl
@@ -98,6 +99,18 @@ 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)?) {
@@ -106,20 +119,11 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
inlineDescriptorTable.indexByValue(descriptor))
val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.functionParent, parentIndex)
if (descriptor.needsInlining) {
val encodedIR: String = IrSerializer( context,
inlineDescriptorTable, stringTable, util, typeSerializer!!, descriptor)
.serializeInlineBody()
val inlineIrBody = KonanLinkData.InlineIrBody
.newBuilder()
.setEncodedIr(encodedIR)
.build()
proto.setExtension(KonanLinkData.inlineIrBody, inlineIrBody)
proto.setInlineIr(
serializeInlineBody(descriptor, typeSerializer!!))
}
super.serializeFunction(descriptor, proto)
}
@@ -129,8 +133,9 @@ 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)
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
fun serializePropertyWithIR(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder, typeSerializer: ((KotlinType)->Int)?) {
val parentIndex = descriptor.parentFqNameIndex()
proto.setExtension(KonanLinkData.propertyParent, parentIndex)
val variable = originalVariables[descriptor]
@@ -144,6 +149,16 @@ 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)) {
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedN
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.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
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
@@ -35,9 +34,9 @@ import org.jetbrains.kotlin.types.KotlinType
// MemberDeserializer to deserialize descriptors declared in IR.
// Consider merging it all to the very MemberDesereializer itself eventually.
class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val module: ModuleDescriptor) {
class LocalDeclarationDeserializer(val rootDescriptor: DeserializedCallableMemberDescriptor, val module: ModuleDescriptor) {
val pkg = rootFunction.getContainingDeclaration() as KonanPackageFragment
val pkg = rootDescriptor.getContainingDeclaration() as KonanPackageFragment
init {
assert(pkg is KonanPackageFragment)
}
@@ -49,8 +48,17 @@ class LocalDeclarationDeserializer(val rootFunction: FunctionDescriptor, val mod
val context = components.createContext(
pkg, nameResolver, typeTable, SinceKotlinInfoTable.EMPTY, null)
val typeParameterProtos = (rootFunction as DeserializedSimpleFunctionDescriptor).proto.typeParameterList
val childContext = context.childContext(rootFunction, typeParameterProtos, nameResolver, typeTable)
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")
}
val childContext = context.childContext(rootDescriptor, typeParameterProtos, nameResolver, typeTable)
val typeDeserializer = childContext.typeDeserializer
val memberDeserializer = MemberDeserializer(childContext)
@@ -0,0 +1,89 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.serialization.KonanIr
import org.jetbrains.kotlin.serialization.KonanLinkData
import org.jetbrains.kotlin.serialization.KonanLinkData.*
import org.jetbrains.kotlin.serialization.ProtoBuf
fun newUniqId(index: Long): KonanLinkData.UniqId =
KonanLinkData.UniqId.newBuilder().setIndex(index).build()
val ProtoBuf.Function.functionIndex: Long
get() = this.getExtension(KonanLinkData.functionIndex).index
val ProtoBuf.Constructor.constructorIndex: Long
get() = this.getExtension(KonanLinkData.constructorIndex).index
val ProtoBuf.Property.propertyIndex: Long
get() = this.getExtension(KonanLinkData.propertyIndex).index
fun ProtoBuf.Function.Builder.setFunctionIndex(index: Long)
= this.setExtension(KonanLinkData.functionIndex, newUniqId(index))
fun ProtoBuf.Constructor.Builder.setConstructorIndex(index: Long)
= this.setExtension(KonanLinkData.constructorIndex, newUniqId(index))
fun ProtoBuf.Property.Builder.setPropertyIndex(index: Long)
= this.setExtension(KonanLinkData.propertyIndex, newUniqId(index))
fun ProtoBuf.Class.Builder.setClassIndex(index: Long)
= this.setExtension(KonanLinkData.classIndex, newUniqId(index))
// -----------------------------------------------------------
val KonanIr.KotlinDescriptor.index: Long
get() = this.uniqId.index
fun KonanIr.KotlinDescriptor.Builder.setIndex(index: Long)
= this.setUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.originalIndex: Long
get() = this.originalUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setOriginalIndex(index: Long)
= this.setOriginalUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.dispatchReceiverIndex: Long
get() = this.dispatchReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setDispatchReceiverIndex(index: Long)
= this.setDispatchReceiverUniqId(newUniqId(index))
val KonanIr.KotlinDescriptor.extensionReceiverIndex: Long
get() = this.extensionReceiverUniqId.index
fun KonanIr.KotlinDescriptor.Builder.setExtensionReceiverIndex(index: Long)
= this.setExtensionReceiverUniqId(newUniqId(index))
// -----------------------------------------------------------
val ProtoBuf.Property.getterIr: InlineIrBody
get() = this.getExtension(inlineGetterIrBody)
fun ProtoBuf.Property.Builder.setGetterIr(body: InlineIrBody): ProtoBuf.Property.Builder =
this.setExtension(inlineGetterIrBody, body)
val ProtoBuf.Property.setterIr: InlineIrBody
get() = this.getExtension(inlineSetterIrBody)
fun ProtoBuf.Property.Builder.setSetterIr(body: InlineIrBody): ProtoBuf.Property.Builder =
this.setExtension(inlineSetterIrBody, body)
val ProtoBuf.Function.inlineIr: InlineIrBody
get() = this.getExtension(inlineIrBody)
fun ProtoBuf.Function.Builder.setInlineIr(body: InlineIrBody): ProtoBuf.Function.Builder =
this.setExtension(inlineIrBody, body)
internal fun printType(proto: ProtoBuf.Type) {
println("debug text: " + proto.getExtension(KonanLinkData.typeText))
}
internal fun printTypeTable(proto: ProtoBuf.TypeTable) {
proto.getTypeList().forEach {
printType(it)
}
}
@@ -20,6 +20,7 @@ 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.ir.ir2string
import org.jetbrains.kotlin.backend.konan.ir.ir2stringWhole
@@ -41,7 +42,7 @@ 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.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -572,15 +573,15 @@ internal class IrSerializer(val context: Context,
// --------- Deserializer part -----------------------------
internal class IrDeserializer(val context: Context,
val rootFunction: DeserializedSimpleFunctionDescriptor) {
val rootFunction: FunctionDescriptor) {
val loopIndex = mutableMapOf<Int, IrLoop>()
val localDeserializer = LocalDeclarationDeserializer(rootFunction, context.moduleDescriptor)
val rootMember = rootFunction.deserializedPropertyIfAccessor
val localDeserializer = LocalDeclarationDeserializer(rootMember, context.moduleDescriptor)
val descriptorDeserializer = IrDescriptorDeserializer(
context, rootFunction, localDeserializer)
context, rootMember, localDeserializer)
fun deserializeKotlinType(proto: KonanIr.KotlinType)
= descriptorDeserializer.deserializeKotlinType(proto)
@@ -1047,7 +1048,7 @@ internal class IrDeserializer(val context: Context,
// We run inline body deserializations after the public descriptor tree
// deserialization is long gone. So we don't have the needed chain of
// deserialization contexts available to take type parameters.
// So typeDeserializer introduces a brand new set of DeserializadTypeParameterDescriptor
// So typeDeserializer introduces a brand new set of DeserializadTypeParameterDescriptors
// for the rootFunction.
// This function takes the type parameters from the rootFunction descriptor
// and substitutes them instead the deserialized ones.
@@ -1058,9 +1059,12 @@ internal class IrDeserializer(val context: Context,
val rootFunctionTypeParameters =
descriptorDeserializer.localDeserializer.childContext.typeDeserializer.ownTypeParameters
val realTypeParameters =
rootFunction.deserializedPropertyIfAccessor.typeParameters
val substitutionContext = rootFunctionTypeParameters.mapIndexed{
index, param ->
Pair(param.typeConstructor, TypeProjectionImpl(rootFunction.typeParameters[index].defaultType))
Pair(param.typeConstructor, TypeProjectionImpl(realTypeParameters[index].defaultType))
}.associate{
(key,value) ->
key to value}
@@ -1073,14 +1077,24 @@ internal class IrDeserializer(val context: Context,
return copyFunctionDeclaration
}
fun decodeDeclaration(): IrDeclaration {
val proto = rootFunction.proto
if (!proto.hasExtension(KonanLinkData.inlineIrBody)) {
throw KonanIrDeserializationException("$rootFunction doesn't have ir serialized.")
val extractInlineProto: KonanLinkData.InlineIrBody
get() = when (rootFunction) {
is DeserializedSimpleFunctionDescriptor -> {
rootFunction.proto.inlineIr
}
is PropertyGetterDescriptor -> {
(rootMember as DeserializedPropertyDescriptor).proto.getterIr
}
is PropertySetterDescriptor -> {
(rootMember as DeserializedPropertyDescriptor).proto.setterIr
}
else -> error("Unexpected descriptor: rootFunction")
}
val inlineProto = proto.getExtension(KonanLinkData.inlineIrBody)
fun decodeDeclaration(): IrDeclaration {
assert(rootFunction.isDeserializableCallable)
val inlineProto = extractInlineProto
val base64 = inlineProto.encodedIr
val byteArray = base64Decode(base64)
val irProto = KonanIr.IrDeclaration.parseFrom(byteArray, KonanSerializerProtocol.extensionRegistry)
@@ -1091,4 +1105,3 @@ internal class IrDeserializer(val context: Context,
return copyFunctionDeclaration
}
}
@@ -18,9 +18,8 @@ package org.jetbrains.kotlin.backend.konan.ir
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -28,8 +27,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.backend.konan.descriptors.EmptyDescriptorVisitorVoid
import org.jetbrains.kotlin.backend.konan.descriptors.DeepVisitor
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.serialization.*
import org.jetbrains.kotlin.backend.konan.llvm.base64Encode
import org.jetbrains.kotlin.backend.konan.llvm.base64Decode
@@ -43,10 +41,7 @@ internal class DeserializerDriver(val context: Context) {
internal fun deserializeInlineBody(descriptor: FunctionDescriptor): IrDeclaration? {
if (!descriptor.needsInlining) return null
if (descriptor !is DeserializedSimpleFunctionDescriptor) {
return null
}
if (!descriptor.isDeserializableCallable) return null
var deserializedIr: IrDeclaration? = null
PhaseManager(context).phase(KonanPhase.DESERIALIZER) {
@@ -77,7 +72,7 @@ internal class DeserializerDriver(val context: Context) {
inner class InlineBodyPrinter: EmptyDescriptorVisitorVoid() {
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): Boolean {
if (descriptor is DeserializedSimpleFunctionDescriptor) {
if (descriptor.isDeserializableCallable) {
this@DeserializerDriver.deserializeInlineBody(descriptor)
}
@@ -44,4 +44,10 @@ fun <T> Collection<T>.atMostOne(): T? {
}
}
inline fun <T> Iterable<T>.atMostOne(predicate: (T) -> Boolean): T? = this.filter(predicate).atMostOne()
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 {
if (this.condition()) then(this)
return this
}