diff --git a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/parameters/EnumConstructor.txt b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/parameters/EnumConstructor.txt index b53f0e322db..2e200dd4cef 100644 --- a/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/parameters/EnumConstructor.txt +++ b/compiler/fir/analysis-tests/testData/loadCompiledKotlin/annotations/parameters/EnumConstructor.txt @@ -15,7 +15,7 @@ public final enum class E : R|kotlin/Enum| { public final val y: R|kotlin/Int| public get(): R|kotlin/Int| - private constructor(x: R|kotlin/String|, y: R|kotlin/Int|): R|test/E| + private constructor(@R|test/A|() x: R|kotlin/String|, @R|test/B|() y: R|kotlin/Int|): R|test/E| public final static fun values(): R|kotlin/Array| { } 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 0fe1d8fb066..677fcdf317d 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 @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass import org.jetbrains.kotlin.load.kotlin.MemberSignature import org.jetbrains.kotlin.metadata.ProtoBuf -import org.jetbrains.kotlin.metadata.deserialization.NameResolver -import org.jetbrains.kotlin.metadata.deserialization.TypeTable -import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull -import org.jetbrains.kotlin.metadata.deserialization.hasReceiver +import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.name.ClassId @@ -145,28 +142,34 @@ class JvmBinaryAnnotationDeserializer( containerSource: DeserializedContainerSource?, callableProto: MessageLite, valueParameterProto: ProtoBuf.ValueParameter, + classProto: ProtoBuf.Class?, nameResolver: NameResolver, typeTable: TypeTable, kind: CallableKind, parameterIndex: Int, ): List { val methodSignature = getCallableSignature(callableProto, nameResolver, typeTable, kind) ?: return emptyList() - val index = parameterIndex + computeJvmParameterIndexShift(callableProto) + val index = parameterIndex + computeJvmParameterIndexShift(classProto, callableProto) val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, index) return findJvmBinaryClassAndLoadMemberAnnotations(containerSource, paramSignature) } - /* - * TODO: Support container proto and fix index shift for - * constructors of inner classes and enums - * - * See [AbstractBinaryClassAnnotationAndConstantLoader] - */ - private fun computeJvmParameterIndexShift(message: MessageLite): Int { + private fun computeJvmParameterIndexShift(classProto: ProtoBuf.Class?, message: MessageLite): Int { return when (message) { is ProtoBuf.Function -> if (message.hasReceiver()) 1 else 0 is ProtoBuf.Property -> if (message.hasReceiver()) 1 else 0 - is ProtoBuf.Constructor -> 0 + is ProtoBuf.Constructor -> { + assert(classProto != null) { + "Constructor call without information about enclosing Class: $message" + } + val kind = Flags.CLASS_KIND.get(classProto!!.flags) ?: ProtoBuf.Class.Kind.CLASS + val isInner = Flags.IS_INNER.get(classProto.flags) + when { + kind == ProtoBuf.Class.Kind.ENUM_CLASS -> 2 + isInner -> 1 + else -> 0 + } + } else -> throw UnsupportedOperationException("Unsupported message: ${message::class.java}") } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index 1c325219007..e5460fdd597 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -135,6 +135,7 @@ abstract class AbstractAnnotationDeserializer( containerSource: DeserializedContainerSource?, callableProto: MessageLite, valueParameterProto: ProtoBuf.ValueParameter, + classProto: ProtoBuf.Class?, nameResolver: NameResolver, typeTable: TypeTable, kind: CallableKind, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 114af526174..d3880e69758 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -100,7 +100,6 @@ fun deserializeClassToSymbol( typeParameters += context.typeDeserializer.ownTypeParameters.map { it.fir } if (status.isInner) typeParameters += parentContext?.allTypeParameters?.map { buildOuterClassTypeParameterRef { this.symbol = it } }.orEmpty() -// annotations += context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver) val typeDeserializer = context.typeDeserializer val classDeserializer = context.memberDeserializer @@ -114,12 +113,21 @@ fun deserializeClassToSymbol( buildResolvedTypeRef { type = it } } - addDeclarations(classProto.functionList.map(classDeserializer::loadFunction)) - addDeclarations(classProto.propertyList.map(classDeserializer::loadProperty)) + addDeclarations( + classProto.functionList.map { + classDeserializer.loadFunction(it, classProto) + } + ) + + addDeclarations( + classProto.propertyList.map { + classDeserializer.loadProperty(it, classProto) + } + ) addDeclarations( classProto.constructorList.map { - classDeserializer.loadConstructor(it, this) + classDeserializer.loadConstructor(it, classProto, this) } ) @@ -167,7 +175,8 @@ fun deserializeClassToSymbol( ClassId.fromString(nameResolver.getQualifiedClassName(nameIndex)) } } - (it.annotations as MutableList) += context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver) + (it.annotations as MutableList) += + context.annotationDeserializer.loadClassAnnotations(classProto, context.nameResolver) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index 049c19dc883..0d8d4d32ee8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -177,7 +177,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { } } - fun loadProperty(proto: ProtoBuf.Property): FirProperty { + fun loadProperty(proto: ProtoBuf.Property, classProto: ProtoBuf.Class? = null): FirProperty { val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags) val callableName = c.nameResolver.getName(proto.name) val symbol = FirPropertySymbol(CallableId(c.packageFqName, c.relativeClassName, callableName)) @@ -237,7 +237,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { valueParameters += local.memberDeserializer.valueParameters( listOf(proto.setterValueParameter), proto, - AbstractAnnotationDeserializer.CallableKind.PROPERTY_SETTER + AbstractAnnotationDeserializer.CallableKind.PROPERTY_SETTER, + classProto ) } } else { @@ -287,7 +288,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { } } - fun loadFunction(proto: ProtoBuf.Function, byteContent: ByteArray? = null): FirSimpleFunction { + fun loadFunction(proto: ProtoBuf.Function, classProto: ProtoBuf.Class? = null): FirSimpleFunction { val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags) val receiverAnnotations = @@ -329,7 +330,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { valueParameters += local.memberDeserializer.valueParameters( proto.valueParameterList, proto, - AbstractAnnotationDeserializer.CallableKind.OTHERS + AbstractAnnotationDeserializer.CallableKind.OTHERS, + classProto ) annotations += c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) @@ -344,7 +346,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { return simpleFunction } - fun loadConstructor(proto: ProtoBuf.Constructor, classBuilder: FirRegularClassBuilder): FirConstructor { + fun loadConstructor(proto: ProtoBuf.Constructor, classProto: ProtoBuf.Class, classBuilder: FirRegularClassBuilder): FirConstructor { val flags = proto.flags val relativeClassName = c.relativeClassName!! val symbol = FirConstructorSymbol(CallableId(c.packageFqName, relativeClassName, relativeClassName.shortName())) @@ -383,6 +385,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { proto.valueParameterList, proto, AbstractAnnotationDeserializer.CallableKind.OTHERS, + classProto, addDefaultValue = classBuilder.symbol.classId == StandardClassIds.Enum ) annotations += @@ -401,6 +404,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { valueParameters: List, callableProto: MessageLite, callableKind: AbstractAnnotationDeserializer.CallableKind, + classProto: ProtoBuf.Class?, addDefaultValue: Boolean = false ): List { return valueParameters.mapIndexed { index, proto -> @@ -423,6 +427,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { c.containerSource, callableProto, proto, + classProto, c.nameResolver, c.typeTable, callableKind,