From 98232265d71e001be886d71b4913cc133bf128c8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 22 Aug 2018 19:31:58 +0200 Subject: [PATCH] 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 --- ...tBinaryClassAnnotationAndConstantLoader.kt | 88 +++++++++---------- ...aryClassAnnotationAndConstantLoaderImpl.kt | 19 +--- .../AnnotationAndConstantLoader.kt | 14 ++- .../AnnotationAndConstantLoaderImpl.kt | 13 ++- .../deserialization/MemberDeserializer.kt | 35 ++++---- .../serialization/deserialization/context.kt | 3 +- .../descriptors/DeserializedAnnotations.kt | 26 ------ .../classFile/KotlinClsStubBuilder.kt | 12 +-- .../AnnotationLoaderForStubBuilderImpl.kt | 15 ++-- .../stubBuilder/CallableClsStubBuilder.kt | 19 ++-- .../stubBuilder/ClsStubBuilderContext.kt | 2 +- 11 files changed, 112 insertions(+), 134 deletions(-) diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index fd445d350da..c105c8c27c3 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.builtins.UnsignedTypes 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.JvmAnnotationNames import org.jetbrains.kotlin.metadata.ProtoBuf @@ -38,10 +37,10 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.KotlinType import java.util.* -abstract class AbstractBinaryClassAnnotationAndConstantLoader( +abstract class AbstractBinaryClassAnnotationAndConstantLoader( storageManager: StorageManager, private val kotlinClassFinder: KotlinClassFinder -) : AnnotationAndConstantLoader { +) : AnnotationAndConstantLoader { private val storage = storageManager.createMemoizedFunction> { kotlinClass -> loadAnnotationsAndInitializers(kotlinClass) @@ -91,48 +90,50 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader { + override fun loadCallableAnnotations(container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind): List { if (kind == AnnotatedCallableKind.PROPERTY) { - proto as ProtoBuf.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 - }) + return loadPropertyAnnotations(container, proto as ProtoBuf.Property, PropertyRelatedElement.PROPERTY) } 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 = + loadPropertyAnnotations(container, proto, PropertyRelatedElement.BACKING_FIELD) + + override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + 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 { + 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 { @@ -143,11 +144,6 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader, fieldAnnotations: List, - fieldUseSiteTarget: AnnotationUseSiteTarget): List - - protected abstract fun transformAnnotations(annotations: List): List - private fun findClassAndLoadMemberAnnotations( container: ProtoContainer, signature: MemberSignature, diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index c5b35c3c17f..875bc02113b 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt @@ -18,7 +18,9 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.builtins.KotlinBuiltIns 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.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor import org.jetbrains.kotlin.metadata.ProtoBuf @@ -39,7 +41,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( private val notFoundClasses: NotFoundClasses, storageManager: StorageManager, kotlinClassFinder: KotlinClassFinder -) : AbstractBinaryClassAnnotationAndConstantLoader, AnnotationWithTarget>( +) : AbstractBinaryClassAnnotationAndConstantLoader>( storageManager, kotlinClassFinder ) { private val annotationDeserializer = AnnotationDeserializer(module, notFoundClasses) @@ -75,19 +77,6 @@ class BinaryClassAnnotationAndConstantLoaderImpl( } } - override fun loadPropertyAnnotations( - propertyAnnotations: List, - fieldAnnotations: List, - fieldUseSiteTarget: AnnotationUseSiteTarget - ): List { - return propertyAnnotations.map { AnnotationWithTarget(it, null) } + - fieldAnnotations.map { AnnotationWithTarget(it, fieldUseSiteTarget) } - } - - override fun transformAnnotations(annotations: List): List { - return annotations.map { AnnotationWithTarget(it, null) } - } - override fun loadAnnotation( annotationClassId: ClassId, source: SourceElement, diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.kt index d3fbbe53e65..04df924de52 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoader.kt @@ -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 { +interface AnnotationAndConstantLoader { fun loadClassAnnotations( container: ProtoContainer.Class ): List @@ -32,7 +32,17 @@ interface AnnotationAndConstantLoader { container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind - ): List + ): List + + fun loadPropertyBackingFieldAnnotations( + container: ProtoContainer, + proto: ProtoBuf.Property + ): List + + fun loadPropertyDelegateFieldAnnotations( + container: ProtoContainer, + proto: ProtoBuf.Property + ): List fun loadEnumEntryAnnotations( container: ProtoContainer, diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt index 18eae62bc01..69b7f4b5fbe 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt @@ -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, AnnotationWithTarget> { +) : AnnotationAndConstantLoader> { private val deserializer = AnnotationDeserializer(module, notFoundClasses) override fun loadClassAnnotations(container: ProtoContainer.Class): List { @@ -44,7 +43,7 @@ class AnnotationAndConstantLoaderImpl( container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind - ): List { + ): List { 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 = + emptyList() + + override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + emptyList() + override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List { val annotations = proto.getExtension(protocol.enumEntryAnnotation).orEmpty() return annotations.map { annotationProto -> diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index 8acb23ffa68..e7a26d476a1 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -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 { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index b75722b2983..15cfd6eeead 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -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, AnnotationWithTarget>, + val annotationAndConstantLoader: AnnotationAndConstantLoader>, val packageFragmentProvider: PackageFragmentProvider, val localClassifierTypeSettings: LocalClassifierTypeSettings, val errorReporter: ErrorReporter, diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedAnnotations.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedAnnotations.kt index 865ffe8231c..d634e26a1b0 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedAnnotations.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedAnnotations.kt @@ -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 -) : 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 = annotations.filter { it.target != null } - - override fun iterator(): Iterator { - return annotations.asSequence().filter { it.target == null }.map { it.annotation }.iterator() - } -} - -class NonEmptyDeserializedAnnotationsWithPossibleTargets( - storageManager: StorageManager, - compute: () -> List -) : DeserializedAnnotationsWithPossibleTargets(storageManager, compute) { - override fun isEmpty(): Boolean = false -} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt index bb2513f23e7..e723213483e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt @@ -23,7 +23,6 @@ import com.intellij.psi.impl.compiled.ClassFileStubBuilder import com.intellij.psi.stubs.PsiFileStub import com.intellij.util.indexing.FileContent 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.decompiler.stubBuilder.* import org.jetbrains.kotlin.load.kotlin.* @@ -125,7 +124,7 @@ class AnnotationLoaderForClassFileStubBuilder( kotlinClassFinder: KotlinClassFinder, private val cachedFile: VirtualFile, private val cachedFileContent: ByteArray -) : AbstractBinaryClassAnnotationAndConstantLoader(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) { +) : AbstractBinaryClassAnnotationAndConstantLoader(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) { override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? { if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) { @@ -147,13 +146,4 @@ class AnnotationLoaderForClassFileStubBuilder( result.add(annotationClassId) return null } - - override fun loadPropertyAnnotations( - propertyAnnotations: List, fieldAnnotations: List, fieldUseSiteTarget: AnnotationUseSiteTarget - ): List { - return propertyAnnotations.map { ClassIdWithTarget(it, null) } + - fieldAnnotations.map { ClassIdWithTarget(it, fieldUseSiteTarget ) } - } - - override fun transformAnnotations(annotations: List) = annotations.map { ClassIdWithTarget(it, null) } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/AnnotationLoaderForStubBuilderImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/AnnotationLoaderForStubBuilderImpl.kt index 7fcdd45cbe8..00e5f8871ef 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/AnnotationLoaderForStubBuilderImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/common/AnnotationLoaderForStubBuilderImpl.kt @@ -16,7 +16,6 @@ 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.deserialization.NameResolver import org.jetbrains.kotlin.name.ClassId @@ -30,7 +29,7 @@ import org.jetbrains.kotlin.types.KotlinType class AnnotationLoaderForStubBuilderImpl( private val protocol: SerializerExtensionProtocol -) : AnnotationAndConstantLoader { +) : AnnotationAndConstantLoader { override fun loadClassAnnotations(container: ProtoContainer.Class): List = container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) } @@ -39,18 +38,22 @@ class AnnotationLoaderForStubBuilderImpl( container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind - ): List { + ): List { val annotations = when (proto) { is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation) is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation) is ProtoBuf.Property -> proto.getExtension(protocol.propertyAnnotation) else -> error("Unknown message: $proto") }.orEmpty() - return annotations.map { - ClassIdWithTarget(container.nameResolver.getClassId(it.id), null) - } + return annotations.map { container.nameResolver.getClassId(it.id) } } + override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + emptyList() + + override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + emptyList() + override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List = proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/CallableClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/CallableClsStubBuilder.kt index 6a7643d17b0..b3d41763fc4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/CallableClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/CallableClsStubBuilder.kt @@ -166,7 +166,7 @@ private class FunctionClsStubBuilder( val annotationIds = c.components.annotationLoader.loadCallableAnnotations( protoContainer, functionProto, AnnotatedCallableKind.FUNCTION ) - createTargetedAnnotationStubs(annotationIds, modifierListStubImpl) + createAnnotationStubs(annotationIds, modifierListStubImpl) } override fun doCreateCallableStub(parent: StubElement): StubElement { @@ -219,10 +219,17 @@ private class PropertyClsStubBuilder( listOf(VISIBILITY, LATEINIT, EXTERNAL_PROPERTY) + constModifier + modalityModifier ) - val annotationIds = c.components.annotationLoader.loadCallableAnnotations( - protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY - ) - createTargetedAnnotationStubs(annotationIds, modifierListStubImpl) + val propertyAnnotations = + c.components.annotationLoader.loadCallableAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY) + val backingFieldAnnotations = + 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): StubElement { @@ -268,7 +275,7 @@ private class ConstructorClsStubBuilder( val annotationIds = c.components.annotationLoader.loadCallableAnnotations( protoContainer, constructorProto, AnnotatedCallableKind.FUNCTION ) - createTargetedAnnotationStubs(annotationIds, modifierListStubImpl) + createAnnotationStubs(annotationIds, modifierListStubImpl) } override fun doCreateCallableStub(parent: StubElement): StubElement { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt index 40d822bb18e..3db6ffcd5a1 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt @@ -33,7 +33,7 @@ data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSite class ClsStubBuilderComponents( val classDataFinder: ClassDataFinder, - val annotationLoader: AnnotationAndConstantLoader, + val annotationLoader: AnnotationAndConstantLoader, val virtualFileForDebug: VirtualFile ) { fun createContext(