JS backend: added tests which pass an extension lambda to native code and visa versa.
Added workarounds in some tests because Rhino wrongly implicitly converts first parameter of `Function.call` to `Object`. But it's contradicts to ES5 specification(par. 15.3.4.4). (#KT-4238, #KT-4345) In progress
This commit is contained in:
@@ -88,4 +88,12 @@ public final class NativeInteropTest extends SingleFileTranslationTest {
|
||||
public void testNativePropertyWithCustomName() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testPassExtLambdaToNative() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testPassExtLambdaFromNative() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
|
||||
+22
-7
@@ -1,15 +1,30 @@
|
||||
package foo
|
||||
|
||||
fun assertEquals<T>(expected: T, actual: T, message: String) {
|
||||
if (expected != actual) throw Exception("Failed when $message, expected = $expected, actual = $actual")
|
||||
}
|
||||
|
||||
// workaround for Rhino
|
||||
var n = 0
|
||||
class A {
|
||||
val i = ++n
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
fun Int.foo(): Boolean {
|
||||
fun Int.bar() = this == 2 && this@foo == 1
|
||||
val b = { this == 1 }
|
||||
fun A.foo() {
|
||||
fun A.bar() {
|
||||
assertEquals(2, this.i, "check this.i in A.bar()")
|
||||
assertEquals(1, this@foo.i, "check this@foo.i in A.bar()")
|
||||
}
|
||||
val b = { assertEquals(1, this.i, "check this.i in b") }
|
||||
|
||||
return this == 1 && 2.bar() && b()
|
||||
}
|
||||
assertEquals(1, this.i, "check this.i in A.foo()")
|
||||
A().bar()
|
||||
b()
|
||||
}
|
||||
|
||||
if (!1.foo()) return "Failed"
|
||||
A().foo()
|
||||
|
||||
return "OK"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
// KT-2388
|
||||
package foo
|
||||
|
||||
var done = 0
|
||||
// workaround for Rhino
|
||||
class Done(val i: Int)
|
||||
|
||||
var done = Done(0)
|
||||
|
||||
object foo {
|
||||
var result = "FAIL"
|
||||
|
||||
val lambda = {
|
||||
result = "foo.lambda OK"
|
||||
done = 3
|
||||
done = Done(3)
|
||||
}
|
||||
|
||||
val extLambda: Int.() -> Unit = {
|
||||
val extLambda: Done.() -> Unit = {
|
||||
result = "foo.extLambda OK"
|
||||
done = this
|
||||
}
|
||||
@@ -22,10 +25,10 @@ class Foo {
|
||||
|
||||
val lambda = {
|
||||
result = "Foo::lambda OK"
|
||||
done = -7
|
||||
done = Done(-7)
|
||||
}
|
||||
|
||||
val extLambda: Int.() -> Unit = {
|
||||
val extLambda: Done.() -> Unit = {
|
||||
result = "Foo::extLambda OK"
|
||||
done = this
|
||||
}
|
||||
@@ -41,20 +44,20 @@ fun box(): String {
|
||||
|
||||
a()
|
||||
if (foo.result != "foo.lambda OK") return "foo.result = \"${foo.result}\", but expected \"foo.lambda OK\""
|
||||
if (done != 3) return "done = $done, but expected 3"
|
||||
if (done.i != 3) return "done.i = ${done.i}, but expected 3"
|
||||
|
||||
23.b()
|
||||
Done(23).b()
|
||||
if (foo.result != "foo.extLambda OK") return "foo.result = \"${foo.result}\", but expected \"foo.extLambda OK\""
|
||||
if (done != 23) return "done = $done, but expected 23"
|
||||
if (done.i != 23) return "done.i = ${done.i}, but expected 23"
|
||||
|
||||
|
||||
c()
|
||||
if (f.result != "Foo::lambda OK") return "a.result = \"${f.result}\", but expected \"Foo::lambda OK\""
|
||||
if (done != -7) return "done = $done, but expected -7"
|
||||
if (done.i != -7) return "done.i = ${done.i}, but expected -7"
|
||||
|
||||
71.d()
|
||||
Done(71).d()
|
||||
if (f.result != "Foo::extLambda OK") return "a.result = \"${f.result}\", but expected \"Foo::extLambda OK\""
|
||||
if (done != 71) return "done = $done, but expected 71"
|
||||
if (done.i != 71) return "done.i = ${done.i}, but expected 71"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package foo
|
||||
|
||||
native
|
||||
class A(val v: String)
|
||||
|
||||
class B {
|
||||
fun bar(a: A, extLambda: A.(Int, String) -> String): String = a.extLambda(7, "_rr_")
|
||||
}
|
||||
|
||||
native
|
||||
fun nativeBox(b: B): String = noImpl
|
||||
|
||||
fun box(): String {
|
||||
val r = nativeBox(B())
|
||||
if (r != "foo_rr_7") return r
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package foo
|
||||
|
||||
native
|
||||
class A(val v: String)
|
||||
|
||||
native
|
||||
fun bar(a: A, extLambda: A.(Int, String) -> String): String = noImpl
|
||||
|
||||
fun box(): String {
|
||||
val a = A("test")
|
||||
|
||||
val r = bar(a) { i, s -> "${this.v} $i $s"}
|
||||
if (r != "test 4 boo") return r
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
function A(v) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
function nativeBox(b) {
|
||||
return b.bar(new A("foo"), function(i, s) { return "" + this.v + s + i })
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
function A(v) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
function bar(a, extLambda) {
|
||||
return extLambda.call(a, 4, "boo")
|
||||
}
|
||||
Reference in New Issue
Block a user