Get KProperty of a non-package extension property
kotlin
Solution
The error you are getting is:
Error:(y, x) Kotlin: 'extProp' is a member and an extension at the same time. References to such elements are not allowed
There is no syntax mechanism to generate a reference to an extension method that also requires a containing class. Your extension for example might use members of the class, and this would need something like "bound references" coming in Kotlin 1.1 (which I'm not sure will cover this case either, it is currently an open question). So for now, there is no `::` syntax available. Things like `Example::String::extProp` are not available, neither is the commonly tried `Example::String.extProp` syntax. But you can find it by reflection.
First you need to know the type you will receive is:
KProperty2<INSTANCE, EXTENDING, PROPTYPE>
Whereas a normal property on a class is:
KProperty1<INSTANCE, PROPTYPE>
You need to know that because any call to the `getter` will require the class instance and an instance of the class the property is extending. So you cannot call it the same way as you would a property reference of a class.
You can use this function to find an extension property declared in a class:
@Suppress("UNCHECKED_CAST")
fun <T: Any, EXTENDING: Any, R: Any> KClass<T>.extProp(extends: KClass<EXTENDING>, name: String, returning: KClass<R>): KProperty2<T, EXTENDING, R> {
return this.declaredMemberExtensionProperties.first {
it.name == name &&
it.parameters.size == 2 &&
it.parameters[0].kind == KParameter.Kind.INSTANCE && it.parameters[0].type == this.defaultType &&
it.parameters[1].kind == KParameter.Kind.EXTENSION_RECEIVER && it.parameters[1].type == extends.defaultType &&
it.returnType == returning.defaultType
} as KProperty2<T, EXTENDING, R>
}
This is a bit overkill for the checking but ensures that it is future-proof in case any other types of extensions are added later. The following is your code updated to use it:
class Example() {
val String.extProp: String
get() = "howdy $this"
fun foo() {
val prop = Example::class.extProp(String::class, "extProp", String::class)
println(prop.get(this, "stringy")) // "howdy stringy"
}
}
Problem
In kotlin, you can use the reference operator to get the KProperty of a package extension property like this: ``` val String.extProp: String get() = "Some get code" fun foo() { val prop: KProperty<String> = String::extProp } ``` However, when the extension property is declared inside a class the reference operator no longer works: ``` class Example() { val String.extProp: String get() = "Some get code" fun foo() { val prop: KProperty<String> = String::extProp // error } } ``` So what I am wondering is how can I change the problematic line in the second example, so the KProperty is gotten?