Simplify deserialization of annotations on backing/delegate fields
Instead of returning the list of targeted annotations in loadCallableAnnotations, add two separate methods to load annotations on the backing field and on the delegate field of the property
This commit is contained in:
+12
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
// The MessageLite instance everywhere should be Constructor, Function or Property
|
||||
// TODO: simplify this interface
|
||||
interface AnnotationAndConstantLoader<out A : Any, out C : Any, out T : Any> {
|
||||
interface AnnotationAndConstantLoader<out A : Any, out C : Any> {
|
||||
fun loadClassAnnotations(
|
||||
container: ProtoContainer.Class
|
||||
): List<A>
|
||||
@@ -32,7 +32,17 @@ interface AnnotationAndConstantLoader<out A : Any, out C : Any, out T : Any> {
|
||||
container: ProtoContainer,
|
||||
proto: MessageLite,
|
||||
kind: AnnotatedCallableKind
|
||||
): List<T>
|
||||
): List<A>
|
||||
|
||||
fun loadPropertyBackingFieldAnnotations(
|
||||
container: ProtoContainer,
|
||||
proto: ProtoBuf.Property
|
||||
): List<A>
|
||||
|
||||
fun loadPropertyDelegateFieldAnnotations(
|
||||
container: ProtoContainer,
|
||||
proto: ProtoBuf.Property
|
||||
): List<A>
|
||||
|
||||
fun loadEnumEntryAnnotations(
|
||||
container: ProtoContainer,
|
||||
|
||||
+9
-4
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.serialization.deserialization
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
@@ -32,7 +31,7 @@ class AnnotationAndConstantLoaderImpl(
|
||||
module: ModuleDescriptor,
|
||||
notFoundClasses: NotFoundClasses,
|
||||
private val protocol: SerializerExtensionProtocol
|
||||
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget> {
|
||||
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>> {
|
||||
private val deserializer = AnnotationDeserializer(module, notFoundClasses)
|
||||
|
||||
override fun loadClassAnnotations(container: ProtoContainer.Class): List<AnnotationDescriptor> {
|
||||
@@ -44,7 +43,7 @@ class AnnotationAndConstantLoaderImpl(
|
||||
container: ProtoContainer,
|
||||
proto: MessageLite,
|
||||
kind: AnnotatedCallableKind
|
||||
): List<AnnotationWithTarget> {
|
||||
): List<AnnotationDescriptor> {
|
||||
val annotations = when (proto) {
|
||||
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
|
||||
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
|
||||
@@ -52,10 +51,16 @@ class AnnotationAndConstantLoaderImpl(
|
||||
else -> error("Unknown message: $proto")
|
||||
}.orEmpty()
|
||||
return annotations.map { annotationProto ->
|
||||
AnnotationWithTarget(deserializer.deserializeAnnotation(annotationProto, container.nameResolver), null)
|
||||
deserializer.deserializeAnnotation(annotationProto, container.nameResolver)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<AnnotationDescriptor> =
|
||||
emptyList()
|
||||
|
||||
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<AnnotationDescriptor> =
|
||||
emptyList()
|
||||
|
||||
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<AnnotationDescriptor> {
|
||||
val annotations = proto.getExtension(protocol.enumEntryAnnotation).orEmpty()
|
||||
return annotations.map { annotationProto ->
|
||||
|
||||
+20
-15
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
||||
@@ -31,11 +30,9 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
fun loadProperty(proto: ProtoBuf.Property): PropertyDescriptor {
|
||||
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
|
||||
|
||||
val propertyAnnotations = getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY)
|
||||
|
||||
val property = DeserializedPropertyDescriptor(
|
||||
c.containingDeclaration, null,
|
||||
propertyAnnotations,
|
||||
getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
|
||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
||||
Flags.IS_VAR.get(flags),
|
||||
@@ -138,17 +135,10 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: add needed methods to AnnotationAndConstantLoader
|
||||
val fieldAnnotations = DeserializedAnnotations(c.storageManager) {
|
||||
propertyAnnotations.getUseSiteTargetedAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.FIELD }.map { it.annotation }
|
||||
}
|
||||
val delegateAnnotations = DeserializedAnnotations(c.storageManager) {
|
||||
propertyAnnotations.getUseSiteTargetedAnnotations()
|
||||
.filter { it.target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD }.map { it.annotation }
|
||||
}
|
||||
property.initialize(
|
||||
getter, setter, FieldDescriptorImpl(fieldAnnotations, property), FieldDescriptorImpl(delegateAnnotations, property),
|
||||
getter, setter,
|
||||
FieldDescriptorImpl(getPropertyFieldAnnotations(proto, isDelegate = false), property),
|
||||
FieldDescriptorImpl(getPropertyFieldAnnotations(proto, isDelegate = true), property),
|
||||
property.checkExperimentalCoroutine(local.typeDeserializer)
|
||||
)
|
||||
|
||||
@@ -358,13 +348,28 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
||||
if (!Flags.HAS_ANNOTATIONS.get(flags)) {
|
||||
return Annotations.EMPTY
|
||||
}
|
||||
return NonEmptyDeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
||||
return NonEmptyDeserializedAnnotations(c.storageManager) {
|
||||
c.containingDeclaration.asProtoContainer()?.let {
|
||||
c.components.annotationAndConstantLoader.loadCallableAnnotations(it, proto, kind).toList()
|
||||
}.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPropertyFieldAnnotations(proto: ProtoBuf.Property, isDelegate: Boolean): Annotations {
|
||||
if (!Flags.HAS_ANNOTATIONS.get(proto.flags)) {
|
||||
return Annotations.EMPTY
|
||||
}
|
||||
return NonEmptyDeserializedAnnotations(c.storageManager) {
|
||||
c.containingDeclaration.asProtoContainer()?.let {
|
||||
if (isDelegate) {
|
||||
c.components.annotationAndConstantLoader.loadPropertyDelegateFieldAnnotations(it, proto).toList()
|
||||
} else {
|
||||
c.components.annotationAndConstantLoader.loadPropertyBackingFieldAnnotations(it, proto).toList()
|
||||
}
|
||||
}.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getReceiverParameterAnnotations(proto: MessageLite, kind: AnnotatedCallableKind): Annotations =
|
||||
DeserializedAnnotations(c.storageManager) {
|
||||
c.containingDeclaration.asProtoContainer()?.let {
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter
|
||||
@@ -36,7 +35,7 @@ class DeserializationComponents(
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val configuration: DeserializationConfiguration,
|
||||
val classDataFinder: ClassDataFinder,
|
||||
val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>,
|
||||
val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>,
|
||||
val packageFragmentProvider: PackageFragmentProvider,
|
||||
val localClassifierTypeSettings: LocalClassifierTypeSettings,
|
||||
val errorReporter: ErrorReporter,
|
||||
|
||||
-26
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
|
||||
@@ -42,28 +41,3 @@ class NonEmptyDeserializedAnnotations(
|
||||
) : DeserializedAnnotations(storageManager, compute) {
|
||||
override fun isEmpty(): Boolean = false
|
||||
}
|
||||
|
||||
open class DeserializedAnnotationsWithPossibleTargets(
|
||||
storageManager: StorageManager,
|
||||
compute: () -> List<AnnotationWithTarget>
|
||||
) : Annotations {
|
||||
private val annotations by storageManager.createLazyValue(compute)
|
||||
|
||||
override fun isEmpty(): Boolean = annotations.isEmpty()
|
||||
|
||||
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? =
|
||||
annotations.firstOrNull { (annotation, target) -> target == null && annotation.fqName == fqName }?.annotation
|
||||
|
||||
override fun getUseSiteTargetedAnnotations(): List<AnnotationWithTarget> = annotations.filter { it.target != null }
|
||||
|
||||
override fun iterator(): Iterator<AnnotationDescriptor> {
|
||||
return annotations.asSequence().filter { it.target == null }.map { it.annotation }.iterator()
|
||||
}
|
||||
}
|
||||
|
||||
class NonEmptyDeserializedAnnotationsWithPossibleTargets(
|
||||
storageManager: StorageManager,
|
||||
compute: () -> List<AnnotationWithTarget>
|
||||
) : DeserializedAnnotationsWithPossibleTargets(storageManager, compute) {
|
||||
override fun isEmpty(): Boolean = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user