Support introspection of parameter names and indices in reflection

This commit is contained in:
Alexander Udalov
2015-07-07 21:02:53 +03:00
parent 87c70aa2ae
commit 5962b79126
15 changed files with 228 additions and 22 deletions
@@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.load.java.structure.reflect.desc
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
@@ -27,12 +26,12 @@ import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import java.lang.reflect.Field
import java.lang.reflect.Method
abstract class DescriptorBasedProperty protected constructor(
abstract class DescriptorBasedProperty<out R> protected constructor(
container: KCallableContainerImpl,
name: String,
signature: String,
descriptorInitialValue: PropertyDescriptor?
) {
) : KCallableImpl<R> {
constructor(container: KCallableContainerImpl, name: String, signature: String) : this(
container, name, signature, null
)
@@ -50,7 +49,7 @@ abstract class DescriptorBasedProperty protected constructor(
val signature: JvmProtoBuf.JvmPropertySignature
)
protected val descriptor: PropertyDescriptor by ReflectProperties.lazySoft<PropertyDescriptor>(descriptorInitialValue) {
override val descriptor: PropertyDescriptor by ReflectProperties.lazySoft<PropertyDescriptor>(descriptorInitialValue) {
container.findPropertyDescriptor(name, signature)
}
@@ -88,7 +87,7 @@ abstract class DescriptorBasedProperty protected constructor(
}
override fun equals(other: Any?): Boolean =
other is DescriptorBasedProperty && descriptor == other.descriptor
other is DescriptorBasedProperty<*> && descriptor == other.descriptor
override fun hashCode(): Int =
descriptor.hashCode()
@@ -16,6 +16,32 @@
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import java.util.ArrayList
import kotlin.reflect.KCallable
import kotlin.reflect.KParameter
interface KCallableImpl<out R> : KCallable<R>
interface KCallableImpl<out R> : KCallable<R> {
val descriptor: CallableMemberDescriptor
override val parameters: List<KParameter>
get() {
val result = ArrayList<KParameter>()
var index = 0
if (descriptor.dispatchReceiverParameter != null) {
result.add(KParameterImpl(index++) { descriptor.dispatchReceiverParameter!! })
}
if (descriptor.extensionReceiverParameter != null) {
result.add(KParameterImpl(index++) { descriptor.extensionReceiverParameter!! })
}
for (i in descriptor.valueParameters.indices) {
result.add(KParameterImpl(index++) { descriptor.valueParameters[i] })
}
result.trimToSize()
return result
}
}
@@ -14,6 +14,7 @@
* limitations under the License.
*/
@file:suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -25,7 +26,7 @@ open class KFunctionImpl protected constructor(
name: String,
signature: String,
descriptorInitialValue: FunctionDescriptor?
) : KFunction<Any?>, FunctionImpl(),
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl(),
KLocalFunction<Any?>, KMemberFunction<Any, Any?>, KTopLevelExtensionFunction<Any?, Any?>, KTopLevelFunction<Any?> {
constructor(container: KCallableContainerImpl, name: String, signature: String) : this(container, name, signature, null)
@@ -33,7 +34,7 @@ open class KFunctionImpl protected constructor(
container, descriptor.getName().asString(), RuntimeTypeMapper.mapSignature(descriptor), descriptor
)
protected val descriptor: FunctionDescriptor by ReflectProperties.lazySoft<FunctionDescriptor>(descriptorInitialValue) {
override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft<FunctionDescriptor>(descriptorInitialValue) {
container.findFunctionDescriptor(name, signature)
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import kotlin.reflect.KParameter
class KParameterImpl(
override val index: Int,
private val computeDescriptor: () -> ParameterDescriptor
) : KParameter {
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
override val name: String? get() {
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
val name = valueParameter.name
return if (name.isSpecial) null else name.asString()
}
}
@@ -23,7 +23,7 @@ import kotlin.reflect.IllegalPropertyAccessException
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.KProperty0
open class KProperty0Impl<out R> : DescriptorBasedProperty, KProperty0<R>, KPropertyImpl<R> {
open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KProperty0<R>, KPropertyImpl<R> {
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
override val name: String get() = descriptor.getName().asString()
@@ -42,7 +42,7 @@ open class KProperty0Impl<out R> : DescriptorBasedProperty, KProperty0<R>, KProp
}
}
class Getter<out R>(override val property: KProperty0Impl<R>) : KPropertyImpl.Getter<R>, KProperty0.Getter<R> {
class Getter<out R>(override val property: KProperty0Impl<R>) : KPropertyImpl.Getter<R>(), KProperty0.Getter<R> {
override fun invoke(): R = property.get()
}
}
@@ -63,7 +63,7 @@ open class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R>, K
}
}
class Setter<R>(override val property: KMutableProperty0Impl<R>) : KMutablePropertyImpl.Setter<R>, KMutableProperty0.Setter<R> {
class Setter<R>(override val property: KMutableProperty0Impl<R>) : KMutablePropertyImpl.Setter<R>(), KMutableProperty0.Setter<R> {
override fun invoke(value: R): Unit = property.set(value)
}
}
@@ -24,7 +24,7 @@ import kotlin.reflect.IllegalPropertyAccessException
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
open class KProperty1Impl<T, out R> : DescriptorBasedProperty, KProperty1<T, R>, KPropertyImpl<R> {
open class KProperty1Impl<T, out R> : DescriptorBasedProperty<R>, KProperty1<T, R>, KPropertyImpl<R> {
constructor(container: KCallableContainerImpl, name: String, signature: String) : super(container, name, signature)
constructor(container: KCallableContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
@@ -56,7 +56,7 @@ open class KProperty1Impl<T, out R> : DescriptorBasedProperty, KProperty1<T, R>,
}
}
class Getter<T, out R>(override val property: KProperty1Impl<T, R>) : KPropertyImpl.Getter<R>, KProperty1.Getter<T, R> {
class Getter<T, out R>(override val property: KProperty1Impl<T, R>) : KPropertyImpl.Getter<R>(), KProperty1.Getter<T, R> {
override fun invoke(receiver: T): R = property.get(receiver)
}
}
@@ -92,7 +92,7 @@ open class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutableProperty1
}
}
class Setter<T, R>(override val property: KMutableProperty1Impl<T, R>) : KMutablePropertyImpl.Setter<R>, KMutableProperty1.Setter<T, R> {
class Setter<T, R>(override val property: KMutableProperty1Impl<T, R>) : KMutablePropertyImpl.Setter<R>(), KMutableProperty1.Setter<T, R> {
override fun invoke(receiver: T, value: R): Unit = property.set(receiver, value)
}
}
@@ -23,7 +23,7 @@ import kotlin.reflect.IllegalPropertyAccessException
import kotlin.reflect.KMutableProperty2
import kotlin.reflect.KProperty2
open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty, KProperty2<D, E, R>, KPropertyImpl<R> {
open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KProperty2<D, E, R>, KPropertyImpl<R> {
constructor(container: KClassImpl<D>, name: String, signature: String) : super(container, name, signature)
constructor(container: KClassImpl<D>, descriptor: PropertyDescriptor) : super(container, descriptor)
@@ -46,7 +46,7 @@ open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty, KProperty2<D,
}
}
class Getter<D, E, out R>(override val property: KProperty2Impl<D, E, R>) : KPropertyImpl.Getter<R>, KProperty2.Getter<D, E, R> {
class Getter<D, E, out R>(override val property: KProperty2Impl<D, E, R>) : KPropertyImpl.Getter<R>(), KProperty2.Getter<D, E, R> {
override fun invoke(receiver1: D, receiver2: E): R = property.get(receiver1, receiver2)
}
}
@@ -70,7 +70,7 @@ class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KMutableProperty
}
}
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KMutablePropertyImpl.Setter<R>, KMutableProperty2.Setter<D, E, R> {
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KMutablePropertyImpl.Setter<R>(), KMutableProperty2.Setter<D, E, R> {
override fun invoke(receiver1: D, receiver2: E, value: R): Unit = property.set(receiver1, receiver2, value)
}
}
@@ -16,8 +16,14 @@
package kotlin.reflect.jvm.internal
import java.lang.reflect.*
import kotlin.reflect.*
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
import org.jetbrains.kotlin.resolve.DescriptorFactory
import java.lang.reflect.Field
import java.lang.reflect.Method
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KProperty
interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
val javaField: Field?
@@ -26,12 +32,19 @@ interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
override val getter: Getter<R>
override val descriptor: PropertyDescriptor
interface Accessor<out R> : KProperty.Accessor<R> {
override val property: KPropertyImpl<R>
}
interface Getter<out R> : KProperty.Getter<R>, KCallableImpl<R> {
abstract class Getter<out R> : KProperty.Getter<R>, Accessor<R>, KCallableImpl<R> {
override val name: String get() = "<get-${property.name}>"
override val descriptor: PropertyGetterDescriptor by ReflectProperties.lazySoft {
// TODO: default getter created this way won't have any source information
property.descriptor.getGetter() ?: DescriptorFactory.createDefaultGetter(property.descriptor)
}
}
}
@@ -41,7 +54,12 @@ interface KMutablePropertyImpl<R> : KMutableProperty<R>, KPropertyImpl<R> {
override val setter: Setter<R>
interface Setter<R> : KMutableProperty.Setter<R>, KPropertyImpl.Accessor<R>, KCallableImpl<Unit> {
abstract class Setter<R> : KMutableProperty.Setter<R>, KPropertyImpl.Accessor<R>, KCallableImpl<Unit> {
override val name: String get() = "<set-${property.name}>"
override val descriptor: PropertySetterDescriptor by ReflectProperties.lazySoft {
// TODO: default setter created this way won't have any source information
property.descriptor.getSetter() ?: DescriptorFactory.createDefaultSetter(property.descriptor)
}
}
}