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:
Alexander Udalov
2018-08-22 19:31:58 +02:00
parent ca3cff9a93
commit 98232265d7
11 changed files with 112 additions and 134 deletions
@@ -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<ClassId, Unit, ClassIdWithTarget>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) {
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit>(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<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) }
}
@@ -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<ClassId, Unit, ClassIdWithTarget> {
) : AnnotationAndConstantLoader<ClassId, Unit> {
override fun loadClassAnnotations(container: ProtoContainer.Class): List<ClassId> =
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<ClassIdWithTarget> {
): List<ClassId> {
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<ClassId> =
emptyList()
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<ClassId> =
emptyList()
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<ClassId> =
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
@@ -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<out PsiElement>): StubElement<out PsiElement> {
@@ -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<out PsiElement>): StubElement<out PsiElement> {
@@ -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<out PsiElement>): StubElement<out PsiElement> {
@@ -33,7 +33,7 @@ data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSite
class ClsStubBuilderComponents(
val classDataFinder: ClassDataFinder,
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit, ClassIdWithTarget>,
val annotationLoader: AnnotationAndConstantLoader<ClassId, Unit>,
val virtualFileForDebug: VirtualFile
) {
fun createContext(