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:
+42
-46
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.load.kotlin
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
@@ -38,10 +37,10 @@ import org.jetbrains.kotlin.storage.StorageManager
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any, T : Any>(
|
abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
private val kotlinClassFinder: KotlinClassFinder
|
private val kotlinClassFinder: KotlinClassFinder
|
||||||
) : AnnotationAndConstantLoader<A, C, T> {
|
) : AnnotationAndConstantLoader<A, C> {
|
||||||
private val storage = storageManager.createMemoizedFunction<KotlinJvmBinaryClass, Storage<A, C>> {
|
private val storage = storageManager.createMemoizedFunction<KotlinJvmBinaryClass, Storage<A, C>> {
|
||||||
kotlinClass ->
|
kotlinClass ->
|
||||||
loadAnnotationsAndInitializers(kotlinClass)
|
loadAnnotationsAndInitializers(kotlinClass)
|
||||||
@@ -91,48 +90,50 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadCallableAnnotations(container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind): List<T> {
|
override fun loadCallableAnnotations(container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind): List<A> {
|
||||||
if (kind == AnnotatedCallableKind.PROPERTY) {
|
if (kind == AnnotatedCallableKind.PROPERTY) {
|
||||||
proto as ProtoBuf.Property
|
return loadPropertyAnnotations(container, proto as ProtoBuf.Property, PropertyRelatedElement.PROPERTY)
|
||||||
|
|
||||||
val syntheticFunctionSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, synthetic = true)
|
|
||||||
val fieldSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, field = true)
|
|
||||||
|
|
||||||
val isConst = Flags.IS_CONST.get(proto.flags)
|
|
||||||
val isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
|
|
||||||
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
|
||||||
findClassAndLoadMemberAnnotations(
|
|
||||||
container,
|
|
||||||
sig,
|
|
||||||
property = true,
|
|
||||||
isConst = isConst,
|
|
||||||
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
|
||||||
)
|
|
||||||
}.orEmpty()
|
|
||||||
|
|
||||||
val fieldAnnotations = fieldSignature?.let { sig ->
|
|
||||||
findClassAndLoadMemberAnnotations(
|
|
||||||
container,
|
|
||||||
sig,
|
|
||||||
property = true,
|
|
||||||
field = true,
|
|
||||||
isConst = isConst,
|
|
||||||
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
|
||||||
)
|
|
||||||
}.orEmpty()
|
|
||||||
|
|
||||||
// TODO: check delegate presence in some other way
|
|
||||||
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations,
|
|
||||||
if (fieldSignature?.signature?.contains(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX) ?: false) {
|
|
||||||
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
AnnotationUseSiteTarget.FIELD
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList()
|
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList()
|
||||||
return transformAnnotations(findClassAndLoadMemberAnnotations(container, signature))
|
return findClassAndLoadMemberAnnotations(container, signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<A> =
|
||||||
|
loadPropertyAnnotations(container, proto, PropertyRelatedElement.BACKING_FIELD)
|
||||||
|
|
||||||
|
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<A> =
|
||||||
|
loadPropertyAnnotations(container, proto, PropertyRelatedElement.DELEGATE_FIELD)
|
||||||
|
|
||||||
|
private enum class PropertyRelatedElement {
|
||||||
|
PROPERTY,
|
||||||
|
BACKING_FIELD,
|
||||||
|
DELEGATE_FIELD,
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadPropertyAnnotations(container: ProtoContainer, proto: ProtoBuf.Property, element: PropertyRelatedElement): List<A> {
|
||||||
|
val isConst = Flags.IS_CONST.get(proto.flags)
|
||||||
|
val isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
|
||||||
|
if (element == PropertyRelatedElement.PROPERTY) {
|
||||||
|
val syntheticFunctionSignature =
|
||||||
|
getPropertySignature(proto, container.nameResolver, container.typeTable, synthetic = true) ?: return emptyList()
|
||||||
|
return findClassAndLoadMemberAnnotations(
|
||||||
|
container, syntheticFunctionSignature, property = true, isConst = isConst,
|
||||||
|
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val fieldSignature =
|
||||||
|
getPropertySignature(proto, container.nameResolver, container.typeTable, field = true) ?: return emptyList()
|
||||||
|
|
||||||
|
// TODO: check delegate presence in some other way
|
||||||
|
val isDelegated = JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX in fieldSignature.signature
|
||||||
|
if (isDelegated != (element == PropertyRelatedElement.DELEGATE_FIELD)) return emptyList()
|
||||||
|
|
||||||
|
return findClassAndLoadMemberAnnotations(
|
||||||
|
container, fieldSignature, property = true, field = true, isConst = isConst,
|
||||||
|
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<A> {
|
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<A> {
|
||||||
@@ -143,11 +144,6 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
return findClassAndLoadMemberAnnotations(container, signature)
|
return findClassAndLoadMemberAnnotations(container, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun loadPropertyAnnotations(propertyAnnotations: List<A>, fieldAnnotations: List<A>,
|
|
||||||
fieldUseSiteTarget: AnnotationUseSiteTarget): List<T>
|
|
||||||
|
|
||||||
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
|
||||||
|
|
||||||
private fun findClassAndLoadMemberAnnotations(
|
private fun findClassAndLoadMemberAnnotations(
|
||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
signature: MemberSignature,
|
signature: MemberSignature,
|
||||||
|
|||||||
+4
-15
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.load.kotlin
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.*
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
@@ -39,7 +41,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
|
|||||||
private val notFoundClasses: NotFoundClasses,
|
private val notFoundClasses: NotFoundClasses,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
kotlinClassFinder: KotlinClassFinder
|
kotlinClassFinder: KotlinClassFinder
|
||||||
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>(
|
) : AbstractBinaryClassAnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>(
|
||||||
storageManager, kotlinClassFinder
|
storageManager, kotlinClassFinder
|
||||||
) {
|
) {
|
||||||
private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses)
|
private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses)
|
||||||
@@ -75,19 +77,6 @@ class BinaryClassAnnotationAndConstantLoaderImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadPropertyAnnotations(
|
|
||||||
propertyAnnotations: List<AnnotationDescriptor>,
|
|
||||||
fieldAnnotations: List<AnnotationDescriptor>,
|
|
||||||
fieldUseSiteTarget: AnnotationUseSiteTarget
|
|
||||||
): List<AnnotationWithTarget> {
|
|
||||||
return propertyAnnotations.map { AnnotationWithTarget(it, null) } +
|
|
||||||
fieldAnnotations.map { AnnotationWithTarget(it, fieldUseSiteTarget) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transformAnnotations(annotations: List<AnnotationDescriptor>): List<AnnotationWithTarget> {
|
|
||||||
return annotations.map { AnnotationWithTarget(it, null) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadAnnotation(
|
override fun loadAnnotation(
|
||||||
annotationClassId: ClassId,
|
annotationClassId: ClassId,
|
||||||
source: SourceElement,
|
source: SourceElement,
|
||||||
|
|||||||
+12
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
|
|
||||||
// The MessageLite instance everywhere should be Constructor, Function or Property
|
// The MessageLite instance everywhere should be Constructor, Function or Property
|
||||||
// TODO: simplify this interface
|
// 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(
|
fun loadClassAnnotations(
|
||||||
container: ProtoContainer.Class
|
container: ProtoContainer.Class
|
||||||
): List<A>
|
): List<A>
|
||||||
@@ -32,7 +32,17 @@ interface AnnotationAndConstantLoader<out A : Any, out C : Any, out T : Any> {
|
|||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
proto: MessageLite,
|
proto: MessageLite,
|
||||||
kind: AnnotatedCallableKind
|
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(
|
fun loadEnumEntryAnnotations(
|
||||||
container: ProtoContainer,
|
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.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
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.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||||
@@ -32,7 +31,7 @@ class AnnotationAndConstantLoaderImpl(
|
|||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
notFoundClasses: NotFoundClasses,
|
notFoundClasses: NotFoundClasses,
|
||||||
private val protocol: SerializerExtensionProtocol
|
private val protocol: SerializerExtensionProtocol
|
||||||
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget> {
|
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>> {
|
||||||
private val deserializer = AnnotationDeserializer(module, notFoundClasses)
|
private val deserializer = AnnotationDeserializer(module, notFoundClasses)
|
||||||
|
|
||||||
override fun loadClassAnnotations(container: ProtoContainer.Class): List<AnnotationDescriptor> {
|
override fun loadClassAnnotations(container: ProtoContainer.Class): List<AnnotationDescriptor> {
|
||||||
@@ -44,7 +43,7 @@ class AnnotationAndConstantLoaderImpl(
|
|||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
proto: MessageLite,
|
proto: MessageLite,
|
||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): List<AnnotationWithTarget> {
|
): List<AnnotationDescriptor> {
|
||||||
val annotations = when (proto) {
|
val annotations = when (proto) {
|
||||||
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
|
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
|
||||||
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
|
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
|
||||||
@@ -52,10 +51,16 @@ class AnnotationAndConstantLoaderImpl(
|
|||||||
else -> error("Unknown message: $proto")
|
else -> error("Unknown message: $proto")
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
return annotations.map { annotationProto ->
|
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> {
|
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<AnnotationDescriptor> {
|
||||||
val annotations = proto.getExtension(protocol.enumEntryAnnotation).orEmpty()
|
val annotations = proto.getExtension(protocol.enumEntryAnnotation).orEmpty()
|
||||||
return annotations.map { annotationProto ->
|
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.builtins.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
||||||
@@ -31,11 +30,9 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
fun loadProperty(proto: ProtoBuf.Property): PropertyDescriptor {
|
fun loadProperty(proto: ProtoBuf.Property): PropertyDescriptor {
|
||||||
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
|
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
|
||||||
|
|
||||||
val propertyAnnotations = getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY)
|
|
||||||
|
|
||||||
val property = DeserializedPropertyDescriptor(
|
val property = DeserializedPropertyDescriptor(
|
||||||
c.containingDeclaration, null,
|
c.containingDeclaration, null,
|
||||||
propertyAnnotations,
|
getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
|
||||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||||
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
||||||
Flags.IS_VAR.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(
|
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)
|
property.checkExperimentalCoroutine(local.typeDeserializer)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -358,13 +348,28 @@ class MemberDeserializer(private val c: DeserializationContext) {
|
|||||||
if (!Flags.HAS_ANNOTATIONS.get(flags)) {
|
if (!Flags.HAS_ANNOTATIONS.get(flags)) {
|
||||||
return Annotations.EMPTY
|
return Annotations.EMPTY
|
||||||
}
|
}
|
||||||
return NonEmptyDeserializedAnnotationsWithPossibleTargets(c.storageManager) {
|
return NonEmptyDeserializedAnnotations(c.storageManager) {
|
||||||
c.containingDeclaration.asProtoContainer()?.let {
|
c.containingDeclaration.asProtoContainer()?.let {
|
||||||
c.components.annotationAndConstantLoader.loadCallableAnnotations(it, proto, kind).toList()
|
c.components.annotationAndConstantLoader.loadCallableAnnotations(it, proto, kind).toList()
|
||||||
}.orEmpty()
|
}.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 =
|
private fun getReceiverParameterAnnotations(proto: MessageLite, kind: AnnotatedCallableKind): Annotations =
|
||||||
DeserializedAnnotations(c.storageManager) {
|
DeserializedAnnotations(c.storageManager) {
|
||||||
c.containingDeclaration.asProtoContainer()?.let {
|
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.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
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.AdditionalClassPartsProvider
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory
|
import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter
|
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter
|
||||||
@@ -36,7 +35,7 @@ class DeserializationComponents(
|
|||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptor: ModuleDescriptor,
|
||||||
val configuration: DeserializationConfiguration,
|
val configuration: DeserializationConfiguration,
|
||||||
val classDataFinder: ClassDataFinder,
|
val classDataFinder: ClassDataFinder,
|
||||||
val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>,
|
val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>>,
|
||||||
val packageFragmentProvider: PackageFragmentProvider,
|
val packageFragmentProvider: PackageFragmentProvider,
|
||||||
val localClassifierTypeSettings: LocalClassifierTypeSettings,
|
val localClassifierTypeSettings: LocalClassifierTypeSettings,
|
||||||
val errorReporter: ErrorReporter,
|
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.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.storage.getValue
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
|
|
||||||
@@ -42,28 +41,3 @@ class NonEmptyDeserializedAnnotations(
|
|||||||
) : DeserializedAnnotations(storageManager, compute) {
|
) : DeserializedAnnotations(storageManager, compute) {
|
||||||
override fun isEmpty(): Boolean = false
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-11
@@ -23,7 +23,6 @@ import com.intellij.psi.impl.compiled.ClassFileStubBuilder
|
|||||||
import com.intellij.psi.stubs.PsiFileStub
|
import com.intellij.psi.stubs.PsiFileStub
|
||||||
import com.intellij.util.indexing.FileContent
|
import com.intellij.util.indexing.FileContent
|
||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.*
|
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.*
|
import org.jetbrains.kotlin.load.kotlin.*
|
||||||
@@ -125,7 +124,7 @@ class AnnotationLoaderForClassFileStubBuilder(
|
|||||||
kotlinClassFinder: KotlinClassFinder,
|
kotlinClassFinder: KotlinClassFinder,
|
||||||
private val cachedFile: VirtualFile,
|
private val cachedFile: VirtualFile,
|
||||||
private val cachedFileContent: ByteArray
|
private val cachedFileContent: ByteArray
|
||||||
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) {
|
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) {
|
||||||
|
|
||||||
override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? {
|
override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? {
|
||||||
if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) {
|
if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) {
|
||||||
@@ -147,13 +146,4 @@ class AnnotationLoaderForClassFileStubBuilder(
|
|||||||
result.add(annotationClassId)
|
result.add(annotationClassId)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadPropertyAnnotations(
|
|
||||||
propertyAnnotations: List<ClassId>, fieldAnnotations: List<ClassId>, fieldUseSiteTarget: AnnotationUseSiteTarget
|
|
||||||
): List<ClassIdWithTarget> {
|
|
||||||
return propertyAnnotations.map { ClassIdWithTarget(it, null) } +
|
|
||||||
fieldAnnotations.map { ClassIdWithTarget(it, fieldUseSiteTarget ) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun transformAnnotations(annotations: List<ClassId>) = annotations.map { ClassIdWithTarget(it, null) }
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-6
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.decompiler.common
|
package org.jetbrains.kotlin.idea.decompiler.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.decompiler.stubBuilder.ClassIdWithTarget
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -30,7 +29,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
|
|
||||||
class AnnotationLoaderForStubBuilderImpl(
|
class AnnotationLoaderForStubBuilderImpl(
|
||||||
private val protocol: SerializerExtensionProtocol
|
private val protocol: SerializerExtensionProtocol
|
||||||
) : AnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget> {
|
) : AnnotationAndConstantLoader<ClassId, Unit> {
|
||||||
|
|
||||||
override fun loadClassAnnotations(container: ProtoContainer.Class): List<ClassId> =
|
override fun loadClassAnnotations(container: ProtoContainer.Class): List<ClassId> =
|
||||||
container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
|
container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
|
||||||
@@ -39,18 +38,22 @@ class AnnotationLoaderForStubBuilderImpl(
|
|||||||
container: ProtoContainer,
|
container: ProtoContainer,
|
||||||
proto: MessageLite,
|
proto: MessageLite,
|
||||||
kind: AnnotatedCallableKind
|
kind: AnnotatedCallableKind
|
||||||
): List<ClassIdWithTarget> {
|
): List<ClassId> {
|
||||||
val annotations = when (proto) {
|
val annotations = when (proto) {
|
||||||
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
|
is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation)
|
||||||
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
|
is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation)
|
||||||
is ProtoBuf.Property -> proto.getExtension(protocol.propertyAnnotation)
|
is ProtoBuf.Property -> proto.getExtension(protocol.propertyAnnotation)
|
||||||
else -> error("Unknown message: $proto")
|
else -> error("Unknown message: $proto")
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
return annotations.map {
|
return annotations.map { container.nameResolver.getClassId(it.id) }
|
||||||
ClassIdWithTarget(container.nameResolver.getClassId(it.id), null)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<ClassId> =
|
||||||
|
emptyList()
|
||||||
|
|
||||||
|
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<ClassId> =
|
||||||
|
emptyList()
|
||||||
|
|
||||||
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<ClassId> =
|
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<ClassId> =
|
||||||
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
|
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
|
||||||
|
|
||||||
|
|||||||
+13
-6
@@ -166,7 +166,7 @@ private class FunctionClsStubBuilder(
|
|||||||
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
||||||
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
|
protoContainer, functionProto, AnnotatedCallableKind.FUNCTION
|
||||||
)
|
)
|
||||||
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
createAnnotationStubs(annotationIds, modifierListStubImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
@@ -219,10 +219,17 @@ private class PropertyClsStubBuilder(
|
|||||||
listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier
|
listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier
|
||||||
)
|
)
|
||||||
|
|
||||||
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
val propertyAnnotations =
|
||||||
protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY
|
c.components.annotationLoader.loadCallableAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY)
|
||||||
)
|
val backingFieldAnnotations =
|
||||||
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
c.components.annotationLoader.loadPropertyBackingFieldAnnotations(protoContainer, propertyProto)
|
||||||
|
val delegateFieldAnnotations =
|
||||||
|
c.components.annotationLoader.loadPropertyDelegateFieldAnnotations(protoContainer, propertyProto)
|
||||||
|
val allAnnotations =
|
||||||
|
propertyAnnotations.map { ClassIdWithTarget(it, null) } +
|
||||||
|
backingFieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.FIELD) } +
|
||||||
|
delegateFieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD) }
|
||||||
|
createTargetedAnnotationStubs(allAnnotations, modifierListStubImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
@@ -268,7 +275,7 @@ private class ConstructorClsStubBuilder(
|
|||||||
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
val annotationIds = c.components.annotationLoader.loadCallableAnnotations(
|
||||||
protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION
|
protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION
|
||||||
)
|
)
|
||||||
createTargetedAnnotationStubs(annotationIds, modifierListStubImpl)
|
createAnnotationStubs(annotationIds, modifierListStubImpl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSite
|
|||||||
|
|
||||||
class ClsStubBuilderComponents(
|
class ClsStubBuilderComponents(
|
||||||
val classDataFinder: ClassDataFinder,
|
val classDataFinder: ClassDataFinder,
|
||||||
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>,
|
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit>,
|
||||||
val virtualFileForDebug: VirtualFile
|
val virtualFileForDebug: VirtualFile
|
||||||
) {
|
) {
|
||||||
fun createContext(
|
fun createContext(
|
||||||
|
|||||||
Reference in New Issue
Block a user