JS backend: add support for break, return, continue, throw in expressions
This commit is contained in:
+44
-6
@@ -1,46 +1,62 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
fun id(s: String, b: Boolean): Boolean {
|
||||
global += s
|
||||
return b
|
||||
}
|
||||
|
||||
fun bar(b: Boolean): String {
|
||||
if (b && return "A")
|
||||
if (id("A", b) && return "A")
|
||||
return "B"
|
||||
else
|
||||
return "C"
|
||||
}
|
||||
|
||||
fun testBreak(b: Boolean, expected: Int) {
|
||||
global = ""
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) b && break
|
||||
if (i == 2) id("A", b) && break
|
||||
}
|
||||
assertEquals(expected, i, "break 1")
|
||||
assertEquals("A", global, "break 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = b && break
|
||||
var x = id("A", b) && break
|
||||
}
|
||||
}
|
||||
assertEquals(expected, i, "break 2")
|
||||
assertEquals("A", global, "break 2")
|
||||
}
|
||||
|
||||
fun testContinue(b: Boolean, expected: Int) {
|
||||
global = ""
|
||||
var i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) b && continue
|
||||
if (i == 2) id("A", b) && continue
|
||||
n++
|
||||
}
|
||||
assertEquals(expected, n, "continue 1")
|
||||
assertEquals("A", global, "continue 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = b && continue
|
||||
var x = id("A", b) && continue
|
||||
assertEquals(x, b)
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(expected, n, "continue 2")
|
||||
assertEquals("A", global, "continue 2")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
@@ -49,11 +65,33 @@ fun box(): String {
|
||||
testBreak(true, 2)
|
||||
testBreak(false, 6)
|
||||
|
||||
global = ""
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) break && id("A", false)
|
||||
}
|
||||
assertEquals(2, i, "break && false")
|
||||
assertEquals("", global, "break && false")
|
||||
|
||||
testContinue(true, 4)
|
||||
testContinue(false, 5)
|
||||
|
||||
assertEquals("A", bar(true))
|
||||
global = ""
|
||||
i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) continue && id("A", false)
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue && false")
|
||||
assertEquals("", global, "continue && false")
|
||||
|
||||
assertEquals("A", bar(true), "bar")
|
||||
assertEquals("A", global, "bar")
|
||||
|
||||
global = ""
|
||||
assertEquals("C", bar(false))
|
||||
assertEquals("A", global, "bar")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
fun f(arg1: String, arg2: String, arg3: String): String {
|
||||
global += ":f:"
|
||||
return arg1 + arg2 + arg3
|
||||
}
|
||||
|
||||
fun id(s: String): String {
|
||||
global += s
|
||||
return s
|
||||
}
|
||||
|
||||
fun bar(s: String): String {
|
||||
return f(id(s), if (true) return ":bar:" else return "b", id(s))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var b: Boolean
|
||||
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) f(id("A"), break, id("B"))
|
||||
}
|
||||
assertEquals(2, i, "break 1")
|
||||
assertEquals("A", global, "break 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = f(id("A"), break, id("B"))
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 2")
|
||||
assertEquals("A", global, "break 2")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = "B" + f(id("A"), break, id("B"))
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 3")
|
||||
assertEquals("A", global, "break 3")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) f(id("A"), continue, id("B"))
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 1")
|
||||
assertEquals("A", global, "continue 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = f(id("A"), continue, id("B"))
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 2")
|
||||
assertEquals("A", global, "continue 2")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = "B" + f(id("A"), continue, id("B"))
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 3")
|
||||
assertEquals("A", global, "continue 3")
|
||||
|
||||
global = ""
|
||||
assertEquals(":bar:", bar("A"))
|
||||
assertEquals("A", global, "bar")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+22
-8
@@ -11,14 +11,14 @@ fun bar(a: A?): String {
|
||||
|
||||
fun testBreak(a: A?, expected: Int) {
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) a ?: break
|
||||
while(i++<5) {
|
||||
if (i==2) a ?: break
|
||||
}
|
||||
assertEquals(expected, i, "break 1")
|
||||
|
||||
i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = a ?: break
|
||||
}
|
||||
}
|
||||
@@ -28,16 +28,16 @@ fun testBreak(a: A?, expected: Int) {
|
||||
fun testContinue(a: A?, expected: Int) {
|
||||
var i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) a ?: continue
|
||||
while(i++<5) {
|
||||
if (i==2) a ?: continue
|
||||
n++
|
||||
}
|
||||
assertEquals(expected, n)
|
||||
|
||||
i = 0
|
||||
n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = a ?: continue
|
||||
}
|
||||
n++
|
||||
@@ -50,9 +50,23 @@ fun box(): String {
|
||||
testBreak(null, 2)
|
||||
testBreak(A(), 6)
|
||||
|
||||
var i = 0
|
||||
while(i++<5) {
|
||||
if (i==2) break ?: null
|
||||
}
|
||||
assertEquals(2, i, "break ?: null")
|
||||
|
||||
testContinue(null, 4)
|
||||
testContinue(A(), 5)
|
||||
|
||||
i = 0
|
||||
var n = 0
|
||||
while(i++<5) {
|
||||
if (i==2) continue ?: null
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue ?: null")
|
||||
|
||||
assertEquals("A", bar(null))
|
||||
assertEquals("B", bar(A()))
|
||||
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
class A {
|
||||
var prop: Boolean = false
|
||||
}
|
||||
|
||||
fun getA(): A = try { global += "getA"; A() } finally {}
|
||||
|
||||
fun barEq(): String {
|
||||
10 == return "eq"
|
||||
}
|
||||
|
||||
fun barLt(): String {
|
||||
10 < (return "lt") as Int
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var b: Boolean
|
||||
|
||||
var i = 0
|
||||
while(i++<5) {
|
||||
if (i==2) 10 == break
|
||||
}
|
||||
assertEquals(2, i, "break 1")
|
||||
|
||||
i = 0
|
||||
while(i++<5) {
|
||||
if (i==2) 10 < (break as Int)
|
||||
}
|
||||
assertEquals(2, i, "break 2")
|
||||
|
||||
i = 0
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = 10 == break;
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 3")
|
||||
|
||||
i = 0
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = 10 < (break as Int)
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 4")
|
||||
|
||||
i = 0
|
||||
var bVar: Boolean
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
bVar = 10 < (break as Int)
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 5")
|
||||
|
||||
i = 0
|
||||
var bVarArray = array(true, false)
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
bVarArray[try { global += "A"; 0} finally {}] = 10 < (break as Int)
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 6")
|
||||
assertEquals("A", global, "break 6")
|
||||
|
||||
i = 0
|
||||
global = ""
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
getA().prop = 10 < (break as Int)
|
||||
}
|
||||
}
|
||||
assertEquals(2, i, "break 7")
|
||||
assertEquals("getA", global, "break 7")
|
||||
|
||||
i = 0
|
||||
var n = 0
|
||||
while(i++<5) {
|
||||
if (i==2) 10 == continue
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 1")
|
||||
|
||||
i = 0
|
||||
n = 0
|
||||
while(i++<5) {
|
||||
if (i==2) 10 < (continue as Int)
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 2")
|
||||
|
||||
i = 0
|
||||
n = 0
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = 10 == continue
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 3")
|
||||
|
||||
i = 0
|
||||
n = 0
|
||||
while(i++<5) {
|
||||
if (i==2) {
|
||||
var x = 10 < (continue as Int)
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue 4")
|
||||
|
||||
assertEquals("eq", barEq())
|
||||
assertEquals("lt", barLt())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
|
||||
fun whileReturn(): String {
|
||||
var i = 0
|
||||
while(if (i<2) true else { global += ":return:"; return ":whileReturn:"}) {
|
||||
i++
|
||||
global += "A"
|
||||
}
|
||||
return ":whileReturn:after:"
|
||||
}
|
||||
|
||||
fun whileImmediateReturn(): String {
|
||||
var i = 0
|
||||
while(return ":whileImmediateReturn:") {
|
||||
global += "A"
|
||||
}
|
||||
return ":whileImmediateReturn:after"
|
||||
}
|
||||
|
||||
fun doWhileReturn(): String {
|
||||
var i = 0
|
||||
do {
|
||||
i++
|
||||
global += "A"
|
||||
}
|
||||
while(if (i<2) true else { global += ":return:"; return ":doWhileReturn:"})
|
||||
return ":doWhileReturn:after:"
|
||||
}
|
||||
|
||||
fun doWhileReturnFromCondition(): String {
|
||||
var i = 0
|
||||
do {
|
||||
global += "A"
|
||||
} while(return ":doWhileReturnFromCondition:")
|
||||
return ":doWhileReturnFromCondition:after"
|
||||
}
|
||||
|
||||
fun doWhileImmediateReturn(): String {
|
||||
var i = 0
|
||||
do {
|
||||
return ":doWhileImmediateReturn:"
|
||||
global += "A"
|
||||
} while(false)
|
||||
return ":doWhileImmediateReturn:after"
|
||||
}
|
||||
|
||||
fun forReturn(b: Boolean): String {
|
||||
var i = 0
|
||||
for(i in (if (b) 1..2 else { global += ":return:"; return ":forReturn:"})) {
|
||||
global += "A"
|
||||
}
|
||||
return ":forReturn:after:"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var i = 0
|
||||
|
||||
// KT-5704 'while' detected as unreachable though loop is running
|
||||
// TODO Remove or uncomment when issue will be fixed
|
||||
//while(if (++i==10) break else continue) {}
|
||||
//assertEquals(10, i)
|
||||
|
||||
i = 0
|
||||
do { i++ } while(if (++i==10) break else continue)
|
||||
assertEquals(10, i)
|
||||
|
||||
assertEquals(":whileReturn:", whileReturn())
|
||||
assertEquals("AA:return:", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":whileImmediateReturn:", whileImmediateReturn())
|
||||
assertEquals("", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":doWhileReturn:", doWhileReturn())
|
||||
assertEquals("AA:return:", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":doWhileReturnFromCondition:", doWhileReturnFromCondition())
|
||||
assertEquals("A", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":doWhileImmediateReturn:", doWhileImmediateReturn())
|
||||
assertEquals("", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":forReturn:after:", forReturn(true))
|
||||
assertEquals("AA", global)
|
||||
|
||||
global = ""
|
||||
assertEquals(":forReturn:", forReturn(false))
|
||||
assertEquals(":return:", global)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+41
-5
@@ -1,46 +1,61 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
fun id(s: String, b: Boolean): Boolean {
|
||||
global += s
|
||||
return b
|
||||
}
|
||||
|
||||
fun bar(b: Boolean): String {
|
||||
if (b || return "A")
|
||||
if (id("A",b) || return "A")
|
||||
return "B"
|
||||
else
|
||||
return "C"
|
||||
}
|
||||
|
||||
fun testBreak(b: Boolean, expected: Int) {
|
||||
global = ""
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) b || break
|
||||
if (i == 2) id("A", b) || break
|
||||
}
|
||||
assertEquals(expected, i, "break 1")
|
||||
assertEquals("A", global, "break 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = b || break
|
||||
var x = id("A", b) || break
|
||||
}
|
||||
}
|
||||
assertEquals(expected, i, "break 2")
|
||||
assertEquals("A", global, "break 2")
|
||||
}
|
||||
|
||||
fun testContinue(b: Boolean, expected: Int) {
|
||||
global = ""
|
||||
var i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) b || continue
|
||||
if (i == 2) id("A", b) || continue
|
||||
n++
|
||||
}
|
||||
assertEquals(expected, n, "continue 1")
|
||||
assertEquals("A", global, "continue 1")
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) {
|
||||
var x = b || continue
|
||||
var x = id("A", b) || continue
|
||||
}
|
||||
n++
|
||||
}
|
||||
assertEquals(expected, n, "continue 2")
|
||||
assertEquals("A", global, "continue 2")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
@@ -48,11 +63,32 @@ fun box(): String {
|
||||
testBreak(true, 6)
|
||||
testBreak(false, 2)
|
||||
|
||||
global = ""
|
||||
var i = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) break || id("A", true)
|
||||
}
|
||||
assertEquals(2, i, "break || true")
|
||||
assertEquals("", global, "break || false")
|
||||
|
||||
testContinue(true, 5)
|
||||
testContinue(false, 4)
|
||||
|
||||
global = ""
|
||||
i = 0
|
||||
var n = 0
|
||||
while (i++ < 5) {
|
||||
if (i == 2) continue || id("A", true)
|
||||
n++
|
||||
}
|
||||
assertEquals(4, n, "continue || true")
|
||||
assertEquals("", global, "continue || true")
|
||||
|
||||
assertEquals("B", bar(true))
|
||||
assertEquals("A", global, "bar")
|
||||
global = ""
|
||||
assertEquals("A", bar(false))
|
||||
assertEquals("A", global, "bar")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -11,6 +11,9 @@ fun box(): String {
|
||||
val a = if (true || if(bar("A", false)) {2} else {3} == 0) { }
|
||||
assertEquals("", global)
|
||||
|
||||
true || if(bar("A", false)) {2} else {3} == 0
|
||||
assertEquals("", global)
|
||||
|
||||
// Simple || Simple
|
||||
global = ""
|
||||
assertEquals(true, bar("A", true) || bar("B", true))
|
||||
|
||||
Reference in New Issue
Block a user