JS backend: add support for break, return, continue, throw in expressions

This commit is contained in:
Michael Nedzelsky
2014-08-26 14:08:32 +04:00
parent 2296eeef84
commit 3578845e87
26 changed files with 711 additions and 131 deletions
@@ -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"
}
@@ -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"
}
@@ -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()))
@@ -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"
}
@@ -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"
}
@@ -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))