Represent the presence of a backing field with just a protobuf

extension bit, instead of a more complex annotation scheme.  The
scheme was initially introduced when Konan still used JS serializer
extension, and we only could apply an additional annotation.
This commit is contained in:
Alexander Gorshenev
2017-04-27 17:57:24 +03:00
committed by alexander-gorshenev
parent cbce4cf994
commit f77a4b9090
5 changed files with 25 additions and 39 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.serialization.KonanLinkData
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.FqName
@@ -45,11 +46,11 @@ fun ClassDescriptor?.signature2Descriptor(methodName: Name, signature:Array<Kotl
}
}
val PropertyDescriptor.backingField: PropertyDescriptor?
get() {
val backingFieldAnnotation = FqName("konan.internal.HasBackingField")
return if (this.annotations.findAnnotation(backingFieldAnnotation) != null) this else null
}
val DeserializedPropertyDescriptor.backingField: PropertyDescriptor?
get() =
if (this.proto.getExtension(KonanLinkData.hasBackingField))
this
else null
fun DeclarationDescriptor.deepPrint() {
this.accept(DeepPrintVisitor(PrintVisitor()), 0)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -103,18 +104,13 @@ internal fun ContextUtils.getFields(classDescriptor: ClassDescriptor): List<Prop
private fun ContextUtils.getDeclaredFields(classDescriptor: ClassDescriptor): List<PropertyDescriptor> {
// TODO: Here's what is going on here:
// The existence of a backing field for a property is only described in the IR,
// but not in the property descriptor.
// That works, while we process the IR, but not for deserialized descriptors.
// but not in the PropertyDescriptor.
//
// So to have something in deserialized descriptors,
// while we still see the IR, we mark the property with an annotation.
//
// We could apply the annotation during IR rewite, but we still are not
// that far in the rewriting infrastructure. So we postpone
// the annotation until the serializer.
// We mark serialized properties with a Konan protobuf extension bit,
// so it is present in DeserializedPropertyDescriptor.
//
// In this function we check the presence of the backing filed
// two ways: first we check IR, then we check the annotation.
// two ways: first we check IR, then we check the protobuf extension.
val irClass = context.ir.moduleIndexForCodegen.classes[classDescriptor]
val fields = if (irClass != null) {
@@ -130,7 +126,7 @@ private fun ContextUtils.getDeclaredFields(classDescriptor: ClassDescriptor): Li
} else {
val properties = classDescriptor.unsubstitutedMemberScope.
getContributedDescriptors().
filterIsInstance<PropertyDescriptor>()
filterIsInstance<DeserializedPropertyDescriptor>()
properties.mapNotNull { it.backingField }
}
@@ -29,15 +29,16 @@ extend Constructor {
extend Function {
repeated Annotation function_annotation = 170;
optional InlineIrBody inline_ir_body = 174;
optional InlineIrBody inline_ir_body = 171;
}
extend Property {
repeated Annotation property_annotation = 170;
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;
optional bool has_backing_field = 171;
optional bool used_as_variable = 172;
optional Annotation.Argument.Value compile_time_value = 173;
optional InlineIrBody inline_getter_ir_body = 174;
optional InlineIrBody inline_setter_ir_body = 175;
}
extend EnumEntry {
@@ -34,7 +34,9 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
override fun shouldUseTypeTable(): Boolean = true
override fun serializeType(type: KotlinType, proto: ProtoBuf.Type.Builder) {
// TODO: For debugging purpose we store the textual
// representation of serialized types.
// To be removed for release 1.0.
proto.setExtension(KonanLinkData.typeText, type.toString())
super.serializeType(type, proto)
@@ -68,26 +70,16 @@ internal class KonanSerializerExtension(val context: Context, val util: KonanSer
super.serializeFunction(descriptor, proto)
}
private val backingFieldClass =
context.builtIns.getKonanInternalClass("HasBackingField").getDefaultType()
private val backingFieldAnnotation = AnnotationDescriptorImpl(
backingFieldClass, emptyMap(), SourceElement.NO_SOURCE)
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
val variable = originalVariables[descriptor]
if (variable != null) {
proto.setExtension(KonanLinkData.usedAsVariable, true)
}
proto.setExtension(KonanLinkData.hasBackingField,
context.ir.propertiesWithBackingFields.contains(descriptor))
super.serializeProperty(descriptor, proto)
if (context.ir.propertiesWithBackingFields.contains(descriptor)) {
proto.addExtension(KonanLinkData.propertyAnnotation,
annotationSerializer.serializeAnnotation(backingFieldAnnotation))
proto.flags = proto.flags or Flags.HAS_ANNOTATIONS.toFlags(true)
}
}
override fun addFunctionIR(proto: ProtoBuf.Function.Builder, serializedIR: String)
@@ -28,10 +28,6 @@ package konan.internal
//@Retention(AnnotationRetention.SOURCE)
annotation class ExportForCppRuntime(val name: String = "")
// This one is used internally to mark the presence of a backing field
// in the absence of IR.
annotation class HasBackingField
/**
* This annotation denotes that the element is intrinsic and its usages require special handling in compiler.
*/
@@ -44,4 +40,4 @@ annotation class Intrinsic
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
annotation class ExportForCompiler
annotation class ExportForCompiler