Support finnaly blocks from inline fun in non-local returns
This commit is contained in:
committed by
Michael Bogdanov
parent
309329afd0
commit
9564eaa6fd
@@ -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()
|
||||
}
|
||||
}
|
||||
+129
@@ -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"
|
||||
}
|
||||
+23
@@ -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
|
||||
}
|
||||
+129
@@ -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"
|
||||
}
|
||||
+23
@@ -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()
|
||||
}
|
||||
}
|
||||
+80
@@ -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"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> R) : R {
|
||||
try {
|
||||
block()
|
||||
} finally {
|
||||
return finallyBlock()
|
||||
}
|
||||
}
|
||||
+59
@@ -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"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) : R {
|
||||
try {
|
||||
return block()
|
||||
} finally {
|
||||
finallyBlock()
|
||||
}
|
||||
}
|
||||
+84
@@ -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"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> R) : R {
|
||||
try {
|
||||
return block()
|
||||
} finally {
|
||||
return finallyBlock()
|
||||
}
|
||||
}
|
||||
+58
@@ -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"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) {
|
||||
try {
|
||||
block()
|
||||
} finally {
|
||||
finallyBlock()
|
||||
}
|
||||
}
|
||||
+57
@@ -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"
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public inline fun <R> doCall(block: ()-> R, finallyBlock: ()-> Unit) : R {
|
||||
try {
|
||||
return block()
|
||||
} finally {
|
||||
finallyBlock()
|
||||
}
|
||||
}
|
||||
+49
@@ -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"
|
||||
}
|
||||
+41
@@ -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
|
||||
//}
|
||||
+48
@@ -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"
|
||||
}
|
||||
+41
@@ -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
|
||||
//}
|
||||
+40
@@ -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"
|
||||
}
|
||||
+15
@@ -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
|
||||
}
|
||||
+120
@@ -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"
|
||||
}
|
||||
+29
@@ -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")
|
||||
}
|
||||
+115
@@ -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"
|
||||
}
|
||||
+32
@@ -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
|
||||
}
|
||||
+36
@@ -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"
|
||||
}
|
||||
+14
@@ -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
|
||||
}
|
||||
+91
@@ -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"
|
||||
}
|
||||
+32
@@ -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
|
||||
}
|
||||
+130
@@ -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"
|
||||
}
|
||||
+30
@@ -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
|
||||
}
|
||||
+102
@@ -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"
|
||||
}
|
||||
+24
@@ -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
|
||||
}
|
||||
+105
@@ -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"
|
||||
}
|
||||
+10
@@ -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"
|
||||
}
|
||||
+278
@@ -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"
|
||||
}
|
||||
+29
@@ -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")
|
||||
}
|
||||
+196
@@ -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"
|
||||
}
|
||||
+12
@@ -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
|
||||
}
|
||||
+168
@@ -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"
|
||||
}
|
||||
+22
@@ -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")
|
||||
}
|
||||
Reference in New Issue
Block a user