diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt index 23e7c7f8961..f5c8db859ac 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConstValueProviderImpl.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET @@ -25,6 +26,10 @@ class ConstValueProviderImpl( val firFile = processingFirFile if (firExpression == null || firFile == null) return null + // We can't evaluate vararg expression, only its arguments. We can accidentally find a const result for vararg + // when there is only one argument, they both are going to have the same offset. + if (firExpression is FirVarargArgumentsExpression) return null + val fileName = firFile.packageFqName.child(Name.identifier(firFile.name)).asString() return if (firExpression is FirQualifiedAccessExpression) { // TODO check that this behavior is expected in ConversionUtils and if not fix it diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K1KotlinpTestGenerated.java b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K1KotlinpTestGenerated.java index c3242240844..d670c97c4f7 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K1KotlinpTestGenerated.java +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K1KotlinpTestGenerated.java @@ -134,6 +134,11 @@ public class K1KotlinpTestGenerated extends AbstractK1KotlinpTest { runTest("libraries/tools/kotlinp/testData/ValueClass.kt"); } + @TestMetadata("VarargInAnnotation.kt") + public void testVarargInAnnotation() throws Exception { + runTest("libraries/tools/kotlinp/testData/VarargInAnnotation.kt"); + } + @TestMetadata("VersionRequirement.kt") public void testVersionRequirement() throws Exception { runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt"); diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K2KotlinpTestGenerated.java b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K2KotlinpTestGenerated.java index b97f15ca58f..34c297a1b31 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K2KotlinpTestGenerated.java +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/K2KotlinpTestGenerated.java @@ -134,6 +134,11 @@ public class K2KotlinpTestGenerated extends AbstractK2KotlinpTest { runTest("libraries/tools/kotlinp/testData/ValueClass.kt"); } + @TestMetadata("VarargInAnnotation.kt") + public void testVarargInAnnotation() throws Exception { + runTest("libraries/tools/kotlinp/testData/VarargInAnnotation.kt"); + } + @TestMetadata("VersionRequirement.kt") public void testVersionRequirement() throws Exception { runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt"); diff --git a/libraries/tools/kotlinp/testData/VarargInAnnotation.kt b/libraries/tools/kotlinp/testData/VarargInAnnotation.kt new file mode 100644 index 00000000000..5f61a404abb --- /dev/null +++ b/libraries/tools/kotlinp/testData/VarargInAnnotation.kt @@ -0,0 +1,41 @@ +import kotlin.reflect.KClass + +@Target(AnnotationTarget.TYPE) +annotation class AnnoString(vararg val value: String) + +@Target(AnnotationTarget.TYPE) +annotation class AnnoInt(vararg val value: Int) + +enum class A { V1, V2 } +@Target(AnnotationTarget.TYPE) +annotation class AnnoEnum(vararg val value: A) + +@Target(AnnotationTarget.TYPE) +annotation class AnnoKClass(vararg val value: KClass<*>) + +@Target(AnnotationTarget.TYPE) +annotation class AnnoAnnotation(vararg val value: AnnoString) + +fun annoStringVararg0(): @AnnoString() Unit {} +fun annoStringVararg1(): @AnnoString("OK") Unit {} +fun annoStringVararg2(): @AnnoString("OK", "OK2") Unit {} + +fun annoIntVararg0(): @AnnoInt() Unit {} +fun annoIntVararg1(): @AnnoInt(0) Unit {} +fun annoIntVararg2(): @AnnoInt(0, 1) Unit {} + +fun annoEnumVararg0(): @AnnoEnum() Unit {} +fun annoEnumVararg1(): @AnnoEnum(A.V1) Unit {} +fun annoEnumVararg2(): @AnnoEnum(A.V1, A.V2) Unit {} + +fun annoKClassVararg0(): @AnnoKClass() Unit {} +fun annoKClassVararg1(): @AnnoKClass(AnnoString::class) Unit {} +fun annoKClassVararg2(): @AnnoKClass(AnnoString::class, AnnoInt::class) Unit {} + +fun annoAnnotationVararg0(): @AnnoAnnotation() Unit {} +fun annoAnnotationVararg1(): @AnnoAnnotation(AnnoString()) Unit {} +fun annoAnnotationVararg2(): @AnnoAnnotation(AnnoString("OK"), AnnoString("OK1", "OK2")) Unit {} + +fun annoArrayVararg0(): @AnnoString(*arrayOf()) Unit {} +fun annoArrayVararg1(): @AnnoString(*arrayOf("OK")) Unit {} +fun annoArrayVararg2(): @AnnoString(*arrayOf("OK", "OK2")) Unit {} diff --git a/libraries/tools/kotlinp/testData/VarargInAnnotation.txt b/libraries/tools/kotlinp/testData/VarargInAnnotation.txt new file mode 100644 index 00000000000..62b878e9a2d --- /dev/null +++ b/libraries/tools/kotlinp/testData/VarargInAnnotation.txt @@ -0,0 +1,147 @@ +// A.class +// ------------------------------------------ +public final enum class A : kotlin/Enum { + + // signature: (Ljava/lang/String;I)V + private constructor() + + V1, + + V2, + + // module name: test-module + + // has Enum.entries +} +// AnnoAnnotation.class +// ------------------------------------------ +public final annotation class AnnoAnnotation : kotlin/Annotation { + + // signature: (Lkotlin/Array;)V + public constructor(vararg value: AnnoString /* kotlin/Array */) + + // getter: value()[LAnnoString; + public final val value: kotlin/Array + public final get + + // module name: test-module +} +// AnnoEnum.class +// ------------------------------------------ +public final annotation class AnnoEnum : kotlin/Annotation { + + // signature: (Lkotlin/Array;)V + public constructor(vararg value: A /* kotlin/Array */) + + // getter: value()[LA; + public final val value: kotlin/Array + public final get + + // module name: test-module +} +// AnnoInt.class +// ------------------------------------------ +public final annotation class AnnoInt : kotlin/Annotation { + + // signature: ([I)V + public constructor(vararg value: kotlin/Int /* kotlin/IntArray */) + + // getter: value()[I + public final val value: kotlin/IntArray + public final get + + // module name: test-module +} +// AnnoKClass.class +// ------------------------------------------ +public final annotation class AnnoKClass : kotlin/Annotation { + + // signature: (Lkotlin/Array;)V + public constructor(vararg value: kotlin/reflect/KClass<*> /* kotlin/Array> */) + + // getter: value()[Ljava/lang/Class; + public final val value: kotlin/Array> + public final get + + // module name: test-module +} +// AnnoString.class +// ------------------------------------------ +public final annotation class AnnoString : kotlin/Annotation { + + // signature: (Lkotlin/Array;)V + public constructor(vararg value: kotlin/String /* kotlin/Array */) + + // getter: value()[Ljava/lang/String; + public final val value: kotlin/Array + public final get + + // module name: test-module +} +// VarargInAnnotationKt.class +// ------------------------------------------ +package { + + // signature: annoAnnotationVararg0()V + public final fun annoAnnotationVararg0(): @AnnoAnnotation(value = []) kotlin/Unit + + // signature: annoAnnotationVararg1()V + public final fun annoAnnotationVararg1(): @AnnoAnnotation(value = [AnnoString(value = [])]) kotlin/Unit + + // signature: annoAnnotationVararg2()V + public final fun annoAnnotationVararg2(): @AnnoAnnotation(value = [AnnoString(value = ["OK"]), AnnoString(value = ["OK1", "OK2"])]) kotlin/Unit + + // signature: annoArrayVararg0()V + public final fun annoArrayVararg0(): @AnnoString(value = []) kotlin/Unit + + // signature: annoArrayVararg1()V + public final fun annoArrayVararg1(): @AnnoString(value = ["OK"]) kotlin/Unit + + // signature: annoArrayVararg2()V + public final fun annoArrayVararg2(): @AnnoString(value = ["OK", "OK2"]) kotlin/Unit + + // signature: annoEnumVararg0()V + public final fun annoEnumVararg0(): @AnnoEnum(value = []) kotlin/Unit + + // signature: annoEnumVararg1()V + public final fun annoEnumVararg1(): @AnnoEnum(value = [A.V1]) kotlin/Unit + + // signature: annoEnumVararg2()V + public final fun annoEnumVararg2(): @AnnoEnum(value = [A.V1, A.V2]) kotlin/Unit + + // signature: annoIntVararg0()V + public final fun annoIntVararg0(): @AnnoInt(value = []) kotlin/Unit + + // signature: annoIntVararg1()V + public final fun annoIntVararg1(): @AnnoInt(value = [0]) kotlin/Unit + + // signature: annoIntVararg2()V + public final fun annoIntVararg2(): @AnnoInt(value = [0, 1]) kotlin/Unit + + // signature: annoKClassVararg0()V + public final fun annoKClassVararg0(): @AnnoKClass(value = []) kotlin/Unit + + // signature: annoKClassVararg1()V + public final fun annoKClassVararg1(): @AnnoKClass(value = [AnnoString::class]) kotlin/Unit + + // signature: annoKClassVararg2()V + public final fun annoKClassVararg2(): @AnnoKClass(value = [AnnoString::class, AnnoInt::class]) kotlin/Unit + + // signature: annoStringVararg0()V + public final fun annoStringVararg0(): @AnnoString(value = []) kotlin/Unit + + // signature: annoStringVararg1()V + public final fun annoStringVararg1(): @AnnoString(value = ["OK"]) kotlin/Unit + + // signature: annoStringVararg2()V + public final fun annoStringVararg2(): @AnnoString(value = ["OK", "OK2"]) kotlin/Unit + + // module name: test-module +} +// META-INF/test-module.kotlin_module +// ------------------------------------------ +module { + package { + VarargInAnnotationKt + } +}