[FIR] Fix a couple of issues in annotation serialization.
This commit is contained in:
committed by
TeamCityServer
parent
3dd27b9b1f
commit
f220e4a5ed
+1
-1
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.metadata.deserialization.Flags
|
|||||||
internal object FirAnnotationArgumentVisitor : AnnotationArgumentVisitor<Unit, FirAnnotationArgumentVisitorData>() {
|
internal object FirAnnotationArgumentVisitor : AnnotationArgumentVisitor<Unit, FirAnnotationArgumentVisitorData>() {
|
||||||
override fun visitAnnotationValue(value: AnnotationValue, data: FirAnnotationArgumentVisitorData) {
|
override fun visitAnnotationValue(value: AnnotationValue, data: FirAnnotationArgumentVisitorData) {
|
||||||
data.builder.type = ProtoBuf.Annotation.Argument.Value.Type.ANNOTATION
|
data.builder.type = ProtoBuf.Annotation.Argument.Value.Type.ANNOTATION
|
||||||
// TODO: annotation = serializeAnnotation(value.value)
|
data.builder.annotation = data.serializer.serializeAnnotation(value.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitArrayValue(value: ArrayValue, data: FirAnnotationArgumentVisitorData) {
|
override fun visitArrayValue(value: ArrayValue, data: FirAnnotationArgumentVisitorData) {
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ class FirAnnotationSerializer(private val session: FirSession, internal val stri
|
|||||||
fun addArgument(argumentExpression: FirExpression, parameterName: Name) {
|
fun addArgument(argumentExpression: FirExpression, parameterName: Name) {
|
||||||
val argument = ProtoBuf.Annotation.Argument.newBuilder()
|
val argument = ProtoBuf.Annotation.Argument.newBuilder()
|
||||||
argument.nameId = stringTable.getStringIndex(parameterName.asString())
|
argument.nameId = stringTable.getStringIndex(parameterName.asString())
|
||||||
argument.setValue(valueProto(argumentExpression.toConstantValue() ?: return))
|
argument.setValue(valueProto(argumentExpression.toConstantValue(session) ?: return))
|
||||||
addArgument(argument)
|
addArgument(argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -884,7 +884,7 @@ class FirElementSerializer private constructor(
|
|||||||
private fun serializeVersionRequirementFromRequireKotlin(annotation: FirAnnotation): ProtoBuf.VersionRequirement.Builder? {
|
private fun serializeVersionRequirementFromRequireKotlin(annotation: FirAnnotation): ProtoBuf.VersionRequirement.Builder? {
|
||||||
val argumentMapping = annotation.argumentMapping.mapping
|
val argumentMapping = annotation.argumentMapping.mapping
|
||||||
|
|
||||||
val versionString = (argumentMapping[RequireKotlinConstants.VERSION]?.toConstantValue() as? StringValue)?.value ?: return null
|
val versionString = (argumentMapping[RequireKotlinConstants.VERSION]?.toConstantValue(session) as? StringValue)?.value ?: return null
|
||||||
val matchResult = RequireKotlinConstants.VERSION_REGEX.matchEntire(versionString) ?: return null
|
val matchResult = RequireKotlinConstants.VERSION_REGEX.matchEntire(versionString) ?: return null
|
||||||
|
|
||||||
val major = matchResult.groupValues.getOrNull(1)?.toIntOrNull() ?: return null
|
val major = matchResult.groupValues.getOrNull(1)?.toIntOrNull() ?: return null
|
||||||
@@ -897,12 +897,12 @@ class FirElementSerializer private constructor(
|
|||||||
writeVersionFull = { proto.versionFull = it }
|
writeVersionFull = { proto.versionFull = it }
|
||||||
)
|
)
|
||||||
|
|
||||||
val message = (argumentMapping[RequireKotlinConstants.MESSAGE]?.toConstantValue() as? StringValue)?.value
|
val message = (argumentMapping[RequireKotlinConstants.MESSAGE]?.toConstantValue(session) as? StringValue)?.value
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
proto.message = stringTable.getStringIndex(message)
|
proto.message = stringTable.getStringIndex(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
when ((argumentMapping[RequireKotlinConstants.LEVEL]?.toConstantValue() as? EnumValue)?.enumEntryName?.asString()) {
|
when ((argumentMapping[RequireKotlinConstants.LEVEL]?.toConstantValue(session) as? EnumValue)?.enumEntryName?.asString()) {
|
||||||
DeprecationLevel.ERROR.name -> {
|
DeprecationLevel.ERROR.name -> {
|
||||||
// ERROR is the default level
|
// ERROR is the default level
|
||||||
}
|
}
|
||||||
@@ -910,7 +910,7 @@ class FirElementSerializer private constructor(
|
|||||||
DeprecationLevel.HIDDEN.name -> proto.level = ProtoBuf.VersionRequirement.Level.HIDDEN
|
DeprecationLevel.HIDDEN.name -> proto.level = ProtoBuf.VersionRequirement.Level.HIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
when ((argumentMapping[RequireKotlinConstants.VERSION_KIND]?.toConstantValue() as? EnumValue)?.enumEntryName?.asString()) {
|
when ((argumentMapping[RequireKotlinConstants.VERSION_KIND]?.toConstantValue(session) as? EnumValue)?.enumEntryName?.asString()) {
|
||||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION.name -> {
|
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION.name -> {
|
||||||
// LANGUAGE_VERSION is the default kind
|
// LANGUAGE_VERSION is the default kind
|
||||||
}
|
}
|
||||||
@@ -920,7 +920,7 @@ class FirElementSerializer private constructor(
|
|||||||
proto.versionKind = ProtoBuf.VersionRequirement.VersionKind.API_VERSION
|
proto.versionKind = ProtoBuf.VersionRequirement.VersionKind.API_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
val errorCode = (argumentMapping[RequireKotlinConstants.ERROR_CODE]?.toConstantValue() as? IntValue)?.value
|
val errorCode = (argumentMapping[RequireKotlinConstants.ERROR_CODE]?.toConstantValue(session) as? IntValue)?.value
|
||||||
if (errorCode != null && errorCode != -1) {
|
if (errorCode != null && errorCode != -1) {
|
||||||
proto.errorCode = errorCode
|
proto.errorCode = errorCode
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -157,6 +157,7 @@ internal class KClassValue(value: Value) : ConstantValue<KClassValue.Value>(valu
|
|||||||
var type = argumentType
|
var type = argumentType
|
||||||
var arrayDimensions = 0
|
var arrayDimensions = 0
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (type.isPrimitiveArray) break
|
||||||
type = type.arrayElementType() ?: break
|
type = type.arrayElementType() ?: break
|
||||||
arrayDimensions++
|
arrayDimensions++
|
||||||
}
|
}
|
||||||
|
|||||||
+85
-21
@@ -5,10 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.serialization.constant
|
package org.jetbrains.kotlin.fir.serialization.constant
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.containingClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.FirAnnotationCallBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationArgumentMapping
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||||
|
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
@@ -16,12 +29,12 @@ import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|
||||||
internal fun FirExpression.toConstantValue(): ConstantValue<*>? = accept(FirToConstantValueTransformer, null)
|
internal fun FirExpression.toConstantValue(session: FirSession): ConstantValue<*>? = accept(FirToConstantValueTransformer, session)
|
||||||
|
|
||||||
internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<*>?, Nothing?>() {
|
internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<*>?, FirSession>() {
|
||||||
override fun visitElement(
|
override fun visitElement(
|
||||||
element: FirElement,
|
element: FirElement,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*>? {
|
): ConstantValue<*>? {
|
||||||
error("Illegal element as annotation argument: ${element::class.qualifiedName} -> ${element.render()}")
|
error("Illegal element as annotation argument: ${element::class.qualifiedName} -> ${element.render()}")
|
||||||
}
|
}
|
||||||
@@ -29,7 +42,7 @@ internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<
|
|||||||
@OptIn(ExperimentalUnsignedTypes::class)
|
@OptIn(ExperimentalUnsignedTypes::class)
|
||||||
override fun <T> visitConstExpression(
|
override fun <T> visitConstExpression(
|
||||||
constExpression: FirConstExpression<T>,
|
constExpression: FirConstExpression<T>,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*>? {
|
): ConstantValue<*>? {
|
||||||
val value = constExpression.value
|
val value = constExpression.value
|
||||||
return when (constExpression.kind) {
|
return when (constExpression.kind) {
|
||||||
@@ -53,59 +66,110 @@ internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<
|
|||||||
|
|
||||||
override fun visitArrayOfCall(
|
override fun visitArrayOfCall(
|
||||||
arrayOfCall: FirArrayOfCall,
|
arrayOfCall: FirArrayOfCall,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*> {
|
): ConstantValue<*> {
|
||||||
return ArrayValue(arrayOfCall.argumentList.arguments.mapNotNull { it.accept(this, null) })
|
return ArrayValue(arrayOfCall.argumentList.arguments.mapNotNull { it.accept(this, data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnnotation(
|
override fun visitAnnotation(
|
||||||
annotation: FirAnnotation,
|
annotation: FirAnnotation,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*> {
|
): ConstantValue<*> {
|
||||||
return AnnotationValue(annotation)
|
return AnnotationValue(annotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: Nothing?): ConstantValue<*> {
|
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: FirSession): ConstantValue<*> {
|
||||||
return visitAnnotation(annotationCall, data)
|
return visitAnnotation(annotationCall, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetClassCall(
|
override fun visitGetClassCall(
|
||||||
getClassCall: FirGetClassCall,
|
getClassCall: FirGetClassCall,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*>? {
|
): ConstantValue<*>? {
|
||||||
return KClassValue.create(getClassCall.typeRef.coneTypeUnsafe())
|
return KClassValue.create(getClassCall.argument.typeRef.coneTypeUnsafe())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitQualifiedAccessExpression(
|
override fun visitQualifiedAccessExpression(
|
||||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*>? {
|
): ConstantValue<*>? {
|
||||||
val symbol = qualifiedAccessExpression.toResolvedCallableSymbol() ?: return null
|
val symbol = qualifiedAccessExpression.toResolvedCallableSymbol() ?: return null
|
||||||
val enumEntry = symbol.fir as? FirEnumEntry ?: return null
|
|
||||||
val classId = enumEntry.returnTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId ?: return null
|
return when {
|
||||||
val outerClassId = classId.outerClassId ?: return null
|
symbol.fir is FirEnumEntry -> {
|
||||||
return EnumValue(outerClassId, enumEntry.name)
|
val classId = symbol.fir.returnTypeRef.coneTypeSafe<ConeClassLikeType>()?.classId ?: return null
|
||||||
|
EnumValue(classId, (symbol.fir as FirEnumEntry).name)
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol is FirConstructorSymbol -> {
|
||||||
|
val constructorCall = qualifiedAccessExpression as FirFunctionCall
|
||||||
|
val constructedClassSymbol = symbol.containingClass()?.toFirRegularClassSymbol(data) ?: return null
|
||||||
|
return if (constructedClassSymbol.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
|
AnnotationValue(
|
||||||
|
buildAnnotationCall {
|
||||||
|
argumentMapping = buildAnnotationArgumentMapping {
|
||||||
|
constructorCall.argumentMapping?.forEach { (firExpression, firValueParameter) ->
|
||||||
|
mapping[firValueParameter.name] = firExpression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
annotationTypeRef = qualifiedAccessExpression.typeRef
|
||||||
|
calleeReference = buildSimpleNamedReference {
|
||||||
|
source = qualifiedAccessExpression.source
|
||||||
|
name = qualifiedAccessExpression.calleeReference.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol.callableId.packageName.asString() == "kotlin" -> {
|
||||||
|
val dispatchReceiver = qualifiedAccessExpression.dispatchReceiver
|
||||||
|
when (symbol.callableId.callableName.asString()) {
|
||||||
|
"toByte" -> ByteValue((dispatchReceiver.accept(this, data)!!.value as Number).toByte())
|
||||||
|
"toLong" -> LongValue((dispatchReceiver.accept(this, data)!!.value as Number).toLong())
|
||||||
|
"toShort" -> ShortValue((dispatchReceiver.accept(this, data)!!.value as Number).toShort())
|
||||||
|
"toFloat" -> FloatValue((dispatchReceiver.accept(this, data)!!.value as Number).toFloat())
|
||||||
|
"toDouble" -> DoubleValue((dispatchReceiver.accept(this, data)!!.value as Number).toDouble())
|
||||||
|
"toChar" -> CharValue((dispatchReceiver.accept(this, data)!!.value as Number).toChar())
|
||||||
|
"unaryMinus" -> {
|
||||||
|
when (val receiverValue = dispatchReceiver.accept(this, data)) {
|
||||||
|
is ByteValue -> ByteValue((-receiverValue.value).toByte())
|
||||||
|
is LongValue -> LongValue(-receiverValue.value)
|
||||||
|
is ShortValue -> ShortValue((-receiverValue.value).toShort())
|
||||||
|
is FloatValue -> FloatValue(-receiverValue.value)
|
||||||
|
is DoubleValue -> DoubleValue(-receiverValue.value)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: Nothing?): ConstantValue<*>? {
|
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression, data: FirSession): ConstantValue<*>? {
|
||||||
return visitQualifiedAccessExpression(propertyAccessExpression, data)
|
return visitQualifiedAccessExpression(propertyAccessExpression, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionCall(
|
override fun visitFunctionCall(
|
||||||
functionCall: FirFunctionCall,
|
functionCall: FirFunctionCall,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*>? {
|
): ConstantValue<*>? {
|
||||||
return visitQualifiedAccessExpression(functionCall, data)
|
return visitQualifiedAccessExpression(functionCall, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVarargArgumentsExpression(
|
override fun visitVarargArgumentsExpression(
|
||||||
varargArgumentsExpression: FirVarargArgumentsExpression,
|
varargArgumentsExpression: FirVarargArgumentsExpression,
|
||||||
data: Nothing?
|
data: FirSession
|
||||||
): ConstantValue<*> {
|
): ConstantValue<*> {
|
||||||
return ArrayValue(varargArgumentsExpression.arguments.mapNotNull { it.accept(this, null) })
|
return ArrayValue(varargArgumentsExpression.arguments.mapNotNull { it.accept(this, data) })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: Nothing?): ConstantValue<*>? {
|
override fun visitNamedArgumentExpression(namedArgumentExpression: FirNamedArgumentExpression, data: FirSession): ConstantValue<*>? {
|
||||||
return namedArgumentExpression.expression.accept(this, null)
|
return namedArgumentExpression.expression.accept(this, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FIR status: Fail: class kotlin.reflect.KClass
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FIR status: assertEquals fails
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FIR status: assertEquals fails (something wrong with argument order/mapping)
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
package test
|
package test
|
||||||
|
|||||||
Reference in New Issue
Block a user