Support finnaly blocks from inline fun in non-local returns

This commit is contained in:
max.kammerer
2014-07-22 13:54:41 +04:00
committed by Michael Bogdanov
parent 309329afd0
commit 9564eaa6fd
55 changed files with 3708 additions and 70 deletions
@@ -0,0 +1,102 @@
import test.*
import Kind.*
enum class Kind {
LOCAL
EXTERNAL
GLOBAL
}
class Holder {
var value: String = ""
}
val FINALLY_CHAIN = "in local finally, in declaration local finally, in external finally, in declaration external finally, in global finally"
class Internal(val value: String)
class External(val value: String)
class Global(val value: String)
fun test1(intKind: Kind, extKind: Kind, holder: Holder): Global {
holder.value = ""
try {
var externalResult = doCall (@ext {
(): External ->
try {
val internalResult = doCall (@int {
(): Internal ->
try {
if (intKind == Kind.GLOBAL) {
return@test1 Global("internal -> global")
}
else if (intKind == EXTERNAL) {
return@ext External("internal -> external")
}
return@int Internal("internal -> local")
}
finally {
holder.value += "in local finally"
}
}, {
holder.value += ", in declaration local finally"
})
if (extKind == GLOBAL || extKind == EXTERNAL) {
return Global("external -> global")
}
External(internalResult.value + ": external -> local");
}
finally {
holder.value += ", in external finally"
}
}, {
holder.value += ", in declaration external finally"
})
return Global(externalResult.value + ": exit")
}
finally {
holder.value += ", in global finally"
}
}
fun box(): String {
var holder = Holder()
var test1 = test1(LOCAL, LOCAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> local: external -> local: exit") return "test1: ${test1}, finally = ${holder.value}"
test1 = test1(EXTERNAL, LOCAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> external: exit") return "test2: ${test1}, finally = ${holder.value}"
test1 = test1(GLOBAL, LOCAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> global") return "test3: ${test1}, finally = ${holder.value}"
test1 = test1(LOCAL, EXTERNAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "external -> global") return "test4: ${test1}, finally = ${holder.value}"
test1 = test1(EXTERNAL, EXTERNAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> external: exit") return "test5: ${test1}, finally = ${holder.value}"
test1 = test1(GLOBAL, EXTERNAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> global") return "test6: ${test1}, finally = ${holder.value}"
test1 = test1(LOCAL, GLOBAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "external -> global") return "test7: ${test1}, finally = ${holder.value}"
test1 = test1(EXTERNAL, GLOBAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> external: exit") return "test8: ${test1}, finally = ${holder.value}"
test1 = test1(GLOBAL, GLOBAL, holder).value
if (holder.value != FINALLY_CHAIN || test1 != "internal -> global") return "test9: ${test1}, finally = ${holder.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyLambda: ()-> Unit) : R {
try {
return block()
} finally {
finallyLambda()
}
}
@@ -0,0 +1,129 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): Int {
val localResult = doCall2 (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return 1
},
{
h.value += ", OK_EXCEPTION"
return 2
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAILT")
return -1;
}
fun test1(h: Holder): Int {
val localResult = doCall2 (
{
h.value += "OK_NONLOCAL"
return 1
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAIL")
return -1;
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
2
},
{
h.value += ", OK_FINALLY"
3
})
return "" + localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
3
})
return "" + localResult;
}
fun test4(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "" + localResult;
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != 2 || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test1 = test1(h)
if (test1 != 1 || h.value != "OK_NONLOCAL, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_NONLOCAL" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,23 @@
package test
public inline fun doCall(block: ()-> Int, exception: (e: Exception)-> Unit, finallyBlock: ()-> Int, res: Int = -111) : Int {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
return res
}
public inline fun <R> doCall2(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R, res: R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
return res
}
@@ -0,0 +1,129 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): Long {
val localResult = doCall2 (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return 1.toLong()
},
{
h.value += ", OK_EXCEPTION"
return 2.toLong()
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAIL")
return -1.toLong()
}
fun test1(h: Holder): Long {
val localResult = doCall2 (
{
h.value += "OK_NONLOCAL"
return 1.toLong()
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAIL")
return -1.toLong()
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
2.toLong()
},
{
h.value += ", OK_FINALLY"
3.toLong()
})
return "" + localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
3.toLong()
})
return "" + localResult;
}
fun test4(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "" + localResult;
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != 2.toLong() || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test1 = test1(h)
if (test1 != 1.toLong() || h.value != "OK_NONLOCAL, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_NONLOCAL" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,23 @@
package test
public inline fun doCall(block: ()-> Long, exception: (e: Exception)-> Unit, finallyBlock: ()-> Long, res: Long = -1111.toLong()) : Long {
try {
block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
return res
}
public inline fun <R> doCall2(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R, res: R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
return res
}
@@ -0,0 +1,113 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder): String {
doCall (
{
h.value += "OK_LOCAL"
},
{
h.value += ", OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
}
)
return "LOCAL";
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
{
h.value += ", OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
})
return "FAIL";
}
fun test3(h: Holder): String {
doCall (
{
h.value += "OK_LOCAL"
},
{
h.value += ", OK_FINALLY1"
return "OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
})
return "FAIL";
}
fun test4(h: Holder): String {
doCall (
{
h.value += "OK_LOCAL"
},
{
h.value += ", OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
return "OK_FINALLY2"
})
return "FAIL";
}
fun test5(h: Holder): String {
doCall (
{
h.value += "OK_LOCAL"
},
{
h.value += ", OK_FINALLY1"
return "OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
return "OK_FINALLY2"
})
return "FAIL";
}
fun box(): String {
var h = Holder()
val test1 = test1(h)
if (test1 != "LOCAL" || h.value != "OK_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_NONLOCAL" || h.value != "OK_NONLOCAL, OK_FINALLY1, OK_FINALLY2") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_FINALLY1" || h.value != "OK_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY2" || h.value != "OK_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test4: ${test4}, holder: ${h.value}"
h = Holder()
val test5 = test5(h)
if (test5 != "OK_FINALLY2" || h.value != "OK_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test5: ${test5}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,14 @@
package test
public inline fun doCall(block: ()-> Unit, finallyBlock1: ()-> Unit, finallyBlock2: ()-> Unit) {
try {
try {
block()
}
finally {
finallyBlock1()
}
} finally {
finallyBlock2()
}
}
@@ -0,0 +1,80 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
"OK_LOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
"OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test4(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun box(): String {
var h = Holder()
val test1 = test1(h)
if (test1 != "OK_FINALLY" || h.value != "OK_LOCAL, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> R) : R {
try {
block()
} finally {
return finallyBlock()
}
}
@@ -0,0 +1,59 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder): String {
val localResult = doCall ({
return "OK_NONLOCAL"
}, {
h.value = "OK_FINALLY"
})
return "FAIL";
}
fun test2(h: Holder): String {
val localResult = doCall (@lambda {
(): String ->
h.value += "OK_LOCAL"
return@lambda "OK_LOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test3(h: Holder): String {
val localResult = doCall ({
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun box(): String {
var h = Holder()
val test1 = test1(h)
if (test1 != "OK_NONLOCAL" || h.value != "OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_FINALLY" || h.value != "OK_LOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) : R {
try {
return block()
} finally {
finallyBlock()
}
}
@@ -0,0 +1,84 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
"OK_LOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test2(h: Holder): String {
val localResult = doCall (
@lambda {
(): String ->
h.value += "OK_NONLOCAL"
return@lambda "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test4(h: Holder): String {
val localResult = doCall (
{
():String ->
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
@l2 {
():String ->
h.value += ", OK_FINALLY"
return@l2 "OK_FINALLY"
})
return localResult;
}
fun box(): String {
var h = Holder()
val test1 = test1(h)
if (test1 != "OK_FINALLY" || h.value != "OK_LOCAL, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> R) : R {
try {
return block()
} finally {
return finallyBlock()
}
}
@@ -0,0 +1,58 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder): String {
doCall ({
return "OK_NONLOCAL"
}, {
h.value = "OK_FINALLY"
})
return "FAIL";
}
fun test2(h: Holder): String {
doCall ({
h.value += "OK_LOCAL"
"OK_LOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun test3(h: Holder): String {
doCall ({
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
}, {
h.value += ", OK_FINALLY"
return "OK_FINALLY"
})
return "FAIL";
}
fun box(): String {
var h = Holder()
val test1 = test1(h)
if (test1 != "OK_NONLOCAL" || h.value != "OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_FINALLY" || h.value != "OK_LOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) {
try {
block()
} finally {
finallyBlock()
}
}
@@ -0,0 +1,57 @@
import test.*
class Holder {
var value: String = ""
}
fun test1(h: Holder) {
val localResult = doCall (
{
h.value = "OK_NONLOCAL"
return
}, {
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
}
fun test2(h: Holder) {
val localResult = doCall (
{
h.value += "OK_LOCAL"
"OK_LOCAL"
}, {
h.value += ", OK_FINALLY"
return
})
}
fun test3(h: Holder) {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return
}, {
h.value += ", OK_FINALLY"
return
})
}
fun box(): String {
var h = Holder()
test1(h)
if (h.value != "OK_NONLOCAL, OK_FINALLY") return "test1 holder: ${h.value}"
h = Holder()
test2(h)
if (h.value != "OK_LOCAL, OK_FINALLY") return "test2 holder: ${h.value}"
h = Holder()
test3(h)
if (h.value != "OK_NONLOCAL, OK_FINALLY") return "test3 holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,9 @@
package test
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) : R {
try {
return block()
} finally {
finallyBlock()
}
}
@@ -0,0 +1,49 @@
import test.*
fun test1(): Int {
var s = 0
doCallAlwaysBreak {
s += it*it
s
}
return s;
}
fun test11(): Int {
return doCallAlwaysBreak {
return -100
}
}
fun test2(): Int {
return doCallAlwaysBreak2 {
return -100
}
}
fun test22(): Int {
var s = 0
doCallAlwaysBreak {
s += it*it
s
}
return s;
}
fun box(): String {
val test1 = test1()
if (test1 != 1) return "test1: ${test1}"
val test11 = test11()
if (test11 != 0) return "test11: ${test11}"
val test2 = test2()
if (test2 != 0) return "test2: ${test2}"
val test22 = test22()
if (test22 != 1) return "test22: ${test22}"
return "OK"
}
@@ -0,0 +1,41 @@
package test
public inline fun doCallAlwaysBreak(block: (i: Int)-> Int) : Int {
var res = 0;
for (i in 1..10) {
try {
block(i)
} finally {
break;
}
}
return res
}
public val z: Boolean = true
public inline fun doCallAlwaysBreak2(block: (i: Int)-> Int) : Int {
var res = 0;
for (i in 1..10) {
try {
res = block(i)
} finally {
if (z)
break
}
}
return res
}
//public inline fun doCallAlwaysBreak2(block: (i: Int)-> Int) : Int {
// var res = 0;
// for (i in 1..10) {
// try {
// res += block(i)
// } finally {
// if (z)
// break
// }
// }
// return res
//}
@@ -0,0 +1,48 @@
import test.*
fun test1(): Int {
var s = 0
doCallAlwaysBreak {
s += it*it
s
}
return s;
}
fun test11(): Int {
return doCallAlwaysBreak {
return -100
}
}
fun test2(): Int {
return doCallAlwaysBreak2 {
return -100
}
}
fun test22(): Int {
var s = 0
doCallAlwaysBreak {
s += it*it
s
}
return s;
}
fun box(): String {
val test1 = test1()
if (test1 != 385) return "test1: ${test1}"
val test11 = test11()
if (test11 != 0) return "test11: ${test11}"
val test2 = test2()
if (test2 != 0) return "test2: ${test2}"
val test22 = test22()
if (test22 != 385) return "test22: ${test22}"
return "OK"
}
@@ -0,0 +1,41 @@
package test
public inline fun doCallAlwaysBreak(block: (i: Int)-> Int) : Int {
var res = 0;
for (i in 1..10) {
try {
res = block(i)
} finally {
continue;
}
}
return res
}
public val z: Boolean = true
public inline fun doCallAlwaysBreak2(block: (i: Int)-> Int) : Int {
var res = 0;
for (i in 1..10) {
try {
res = block(i)
} finally {
if (z)
continue
}
}
return res
}
//public inline fun doCallAlwaysBreak2(block: (i: Int)-> Int) : Int {
// var res = 0;
// for (i in 1..10) {
// try {
// res += block(i)
// } finally {
// if (z)
// continue
// }
// }
// return res
//}
@@ -0,0 +1,40 @@
import test.*
class Holder {
var value: Int = 0
}
fun test1(): Int {
var s = 0
doCall (
{
s += it * it
s
},
{
s += it
}
)
return s;
}
fun test11(h: Holder): Int {
return doCall (
{
return -100
}, {
h.value += it
})
}
fun box(): String {
val test1 = test1()
if (test1 != 935) return "test1: ${test1}"
val h = Holder()
val test11 = test11(h)
if (test11 != -100 && h.value != 55) return "test11: ${test11} holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,15 @@
package test
public inline fun doCall(block: (i: Int)-> Int, fblock: (i: Int)-> Unit) : Int {
var res = 0;
for (i in 1..10) {
try {
res = block(i)
} finally {
for (i in 1..10) {
fblock(i)
}
}
}
return res
}
@@ -0,0 +1,120 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
try {
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
} finally {
h.value += ", OK_FINALLY_INNER"
}
})
return localResult;
}
catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
}
else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test01(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
throw Exception1("1")
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
try {
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
} catch(e: RuntimeException) {
h.value += ", OK_CATCHED"
} finally {
h.value += ", OK_FINALLY_INNER"
}
"OK_FINALLY"
})
return localResult;
}
fun test02(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
throw Exception2("1")
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
try {
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
} catch(e: RuntimeException) {
h.value += ", OK_CATCHED"
} finally {
h.value += ", OK_FINALLY_INNER"
}
"OK_FINALLY"
}, "OK")
return localResult;
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != "CATCHED_EXCEPTION" || h.value != "OK_NON_LOCAL, OK_FINALLY, OK_FINALLY_INNER") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test01 = test01(h)
if (test01 != "OK_EXCEPTION1" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY, OK_CATCHED, OK_FINALLY_INNER") return "test01: ${test01}, holder: ${h.value}"
h = Holder()
val test02 = test02(h)
if (test02 != "OK_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY, OK_CATCHED, OK_FINALLY_INNER") return "test02: ${test02}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,29 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception: (e: Exception)-> Unit, exception2: (e: Exception)-> Unit, finallyBlock: ()-> String, res: String = "Fail") : String {
try {
block()
} catch (e: Exception1) {
exception(e)
} catch (e: Exception2) {
exception2(e)
} finally {
finallyBlock()
}
return res
}
public inline fun <R> doCall2(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
throw java.lang.RuntimeException("fail")
}
@@ -0,0 +1,115 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder, throwEx1: Boolean, throwEx2: Boolean, throwEx3: Boolean = false, throwEx4: Boolean = false): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
if (throwEx1) {
throw Exception1("1")
}
if (throwEx2) {
throw Exception2("1")
}
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
if (throwEx3) {
throw Exception1("3_1")
}
if (throwEx4) {
throw Exception2("4_1")
}
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
if (throwEx3) {
throw Exception1("3_2")
}
if (throwEx4) {
throw Exception2("4_2")
}
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY1"
try {
try {
throw Exception1("fail")
}
catch (e: RuntimeException) {
h.value += ", CATCHED1"
}
finally {
h.value += ", ADDITIONAL"
}
} finally {
h.value += " FINALLY1"
}
"OK_FINALLY1"
},
{
h.value += ", OK_EXCEPTION3"
return "OK_EXCEPTION3"
},
{
h.value += ", OK_EXCEPTION4"
return "OK_EXCEPTION4"
},
{
h.value += ", OK_FINALLY2"
try {
try {
throw Exception1("fail2")
} catch (e: RuntimeException) {
h.value += ", CATCHED2"
} finally {
h.value += ", ADDITIONAL"
}
} finally {
h.value += " FINALLY2"
}
"OK_FINALLY2"
})
return localResult;
return "FAIL";
}
fun box(): String {
var h = Holder()
var test0 = test0(h, false, false)
if (test0 != "OK_NON_LOCAL" || h.value != "OK_NON_LOCAL, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_1: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false)
if (test0 != "OK_EXCEPTION1" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_2: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true)
if (test0 != "OK_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_3: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false, true, false)
if (test0 != "OK_EXCEPTION3" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_EXCEPTION3, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_4: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false, false, true)
if (test0 != "OK_EXCEPTION4" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_EXCEPTION4, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_5: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true, true, false)
if (test0 != "OK_EXCEPTION3" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_EXCEPTION3, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_6: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true, false, true)
if (test0 != "OK_EXCEPTION4" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, CATCHED1, ADDITIONAL FINALLY1, OK_EXCEPTION4, OK_FINALLY2, CATCHED2, ADDITIONAL FINALLY2") return "test0_7: ${test0}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,32 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception1: (e: Exception)-> Unit, exception2: (e: Exception)-> Unit, finallyBlock: ()-> String,
exception3: (e: Exception)-> Unit, exception4: (e: Exception)-> Unit, finallyBlock2: ()-> String, res: String = "Fail") : String {
try {
try {
block()
}
catch (e: Exception1) {
exception1(e)
}
catch (e: Exception2) {
exception2(e)
}
finally {
finallyBlock()
}
} catch (e: Exception1) {
exception3(e)
}
catch (e: Exception2) {
exception4(e)
}
finally {
finallyBlock2()
}
return res
}
@@ -0,0 +1,36 @@
import test.*
class Holder {
var value: String = ""
}
fun test01(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
throw Exception1("1")
"OK_NON_LOCAL_RES"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
try {
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
} catch(e: RuntimeException) {
h.value += ", OK_CATCHED"
}
"OK_FINALLY_RES"
}, "FAIL")
return localResult;
}
fun box(): String {
var h = Holder()
val test01 = test01(h)
if (test01 != "OK_EXCEPTION1" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY, OK_CATCHED") return "test01: ${test01}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,14 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception: (e: Exception)-> Unit, finallyBlock: ()-> String, res: String = "Fail") : String {
try {
block()
} catch (e: Exception1) {
exception(e)
} finally {
finallyBlock()
}
return res
}
@@ -0,0 +1,91 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder, throwEx1: Boolean, throwEx2: Boolean, throwEx3: Boolean = false, throwEx4: Boolean = false): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
if (throwEx1) {
throw Exception1("1")
}
if (throwEx2) {
throw Exception2("1")
}
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
if (throwEx3) {
throw Exception1("3_1")
}
if (throwEx4) {
throw Exception2("4_1")
}
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
if (throwEx3) {
throw Exception1("3_2")
}
if (throwEx4) {
throw Exception2("4_2")
}
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY1"
"OK_FINALLY1"
},
{
h.value += ", OK_EXCEPTION3"
return "OK_EXCEPTION3"
},
{
h.value += ", OK_EXCEPTION4"
return "OK_EXCEPTION4"
},
{
h.value += ", OK_FINALLY2"
"OK_FINALLY2"
})
return localResult;
return "FAIL";
}
fun box(): String {
var h = Holder()
var test0 = test0(h, false, false)
if (test0 != "OK_NON_LOCAL" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_1: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false)
if (test0 != "OK_EXCEPTION1" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_2: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true)
if (test0 != "OK_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, OK_FINALLY2") return "test0_3: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false, true, false)
if (test0 != "OK_EXCEPTION3" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, OK_EXCEPTION3, OK_FINALLY2") return "test0_4: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, false, false, true)
if (test0 != "OK_EXCEPTION4" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY1, OK_EXCEPTION4, OK_FINALLY2") return "test0_5: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true, true, false)
if (test0 != "OK_EXCEPTION3" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, OK_EXCEPTION3, OK_FINALLY2") return "test0_6: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, true, false, true)
if (test0 != "OK_EXCEPTION4" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY1, OK_EXCEPTION4, OK_FINALLY2") return "test0_7: ${test0}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,32 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception1: (e: Exception)-> Unit, exception2: (e: Exception)-> Unit, finallyBlock: ()-> String,
exception3: (e: Exception)-> Unit, exception4: (e: Exception)-> Unit, finallyBlock2: ()-> String, res: String = "Fail") : String {
try {
try {
block()
}
catch (e: Exception1) {
exception1(e)
}
catch (e: Exception2) {
exception2(e)
}
finally {
finallyBlock()
}
} catch (e: Exception1) {
exception3(e)
}
catch (e: Exception2) {
exception4(e)
}
finally {
finallyBlock2()
}
return res
}
@@ -0,0 +1,130 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(
h: Holder,
throwExceptionInTry: Boolean,
throwInternalEx2: Boolean = false,
throwInternalFinEx1: Boolean = false,
throwInternalFinEx2: Boolean = false,
throwExternalFinEx1: Boolean = false,
throwExternalFinEx2: Boolean = false,
res: String = "Fail"
): String {
try {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
if (throwExceptionInTry) {
throw Exception1("1")
}
return "OK_NON_LOCAL"
},
{
h.value += ", OK_INTERNAL_EXCEPTION1"
if (throwInternalEx2) {
throw Exception2("2_1")
}
return "OK_INTERNAL_EXCEPTION1"
},
{
h.value += ", OK_FINALLY1"
if (throwInternalFinEx1) {
throw Exception1("EXCEPTION_IN_INTERNAL_FINALLY")
}
if (throwInternalFinEx2) {
throw Exception2("EXCEPTION222_IN_INTERNAL_FINALLY")
}
"OK_FINALLY1"
},
{
h.value += ", OK_EXTERNAL_EXCEPTION2"
return "OK_EXTERNAL_EXCEPTION2"
},
{
h.value += ", OK_FINALLY2"
if (throwExternalFinEx1) {
throw Exception1("EXCEPTION_IN_EXTERNAL_FINALLY")
}
if (throwExternalFinEx2) {
throw Exception2("EXCEPTION222_IN_EXTERNAL_FINALLY")
}
"OK_FINALLY2"
}, res)
return localResult;
} catch(e: Exception1) {
return e.getMessage()!!
} catch(e: Exception2) {
return e.getMessage()!!
}
}
fun box(): String {
var h = Holder()
var test0 = test0(h, false, throwExternalFinEx1 = false, res = "OK")
if (test0 != "OK_INNER_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_1: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwExternalFinEx1 = true, res = "OK")
if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_2: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwExternalFinEx2 = true, res = "OK")
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_4: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwExternalFinEx1 = true, res = "OK")
if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_3: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalEx2 = true, throwExternalFinEx1 = true, res = "OK")
if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_5: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalEx2 = true, throwExternalFinEx2 = true, res = "OK")
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_6: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwInternalFinEx1 = true)
if (test0 != "EXCEPTION_IN_INTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_7: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwInternalFinEx1 = true, throwExternalFinEx2 = true)
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_71: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwInternalFinEx2 = true)
if (test0 != "OK_EXTERNAL_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_8: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, false, throwInternalFinEx2 = true, throwExternalFinEx2 = true)
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_81: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalFinEx1 = true)
if (test0 != "EXCEPTION_IN_INTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_9: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalFinEx1 = true, throwExternalFinEx2 = true)
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_10: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalFinEx2 = true)
if (test0 != "OK_EXTERNAL_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_11: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, true, throwInternalFinEx2 = true, throwExternalFinEx2 = true)
if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_12: ${test0}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,30 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception1: (e: Exception)-> Unit, finallyBlock: ()-> String,
exception3: (e: Exception)-> Unit, finallyBlock2: ()-> String, res: String = "Fail") : String {
try {
try {
block()
}
catch (e: Exception1) {
exception1(e)
}
finally {
if (true) {
finallyBlock()
/*External finally would be injected here*/
return res + "_INNER_FINALLY"
}
}
} catch (e: Exception2) {
exception3(e)
}
finally {
finallyBlock2()
}
return res
}
@@ -0,0 +1,102 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(
h: Holder,
throwExternalFinEx1: Boolean = false,
res: String = "Fail"
): String {
try {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
return "OK_NON_LOCAL"
},
{
h.value += ", OK_FINALLY1"
"OK_FINALLY1"
},
{
h.value += ", OK_FINALLY2"
if (throwExternalFinEx1) {
throw Exception1("EXCEPTION_IN_EXTERNAL_FINALLY")
}
"OK_FINALLY2"
}, res)
return localResult;
} catch(e: Exception1) {
return e.getMessage()!!
} catch(e: Exception2) {
return e.getMessage()!!
}
}
fun box(): String {
var h = Holder()
var test0 = test0(h, res = "OK")
if (test0 != "OK_INNER_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_1: ${test0}, holder: ${h.value}"
h = Holder()
test0 = test0(h, throwExternalFinEx1 = true, res = "OK")
if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_2: ${test0}, holder: ${h.value}"
// h = Holder()
// test0 = test0(h, throwExternalFinEx2 = true, res = "OK")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_4: ${test0}, holder: ${h.value}"
// h = Holder()
// test0 = test0(h, true, throwExternalFinEx1 = true, res = "OK")
// if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_3: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, true, throwInternalEx2 = true, throwExternalFinEx1 = true, res = "OK")
// if (test0 != "EXCEPTION_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_5: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, true, throwInternalEx2 = true, throwExternalFinEx2 = true, res = "OK")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_6: ${test0}, holder: ${h.value}"
//
//
//
// h = Holder()
// test0 = test0(h, false, throwInternalFinEx1 = true, res = "FAIL")
// if (test0 != "EXCEPTION_IN_INTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_7: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, false, throwInternalFinEx1 = true, throwExternalFinEx2 = true, res = "FAIL")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_FINALLY2") return "test0_71: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, false, throwInternalFinEx2 = true, res = "FAIL")
// if (test0 != "OK_EXTERNAL_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_8: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, false, throwInternalFinEx2 = true, throwExternalFinEx2 = true, res = "FAIL")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_81: ${test0}, holder: ${h.value}"
//
//
//
// h = Holder()
// test0 = test0(h, true, throwInternalFinEx1 = true, res = "FAIL")
// if (test0 != "EXCEPTION_IN_INTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_9: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, true, throwInternalFinEx1 = true, throwExternalFinEx2 = true, res = "FAIL")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_FINALLY2") return "test0_10: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, true, throwInternalFinEx2 = true, res = "FAIL")
// if (test0 != "OK_EXTERNAL_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_11: ${test0}, holder: ${h.value}"
//
// h = Holder()
// test0 = test0(h, true, throwInternalFinEx2 = true, throwExternalFinEx2 = true, res = "FAIL")
// if (test0 != "EXCEPTION222_IN_EXTERNAL_FINALLY" || h.value != "OK_NON_LOCAL, OK_INTERNAL_EXCEPTION1, OK_FINALLY1, OK_EXTERNAL_EXCEPTION2, OK_FINALLY2") return "test0_12: ${test0}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,24 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, finallyBlock: ()-> String,
finallyBlock2: ()-> String, res: String = "Fail") : String {
try {
try {
block()
}
finally {
if (true) {
finallyBlock()
/*External finally would be injected here*/
return res + "_INNER_FINALLY"
}
}
} finally {
finallyBlock2()
}
return res
}
@@ -0,0 +1,105 @@
import test.*
class Holder {
var value: String = ""
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
})
return localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
})
return localResult;
}
fun test4(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
})
return localResult;
}
fun test5(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
if (true) {
throw java.lang.RuntimeException("EXCEPTION")
}
h.value += "fail"
return "OK_EXCEPTION"
})
return localResult;
} catch (e: RuntimeException) {
if (e.getMessage() != "EXCEPTION") {
return "FAIL in exception: " + e.getMessage()
} else {
return "CATCHED_EXCEPTION"
}
}
}
fun box(): String {
var h = Holder()
val test2 = test2(h)
if (test2 != "OK_NONLOCAL" || h.value != "OK_NONLOCAL") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION") return "test4: ${test4}, holder: ${h.value}"
h = Holder()
val test5 = test5(h)
if (test5 != "CATCHED_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION") return "test5: ${test5}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,10 @@
package test
public inline fun doCall(block: ()-> String, exception: (e: Exception)-> Unit) : String {
try {
return block()
} catch (e: Exception) {
exception(e)
}
return "Fail in doCall"
}
@@ -0,0 +1,278 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
})
return localResult;
}
catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
}
else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test01(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
throw Exception1("1")
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun test02(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
throw Exception2("1")
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun test1(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw Exception1("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
}, "Fail")
}
catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
}
else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test2(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw Exception1("1")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
throw Exception2("2")
"OK_EXCEPTION"
},
{
h.value += ", OK_EXCEPTION2"
"OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
catch (e: Exception2) {
return "CATCHED_EXCEPTION"
}
return "Fail";
}
fun test3(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw Exception2("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION1"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
}, "Fail")
}
catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
}
else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test4(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw Exception2("1")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION1"
return "OK_EXCEPTION"
},
{
h.value += ", OK_EXCEPTION2"
throw Exception1("1")
"OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
catch (e: Exception1) {
return "CATCHED_EXCEPTION"
}
return "Fail";
}
fun test5(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw Exception2("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
throw java.lang.RuntimeException("FAIL_EX")
"OK_EXCEPTION"
},
{
h.value += ", OK_EXCEPTION2"
return "OK_EXCEPTION2"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != "CATCHED_EXCEPTION" || h.value != "OK_NON_LOCAL, OK_FINALLY") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test01 = test01(h)
if (test01 != "OK_EXCEPTION1" || h.value != "OK_NON_LOCAL, OK_EXCEPTION1, OK_FINALLY") return "test01: ${test01}, holder: ${h.value}"
h = Holder()
val test02 = test02(h)
if (test02 != "OK_EXCEPTION2" || h.value != "OK_NON_LOCAL, OK_EXCEPTION2, OK_FINALLY") return "test02: ${test02}, holder: ${h.value}"
h = Holder()
val test1 = test1(h)
if (test1 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION1, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION1, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION2, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION2, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
h = Holder()
val test5 = test5(h)
if (test5 != "OK_EXCEPTION2" || h.value != "OK_LOCAL, OK_EXCEPTION2, OK_FINALLY") return "test5: ${test5}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,29 @@
package test
public class Exception1(message: String) : java.lang.RuntimeException(message)
public class Exception2(message: String) : java.lang.RuntimeException(message)
public inline fun doCall(block: ()-> String, exception: (e: Exception)-> Unit, exception2: (e: Exception)-> Unit, finallyBlock: ()-> String, res: String = "Fail") : String {
try {
block()
} catch (e: Exception1) {
exception(e)
} catch (e: Exception2) {
exception2(e)
} finally {
finallyBlock()
}
return res
}
public inline fun <R> doCall2(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
throw java.lang.RuntimeException("fail")
}
@@ -0,0 +1,196 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "Fail")
return localResult;
}
fun test1(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw java.lang.RuntimeException()
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "OK")
return localResult;
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAIL")
return localResult;
}
fun test3(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
}, "FAIL")
return localResult;
}
fun test4(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
return "OK_FINALLY"
}, "FAIL")
return localResult;
}
fun test5(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
return "OK_FINALLY"
}, "FAIL")
return localResult;
}
fun test6(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_NONLOCAL"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_NONLOCAL"
},
{
h.value += ", OK_EXCEPTION"
if (true) {
throw java.lang.RuntimeException()
}
h.value += "fail"
return "OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
},
"FAIL1")
} catch (e: Exception) {
return "OK"
}
return "FAIL2";
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != "OK_LOCAL" || h.value != "OK_LOCAL, OK_FINALLY") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test1 = test1(h)
if (test1 != "OK" || h.value != "OK_LOCAL, OK_EXCEPTION, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_NONLOCAL" || h.value != "OK_NONLOCAL, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "OK_EXCEPTION" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
h = Holder()
val test5 = test5(h)
if (test5 != "OK_FINALLY" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test5: ${test5}, holder: ${h.value}"
h = Holder()
val test6 = test6(h)
if (test6 != "OK" || h.value != "OK_NONLOCAL, OK_EXCEPTION, OK_FINALLY") return "test6: ${test6}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,12 @@
package test
public inline fun <R> doCall(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R, res: R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
return res
}
@@ -0,0 +1,168 @@
import test.*
class Holder {
var value: String = ""
}
fun test0(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_NON_LOCAL"
return "OK_NON_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
})
return localResult;
} catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
} else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test1(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw java.lang.RuntimeException("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
})
} catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
} else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test2(h: Holder): String {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw java.lang.RuntimeException()
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
return localResult;
}
fun test3(h: Holder): String {
try {
val localResult = doCall (
{
h.value += "OK_LOCAL"
throw java.lang.RuntimeException("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
throw java.lang.RuntimeException("FAIL_EX")
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
throw java.lang.RuntimeException("FINALLY")
"OK_FINALLY"
})
} catch (e: RuntimeException) {
if (e.getMessage() != "FINALLY") {
return "FAIL in exception: " + e.getMessage()
} else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun test4(h: Holder): String {
try {
val localResult = doCall2 (
{
h.value += "OK_LOCAL"
throw java.lang.RuntimeException("FAIL")
"OK_LOCAL"
},
{
h.value += ", OK_EXCEPTION"
throw java.lang.RuntimeException("EXCEPTION")
"OK_EXCEPTION"
},
{
h.value += ", OK_FINALLY"
"OK_FINALLY"
})
} catch (e: RuntimeException) {
if (e.getMessage() != "EXCEPTION") {
return "FAIL in exception: " + e.getMessage()
} else {
return "CATCHED_EXCEPTION"
}
}
return "FAIL";
}
fun box(): String {
var h = Holder()
val test0 = test0(h)
if (test0 != "CATCHED_EXCEPTION" || h.value != "OK_NON_LOCAL, OK_FINALLY") return "test0: ${test0}, holder: ${h.value}"
h = Holder()
val test1 = test1(h)
if (test1 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION, OK_FINALLY") return "test1: ${test1}, holder: ${h.value}"
h = Holder()
val test2 = test2(h)
if (test2 != "OK_FINALLY" || h.value != "OK_LOCAL, OK_EXCEPTION, OK_FINALLY") return "test2: ${test2}, holder: ${h.value}"
h = Holder()
val test3 = test3(h)
if (test3 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION, OK_FINALLY") return "test3: ${test3}, holder: ${h.value}"
h = Holder()
val test4 = test4(h)
if (test4 != "CATCHED_EXCEPTION" || h.value != "OK_LOCAL, OK_EXCEPTION, OK_FINALLY") return "test4: ${test4}, holder: ${h.value}"
return "OK"
}
@@ -0,0 +1,22 @@
package test
public inline fun <R> doCall(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
return finallyBlock()
}
}
public inline fun <R> doCall2(block: ()-> R, exception: (e: Exception)-> Unit, finallyBlock: ()-> R) : R {
try {
return block()
} catch (e: Exception) {
exception(e)
} finally {
finallyBlock()
}
throw java.lang.RuntimeException("fail")
}