JS/Inlining: in function call like fn() extract fn to a local variable, since fn can be access to property with side effects. Add tests to prove that evaluation order became proper in certain cases. Fix KT-11711, KT-7674, KT-7043

This commit is contained in:
Alexey Andreev
2016-05-06 13:27:59 +03:00
parent c3d0fca92b
commit 4783c9b612
6 changed files with 205 additions and 1 deletions
@@ -0,0 +1,101 @@
// See KT-11711
package foo
interface A {
val b: B
}
interface B {
fun c(a: Any?)
}
val a: A
get() {
log("a.get")
return object : A {
override val b: B
get() {
log("b.get")
return object : B {
override fun c(a: Any?) {
log("c()")
}
}
}
}
}
val g: Any?
get() {
log("g.get")
return "c"
}
inline fun foo(): Any? {
log("foo()")
return g;
}
inline fun bar(): Any? {
return g;
}
inline fun baz(): Any? {
return log("baz()");
}
inline fun boo(a: Any?): Any? {
return log("boo()");
}
fun box(): String {
log("--1--")
a.b.c(g)
log("--2--")
a.b.c(foo())
log("--3--")
a.b.c(bar())
log("--4--")
a.b.c(baz())
log("--5--")
a.b.c(boo(g))
assertEquals("""--1--
a.get
b.get
g.get
c()
--2--
a.get
b.get
foo()
g.get
c()
--3--
a.get
b.get
g.get
c()
--4--
a.get
b.get
baz()
c()
--5--
a.get
b.get
g.get
boo()
c()
""", pullLog().replace(';', '\n'))
return "OK"
}
@@ -0,0 +1,24 @@
// See KT-7674
package foo
class A(val a: Int) {
val plus: (Int)->Int
get() {
log("get plus fun")
return {
log("do plus")
a + it
}
}
}
inline fun <T : Any> id(x: T): T {
log(x.toString())
return x
}
fun box(): String {
assertEquals(3, A(id(1)).plus(id(2)))
assertEquals("1;get plus fun;2;do plus;", pullLog())
return "OK"
}
@@ -0,0 +1,20 @@
// Looks similar to KT-7674
package foo
inline fun bar(): Int {
log("bar")
return 10
}
val x: Int
get() {
log("x")
return 1
}
fun box(): String {
assertEquals(12, x + bar() + x)
assertEquals("x;bar;x;", pullLog())
return "OK"
}
@@ -0,0 +1,27 @@
// See KT-7043, KT-11711
package foo
inline fun foo(b: Any) {
val t = aa[0]
val a = b
}
val a: Array<String>
get() {
log("a.get")
return arrayOf("a")
}
val aa: Array<String>
get() {
log("aa.get")
return arrayOf("aa")
}
fun box(): String {
foo(a[0])
assertEquals("a.get;aa.get;", pullLog())
return "OK"
}