diff --git a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/MultiDimensionalArrayMethod.txt b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/MultiDimensionalArrayMethod.txt index 4aa687eec30..5f3a5cea75b 100644 --- a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/MultiDimensionalArrayMethod.txt +++ b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/MultiDimensionalArrayMethod.txt @@ -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>>| - public abstract val bar: R|kotlin/Array>| + @PROPERTY:R|test/Anno|(s = String(bar)) public abstract val bar: R|kotlin/Array>| public get(): R|kotlin/Array>| } diff --git a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.txt b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.txt index 2ec73459728..0cab4028728 100644 --- a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.txt +++ b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.txt @@ -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| } diff --git a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/Trait.txt b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/Trait.txt index c45e763d696..256705eb4f3 100644 --- a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/Trait.txt +++ b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/propertiesWithoutBackingFields/Trait.txt @@ -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| } diff --git a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/withUseSiteTarget/PropertyAndAccessor.txt b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/withUseSiteTarget/PropertyAndAccessor.txt index 575844f52c5..208116d365c 100644 --- a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/withUseSiteTarget/PropertyAndAccessor.txt +++ b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/withUseSiteTarget/PropertyAndAccessor.txt @@ -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 = (String(setter))) public 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 = (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 = (String(setter))) public set(: R|kotlin/Int|): R|kotlin/Unit| diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index 4ba6d4d960b..3f83309f35d 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -78,6 +78,7 @@ abstract class AbstractAnnotationDeserializer( open fun loadPropertyAnnotations( containerSource: DeserializedContainerSource?, propertyProto: ProtoBuf.Property, + containingClassProto: ProtoBuf.Class?, nameResolver: NameResolver, typeTable: TypeTable ): List { diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index 6a356e01633..d2c7b473cdb 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -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 diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt index d132752d9a5..c9a8b148c8e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt @@ -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 { 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 { - return annotationInfo.memberAnnotations[memberSignature] ?: emptyList() + val info = if (searchInDefaultImpls) { + annotationInfoForDefaultImpls ?: return emptyList() + } else { + annotationInfo + } + return info.memberAnnotations[memberSignature] ?: emptyList() } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt index 36f6d1fd49e..edd1063446d 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt @@ -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, diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccess.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccess.kt index 0b7a1adc24d..c401f612bd7 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccess.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccess.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // !JVM_DEFAULT_MODE: enable // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface.kt index c3561e2e0cd..aec8cdfc486 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // !JVM_DEFAULT_MODE: enable // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt index 6a7ac09d6f6..ed13b6324a1 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/jvm8/defaults/superPropAccessFromInterface2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // !JVM_DEFAULT_MODE: enable // JVM_TARGET: 1.8 // WITH_RUNTIME