From 535806d0ab50d8ef2188a445bf1e22d28c8dc306 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Wed, 26 Apr 2023 14:00:10 +0200 Subject: [PATCH] [K2] Force interpretation of default argument for annotation's property We miss these expression because they might be represented as `IrGetFiled` values, but they still must be turned into `IrConst`. #KT-58007 Fixed --- .../checker/IrConstAnnotationTransformer.kt | 13 +++++++++---- .../IrConstDeclarationAnnotationTransformer.kt | 12 ++++++++++++ .../serialization/annotationWithDefaults.kt | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstAnnotationTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstAnnotationTransformer.kt index 2babb5e0e6d..0963c38efd9 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstAnnotationTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstAnnotationTransformer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.interpreter.IrInterpreter @@ -34,10 +35,14 @@ internal abstract class IrConstAnnotationTransformer( private fun transformAnnotation(annotation: IrConstructorCall) { for (i in 0 until annotation.valueArgumentsCount) { val arg = annotation.getValueArgument(i) ?: continue - when (arg) { - is IrVararg -> annotation.putValueArgument(i, arg.transformVarArg()) - else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type)) - } + annotation.putValueArgument(i, transformAnnotationArgument(arg, annotation.symbol.owner.valueParameters[i])) + } + } + + protected fun transformAnnotationArgument(argument: IrExpression, valueParameter: IrValueParameter): IrExpression { + return when (argument) { + is IrVararg -> argument.transformVarArg() + else -> argument.transformSingleArg(valueParameter.type) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstDeclarationAnnotationTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstDeclarationAnnotationTransformer.kt index c6cb8fe1207..410fe20fa8a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstDeclarationAnnotationTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstDeclarationAnnotationTransformer.kt @@ -6,12 +6,16 @@ package org.jetbrains.kotlin.ir.interpreter.checker import org.jetbrains.kotlin.constant.EvaluatedConstTracker +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrErrorExpression +import org.jetbrains.kotlin.ir.expressions.IrVararg import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.util.primaryConstructor internal class IrConstDeclarationAnnotationTransformer( interpreter: IrInterpreter, @@ -29,6 +33,14 @@ internal class IrConstDeclarationAnnotationTransformer( override fun visitDeclaration(declaration: IrDeclarationBase, data: Nothing?): IrStatement { transformAnnotations(declaration) + if (declaration is IrClass && declaration.kind == ClassKind.ANNOTATION_CLASS) { + declaration.primaryConstructor?.valueParameters?.forEach { + val defaultExpression = it.defaultValue?.expression ?: return@forEach + if (defaultExpression.canBeInterpreted()) { + it.defaultValue?.expression = transformAnnotationArgument(defaultExpression, it) + } + } + } return super.visitDeclaration(declaration, data) } } diff --git a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt index f2997ba88b8..ef13b1fd2ba 100644 --- a/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt +++ b/compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationWithDefaults.kt @@ -5,6 +5,21 @@ // MODULE: lib // FILE: lib.kt +import kotlin.reflect.KClass + +@Target(AnnotationTarget.FIELD) +@Retention(AnnotationRetention.RUNTIME) +annotation class IntegerNumberValid( + val message: String = "Has illegal integer number value", + val groups: Array> = [], + + val minimum: Long = Long.MIN_VALUE, + val maximum: Long = Long.MAX_VALUE, + + val minMaxArray: LongArray = longArrayOf(Long.MIN_VALUE, Long.MAX_VALUE), + val minMaxArrayCollection: LongArray = [Long.MIN_VALUE, Long.MAX_VALUE], +) + @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.BINARY) annotation class AnnotationWithDefault(val str: String = "Str" + "ing")