blob: 90b3daf12fd60528620384d0f855147242006237 [file]
// LANGUAGE: +FullValueClasses, -PropertyParamAnnotationDefaultTargetMode
// TARGET_BACKEND: JVM
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// WITH_REFLECT
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
@Repeatable
annotation class Ann
abstract value class Sealed
abstract value class Base: Sealed()
@[Ann Ann]
value class A @Ann constructor(
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
val x: Int,
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
val y: Int,
): Base() {
operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
return 0
}
}
@[Ann Ann]
value class B @Ann constructor(
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
val x: A,
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
val y: A?,
) {
@JvmName("otherName")
fun f() = Unit
}
typealias NullableA = A?
@[Ann Ann]
class C @Ann constructor(
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
@set:[Ann Ann]
@setparam:[Ann Ann]
var x: A,
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
@set:[Ann Ann]
@setparam:[Ann Ann]
var y: A?,
@[Ann Ann]
@param:[Ann Ann]
@property:[Ann Ann]
@field:[Ann Ann]
@get:[Ann Ann]
@set:[Ann Ann]
@setparam:[Ann Ann]
var yTa: NullableA,
) {
@delegate:[Ann Ann]
@property:[Ann Ann]
@get:[Ann Ann]
val z by lazy { A(-100, -200) }
@delegate:[Ann Ann]
@property:[Ann Ann]
@get:[Ann Ann]
val c by A(-100, -200)
@delegate:[Ann Ann]
@property:[Ann Ann]
@get:[Ann Ann]
val d by ::z
@JvmField
val e = x
init {
if (2 + 2 == 4) {
@[Ann Ann]
val x = 4
@[Ann Ann]
val y = A(1, 2)
}
fun f() {
if (2 + 2 == 4) {
@[Ann Ann]
val x = 4
@[Ann Ann]
val y = A(1, 2)
}
}
}
}
@[Ann Ann]
fun @receiver:[Ann Ann] A.t(@[Ann Ann] a: A, @[Ann Ann] b: B, @[Ann Ann] c: C) {
if (2 + 2 == 4) {
@[Ann Ann]
val x = 4
@[Ann Ann]
val y = A(1, 2)
}
fun f() {
if (2 + 2 == 4) {
@[Ann Ann]
val x1 = 4
@[Ann Ann]
val y1 = A(1, 2)
}
}
}
@[Ann Ann]
fun @receiver:[Ann Ann] C.t(@[Ann Ann] a: A, @[Ann Ann] b: B, @[Ann Ann] c: C) = 4
@[Ann Ann]
var @receiver:[Ann Ann] A.tP
@[Ann Ann]
get() = A(1, 2)
@[Ann Ann]
set(@[Ann Ann] _) = Unit
@[Ann Ann]
var @receiver:[Ann Ann] C.tP
@[Ann Ann]
get() = A(1, 2)
@[Ann Ann]
set(@[Ann Ann] _) = Unit
fun box(): String {
if (!A::class.isValue) return "Failed: A class should be a value class"
if (!B::class.isValue) return "Failed: B class should be a value class"
if (C::class.isValue) return "Failed: C class should be not a value class"
// Check class annotations
if (A::class.annotations.count { it is Ann } != 2) return "Failed: A class should have 2 @Ann"
if (B::class.annotations.count { it is Ann } != 2) return "Failed: B class should have 2 @Ann"
if (C::class.annotations.count { it is Ann } != 2) return "Failed: C class should have 2 @Ann"
// Check constructor annotations
if (A::class.constructors.first().annotations.count { it is Ann } != 1) return "Failed: A constructor @Ann"
if (B::class.constructors.first().annotations.count { it is Ann } != 1) return "Failed: B constructor @Ann"
if (C::class.constructors.first().annotations.count { it is Ann } != 1) return "Failed: C constructor @Ann"
// Check property annotations for A
val aProps = A::class.members.filter { it.name in setOf("x", "y") }
for (prop in aProps) {
if (prop.annotations.count { it is Ann } != 2) return "Failed: A property ${prop.name} @Ann count"
}
// Check B's properties
val bProps = B::class.members.filter { it.name in setOf("x", "y") }
for (prop in bProps) {
if (prop.annotations.count { it is Ann } != 2) return "Failed: B property ${prop.name} @Ann count"
}
// Check C's properties including delegates
val cProps = C::class.members.filter { it.name in setOf("x", "y", "yTa", "z", "c", "d") }
for (prop in cProps) {
if (prop.annotations.count { it is Ann } < 2) return "Failed: C property ${prop.name} @Ann count"
}
// Check extension function annotations
if (A::tP.annotations.count { it is Ann } != 2) return "Failed: A.t extension @Ann count"
if (C::tP.annotations.count { it is Ann } != 2) return "Failed: C.t extension @Ann count"
fun KClass<*>.superClass() = supertypes.single().classifier as KClass<*>
if (!(A::class.superClass().isValue)) return "Failed: Base is not a value class"
if (!(A::class.superClass().superClass().isValue)) return "Failed: Sealed is not a value class"
return "OK"
}