Prohibit callable references to object members

To be able to make them more useful in the future, i.e. bound to the object
instance
This commit is contained in:
Alexander Udalov
2015-10-14 16:39:43 +03:00
parent 63dfe13c43
commit ced1edcf98
26 changed files with 122 additions and 218 deletions
@@ -1,6 +1,8 @@
import kotlin.jvm.JvmStatic as static
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.KCallable
import kotlin.reflect.KFunction
import kotlin.reflect.KMutableProperty
var foo: String = ""
@@ -11,7 +13,9 @@ class A(private var bar: String = "") {
object O {
private @static var baz: String = ""
@static fun getBaz() = O::baz.apply { isAccessible = true }
@static fun getBaz() = (O::class.members.single { it.name == "baz" } as KMutableProperty<*>).apply { isAccessible = true }
fun getGetBaz() = O::class.members.single { it.name == "getBaz" } as KFunction<*>
}
fun check(callable: KCallable<*>, vararg args: Any?) {
@@ -44,8 +48,8 @@ fun box(): String {
check(::A)
check(::A, null, "")
check(O::getBaz)
check(O::getBaz, null, "")
check(O.getGetBaz())
check(O.getGetBaz(), null, "")
val f = ::foo
@@ -11,7 +11,7 @@ class C {
}
fun box(): String {
(Obj::foo).call(Obj)
(C.Companion::bar).call(C.Companion)
(Obj::class.members.single { it.name == "foo" }).call(Obj)
(C.Companion::class.members.single { it.name == "bar" }).call(C.Companion)
return "OK"
}
@@ -4,32 +4,34 @@ object Obj {
@static fun foo(s: String) {}
@static fun bar() {}
@static fun sly(obj: Obj) {}
operator fun get(name: String) = Obj::class.members.single { it.name == name }
}
fun box(): String {
// This should succeed
(Obj::foo).call(Obj, "")
(Obj::bar).call(Obj)
(Obj::sly).call(Obj, Obj)
(Obj["foo"]).call(Obj, "")
(Obj["bar"]).call(Obj)
(Obj["sly"]).call(Obj, Obj)
// This shouldn't: first argument should always be Obj
try {
(Obj::foo).call(null, "")
(Obj["foo"]).call(null, "")
return "Fail foo"
} catch (e: IllegalArgumentException) {}
try {
(Obj::bar).call("")
(Obj["bar"]).call("")
return "Fail bar"
} catch (e: IllegalArgumentException) {}
try {
(Obj::sly).call(Obj)
(Obj["sly"]).call(Obj)
return "Fail sly 1"
} catch (e: IllegalArgumentException) {}
try {
(Obj::sly).call(null, Obj)
(Obj["sly"]).call(null, Obj)
return "Fail sly 2"
} catch (e: IllegalArgumentException) {}
@@ -15,7 +15,7 @@ fun nullableUnit(unit: Boolean): Unit? = if (unit) Unit else null
fun box(): String {
assertEquals(Unit, ::foo.call())
assertEquals(Unit, A::bar.call(A()))
assertEquals(Unit, O::baz.call(O))
assertEquals(Unit, O::class.members.single { it.name == "baz" }.call(O))
assertEquals(Unit, (::nullableUnit).call(true))
assertEquals(null, (::nullableUnit).call(false))