[K2] Instantiation of annotations having default values for properties
This commit adds missing pieces for the puzzle: Annotation instantiation feature uses IrProperty's initializer to instantiate properties from other modules that have default values which weren't specified on call site. To support this feature properly, Fir2IrVisitor should fill LazyIrProperty's backing field initializer with information from Fir. To get this information into Fir, FirMemberDeserializer should be able to read it from KotlinJvmBinaryClass with AnnotationLoaderVisitorImpl. (klibs are unsupported for now) There's a catch with enum entries references: we can't access session.SymbolProvider to resolve it because we're still at the deserialization stage, and it can cause StackOverflow if enum is nested in the same class (see RequiresOptIn.Level). To mitigate this, a new FirEnumEntryDeserializedAccessExpression is produced instead; it is later replaced with the correct reference in the Fir2IrVisitor. ^KT-58137 Fixed Also add test to loadJava folder with annotations default values that verifies metadata loading
This commit is contained in:
committed by
Space Team
parent
d757847ed6
commit
c4255f9a9e
@@ -61,12 +61,12 @@ internal fun Any?.createConstantOrError(session: FirSession): FirExpression {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? {
|
||||
internal fun Any?.createConstantIfAny(session: FirSession, unsigned: Boolean = false): FirExpression? {
|
||||
return when (this) {
|
||||
is Byte -> buildConstExpression(null, ConstantValueKind.Byte, this).setProperType(session)
|
||||
is Short -> buildConstExpression(null, ConstantValueKind.Short, this).setProperType(session)
|
||||
is Int -> buildConstExpression(null, ConstantValueKind.Int, this).setProperType(session)
|
||||
is Long -> buildConstExpression(null, ConstantValueKind.Long, this).setProperType(session)
|
||||
is Byte -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedByte else ConstantValueKind.Byte, this).setProperType(session)
|
||||
is Short -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedShort else ConstantValueKind.Short, this).setProperType(session)
|
||||
is Int -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedInt else ConstantValueKind.Int, this).setProperType(session)
|
||||
is Long -> buildConstExpression(null, if (unsigned) ConstantValueKind.UnsignedLong else ConstantValueKind.Long, this).setProperType(session)
|
||||
is Char -> buildConstExpression(null, ConstantValueKind.Char, this).setProperType(session)
|
||||
is Float -> buildConstExpression(null, ConstantValueKind.Float, this).setProperType(session)
|
||||
is Double -> buildConstExpression(null, ConstantValueKind.Double, this).setProperType(session)
|
||||
|
||||
+149
-129
@@ -7,157 +7,142 @@ package org.jetbrains.kotlin.fir.java.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.SpecialJvmAnnotations
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.java.createConstantOrError
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
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.findKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.utils.toMetadataVersion
|
||||
|
||||
internal class AnnotationsLoader(private val session: FirSession, private val kotlinClassFinder: KotlinClassFinder) {
|
||||
private abstract inner class AnnotationsLoaderVisitorImpl(val enumEntryReferenceCreator: (ClassId, Name) -> FirExpression) : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
abstract fun visitExpression(name: Name?, expr: FirExpression)
|
||||
|
||||
abstract val visitNullNames: Boolean
|
||||
|
||||
abstract fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List<FirExpression>): FirTypeRef?
|
||||
|
||||
override fun visit(name: Name?, value: Any?) {
|
||||
visitExpression(name, createConstant(value))
|
||||
}
|
||||
|
||||
private fun ClassLiteralValue.toFirClassReferenceExpression(): FirClassReferenceExpression {
|
||||
val resolvedClassTypeRef = classId.toLookupTag().toDefaultResolvedTypeRef()
|
||||
return buildClassReferenceExpression {
|
||||
classTypeRef = resolvedClassTypeRef
|
||||
typeRef = buildResolvedTypeRef {
|
||||
type = StandardClassIds.KClass.constructClassLikeType(arrayOf(resolvedClassTypeRef.type), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) {
|
||||
visitExpression(name, buildGetClassCall {
|
||||
val argument = value.toFirClassReferenceExpression()
|
||||
argumentList = buildUnaryArgumentList(argument)
|
||||
typeRef = argument.typeRef
|
||||
})
|
||||
}
|
||||
|
||||
override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) {
|
||||
if (name == null && !visitNullNames) return
|
||||
visitExpression(name, enumEntryReferenceCreator(enumClassId, enumEntryName))
|
||||
}
|
||||
|
||||
override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? {
|
||||
if (name == null && !visitNullNames) return null
|
||||
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
|
||||
private val elements = mutableListOf<FirExpression>()
|
||||
|
||||
override fun visit(value: Any?) {
|
||||
elements.add(createConstant(value))
|
||||
}
|
||||
|
||||
override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) {
|
||||
elements.add(enumEntryReferenceCreator(enumClassId, enumEntryName))
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(value: ClassLiteralValue) {
|
||||
elements.add(buildGetClassCall {
|
||||
val argument = value.toFirClassReferenceExpression()
|
||||
argumentList = buildUnaryArgumentList(argument)
|
||||
typeRef = argument.typeRef
|
||||
})
|
||||
}
|
||||
|
||||
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
val list = mutableListOf<FirAnnotation>()
|
||||
val visitor = loadAnnotation(classId, list, enumEntryReferenceCreator)
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
elements.add(list.single())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
visitExpression(name, buildArrayOfCall {
|
||||
guessArrayTypeIfNeeded(name, elements)?.let { typeRef = it }
|
||||
argumentList = buildArgumentList {
|
||||
arguments += elements
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(name: Name?, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
if (name == null && !visitNullNames) return null
|
||||
val list = mutableListOf<FirAnnotation>()
|
||||
val visitor = loadAnnotation(classId, list, enumEntryReferenceCreator)
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
visitExpression(name, list.single())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createConstant(value: Any?): FirExpression {
|
||||
return value.createConstantOrError(session)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAnnotation(
|
||||
annotationClassId: ClassId, result: MutableList<FirAnnotation>,
|
||||
annotationClassId: ClassId, result: MutableList<FirAnnotation>, enumEntryReferenceCreator: (ClassId, Name) -> FirExpression
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
val lookupTag = annotationClassId.toLookupTag()
|
||||
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
return object : AnnotationsLoaderVisitorImpl(enumEntryReferenceCreator) {
|
||||
private val argumentMap = mutableMapOf<Name, FirExpression>()
|
||||
|
||||
override fun visit(name: Name?, value: Any?) {
|
||||
if (name != null) {
|
||||
argumentMap[name] = createConstant(value)
|
||||
}
|
||||
override fun visitExpression(name: Name?, expr: FirExpression) {
|
||||
if (name != null) argumentMap[name] = expr
|
||||
}
|
||||
|
||||
private fun ClassLiteralValue.toFirClassReferenceExpression(): FirClassReferenceExpression {
|
||||
val resolvedClassTypeRef = classId.toLookupTag().toDefaultResolvedTypeRef()
|
||||
return buildClassReferenceExpression {
|
||||
classTypeRef = resolvedClassTypeRef
|
||||
typeRef = buildResolvedTypeRef {
|
||||
type = StandardClassIds.KClass.constructClassLikeType(arrayOf(resolvedClassTypeRef.type), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
override val visitNullNames: Boolean = false
|
||||
|
||||
private fun ClassId.toEnumEntryReferenceExpression(name: Name): FirExpression {
|
||||
return buildPropertyAccessExpression {
|
||||
val entryPropertySymbol =
|
||||
session.symbolProvider.getClassDeclaredPropertySymbols(
|
||||
this@toEnumEntryReferenceExpression, name,
|
||||
).firstOrNull()
|
||||
|
||||
calleeReference = when {
|
||||
entryPropertySymbol != null -> {
|
||||
buildResolvedNamedReference {
|
||||
this.name = name
|
||||
resolvedSymbol = entryPropertySymbol
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
buildErrorNamedReference {
|
||||
diagnostic = ConeSimpleDiagnostic(
|
||||
"Strange deserialized enum value: ${this@toEnumEntryReferenceExpression}.$name",
|
||||
DiagnosticKind.Java,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(
|
||||
this@toEnumEntryReferenceExpression.toLookupTag(),
|
||||
emptyArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) {
|
||||
if (name == null) return
|
||||
argumentMap[name] = buildGetClassCall {
|
||||
val argument = value.toFirClassReferenceExpression()
|
||||
argumentList = buildUnaryArgumentList(argument)
|
||||
typeRef = argument.typeRef
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) {
|
||||
if (name == null) return
|
||||
argumentMap[name] = enumClassId.toEnumEntryReferenceExpression(enumEntryName)
|
||||
}
|
||||
|
||||
override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? {
|
||||
override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List<FirExpression>): FirTypeRef? {
|
||||
// Needed if we load a default value which is another annotation that has array value in it. e.g.:
|
||||
// To instantiate Deprecated() we need a default value for ReplaceWith() that has imports: Array<String> with default value [].
|
||||
if (name == null) return null
|
||||
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
|
||||
private val elements = mutableListOf<FirExpression>()
|
||||
|
||||
override fun visit(value: Any?) {
|
||||
elements.add(createConstant(value))
|
||||
}
|
||||
|
||||
override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) {
|
||||
elements.add(enumClassId.toEnumEntryReferenceExpression(enumEntryName))
|
||||
}
|
||||
|
||||
override fun visitClassLiteral(value: ClassLiteralValue) {
|
||||
elements.add(
|
||||
buildGetClassCall {
|
||||
val argument = value.toFirClassReferenceExpression()
|
||||
argumentList = buildUnaryArgumentList(argument)
|
||||
typeRef = argument.typeRef
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
val list = mutableListOf<FirAnnotation>()
|
||||
val visitor = loadAnnotation(classId, list)
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
elements.add(list.single())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
argumentMap[name] = buildArrayOfCall {
|
||||
argumentList = buildArgumentList {
|
||||
arguments += elements
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(name: Name?, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
if (name == null) return null
|
||||
val list = mutableListOf<FirAnnotation>()
|
||||
val visitor = loadAnnotation(classId, list)
|
||||
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
|
||||
override fun visitEnd() {
|
||||
visitor.visitEnd()
|
||||
argumentMap[name] = list.single()
|
||||
}
|
||||
}
|
||||
// Note: generally we are not allowed to resolve anything, as this is might lead to recursive resolve problems
|
||||
// However, K1 deserializer did exactly the same and no issues were reported.
|
||||
val propS = session.symbolProvider.getClassDeclaredPropertySymbols(annotationClassId, name).firstOrNull()
|
||||
return propS?.resolvedReturnTypeRef
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
@@ -173,9 +158,35 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createConstant(value: Any?): FirExpression {
|
||||
return value.createConstantOrError(session)
|
||||
internal fun loadAnnotationMethodDefaultValue(
|
||||
methodSignature: MemberSignature,
|
||||
consumeResult: (FirExpression) -> Unit
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
|
||||
return object : AnnotationsLoaderVisitorImpl(this::toEnumEntryReferenceExpressionUnresolved) {
|
||||
var defaultValue: FirExpression? = null
|
||||
|
||||
override fun visitExpression(name: Name?, expr: FirExpression) {
|
||||
defaultValue = expr
|
||||
}
|
||||
|
||||
override val visitNullNames: Boolean = true
|
||||
|
||||
override fun guessArrayTypeIfNeeded(name: Name?, arrayOfElements: List<FirExpression>): FirTypeRef {
|
||||
val descName = methodSignature.signature.substringAfterLast(')').removePrefix("[")
|
||||
val targetClassId = JvmPrimitiveType.getByDesc(descName)?.primitiveType?.typeFqName?.let { ClassId.topLevel(it) }
|
||||
?: FileBasedKotlinClass.resolveNameByInternalName(
|
||||
descName.removePrefix("L").removeSuffix(";"),
|
||||
// It seems that some inner classes info is required, but so far there are no problems with them (see six() in multimoduleCreation test)
|
||||
FileBasedKotlinClass.InnerClassesInfo()
|
||||
)
|
||||
return targetClassId.toLookupTag().constructClassType(arrayOf(), false).createOutArrayType().toFirResolvedTypeRef()
|
||||
}
|
||||
|
||||
override fun visitEnd() {
|
||||
defaultValue?.let(consumeResult)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,8 +198,7 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
val classReference = getClassCall.argument as? FirClassReferenceExpression ?: return false
|
||||
val containerType = classReference.classTypeRef.coneType as? ConeClassLikeType ?: return false
|
||||
val classId = containerType.lookupTag.classId
|
||||
if (classId.outerClassId == null ||
|
||||
classId.shortClassName.asString() != JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME
|
||||
if (classId.outerClassId == null || classId.shortClassName.asString() != JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME
|
||||
) return false
|
||||
|
||||
val klass = kotlinClassFinder.findKotlinClass(classId, session.languageVersionSettings.languageVersion.toMetadataVersion())
|
||||
@@ -199,11 +209,21 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
|
||||
annotationClassId: ClassId, result: MutableList<FirAnnotation>,
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
if (annotationClassId in SpecialJvmAnnotations.SPECIAL_ANNOTATIONS) return null
|
||||
return loadAnnotation(annotationClassId, result)
|
||||
// Note: we shouldn't resolve enum entries here either: KT-58294
|
||||
return loadAnnotation(annotationClassId, result, this::toEnumEntryReferenceExpressionWithResolve)
|
||||
}
|
||||
|
||||
private fun ConeClassLikeLookupTag.toDefaultResolvedTypeRef(): FirResolvedTypeRef =
|
||||
buildResolvedTypeRef {
|
||||
type = constructClassType(emptyArray(), isNullable = false)
|
||||
}
|
||||
|
||||
private fun toEnumEntryReferenceExpressionWithResolve(classId: ClassId, name: Name): FirPropertyAccessExpression =
|
||||
toEnumEntryReferenceExpressionUnresolved(classId, name).toQualifiedPropertyAccessExpression(session)
|
||||
|
||||
private fun toEnumEntryReferenceExpressionUnresolved(classId: ClassId, name: Name): FirEnumEntryDeserializedAccessExpression =
|
||||
buildEnumEntryDeserializedAccessExpression {
|
||||
enumClassId = classId
|
||||
enumEntryName = name
|
||||
}
|
||||
}
|
||||
|
||||
+41
-5
@@ -10,10 +10,19 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
|
||||
import org.jetbrains.kotlin.fir.java.createConstantIfAny
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isUnsignedType
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
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.load.kotlin.getPropertySignature
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
@@ -24,6 +33,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.toMetadataVersion
|
||||
|
||||
@@ -197,6 +207,24 @@ class JvmBinaryAnnotationDeserializer(
|
||||
return findJvmBinaryClassAndLoadMemberAnnotations(paramSignature)
|
||||
}
|
||||
|
||||
override fun loadAnnotationPropertyDefaultValue(
|
||||
containerSource: DeserializedContainerSource?,
|
||||
propertyProto: ProtoBuf.Property,
|
||||
expectedPropertyType: FirTypeRef,
|
||||
nameResolver: NameResolver,
|
||||
typeTable: TypeTable
|
||||
): FirExpression? {
|
||||
val signature = getCallableSignature(propertyProto, nameResolver, typeTable, CallableKind.PROPERTY_GETTER) ?: return null
|
||||
val firExpr = annotationInfo.annotationMethodsDefaultValues[signature]
|
||||
return if (firExpr is FirConstExpression<*> && expectedPropertyType.coneType.isUnsignedType && firExpr.kind.isSignedNumber)
|
||||
firExpr.value.createConstantIfAny(session, unsigned = true)
|
||||
else
|
||||
firExpr
|
||||
}
|
||||
|
||||
private val <T> ConstantValueKind<T>.isSignedNumber: Boolean
|
||||
get() = this is ConstantValueKind.Byte || this is ConstantValueKind.Short || this is ConstantValueKind.Int || this is ConstantValueKind.Long
|
||||
|
||||
private fun computeJvmParameterIndexShift(classProto: ProtoBuf.Class?, message: MessageLite): Int {
|
||||
return when (message) {
|
||||
is ProtoBuf.Function -> if (message.hasReceiver()) 1 else 0
|
||||
@@ -268,7 +296,10 @@ class JvmBinaryAnnotationDeserializer(
|
||||
}
|
||||
|
||||
// TODO: Rename this once property constants are recorded as well
|
||||
private data class MemberAnnotations(val memberAnnotations: MutableMap<MemberSignature, MutableList<FirAnnotation>>)
|
||||
private data class MemberAnnotations(
|
||||
val memberAnnotations: MutableMap<MemberSignature, MutableList<FirAnnotation>>,
|
||||
val annotationMethodsDefaultValues: Map<MemberSignature, FirExpression>
|
||||
)
|
||||
|
||||
// TODO: better to be in KotlinDeserializedJvmSymbolsProvider?
|
||||
private fun FirSession.loadMemberAnnotations(
|
||||
@@ -278,6 +309,7 @@ private fun FirSession.loadMemberAnnotations(
|
||||
): MemberAnnotations {
|
||||
val memberAnnotations = hashMapOf<MemberSignature, MutableList<FirAnnotation>>()
|
||||
val annotationsLoader = AnnotationsLoader(this, kotlinClassFinder)
|
||||
val annotationMethodsDefaultValues = hashMapOf<MemberSignature, FirExpression>()
|
||||
|
||||
kotlinBinaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
||||
@@ -288,6 +320,7 @@ private fun FirSession.loadMemberAnnotations(
|
||||
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc)
|
||||
if (initializer != null) {
|
||||
// TODO: load constant
|
||||
// TODO: Given there is FirConstDeserializer, maybe this comment is obsolete?
|
||||
}
|
||||
return MemberAnnotationVisitor(signature)
|
||||
}
|
||||
@@ -310,8 +343,7 @@ private fun FirSession.loadMemberAnnotations(
|
||||
}
|
||||
|
||||
override fun visitAnnotationMemberDefaultValue(): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
|
||||
// TODO: load annotation default values to properly support annotation instantiation feature
|
||||
return null
|
||||
return annotationsLoader.loadAnnotationMethodDefaultValue(signature) { annotationMethodsDefaultValues[signature] = it }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,5 +362,9 @@ private fun FirSession.loadMemberAnnotations(
|
||||
}
|
||||
}, byteContent)
|
||||
|
||||
return MemberAnnotations(memberAnnotations)
|
||||
|
||||
return MemberAnnotations(
|
||||
memberAnnotations,
|
||||
annotationMethodsDefaultValues
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user