Move codegen tests on old language versions under oldLanguageVersions/
This directory is skipped in JVM IR test generator, so they won't show up as failed anymore. Note that only failing tests are moved to oldLanguageVersions/. Tests which already pass are still being run. It may be useful not to break them in case we _do_ need to support some pre-1.3 language feature switches in JVM IR.
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
// !LANGUAGE: -ProperForInArrayLoopRangeVariableAssignmentSemantic
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun box(): String {
|
||||
var xs = intArrayOf(1, 2, 3)
|
||||
var sum = 0
|
||||
for (x in xs) {
|
||||
sum = sum * 10 + x
|
||||
xs = intArrayOf(4, 5)
|
||||
}
|
||||
return if (sum == 15) "OK" else "Fail: $sum"
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines -ExperimentalBuilderInference
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
interface AsyncGenerator<in T> {
|
||||
suspend fun yield(value: T)
|
||||
}
|
||||
|
||||
interface AsyncSequence<out T> {
|
||||
operator fun iterator(): AsyncIterator<T>
|
||||
}
|
||||
|
||||
interface AsyncIterator<out T> {
|
||||
operator suspend fun hasNext(): Boolean
|
||||
operator suspend fun next(): T
|
||||
}
|
||||
|
||||
fun <T> asyncGenerate(block: suspend AsyncGenerator<T>.() -> Unit): AsyncSequence<T> = object : AsyncSequence<T> {
|
||||
override fun iterator(): AsyncIterator<T> {
|
||||
val iterator = AsyncGeneratorIterator<T>()
|
||||
iterator.nextStep = block.createCoroutine(receiver = iterator, completion = iterator)
|
||||
return iterator
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncGeneratorIterator<T>: AsyncIterator<T>, AsyncGenerator<T>, ContinuationAdapter<Unit>() {
|
||||
var computedNext = false
|
||||
var nextValue: T? = null
|
||||
var nextStep: Continuation<Unit>? = null
|
||||
|
||||
// if (computesNext) computeContinuation is Continuation<T>
|
||||
// if (!computesNext) computeContinuation is Continuation<Boolean>
|
||||
var computesNext = false
|
||||
var computeContinuation: Continuation<*>? = null
|
||||
|
||||
override val context = EmptyCoroutineContext
|
||||
|
||||
suspend fun computeHasNext(): Boolean = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = false
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun computeNext(): T = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = true
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun resumeIterator(exception: Throwable?) {
|
||||
if (exception != null) {
|
||||
done()
|
||||
computeContinuation!!.resumeWithException(exception)
|
||||
return
|
||||
}
|
||||
if (computesNext) {
|
||||
computedNext = false
|
||||
(computeContinuation as Continuation<T>).resume(nextValue as T)
|
||||
} else {
|
||||
(computeContinuation as Continuation<Boolean>).resume(nextStep != null)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun hasNext(): Boolean {
|
||||
if (!computedNext) return computeHasNext()
|
||||
return nextStep != null
|
||||
}
|
||||
|
||||
override suspend fun next(): T {
|
||||
if (!computedNext) return computeNext()
|
||||
computedNext = false
|
||||
return nextValue as T
|
||||
}
|
||||
|
||||
private fun done() {
|
||||
computedNext = true
|
||||
nextStep = null
|
||||
}
|
||||
|
||||
// Completion continuation implementation
|
||||
override fun resume(value: Unit) {
|
||||
done()
|
||||
resumeIterator(null)
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
done()
|
||||
resumeIterator(exception)
|
||||
}
|
||||
|
||||
// Generator implementation
|
||||
override suspend fun yield(value: T): Unit = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computedNext = true
|
||||
nextValue = value
|
||||
nextStep = c
|
||||
resumeIterator(null)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun cst(a: Any?): String? = a as String?
|
||||
fun any(a: Any?): Any? = a
|
||||
|
||||
fun box(): String {
|
||||
val seq = asyncGenerate {
|
||||
yield("O")
|
||||
yield("K")
|
||||
}
|
||||
|
||||
var res = ""
|
||||
|
||||
builder {
|
||||
// type of `prev` should be j/l/Object everywhere (even in a expected type position)
|
||||
var prev: Any? = null
|
||||
for (i in seq) {
|
||||
res += i
|
||||
prev = any(res)
|
||||
// merge of NULL_VALUE and j/l/Object should result in common j/l/Object value
|
||||
// but it was NULL_VALUE and we do not spill null values, we just put
|
||||
// ACONST_NULL after suspension point instead
|
||||
}
|
||||
|
||||
res = cst(prev) ?: "fail 1"
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines -ExperimentalBuilderInference
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
interface AsyncGenerator<in T> {
|
||||
suspend fun yield(value: T)
|
||||
}
|
||||
|
||||
interface AsyncSequence<out T> {
|
||||
operator fun iterator(): AsyncIterator<T>
|
||||
}
|
||||
|
||||
interface AsyncIterator<out T> {
|
||||
operator suspend fun hasNext(): Boolean
|
||||
operator suspend fun next(): T
|
||||
}
|
||||
|
||||
fun <T> asyncGenerate(block: suspend AsyncGenerator<T>.() -> Unit): AsyncSequence<T> = object : AsyncSequence<T> {
|
||||
override fun iterator(): AsyncIterator<T> {
|
||||
val iterator = AsyncGeneratorIterator<T>()
|
||||
iterator.nextStep = block.createCoroutine(receiver = iterator, completion = iterator)
|
||||
return iterator
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncGeneratorIterator<T>: AsyncIterator<T>, AsyncGenerator<T>, ContinuationAdapter<Unit>() {
|
||||
var computedNext = false
|
||||
var nextValue: T? = null
|
||||
var nextStep: Continuation<Unit>? = null
|
||||
|
||||
// if (computesNext) computeContinuation is Continuation<T>
|
||||
// if (!computesNext) computeContinuation is Continuation<Boolean>
|
||||
var computesNext = false
|
||||
var computeContinuation: Continuation<*>? = null
|
||||
|
||||
override val context = EmptyCoroutineContext
|
||||
|
||||
suspend fun computeHasNext(): Boolean = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = false
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun computeNext(): T = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = true
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun resumeIterator(exception: Throwable?) {
|
||||
if (exception != null) {
|
||||
done()
|
||||
computeContinuation!!.resumeWithException(exception)
|
||||
return
|
||||
}
|
||||
if (computesNext) {
|
||||
computedNext = false
|
||||
(computeContinuation as Continuation<T>).resume(nextValue as T)
|
||||
} else {
|
||||
(computeContinuation as Continuation<Boolean>).resume(nextStep != null)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun hasNext(): Boolean {
|
||||
if (!computedNext) return computeHasNext()
|
||||
return nextStep != null
|
||||
}
|
||||
|
||||
override suspend fun next(): T {
|
||||
if (!computedNext) return computeNext()
|
||||
computedNext = false
|
||||
return nextValue as T
|
||||
}
|
||||
|
||||
private fun done() {
|
||||
computedNext = true
|
||||
nextStep = null
|
||||
}
|
||||
|
||||
// Completion continuation implementation
|
||||
override fun resume(value: Unit) {
|
||||
done()
|
||||
resumeIterator(null)
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
done()
|
||||
resumeIterator(exception)
|
||||
}
|
||||
|
||||
// Generator implementation
|
||||
override suspend fun yield(value: T): Unit = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computedNext = true
|
||||
nextValue = value
|
||||
nextStep = c
|
||||
resumeIterator(null)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T> AsyncSequence<T>.toList(): List<T> {
|
||||
val out = arrayListOf<T>()
|
||||
for (e in this@toList) out += e // fails at this line
|
||||
return out
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val seq = asyncGenerate {
|
||||
yield("O")
|
||||
yield("K")
|
||||
}
|
||||
|
||||
var res = listOf<String>()
|
||||
|
||||
builder {
|
||||
res = seq.toList()
|
||||
}
|
||||
|
||||
if (res.size > 2) return "fail 1: ${res.size}"
|
||||
|
||||
return res[0] + res[1]
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines -ExperimentalBuilderInference
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
interface AsyncGenerator<in T> {
|
||||
suspend fun yield(value: T)
|
||||
}
|
||||
|
||||
interface AsyncSequence<out T> {
|
||||
operator fun iterator(): AsyncIterator<T>
|
||||
}
|
||||
|
||||
interface AsyncIterator<out T> {
|
||||
operator suspend fun hasNext(): Boolean
|
||||
operator suspend fun next(): T
|
||||
}
|
||||
|
||||
fun <T> asyncGenerate(block: suspend AsyncGenerator<T>.() -> Unit): AsyncSequence<T> = object : AsyncSequence<T> {
|
||||
override fun iterator(): AsyncIterator<T> {
|
||||
val iterator = AsyncGeneratorIterator<T>()
|
||||
iterator.nextStep = block.createCoroutine(receiver = iterator, completion = iterator)
|
||||
return iterator
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncGeneratorIterator<T>: AsyncIterator<T>, AsyncGenerator<T>, ContinuationAdapter<Unit>() {
|
||||
var computedNext = false
|
||||
var nextValue: T? = null
|
||||
var nextStep: Continuation<Unit>? = null
|
||||
|
||||
// if (computesNext) computeContinuation is Continuation<T>
|
||||
// if (!computesNext) computeContinuation is Continuation<Boolean>
|
||||
var computesNext = false
|
||||
var computeContinuation: Continuation<*>? = null
|
||||
|
||||
override val context = EmptyCoroutineContext
|
||||
|
||||
suspend fun computeHasNext(): Boolean = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = false
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
suspend fun computeNext(): T = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computesNext = true
|
||||
computeContinuation = c
|
||||
nextStep!!.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun resumeIterator(exception: Throwable?) {
|
||||
if (exception != null) {
|
||||
done()
|
||||
computeContinuation!!.resumeWithException(exception)
|
||||
return
|
||||
}
|
||||
if (computesNext) {
|
||||
computedNext = false
|
||||
(computeContinuation as Continuation<T>).resume(nextValue as T)
|
||||
} else {
|
||||
(computeContinuation as Continuation<Boolean>).resume(nextStep != null)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun hasNext(): Boolean {
|
||||
if (!computedNext) return computeHasNext()
|
||||
return nextStep != null
|
||||
}
|
||||
|
||||
override suspend fun next(): T {
|
||||
if (!computedNext) return computeNext()
|
||||
computedNext = false
|
||||
return nextValue as T
|
||||
}
|
||||
|
||||
private fun done() {
|
||||
computedNext = true
|
||||
nextStep = null
|
||||
}
|
||||
|
||||
// Completion continuation implementation
|
||||
override fun resume(value: Unit) {
|
||||
done()
|
||||
resumeIterator(null)
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
done()
|
||||
resumeIterator(exception)
|
||||
}
|
||||
|
||||
// Generator implementation
|
||||
override suspend fun yield(value: T): Unit = suspendCoroutineUninterceptedOrReturn { c ->
|
||||
computedNext = true
|
||||
nextValue = value
|
||||
nextStep = c
|
||||
resumeIterator(null)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val seq = asyncGenerate {
|
||||
yield("O")
|
||||
yield("K")
|
||||
}
|
||||
|
||||
var res = ""
|
||||
|
||||
builder {
|
||||
for (i in seq) {
|
||||
res += i
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
enum class Foo(vararg expected: String) {
|
||||
A("start", "A", "end"),
|
||||
B("start", "BCD", "end"),
|
||||
C("start", "BCD", "end"),
|
||||
D("start", "BCD", "end"),
|
||||
E("start", "E", "end"),
|
||||
F("start", "end");
|
||||
|
||||
val expected = expected.toList()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
for (c in Foo.values()) {
|
||||
val actual = getSequence(c).toList()
|
||||
if (actual != c.expected) {
|
||||
return "FAIL: -- ${c.expected} != $actual"
|
||||
}
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun getSequence(a: Foo) =
|
||||
buildSequence {
|
||||
yield("start")
|
||||
when (a) {
|
||||
Foo.A -> {
|
||||
yield("A")
|
||||
}
|
||||
Foo.B,
|
||||
Foo.C,
|
||||
Foo.D-> {
|
||||
yield("BCD")
|
||||
}
|
||||
Foo.E-> {
|
||||
yield("E")
|
||||
}
|
||||
}
|
||||
yield("end")
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
class A<T : String> {
|
||||
suspend fun foo() {}
|
||||
|
||||
suspend fun bar(): T {
|
||||
foo()
|
||||
return suspendCoroutineUninterceptedOrReturn { x ->
|
||||
x.resume(x.toString() as T)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
|
||||
builder {
|
||||
result = A<String>().bar()
|
||||
}
|
||||
|
||||
return if (result == "(kotlin.coroutines.experimental.Continuation<T>) -> kotlin.Any?") "OK" else "Fail: $result"
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
|
||||
|
||||
fun runCustomLambdaAsCoroutine(e: Throwable? = null, x: (Continuation<String>) -> Any?): String {
|
||||
var result = "fail"
|
||||
var wasIntercepted = false
|
||||
val c = (x as suspend () -> String).createCoroutine(object: helpers.ContinuationAdapter<String>() {
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
throw exception
|
||||
}
|
||||
|
||||
override val context: CoroutineContext
|
||||
get() = object: ContinuationInterceptor {
|
||||
override fun <R> fold(initial: R, operation: (R, CoroutineContext.Element) -> R): R {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
override fun <E : CoroutineContext.Element> get(key: CoroutineContext.Key<E>): E? {
|
||||
if (key == ContinuationInterceptor.Key) {
|
||||
return this as E
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>) = object : helpers.ContinuationAdapter<T>() {
|
||||
override val context: CoroutineContext
|
||||
get() = continuation.context
|
||||
|
||||
override fun resume(value: T) {
|
||||
wasIntercepted = true
|
||||
continuation.resume(value)
|
||||
}
|
||||
|
||||
override fun resumeWithException(exception: Throwable) {
|
||||
wasIntercepted = true
|
||||
continuation.resumeWithException(exception)
|
||||
}
|
||||
}
|
||||
|
||||
override fun minusKey(key: CoroutineContext.Key<*>): CoroutineContext {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
override fun plus(context: CoroutineContext): CoroutineContext {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
override val key: CoroutineContext.Key<*>
|
||||
get() = ContinuationInterceptor.Key
|
||||
}
|
||||
|
||||
override fun resume(value: String) {
|
||||
result = value
|
||||
}
|
||||
})
|
||||
|
||||
if (e != null)
|
||||
c.resumeWithException(e)
|
||||
else
|
||||
c.resume(Unit)
|
||||
|
||||
if (!wasIntercepted) return "was not intercepted"
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val x = runCustomLambdaAsCoroutine {
|
||||
it.resume("OK")
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
if (x != "OK") return "fail 1: $x"
|
||||
|
||||
val y = runCustomLambdaAsCoroutine {
|
||||
"OK"
|
||||
}
|
||||
|
||||
if (y != "OK") return "fail 2: $x"
|
||||
|
||||
|
||||
try {
|
||||
runCustomLambdaAsCoroutine(RuntimeException("OK")) {
|
||||
throw RuntimeException("fail 3")
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
return e.message!!
|
||||
}
|
||||
|
||||
return "fail 3"
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JS_IR, JS
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
val lambda1 = { x: Any -> } as (Any) -> Unit
|
||||
val suspendLambda0: suspend () -> Unit = {}
|
||||
|
||||
fun box(): String {
|
||||
assert(lambda1 is SuspendFunction0<*>) { "Failed: lambda1 !is SuspendFunction0<*>" }
|
||||
assert(suspendLambda0 is Function1<*, *>) { "Failed: suspendLambda0 is Function1<*, *>" }
|
||||
assert(suspendLambda0 is SuspendFunction0<*>) { "Failed: suspendLambda0 is SuspendFunction0<*>" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
// TARGET_BACKEND: JVM
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
suspend fun suspendHere(): Unit = suspendCoroutineUninterceptedOrReturn { x ->
|
||||
x.resume(Unit)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
fun builder1(c: suspend () -> Unit) {
|
||||
(c as Continuation<Unit>).resume(Unit)
|
||||
}
|
||||
|
||||
fun builder2(c: suspend () -> Unit) {
|
||||
val continuation = c.createCoroutine(EmptyContinuation)
|
||||
|
||||
val delegateField = continuation.javaClass.getDeclaredField("delegate")
|
||||
delegateField.setAccessible(true)
|
||||
val originalContinuation = delegateField.get(continuation)
|
||||
|
||||
val declaredField = originalContinuation.javaClass.superclass.getDeclaredField("label")
|
||||
declaredField.setAccessible(true)
|
||||
declaredField.set(originalContinuation, -3)
|
||||
continuation.resume(Unit)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
try {
|
||||
builder1 {
|
||||
suspendHere()
|
||||
}
|
||||
return "fail 1"
|
||||
} catch (e: kotlin.KotlinNullPointerException) {
|
||||
}
|
||||
|
||||
try {
|
||||
builder2 {
|
||||
suspendHere()
|
||||
}
|
||||
return "fail 3"
|
||||
} catch (e: java.lang.IllegalStateException) {
|
||||
if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 4: ${e.message!!}"
|
||||
}
|
||||
|
||||
var result = "OK"
|
||||
|
||||
try {
|
||||
builder1 {
|
||||
result = "fail 5"
|
||||
}
|
||||
return "fail 6"
|
||||
} catch (e: kotlin.KotlinNullPointerException) {
|
||||
}
|
||||
|
||||
try {
|
||||
builder2 {
|
||||
result = "fail 8"
|
||||
}
|
||||
return "fail 9"
|
||||
} catch (e: java.lang.IllegalStateException) {
|
||||
if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 10: ${e.message!!}"
|
||||
return result
|
||||
}
|
||||
|
||||
return "fail"
|
||||
}
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_COROUTINES
|
||||
// WITH_RUNTIME
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
interface I {}
|
||||
|
||||
suspend inline fun foo() = object : I {}
|
||||
|
||||
// MODULE: useLib(lib)
|
||||
// FILE: UseLib.java
|
||||
import kotlin.coroutines.experimental.*;
|
||||
import kotlin.Unit;
|
||||
|
||||
public class UseLib {
|
||||
public static String useFoo() {
|
||||
Object i = LibKt.foo(new MyContinuation());
|
||||
return i.getClass().getName() + " " + i.getClass().getEnclosingClass().getName() + " " + i.getClass().getEnclosingClass().getEnclosingClass();
|
||||
}
|
||||
}
|
||||
|
||||
class MyContinuation implements Continuation<I> {
|
||||
public CoroutineContext getContext() {
|
||||
return EmptyCoroutineContext.INSTANCE;
|
||||
}
|
||||
public void resume(I value) {}
|
||||
public void resumeWithException(Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(useLib)
|
||||
// FILE: main.kt
|
||||
|
||||
fun box(): String {
|
||||
val res = UseLib.useFoo()
|
||||
if (res == "LibKt\$foo\$2 LibKt null") {
|
||||
return "OK"
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// WITH_COROUTINES
|
||||
// WITH_REFLECT
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
class A {
|
||||
fun noArgs() = "OK"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (A::noArgs.isSuspend) return "FAIL"
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
// FILE: I.kt
|
||||
|
||||
interface I {
|
||||
suspend fun foo(x: Int): String
|
||||
suspend fun bar(x: Int): String
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass implements I {
|
||||
@Override
|
||||
public String foo(int x, kotlin.coroutines.experimental.Continuation<? super String> continuation) {
|
||||
return "O";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object bar(int x, kotlin.coroutines.experimental.Continuation<? super String> continuation) {
|
||||
return foo(x, continuation);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
class K : JavaClass() {
|
||||
override suspend fun foo(x: Int): String = super.foo(x) + suspendCoroutine { it.resume("K") }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
|
||||
builder {
|
||||
// Changing the call to 'K().bar(1)' doesn't work because of KT-25036
|
||||
result = K().foo(1)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// DONT_TARGET_EXACT_BACKEND: JS_IR
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
val f = run {
|
||||
buildSequence {
|
||||
if (true) {
|
||||
yield("OK")
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return f[0]
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// FILE: main.kt
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
open class A(val v: String) {
|
||||
suspend fun suspendThere(v: String): String = suspendCoroutineUninterceptedOrReturn { x ->
|
||||
x.resume(v)
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
open suspend fun suspendHere(): String = suspendThere("O") + suspendThere(v)
|
||||
}
|
||||
|
||||
class B(v: String) : A(v) {
|
||||
override suspend fun suspendHere(): String = super.suspendHere() + suspendThere("56")
|
||||
}
|
||||
|
||||
fun builder(c: suspend A.() -> Unit) {
|
||||
c.startCoroutine(B("K"), EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = JavaClass.foo()
|
||||
|
||||
if (result != "OK56") return "fail 1: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
import kotlin.coroutines.experimental.*;
|
||||
public class JavaClass {
|
||||
public static String foo() {
|
||||
final String[] res = new String[1];
|
||||
|
||||
new B("K").suspendHere(new Continuation<String>() {
|
||||
@Override
|
||||
public CoroutineContext getContext() {
|
||||
return EmptyCoroutineContext.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume(String s) {
|
||||
res[0] = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeWithException(Throwable throwable) {
|
||||
}
|
||||
});
|
||||
|
||||
return res[0];
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// !LANGUAGE: -ReleaseCoroutines
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
// FILE: I.kt
|
||||
|
||||
interface I {
|
||||
suspend fun foo(x: Int): String
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
|
||||
public class JavaClass implements I {
|
||||
@Override
|
||||
public Object foo(int x, kotlin.coroutines.experimental.Continuation<? super String> continuation) {
|
||||
continuation.resume("OK");
|
||||
return kotlin.coroutines.experimental.intrinsics.IntrinsicsKt.getCOROUTINE_SUSPENDED();
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
import helpers.*
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
|
||||
builder {
|
||||
result = JavaClass().foo(1)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// !LANGUAGE: -DataClassInheritance
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
data class Foo(val s: String)
|
||||
|
||||
fun box(): String {
|
||||
val f1 = Foo("OK")
|
||||
val f2 = Foo("OK")
|
||||
if (f1 != f2) return "Fail equals"
|
||||
if (f1.hashCode() != f2.hashCode()) return "Fail hashCode"
|
||||
if (f1.toString() != f2.toString() || f1.toString() != "Foo(s=OK)") return "Fail toString: $f1 $f2"
|
||||
|
||||
return f1.s
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// !LANGUAGE: -FunctionTypesWithBigArity
|
||||
|
||||
// This test does not make sense for JVM because a diagnostic is reported when function types with big arity are not available
|
||||
// (see diagnostics/tests/sourceCompatibility/noBigFunctionTypes.kt)
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
|
||||
class A
|
||||
|
||||
fun foo(
|
||||
p00: A, p01: A, p02: A, p03: A, p04: A, p05: A, p06: A, p07: A, p08: A, p09: A,
|
||||
p10: A, p11: A, p12: A, p13: A, p14: A, p15: A, p16: A, p17: A, p18: A, p19: A,
|
||||
p20: A, p21: A, p22: A, p23: A, p24: A, p25: A, p26: A, p27: A, p28: A, p29: A
|
||||
): String = "OK"
|
||||
|
||||
fun bar(x: Function30<A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, String>): String {
|
||||
val a = A()
|
||||
return x(a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return bar(::foo)
|
||||
}
|
||||
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
// !LANGUAGE: -ThrowNpeOnExplicitEqualsForBoxedNull
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(J.BOOL_NULL.equals(null), true)
|
||||
assertEquals(J.CHAR_NULL.equals(null), true)
|
||||
assertEquals(J.BYTE_NULL.equals(null), true)
|
||||
assertEquals(J.SHORT_NULL.equals(null), true)
|
||||
assertEquals(J.INT_NULL.equals(null), true)
|
||||
assertEquals(J.LONG_NULL.equals(null), true)
|
||||
assertEquals(J.FLOAT_NULL.equals(null), true)
|
||||
assertEquals(J.DOUBLE_NULL.equals(null), true)
|
||||
|
||||
assertEquals(J.BOOL_NULL == null, true)
|
||||
assertEquals(J.CHAR_NULL == null, true)
|
||||
assertEquals(J.BYTE_NULL == null, true)
|
||||
assertEquals(J.SHORT_NULL == null, true)
|
||||
assertEquals(J.INT_NULL == null, true)
|
||||
assertEquals(J.LONG_NULL == null, true)
|
||||
assertEquals(J.FLOAT_NULL == null, true)
|
||||
assertEquals(J.DOUBLE_NULL == null, true)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: J.java
|
||||
public class J {
|
||||
public static Boolean BOOL_NULL = null;
|
||||
public static Character CHAR_NULL = null;
|
||||
public static Byte BYTE_NULL = null;
|
||||
public static Short SHORT_NULL = null;
|
||||
public static Integer INT_NULL = null;
|
||||
public static Long LONG_NULL = null;
|
||||
public static Float FLOAT_NULL = null;
|
||||
public static Double DOUBLE_NULL = null;
|
||||
}
|
||||
Reference in New Issue
Block a user