diff --git a/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt b/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt index ba94105b83a..cbcd6a7ff82 100644 --- a/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt +++ b/compiler/fir/analysis-tests/testData/builtIns/kotlin.txt @@ -339,7 +339,7 @@ public abstract interface Comparable : R|kotlin/Any| { } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/MustBeDocumented|() public final annotation class Deprecated : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/MustBeDocumented|() public final annotation class Deprecated : R|kotlin/Annotation| { public final val level: R|kotlin/DeprecationLevel| public get(): R|kotlin/DeprecationLevel| @@ -353,7 +353,7 @@ public abstract interface Comparable : R|kotlin/Any| { } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.4)) public final annotation class DeprecatedSinceKotlin : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.4)) public final annotation class DeprecatedSinceKotlin : R|kotlin/Annotation| { public final val errorSince: R|kotlin/String| public get(): R|kotlin/String| @@ -484,7 +484,7 @@ public final class Double : R|kotlin/Number|, R|kotlin/Comparable public final operator fun times(other: R|kotlin/Short|): R|kotlin/Double| - @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.), replaceWith = @R|kotlin/ReplaceWith|(expression = String(toInt().toByte())) ) public open fun toByte(): R|kotlin/Byte| + @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.), replaceWith = @R|kotlin/ReplaceWith|(imports = (), expression = String(toInt().toByte())) ) public open fun toByte(): R|kotlin/Byte| public open fun toChar(): R|kotlin/Char| @@ -496,7 +496,7 @@ public final class Double : R|kotlin/Number|, R|kotlin/Comparable public open fun toLong(): R|kotlin/Long| - @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.), replaceWith = @R|kotlin/ReplaceWith|(expression = String(toInt().toShort())) ) public open fun toShort(): R|kotlin/Short| + @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.), replaceWith = @R|kotlin/ReplaceWith|(imports = (), expression = String(toInt().toShort())) ) public open fun toShort(): R|kotlin/Short| public final operator fun unaryMinus(): R|kotlin/Double| @@ -524,7 +524,7 @@ public final class DoubleArray : R|kotlin/Any|, R|kotlin/Cloneable|, R|java/io/S } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class DslMarker : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|())) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class DslMarker : R|kotlin/Annotation| { public constructor(): R|kotlin/DslMarker| } @@ -555,7 +555,7 @@ public abstract class Enum : R|kotlin/Comparable|, R|java/io/Serializable| } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/MustBeDocumented|() public final annotation class ExtensionFunctionType : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) @R|kotlin/annotation/MustBeDocumented|() public final annotation class ExtensionFunctionType : R|kotlin/Annotation| { public constructor(): R|kotlin/ExtensionFunctionType| } @@ -663,7 +663,7 @@ public final class Float : R|kotlin/Number|, R|kotlin/Comparable|, public final operator fun times(other: R|kotlin/Short|): R|kotlin/Float| - @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.), replaceWith = @R|kotlin/ReplaceWith|(expression = String(toInt().toByte())) ) public open fun toByte(): R|kotlin/Byte| + @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Byte.), replaceWith = @R|kotlin/ReplaceWith|(imports = (), expression = String(toInt().toByte())) ) public open fun toByte(): R|kotlin/Byte| public open fun toChar(): R|kotlin/Char| @@ -675,7 +675,7 @@ public final class Float : R|kotlin/Number|, R|kotlin/Comparable|, public open fun toLong(): R|kotlin/Long| - @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.), replaceWith = @R|kotlin/ReplaceWith|(expression = String(toInt().toShort())) ) public open fun toShort(): R|kotlin/Short| + @R|kotlin/Deprecated|(message = String(Unclear conversion. To achieve the same result convert to Int explicitly and then to Short.), replaceWith = @R|kotlin/ReplaceWith|(imports = (), expression = String(toInt().toShort())) ) public open fun toShort(): R|kotlin/Short| public final operator fun unaryMinus(): R|kotlin/Float| @@ -1042,7 +1042,7 @@ public abstract class Number : R|kotlin/Any|, R|java/io/Serializable| { } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class ParameterName : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class ParameterName : R|kotlin/Annotation| { public final val name: R|kotlin/String| public get(): R|kotlin/String| @@ -1050,12 +1050,12 @@ public abstract class Number : R|kotlin/Any|, R|java/io/Serializable| { } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class PublishedApi : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|())) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() @R|kotlin/SinceKotlin|(version = String(1.1)) public final annotation class PublishedApi : R|kotlin/Annotation| { public constructor(): R|kotlin/PublishedApi| } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class ReplaceWith : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = ()) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class ReplaceWith : R|kotlin/Annotation| { public final val expression: R|kotlin/String| public get(): R|kotlin/String| @@ -1208,7 +1208,7 @@ public final class ShortArray : R|kotlin/Any|, R|kotlin/Cloneable|, R|java/io/Se } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class SinceKotlin : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.FIELD|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.BINARY|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class SinceKotlin : R|kotlin/Annotation| { public final val version: R|kotlin/String| public get(): R|kotlin/String| @@ -1237,7 +1237,7 @@ public final class String : R|kotlin/Comparable|, R|kotlin/CharSe } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.SOURCE|()) public final annotation class Suppress : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|(), R|kotlin/annotation/AnnotationTarget.TYPE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.FIELD|(), R|kotlin/annotation/AnnotationTarget.LOCAL_VARIABLE|(), R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.TYPE|(), R|kotlin/annotation/AnnotationTarget.EXPRESSION|(), R|kotlin/annotation/AnnotationTarget.FILE|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.SOURCE|()) public final annotation class Suppress : R|kotlin/Annotation| { public final val names: R|kotlin/Array| public get(): R|kotlin/Array| @@ -1269,7 +1269,7 @@ public final object Unit : R|kotlin/Any| { } -@R|kotlin/annotation/Target|() @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.SOURCE|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class UnsafeVariance : R|kotlin/Annotation| { +@R|kotlin/annotation/Target|(allowedTargets = (R|kotlin/annotation/AnnotationTarget.TYPE|())) @R|kotlin/annotation/Retention|(value = R|kotlin/annotation/AnnotationRetention.SOURCE|()) @R|kotlin/annotation/MustBeDocumented|() public final annotation class UnsafeVariance : R|kotlin/Annotation| { public constructor(): R|kotlin/UnsafeVariance| } 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 3d260dc5a78..0a182ea5443 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 @@ -23,10 +23,9 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedSymbolError import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import org.jetbrains.kotlin.fir.types.constructType import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf.Annotation.Argument.Value.Type.* import org.jetbrains.kotlin.metadata.deserialization.Flags @@ -180,7 +179,7 @@ abstract class AbstractAnnotationDeserializer( arguments = proto.argumentList.mapNotNull { val name = nameResolver.getName(it.nameId) val parameter = parameterByName[name] ?: return@mapNotNull null - val value = resolveValue(parameter.returnTypeRef, it.value, nameResolver) ?: return@mapNotNull null + val value = resolveValue(parameter.returnTypeRef.coneType, it.value, nameResolver) buildNamedArgumentExpression { expression = value isSpread = false @@ -207,16 +206,32 @@ abstract class AbstractAnnotationDeserializer( } fun resolveValue( - expectedType: FirTypeRef, value: ProtoBuf.Annotation.Argument.Value, nameResolver: NameResolver - ): FirExpression? { - // TODO: val isUnsigned = Flags.IS_UNSIGNED.get(value.flags) + expectedType: ConeKotlinType, value: ProtoBuf.Annotation.Argument.Value, nameResolver: NameResolver + ): FirExpression { + val isUnsigned = Flags.IS_UNSIGNED.get(value.flags) + + return when (value.type) { + BYTE -> { + val kind = if (isUnsigned) FirConstKind.UnsignedByte else FirConstKind.Byte + const(kind, value.intValue.toByte()) + } + + SHORT -> { + val kind = if (isUnsigned) FirConstKind.UnsignedShort else FirConstKind.Short + const(kind, value.intValue.toShort()) + } + + INT -> { + val kind = if (isUnsigned) FirConstKind.UnsignedInt else FirConstKind.Int + const(kind, value.intValue.toInt()) + } + + LONG -> { + val kind = if (isUnsigned) FirConstKind.UnsignedLong else FirConstKind.Long + const(kind, value.intValue) + } - val result: FirExpression = when (value.type) { - BYTE -> const(FirConstKind.Byte, value.intValue.toByte()) CHAR -> const(FirConstKind.Char, value.intValue.toChar()) - SHORT -> const(FirConstKind.Short, value.intValue.toShort()) - INT -> const(FirConstKind.Int, value.intValue.toInt()) - LONG -> const(FirConstKind.Long, value.intValue) FLOAT -> const(FirConstKind.Float, value.floatValue) DOUBLE -> const(FirConstKind.Double, value.doubleValue) BOOLEAN -> const(FirConstKind.Boolean, (value.intValue != 0L)) @@ -238,28 +253,35 @@ abstract class AbstractAnnotationDeserializer( val classId = nameResolver.getClassId(value.classId) val entryName = nameResolver.getName(value.enumValueId) - val enumLookupTag = ConeClassLikeLookupTagImpl(classId) - val enumSymbol = enumLookupTag.toSymbol(this@AbstractAnnotationDeserializer.session) + val enumSymbol = enumLookupTag.toSymbol(session) val firClass = enumSymbol?.fir as? FirRegularClass val enumEntries = firClass?.collectEnumEntries() ?: emptyList() val enumEntrySymbol = enumEntries.find { it.name == entryName } - this.calleeReference = enumEntrySymbol?.let { + calleeReference = enumEntrySymbol?.let { buildResolvedNamedReference { name = entryName resolvedSymbol = it.symbol } } ?: buildErrorNamedReference { - diagnostic = ConeSimpleDiagnostic("Strange deserialized enum value: $classId.$entryName", DiagnosticKind.DeserializationError) + diagnostic = + ConeSimpleDiagnostic("Strange deserialized enum value: $classId.$entryName", DiagnosticKind.DeserializationError) } } -// ARRAY -> { -// TODO: see AnnotationDeserializer -// } -// else -> error("Unsupported annotation argument type: ${value.type} (expected $expectedType)") - else -> return null + ARRAY -> { + val expectedArrayElementType = expectedType.arrayElementType() ?: session.builtinTypes.anyType.type + buildArrayOfCall { + argumentList = buildArgumentList { + value.arrayElementList.mapTo(arguments) { resolveValue(expectedArrayElementType, it, nameResolver) } + } + typeRef = buildResolvedTypeRef { + type = expectedArrayElementType.createArrayType() + } + } + } + + else -> error("Unsupported annotation argument type: ${value.type} (expected $expectedType)") } - return result } private fun const(kind: FirConstKind, value: T) = buildConstExpression(null, kind, value)