[K2] Properly serialize annotation that has vararg with single argument

#KT-60163 Fixed
This commit is contained in:
Ivan Kylchik
2023-08-07 12:04:45 +02:00
committed by Space Team
parent 8ff2782045
commit 7cbf3b28ca
5 changed files with 203 additions and 0 deletions
@@ -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
@@ -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");
@@ -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");
+41
View File
@@ -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 {}
+147
View File
@@ -0,0 +1,147 @@
// A.class
// ------------------------------------------
public final enum class A : kotlin/Enum<A> {
// signature: <init>(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: <init>(Lkotlin/Array;)V
public constructor(vararg value: AnnoString /* kotlin/Array<out AnnoString> */)
// getter: value()[LAnnoString;
public final val value: kotlin/Array<out AnnoString>
public final get
// module name: test-module
}
// AnnoEnum.class
// ------------------------------------------
public final annotation class AnnoEnum : kotlin/Annotation {
// signature: <init>(Lkotlin/Array;)V
public constructor(vararg value: A /* kotlin/Array<out A> */)
// getter: value()[LA;
public final val value: kotlin/Array<out A>
public final get
// module name: test-module
}
// AnnoInt.class
// ------------------------------------------
public final annotation class AnnoInt : kotlin/Annotation {
// signature: <init>([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: <init>(Lkotlin/Array;)V
public constructor(vararg value: kotlin/reflect/KClass<*> /* kotlin/Array<out kotlin/reflect/KClass<*>> */)
// getter: value()[Ljava/lang/Class;
public final val value: kotlin/Array<out kotlin/reflect/KClass<*>>
public final get
// module name: test-module
}
// AnnoString.class
// ------------------------------------------
public final annotation class AnnoString : kotlin/Annotation {
// signature: <init>(Lkotlin/Array;)V
public constructor(vararg value: kotlin/String /* kotlin/Array<out kotlin/String> */)
// getter: value()[Ljava/lang/String;
public final val value: kotlin/Array<out kotlin/String>
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 <root> {
VarargInAnnotationKt
}
}