[K2] Properly serialize annotation that has vararg with single argument
#KT-60163 Fixed
This commit is contained in:
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
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.packageFqName
|
||||||
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
|
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
@@ -25,6 +26,10 @@ class ConstValueProviderImpl(
|
|||||||
val firFile = processingFirFile
|
val firFile = processingFirFile
|
||||||
if (firExpression == null || firFile == null) return null
|
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()
|
val fileName = firFile.packageFqName.child(Name.identifier(firFile.name)).asString()
|
||||||
return if (firExpression is FirQualifiedAccessExpression) {
|
return if (firExpression is FirQualifiedAccessExpression) {
|
||||||
// TODO check that this behavior is expected in ConversionUtils and if not fix it
|
// TODO check that this behavior is expected in ConversionUtils and if not fix it
|
||||||
|
|||||||
Generated
+5
@@ -134,6 +134,11 @@ public class K1KotlinpTestGenerated extends AbstractK1KotlinpTest {
|
|||||||
runTest("libraries/tools/kotlinp/testData/ValueClass.kt");
|
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")
|
@TestMetadata("VersionRequirement.kt")
|
||||||
public void testVersionRequirement() throws Exception {
|
public void testVersionRequirement() throws Exception {
|
||||||
runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt");
|
runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt");
|
||||||
|
|||||||
Generated
+5
@@ -134,6 +134,11 @@ public class K2KotlinpTestGenerated extends AbstractK2KotlinpTest {
|
|||||||
runTest("libraries/tools/kotlinp/testData/ValueClass.kt");
|
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")
|
@TestMetadata("VersionRequirement.kt")
|
||||||
public void testVersionRequirement() throws Exception {
|
public void testVersionRequirement() throws Exception {
|
||||||
runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt");
|
runTest("libraries/tools/kotlinp/testData/VersionRequirement.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 {}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user