Correct behaviour for break / continue inside function call arguments, including multiple ones. Additional tests.

This commit is contained in:
Mikhail Glukhikh
2015-04-21 14:42:11 +03:00
parent 3702089396
commit fd789cb68e
16 changed files with 188 additions and 2 deletions
@@ -0,0 +1,16 @@
fun bar(): Boolean { return true }
fun gav(w: String, arg: Any, z: String): String
{ return if (arg is String) <!DEBUG_INFO_SMARTCAST!>arg<!> else if (z != "") z else w }
public fun foo(x: String?, z: String?, w: String?): Int {
do {
gav(w!!, if (x == null) break else <!DEBUG_INFO_SMARTCAST!>x<!>, z!!)
} while (bar())
// w is not null because of w!!
<!DEBUG_INFO_SMARTCAST!>w<!>.length()
// z is nullable despite of z!!
z<!UNSAFE_CALL!>.<!>length()
// x is null because of the break
return x<!UNSAFE_CALL!>.<!>length()
}
@@ -0,0 +1,5 @@
package
internal fun bar(): kotlin.Boolean
public fun foo(/*0*/ x: kotlin.String?, /*1*/ z: kotlin.String?, /*2*/ w: kotlin.String?): kotlin.Int
internal fun gav(/*0*/ w: kotlin.String, /*1*/ arg: kotlin.Any, /*2*/ z: kotlin.String): kotlin.String
@@ -0,0 +1,13 @@
fun bar(): Boolean { return true }
fun gav(arg: Any, z: String): String { return if (arg is String) <!DEBUG_INFO_SMARTCAST!>arg<!> else z }
public fun foo(x: String?, z: String?): Int {
do {
gav(if (x == null) break else <!DEBUG_INFO_SMARTCAST!>x<!>, z!!)
} while (bar())
// z is nullable despite of z!!
z<!UNSAFE_CALL!>.<!>length()
// x is null because of the break
return x<!UNSAFE_CALL!>.<!>length()
}
@@ -0,0 +1,5 @@
package
internal fun bar(): kotlin.Boolean
public fun foo(/*0*/ x: kotlin.String?, /*1*/ z: kotlin.String?): kotlin.Int
internal fun gav(/*0*/ arg: kotlin.Any, /*1*/ z: kotlin.String): kotlin.String
@@ -0,0 +1,14 @@
fun bar(): Boolean { return true }
fun gav(arg: Any): String { return if (arg is String) <!DEBUG_INFO_SMARTCAST!>arg<!> else "" }
public fun foo(x: String?): Int {
var y: Any
do {
y = ""
y = gav(if (x == null) break else <!DEBUG_INFO_SMARTCAST!>x<!>)
} while (bar())
y.hashCode()
// x is null because of the break
return x<!UNSAFE_CALL!>.<!>length()
}
@@ -0,0 +1,5 @@
package
internal fun bar(): kotlin.Boolean
public fun foo(/*0*/ x: kotlin.String?): kotlin.Int
internal fun gav(/*0*/ arg: kotlin.Any): kotlin.String
@@ -0,0 +1,13 @@
fun bar(): Boolean { return true }
fun gav(z: String, arg: Any): String { return if (arg is String) <!DEBUG_INFO_SMARTCAST!>arg<!> else z }
public fun foo(x: String?, z: String?): Int {
do {
gav(z!!, if (x == null) break else <!DEBUG_INFO_SMARTCAST!>x<!>)
} while (bar())
// z is not null because of z!!
<!DEBUG_INFO_SMARTCAST!>z<!>.length()
// x is null because of the break
return x<!UNSAFE_CALL!>.<!>length()
}
@@ -0,0 +1,5 @@
package
internal fun bar(): kotlin.Boolean
public fun foo(/*0*/ x: kotlin.String?, /*1*/ z: kotlin.String?): kotlin.Int
internal fun gav(/*0*/ z: kotlin.String, /*1*/ arg: kotlin.Any): kotlin.String
@@ -0,0 +1,16 @@
fun bar(): Boolean { return true }
fun gav(z: String, w: String, arg: Any): String
{ return if (arg is String) <!DEBUG_INFO_SMARTCAST!>arg<!> else if (z != "") z else w }
public fun foo(x: String?, z: String?, w: String?): Int {
do {
gav(z!!, w!!, if (x == null) break else <!DEBUG_INFO_SMARTCAST!>x<!>)
} while (bar())
// w is not null because of w!!
<!DEBUG_INFO_SMARTCAST!>w<!>.length()
// z is not null because of z!!
<!DEBUG_INFO_SMARTCAST!>z<!>.length()
// x is null because of the break
return x<!UNSAFE_CALL!>.<!>length()
}
@@ -0,0 +1,5 @@
package
internal fun bar(): kotlin.Boolean
public fun foo(/*0*/ x: kotlin.String?, /*1*/ z: kotlin.String?, /*2*/ w: kotlin.String?): kotlin.Int
internal fun gav(/*0*/ z: kotlin.String, /*1*/ w: kotlin.String, /*2*/ arg: kotlin.Any): kotlin.String
@@ -0,0 +1,14 @@
fun foo(x: String): String? = x
fun calc(x: String?, y: String?): Int {
do {
// Smart cast because of x!! in receiver
foo(x!!)?.subSequence(0, if (<!DEBUG_INFO_SMARTCAST!>x<!>.length() > 0) 5 else break)
y!!.length()
// x is not null in condition but we do not see it yet
} while (x<!UNSAFE_CALL!>.<!>length() > 0)
// y is nullable because of break
y<!UNSAFE_CALL!>.<!>length()
// x is not null, at least in theory
return <!DEBUG_INFO_SMARTCAST!>x<!>.length()
}
@@ -0,0 +1,4 @@
package
internal fun calc(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Int
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?
@@ -0,0 +1,12 @@
fun foo(x: String): String? = x
fun calc(x: String?): Int {
do {
// Smart cast because of x!! in receiver
foo(x!!)?.subSequence(0, <!DEBUG_INFO_SMARTCAST!>x<!>.length())
// Smart cast because of x!! in receiver
if (<!DEBUG_INFO_SMARTCAST!>x<!>.length() == 0) break
} while (true)
// Here x is also not null
return <!DEBUG_INFO_SMARTCAST!>x<!>.length()
}
@@ -0,0 +1,4 @@
package
internal fun calc(/*0*/ x: kotlin.String?): kotlin.Int
internal fun foo(/*0*/ x: kotlin.String): kotlin.String?