[FIR] Properly deserialize annotations of properties in interfaces

This commit is contained in:
Dmitriy Novozhilov
2021-03-01 13:11:42 +03:00
committed by TeamCityServer
parent c6f56b9809
commit a7e6667648
11 changed files with 28 additions and 14 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.MemberSignature
import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -26,12 +27,20 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
class JvmBinaryAnnotationDeserializer(
val session: FirSession,
kotlinBinaryClass: KotlinJvmBinaryClass,
kotlinClassFinder: KotlinClassFinder,
byteContent: ByteArray?
) : AbstractAnnotationDeserializer(session) {
private val annotationInfo by lazy(LazyThreadSafetyMode.PUBLICATION) {
session.loadMemberAnnotations(kotlinBinaryClass, byteContent)
}
private val annotationInfoForDefaultImpls by lazy(LazyThreadSafetyMode.PUBLICATION) {
val defaultImplsClassId = kotlinBinaryClass.classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME))
val (defaultImplsClass, defaultImplsByteContent) = kotlinClassFinder.findKotlinClassOrContent(defaultImplsClassId) as? KotlinClassFinder.Result.KotlinClass
?: return@lazy null
session.loadMemberAnnotations(defaultImplsClass, defaultImplsByteContent)
}
override fun inheritAnnotationInfo(parent: AbstractAnnotationDeserializer) {
if (parent is JvmBinaryAnnotationDeserializer) {
annotationInfo.memberAnnotations.putAll(parent.annotationInfo.memberAnnotations)
@@ -66,11 +75,13 @@ class JvmBinaryAnnotationDeserializer(
override fun loadPropertyAnnotations(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
containingClassProto: ProtoBuf.Class?,
nameResolver: NameResolver,
typeTable: TypeTable
): List<FirAnnotationCall> {
val signature = getPropertySignature(propertyProto, nameResolver, typeTable, synthetic = true) ?: return emptyList()
return findJvmBinaryClassAndLoadMemberAnnotations(signature).map {
val classIsInterface = containingClassProto?.let { Flags.CLASS_KIND.get(it.flags) == ProtoBuf.Class.Kind.INTERFACE } ?: false
return findJvmBinaryClassAndLoadMemberAnnotations(signature, searchInDefaultImpls = classIsInterface).map {
buildAnnotationCall {
annotationTypeRef = it.annotationTypeRef
argumentList = it.argumentList
@@ -253,9 +264,14 @@ class JvmBinaryAnnotationDeserializer(
}
private fun findJvmBinaryClassAndLoadMemberAnnotations(
memberSignature: MemberSignature
memberSignature: MemberSignature, searchInDefaultImpls: Boolean = false
): List<FirAnnotationCall> {
return annotationInfo.memberAnnotations[memberSignature] ?: emptyList()
val info = if (searchInDefaultImpls) {
annotationInfoForDefaultImpls ?: return emptyList()
} else {
annotationInfo
}
return info.memberAnnotations[memberSignature] ?: emptyList()
}
}
@@ -112,7 +112,7 @@ class KotlinDeserializedJvmSymbolsProvider(
packageProto,
FirDeserializationContext.createForPackage(
packageFqName, packageProto, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, byteContent),
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, kotlinClassFinder, byteContent),
FirConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
source
),
@@ -197,7 +197,7 @@ class KotlinDeserializedJvmSymbolsProvider(
val symbol = FirRegularClassSymbol(classId)
deserializeClassToSymbol(
classId, classProto, symbol, nameResolver, session,
JvmBinaryAnnotationDeserializer(session, kotlinClass.kotlinJvmBinaryClass, kotlinClass.byteContent),
JvmBinaryAnnotationDeserializer(session, kotlinClass.kotlinJvmBinaryClass, kotlinClassFinder, kotlinClass.byteContent),
kotlinScopeProvider,
parentContext, KotlinJvmBinarySourceElement(kotlinClass.kotlinJvmBinaryClass),
deserializeNestedClass = this::getClass,