| // WITH_STDLIB | |
| // KJS_WITH_FULL_RUNTIME | |
| // FILE: 1.kt | |
| class My(val value: Int) | |
| inline fun <T, R> T.performWithFinally(job: (T)-> R, finally: (T) -> R) : R { | |
| try { | |
| return job(this) | |
| } finally { | |
| return finally(this) | |
| } | |
| } | |
| inline fun <T, R> T.performWithFailFinally(job: (T)-> R, failJob : (e: RuntimeException, T) -> R, finally: (T) -> R) : R { | |
| try { | |
| return job(this) | |
| } catch (e: RuntimeException) { | |
| return failJob(e, this) | |
| } finally { | |
| return finally(this) | |
| } | |
| } | |
| inline fun String.toInt2() : Int = this.toInt() | |
| // FILE: 2.kt | |
| fun test1(): Int { | |
| var res = My(111).performWithFinally<My, Int>( | |
| { | |
| 1 | |
| }, { | |
| it.value | |
| }) | |
| return res | |
| } | |
| fun test11(): Int { | |
| var result = -1; | |
| val res = My(111).performWithFinally<My, Int>( | |
| { | |
| try { | |
| result = it.value | |
| throw RuntimeException("1") | |
| } catch (e: RuntimeException) { | |
| ++result | |
| throw RuntimeException("2") | |
| } | |
| }, | |
| { | |
| ++result | |
| }) | |
| return res | |
| } | |
| fun test2(): Int { | |
| var res = My(111).performWithFinally<My, Int>( | |
| { | |
| throw RuntimeException("1") | |
| }, | |
| { | |
| it.value | |
| }) | |
| return res | |
| } | |
| fun test3(): Int { | |
| try { | |
| var result = -1; | |
| val res = My(111).performWithFailFinally<My, Int>( | |
| { | |
| result = it.value; | |
| throw RuntimeException("-1") | |
| }, | |
| { e, z -> | |
| ++result | |
| throw RuntimeException("-2") | |
| }, | |
| { | |
| ++result | |
| }) | |
| return res | |
| } catch (e: RuntimeException) { | |
| return e.message?.toInt()!! | |
| } | |
| } | |
| fun box(): String { | |
| if (test1() != 111) return "test1: ${test1()}" | |
| if (test11() != 113) return "test11: ${test11()}" | |
| if (test2() != 111) return "test2: ${test2()}" | |
| if (test3() != 113) return "test3: ${test3()}" | |
| return "OK" | |
| } |