[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
@@ -9,7 +9,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
public abstract interface T : R|kotlin/Any| {
@R|test/Anno|(s = String(foo)) public abstract fun foo(): R|kotlin/Array<kotlin/Array<kotlin/Array<test/T>>>|
public abstract val bar: R|kotlin/Array<kotlin/Array<kotlin/BooleanArray>>|
@PROPERTY:R|test/Anno|(s = String(bar)) public abstract val bar: R|kotlin/Array<kotlin/Array<kotlin/BooleanArray>>|
public get(): R|kotlin/Array<kotlin/Array<kotlin/BooleanArray>>|
}
@@ -5,7 +5,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
public final class Class : R|kotlin/Any| {
public abstract interface Trait : R|kotlin/Any| {
public abstract val property: R|kotlin/Int|
@PROPERTY:R|test/Anno|() public abstract val property: R|kotlin/Int|
public get(): R|kotlin/Int|
}
@@ -4,7 +4,7 @@ public final annotation class Anno : R|kotlin/Annotation| {
}
public abstract interface Trait : R|kotlin/Any| {
public abstract val property: R|kotlin/Int|
@PROPERTY:R|test/Anno|() public abstract val property: R|kotlin/Int|
public get(): R|kotlin/Int|
}
@@ -19,11 +19,11 @@ public abstract interface I : R|kotlin/Any| {
@R|test/A|(value = String(getter)) public get(): R|kotlin/Int|
@R|test/B|(value = <implicitArrayOf>(String(setter))) public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
public abstract var propertyAndGetter: R|kotlin/Int|
@PROPERTY:R|test/A|(value = String(property)) public abstract var propertyAndGetter: R|kotlin/Int|
@R|test/B|(value = <implicitArrayOf>(String(getter))) public get(): R|kotlin/Int|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
public abstract var propertyAndSetter: R|kotlin/Int|
@PROPERTY:R|test/A|(value = String(property)) public abstract var propertyAndSetter: R|kotlin/Int|
public get(): R|kotlin/Int|
@R|test/B|(value = <implicitArrayOf>(String(setter))) public set(<set-?>: R|kotlin/Int|): R|kotlin/Unit|
@@ -78,6 +78,7 @@ abstract class AbstractAnnotationDeserializer(
open fun loadPropertyAnnotations(
containerSource: DeserializedContainerSource?,
propertyProto: ProtoBuf.Property,
containingClassProto: ProtoBuf.Class?,
nameResolver: NameResolver,
typeTable: TypeTable
): List<FirAnnotationCall> {
@@ -311,7 +311,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir }
annotations +=
c.annotationDeserializer.loadPropertyAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
c.annotationDeserializer.loadPropertyAnnotations(c.containerSource, proto, classProto, local.nameResolver, local.typeTable)
annotations +=
c.annotationDeserializer.loadPropertyBackingFieldAnnotations(
c.containerSource, proto, local.nameResolver, local.typeTable
@@ -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,
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// !JVM_DEFAULT_MODE: enable
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// !JVM_DEFAULT_MODE: enable
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// !JVM_DEFAULT_MODE: enable
// JVM_TARGET: 1.8
// WITH_RUNTIME