Simplify function hierarchy in reflection

Get rid of all classes except kotlin.reflect.KFunction, which will be used to
represent all kinds of simple functions.

Lots of changes to test data are related to the fact that KFunction is not an
extension function (as opposed to KMemberFunction and KExtensionFunction who
were) and so a member or an extension function reference now requires all
arguments be passed to it in the parentheses, including receivers. This is
probably temporary until we support calling any function both as a free
function and as an extension. In JS, functions and extension functions are not
interchangeable, so tests on this behavior are removed until this is supported
This commit is contained in:
Alexander Udalov
2015-06-23 20:34:25 +03:00
parent 3549e1e035
commit c3b97e0668
113 changed files with 350 additions and 534 deletions
@@ -9,4 +9,4 @@ class B : A() {
override fun foo() = "OK"
}
fun box(): String = B().(A::foo)()
fun box(): String = (A::foo)(B())
@@ -2,7 +2,7 @@
package foo
fun box(): String {
if (true.(Boolean::not)() != false) return "Fail 1"
if (false.(Boolean::not)() != true) return "Fail 2"
if ((Boolean::not)(true) != false) return "Fail 1"
if ((Boolean::not)(false) != true) return "Fail 2"
return "OK"
}
@@ -12,14 +12,14 @@ fun box():String {
val a = A()
var r = a.(A::memBar)("!!")
var r = (A::memBar)(a, "!!")
if (r != "sA:memBar:!!") return r
r = a.(A::extBar)("!!")
r = (A::extBar)(a, "!!")
if (r != "sA:extBar:!!") return r
r = a.(A::locExtBar)("!!")
r = (A::locExtBar)(a, "!!")
if (r != "sA:locExtBar:!!") return r
return "OK"
}
}
@@ -1,7 +1,7 @@
package foo
fun run(a: A, arg: String, funRef:A.(String) -> String): String {
return a.(funRef)(arg)
fun run(a: A, arg: String, funRef:(A, String) -> String): String {
return funRef(a, arg)
}
class A {
@@ -25,8 +25,8 @@ fun box():String {
r = run(a, "!!", A::locExtBar)
if (r != "sA:locExtBar:!!") return r
r = run(a, "!!") {A.(other:String):String -> s + ":literal:" + other }
r = run(a, "!!") {(a: A, other: String): String -> a.s + ":literal:" + other }
if (r != "sA:literal:!!") return r
return "OK"
}
}
@@ -4,7 +4,7 @@ package foo
class A {
fun bar(k: Int) = k
fun result() = this.(::bar)(111)
fun result() = (::bar)(this, 111)
}
fun box(): String {
@@ -6,7 +6,7 @@ class A {
fun k(k: Int) = k
}
fun A.bar() = this.(::o)() + this.(A::k)(222)
fun A.bar() = (::o)(this) + (A::k)(this, 222)
fun box(): String {
val result = A().bar()
@@ -1,22 +1,12 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, funRef:A.() -> String): String {
return arg1.funRef()
}
class A {
fun foo() = "OK"
}
fun box(): String {
val x = A::foo
var r = A().x()
if (r != "OK") return r
r = run(A(), A::foo)
if (r != "OK") return r
return "OK"
var r = x(A())
return r
}
@@ -1,21 +1,13 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> String): String {
return arg1.funRef(arg2)
}
class A {
fun foo(result: String):String = result
}
fun box(): String {
val x = A::foo
var r = A().x("OK")
var r = x(A(), "OK")
if (r != "OK") return r
r = run(A(), "OK", A::foo)
if (r != "OK") return r
return "OK"
return r
}
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, funRef:A.() -> Unit): Unit {
return arg1.funRef()
}
class A {
var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x()
var r = a.result
if (r != "OK") return r
val a1 = A()
run(a1, A::foo)
r = a.result
if (r != "OK") return r
return "OK"
x(a)
return a.result
}
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, arg2: String, funRef:A.(String) -> Unit): Unit {
return arg1.funRef(arg2)
}
class A {
var result = "Fail"
@@ -16,14 +12,6 @@ class A {
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
var r = a.result
if (r != "OK") return r
val a1 = A()
run(a1, "OK", A::foo)
r = a1.result
if (r != "OK") return r
return "OK"
x(a, "OK")
return a.result
}
@@ -11,6 +11,6 @@ class B : A() {
fun box(): String {
val b = B()
var ref = A::foo
val result = b.(ref)("1", "2")
val result = ref(b, "1", "2")
return (if (result == "fooB:12") "OK" else result)
}
@@ -10,6 +10,6 @@ object B : A() {
fun box(): String {
var ref = B::foo
val result = B.(ref)("1", "2")
val result = ref(B, "1", "2")
return (if (result == "fooB:12") "OK" else result)
}
@@ -5,5 +5,5 @@ class A
fun box(): String {
fun A.foo() = "OK"
return A().(A::foo)()
return (A::foo)(A())
}
@@ -2,7 +2,7 @@
package foo
class A {
fun result() = this.(::bar)("OK")
fun result() = (::bar)(this, "OK")
}
fun A.bar(x: String) = x
@@ -3,7 +3,7 @@ package foo
class A
fun A.foo() = this.(A::bar)("OK")
fun A.foo() = (A::bar)(this, "OK")
fun A.bar(x: String) = x
@@ -1,8 +1,8 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun <T> run(arg1: A, arg2: T, funRef:A.(T) -> T): T {
return arg1.funRef(arg2)
fun <T> run(arg1: A, arg2: T, funRef:(A, T) -> T): T {
return funRef(arg1, arg2)
}
class A {
@@ -17,9 +17,9 @@ fun A.bar(x: Int): Int {
fun box(): Boolean {
val funRef = A::bar
val obj = A()
var result = obj.(funRef)(25)
var result = funRef(obj, 25)
if (result != 25 || obj.xx != 200) return false
result = run(A(), 25, funRef)
return result == 25 && obj.xx == 200
}
}
@@ -11,7 +11,7 @@ fun A.foo() = "OK"
fun box(): String {
val x = A::foo
var r = A().x()
var r = x(A())
if (r != "OK") return r
r = run(A(), A::foo)
@@ -11,7 +11,7 @@ fun A.foo(result: String) = result
fun box(): String {
val x = A::foo
var r = A().x("OK")
var r = x(A(), "OK")
if (r != "OK") return r
r = run(A(), "OK", A::foo)
@@ -1,10 +1,6 @@
// This test was adapted from compiler/testData/codegen/boxWithStdlib/callableReference/function/.
package foo
fun run(arg1: A, funRef:A.() -> Unit): Unit {
return arg1.funRef()
}
class A {
var result = "Fail"
}
@@ -16,11 +12,7 @@ fun A.foo() {
fun box(): String {
val a = A()
val x = A::foo
a.x()
x(a)
if (a.result != "OK") return a.result
val a1 = A()
run(a1, A::foo)
return a.result
}
@@ -16,7 +16,7 @@ fun A.foo(newResult: String) {
fun box(): String {
val a = A()
val x = A::foo
a.x("OK")
x(a, "OK")
if (a.result != "OK") return a.result
@@ -3,5 +3,5 @@ package foo
fun box(): String {
fun Int.is42With(that: Int) = this + 2 * that == 42
return if (16.(Int::is42With)(13)) "OK" else "Fail"
return if ((Int::is42With)(16, 13)) "OK" else "Fail"
}
@@ -9,6 +9,6 @@ fun box(): String {
fun A.ext() { result = "OK" }
val f = A::ext
A().f()
f(A())
return result
}
@@ -1,6 +1,6 @@
package foo
fun Int.sum0(other: Int): Int = this + other;
fun Int.sum0(other: Int): Int = this + other
fun box(): String {
fun Int.sum1(other: Int): Int = this + other
@@ -13,8 +13,8 @@ fun box(): String {
x = x.sum2(5)
var y = 10
y = y.(Int::sum0)(5)
y = y.(Int::sum1)(5)
y = (Int::sum0)(y, 5)
y = (Int::sum1)(y, 5)
y = y.sum2(5)
var result:String = (if (x == y && x == 25) "OK" else "x=${x} y=${y}")
@@ -2,7 +2,7 @@ package foo
fun box(): String {
var s = "abc"
assertEquals("ABC", s.(String::toUpperCase)())
assertEquals("ABC", (String::toUpperCase)(s))
return "OK"
}
@@ -3,10 +3,10 @@ package foo
fun A.f(s: String) = value + s
class A(val value: String) {
fun bar(s: String) = (::f)(s)
fun bar(s: String) = (::f)(this, s)
}
fun A.baz(s: String) = (::f)(s)
fun A.baz(s: String) = (::f)(this, s)
fun box(): String {
val a = A("aaa")
+12 -4
View File
@@ -337,7 +337,9 @@ var Kotlin = {};
// TODO Store callable references for members in class
Kotlin.getCallableRefForMemberFunction = function (klass, memberName) {
return function () {
return this[memberName].apply(this, arguments);
var args = [].slice.call(arguments);
var instance = args.shift();
return instance[memberName].apply(instance, args);
};
};
@@ -345,9 +347,15 @@ var Kotlin = {};
// extFun expected receiver as the first argument
Kotlin.getCallableRefForExtensionFunction = function (extFun) {
return function () {
var args = [this];
Array.prototype.push.apply(args, arguments);
return extFun.apply(null, args);
return extFun.apply(null, arguments);
};
};
Kotlin.getCallableRefForLocalExtensionFunction = function (extFun) {
return function () {
var args = [].slice.call(arguments);
var instance = args.shift();
return extFun.apply(instance, args);
};
};
@@ -7,9 +7,9 @@ fun A.ext2(s: String): String = "A.ext2: ${this.v} ${s}"
fun box(): Boolean {
assertEquals("topLevelFun: A", (::topLevelFun)("A"))
assertEquals("A.ext1: test B", A("test").(A::ext1)("B"))
assertEquals("A.ext2: test B", A("test").(A::ext2)("B"))
assertEquals("memA: test C", A("test").(A::memA)("C"))
assertEquals("A.ext1: test B", (A::ext1)(A("test"), "B"))
assertEquals("A.ext2: test B", (A::ext2)(A("test"), "B"))
assertEquals("memA: test C", (A::memA)(A("test"), "C"))
assertEquals(100, ::topLevelVar.get())
::topLevelVar.set(500)
@@ -25,5 +25,5 @@ fun box(): Boolean {
(A::extProp).set(a, "new text")
assertEquals("new text", (A::extProp).get(a))
return true;
}
return true
}
@@ -22,8 +22,8 @@ fun box(): String {
assertEquals("A.bar A", a.bar())
assertEquals("B.bar B", b.bar())
assertEquals("A.bar A", a.(A::bar)())
assertEquals("B.bar B", b.(A::bar)())
assertEquals("A.bar A", (A::bar)(a))
assertEquals("B.bar B", (A::bar)(b))
a.prop = "prop"
assertEquals("prop", a.prop)
@@ -31,10 +31,10 @@ fun box(): String {
a = b
assertEquals("B.bar B", a.bar())
assertEquals("B.bar B", a.(A::bar)())
assertEquals("B.bar B", (A::bar)(a))
assertEquals("B prop", a.prop)
assertEquals("B prop", (A::prop).get(a))
return "OK";
return "OK"
}
@@ -16,13 +16,13 @@ fun box(): String {
val a = A("test")
assertEquals("A.m test 4 boo", a.m(4, "boo"))
assertEquals("A.m test 4 boo", bar(a, A::m))
assertEquals("A.m test 4 boo", bar(a, fun A.(i, s) = (A::m)(this, i, s)))
assertEquals("nativeExt test 4 boo", a.nativeExt(4, "boo"))
assertEquals("nativeExt test 4 boo", bar(a, A::nativeExt))
assertEquals("nativeExt test 4 boo", bar(a, fun A.(i, s) = (A::nativeExt)(this, i, s)))
assertEquals("nativeExt2 test 4 boo", a.nativeExt2(4, "boo"))
assertEquals("nativeExt2 test 4 boo", bar(a, A::nativeExt2))
assertEquals("nativeExt2 test 4 boo", bar(a, fun A.(i, s) = (A::nativeExt2)(this, i, s)))
return "OK"
}
@@ -21,18 +21,18 @@ fun box(): String {
fun A.LocalExt(i:Int, s:String): String = "A::LocalExt ${this.v} $i $s"
r = bar(a, A::topLevelExt)
r = bar(a, fun A.(i, s) = (A::topLevelExt)(this, i, s))
if (r != "A::topLevelExt test 4 boo") return r
r = bar(a, A::LocalExt)
r = bar(a, fun A.(i, s) = (A::LocalExt)(this, i, s))
if (r != "A::LocalExt test 4 boo") return r
r = bar(a, A::m)
r = bar(a, fun A.(i, s) = (A::m)(this, i, s))
if (r != "A.m test 4 boo") return r
val b = B("test")
r = bar(b, A::m)
r = bar(b, fun A.(i, s) = (A::m)(this, i, s))
if (r != "B.m test 4 boo") return r
return "OK"
}
}