diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt index 59ec718a015..cf963cb2e24 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedAnnotationDeserializer.kt @@ -117,10 +117,17 @@ class StubBasedAnnotationDeserializer( } ) } - is ArrayValue -> buildArrayOfCall { - source = KtRealPsiSourceElement(sourceElement) - argumentList = buildArgumentList { - value.value.mapTo(arguments) { resolveValue(sourceElement, it) } + is ArrayValue -> { + buildArrayOfCall { + source = KtRealPsiSourceElement(sourceElement) + typeRef = buildResolvedTypeRef { + // Not quite precise, yet doesn't require annotation resolution + type = (inferArrayValueType(value.value) ?: session.builtinTypes.anyType.type).createArrayType() + } + + argumentList = buildArgumentList { + value.value.mapTo(arguments) { resolveValue(sourceElement, it) } + } } } is AnnotationValue -> { @@ -148,6 +155,44 @@ class StubBasedAnnotationDeserializer( } } + private fun inferArrayValueType(values: List>): ConeClassLikeType? { + if (values.isNotEmpty()) { + val firstValue = values.first() + + for ((index, value) in values.withIndex()) { + if (index > 0 && value.javaClass != firstValue.javaClass) { + return null + } + } + + return when (firstValue) { + is BooleanValue -> session.builtinTypes.booleanType.type + is ByteValue -> session.builtinTypes.byteType.type + is CharValue -> session.builtinTypes.charType.type + is ShortValue -> session.builtinTypes.shortType.type + is IntValue -> session.builtinTypes.intType.type + is LongValue -> session.builtinTypes.longType.type + is UByteValue -> session.builtinTypes.byteType.type + is UShortValue -> session.builtinTypes.shortType.type + is UIntValue -> session.builtinTypes.intType.type + is ULongValue -> session.builtinTypes.longType.type + is DoubleValue -> session.builtinTypes.doubleType.type + is FloatValue -> session.builtinTypes.floatType.type + is AnnotationValue -> session.builtinTypes.annotationType.type + is StringValue -> session.builtinTypes.stringType.type + is EnumValue -> firstValue.enumClassId.constructClassLikeType(ConeTypeProjection.EMPTY_ARRAY, isNullable = false) + is ArrayValue -> values.firstNotNullOfOrNull { inferArrayValueType((it as ArrayValue).value) }?.createArrayType() + is KClassValue -> { + val kClassType = session.builtinTypes.anyType.type + StandardClassIds.KClass.constructClassLikeType(arrayOf(kClassType), isNullable = false) + } + else -> null + } + } + + return null + } + private fun const( kind: ConstantValueKind, value: T,