blob: baf9f0c73b2e6c7783aa3330cff800c4c93635ec [file]
// LANGUAGE: +FullValueClasses
// ISSUE: KT-84904
// MODULE: lib
// FILE: lib.kt
package lib
interface Coordinates {
fun sum(): Int
}
value class Point(val x: Int, val y: Int) : Coordinates {
override fun sum(): Int = x + y
}
value class Envelope(val point: Point, val id: Long?)
interface Transformer<T> {
fun transform(value: T): T
}
interface Producer<T> {
fun produce(): T
}
interface PointOperation {
fun move(value: Point): Point
}
interface PointFactory {
fun create(x: Int = 20, y: Int = 21): Point
}
object PointTransformer : Transformer<Point> {
override fun transform(value: Point): Point =
Point(value.x + 1, value.y + 1)
}
object NullablePointTransformer : Transformer<Point?> {
override fun transform(value: Point?): Point? =
value?.let { Point(it.x + 2, it.y + 2) }
}
object PointProducer : Producer<Point> {
override fun produce(): Point = Point(30, 31)
}
object NullablePointProducer : Producer<Point?> {
override fun produce(): Point? = Point(32, 33)
}
object NullPointProducer : Producer<Point?> {
override fun produce(): Point? = null
}
object MovingPointOperation : PointOperation {
override fun move(value: Point): Point =
Point(value.x + 10, value.y + 10)
}
object DefaultPointFactory : PointFactory {
override fun create(x: Int, y: Int): Point =
Point(x, y)
}
fun consumeAsInterface(value: Coordinates): Int =
value.sum()
fun transformThroughGenericBridge(
transformer: Transformer<Point>,
value: Point
): Point =
transformer.transform(value)
fun transformNullableThroughGenericBridge(
transformer: Transformer<Point?>,
value: Point?
): Point? =
transformer.transform(value)
fun produceThroughGenericBridge(
producer: Producer<Point>
): Point =
producer.produce()
fun produceNullableThroughGenericBridge(
producer: Producer<Point?>
): Point? =
producer.produce()
fun moveThroughPointBridge(
operation: PointOperation,
value: Point
): Point =
operation.move(value)
fun createThroughDefaultDispatch(
factory: PointFactory
): Point =
factory.create()
fun makeEnvelope(point: Point, id: Long?): Envelope =
Envelope(point, id)
fun consumeEnvelope(envelope: Envelope): Long =
envelope.point.sum().toLong() + (envelope.id ?: -100L)
// MODULE: main(lib)
// FILE: main.kt
import lib.*
fun box(): String {
val point = Point(1, 2)
if (consumeAsInterface(point) != 3) {
return "FAIL interface dispatch"
}
val transformed =
transformThroughGenericBridge(PointTransformer, point)
if (transformed != Point(2, 3)) {
return "FAIL generic bridge"
}
val transformedNullable =
transformNullableThroughGenericBridge(
NullablePointTransformer,
point
)
if (transformedNullable != Point(3, 4)) {
return "FAIL nullable generic bridge"
}
if (
transformNullableThroughGenericBridge(
NullablePointTransformer,
null
) != null
) {
return "FAIL nullable generic bridge"
}
val produced =
produceThroughGenericBridge(PointProducer)
if (produced != Point(30, 31)) {
return "FAIL generic return bridge"
}
val producedNullable =
produceNullableThroughGenericBridge(NullablePointProducer)
if (producedNullable != Point(32, 33)) {
return "FAIL nullable generic return bridge"
}
if (produceNullableThroughGenericBridge(NullPointProducer) != null) {
return "FAIL nullable generic return bridge"
}
val moved =
moveThroughPointBridge(MovingPointOperation, point)
if (moved != Point(11, 12)) {
return "FAIL non-generic MFVC bridge"
}
val defaultDispatched =
createThroughDefaultDispatch(DefaultPointFactory)
if (defaultDispatched != Point(20, 21)) {
return "FAIL default dispatch"
}
val envelope = makeEnvelope(point, 40L)
if (consumeEnvelope(envelope) != 43L) {
return "FAIL nested representation"
}
val nullableEnvelope = makeEnvelope(point, null)
if (consumeEnvelope(nullableEnvelope) != -97L) {
return "FAIL nested nullable representation"
}
return "OK"
}