snrostov
01/25/2018, 9:22 AMclass Builder<T> {
operator fun <V> getProperty(key: KProperty1<T, V>): V
operator fun <@kotlin.internal.OnlyInputTypes V> setProperty(key: KProperty1<T, V>, value: V)
}
class MyUser(val name: String, val age: Int)
fun buildUser() {
val userBuilder = Builder<MyUser>()
userBuilder.name = "test"
userBuilder.age = 132
// should be compiled to:
// userBuilder.setProperty(MyUser::name, "test")
// userBuilder.setProperty(MyUser::age, 132)
// @OnlyInputTypes is required to disallow userBuilder.name = 123, since R in KProperty1 is contravariant
}
Another use case is LINQ:
class Expression<T> {
operator fun <V> getProperty(key: KProperty1<T, V>): Expression<V>
}
fun Expression<T>.equals(other: Expression<T>): Expression<Boolean> = TODO()
fun Expression<T>.greater(other: Expression<T>): Expression<Boolean> = TODO()
fun Expression<Boolean>.and(other: Expression<Boolean>): Expression<Boolean> = TODO()
inline fun <reified T> query(predicateProvider: Expression<T>.() -> Expression<Boolean>) = TODO()
fun makeQuery() = query<MyUser> { (name == "test") and (age greater name.size) }
// lambda should be compiled to:
// (getProperty(MyUser::name) == "test") and (getProperty(MyUser::age) greater getProperty(MyUser::age).getProperty(String::size))
Second use case may be also covered by expression trees, but first likely not.Ruckus
01/25/2018, 4:23 PMget
and set
operators, in which case it would just be:
userBuilder["name"] = "test"
userBuilder["age"] = 132
snrostov
01/25/2018, 4:25 PMMyUser
.snrostov
01/25/2018, 4:25 PMRuckus
01/25/2018, 4:26 PMRuckus
01/25/2018, 4:26 PMsnrostov
01/25/2018, 4:27 PMBuilder<MyUser>().setProperty(AnotherObj::anotherProp)
, only MyUser
properties will be acceptedRuckus
01/25/2018, 4:29 PM