Reflection: add API for declaration modifiers
#KT-10447 Fixed
This commit is contained in:
@@ -62,4 +62,19 @@ public interface KCallable<out R> : KAnnotatedElement {
|
||||
* or its type does not match the type of the provided value, an exception is thrown.
|
||||
*/
|
||||
public fun callBy(args: Map<KParameter, Any?>): R
|
||||
|
||||
/**
|
||||
* `true` if this callable is `final`.
|
||||
*/
|
||||
public val isFinal: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this callable is `open`.
|
||||
*/
|
||||
public val isOpen: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this callable is `abstract`.
|
||||
*/
|
||||
public val isAbstract: Boolean
|
||||
}
|
||||
|
||||
@@ -73,6 +73,49 @@ public interface KClass<T : Any> : KDeclarationContainer, KAnnotatedElement, KCl
|
||||
*/
|
||||
public val supertypes: List<KType>
|
||||
|
||||
/**
|
||||
* `true` if this class is `final`.
|
||||
*/
|
||||
public val isFinal: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is `open`.
|
||||
*/
|
||||
public val isOpen: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is `abstract`.
|
||||
*/
|
||||
public val isAbstract: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is `sealed`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/classes.html#sealed-classes)
|
||||
* for more information.
|
||||
*/
|
||||
public val isSealed: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is a data class.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/data-classes.html)
|
||||
* for more information.
|
||||
*/
|
||||
public val isData: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is an inner class.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/nested-classes.html#inner-classes)
|
||||
* for more information.
|
||||
*/
|
||||
public val isInner: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this class is a companion object.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects)
|
||||
* for more information.
|
||||
*/
|
||||
public val isCompanion: Boolean
|
||||
|
||||
/**
|
||||
* Returns `true` if [other] is a [KClass] instance representing the same class on a given platform.
|
||||
*
|
||||
|
||||
@@ -19,4 +19,44 @@ package kotlin.reflect
|
||||
/**
|
||||
* Represents a function with introspection capabilities.
|
||||
*/
|
||||
public interface KFunction<out R> : KCallable<R>, Function<R>
|
||||
public interface KFunction<out R> : KCallable<R>, Function<R> {
|
||||
/**
|
||||
* `true` if this function is `inline`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/inline-functions.html)
|
||||
* for more information.
|
||||
*/
|
||||
public val isInline: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this function is `external`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/java-interop.html#using-jni-with-kotlin)
|
||||
* for more information.
|
||||
*/
|
||||
public val isExternal: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this function is `operator`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/operator-overloading.html)
|
||||
* for more information.
|
||||
*/
|
||||
public val isOperator: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this function is `infix`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/functions.html#infix-notation)
|
||||
* for more information.
|
||||
*/
|
||||
public val isInfix: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this function is `tailrec`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions)
|
||||
* for more information.
|
||||
*/
|
||||
public val isTailrec: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this is a suspending function.
|
||||
*/
|
||||
public val isSuspend: Boolean
|
||||
}
|
||||
|
||||
@@ -69,4 +69,30 @@ public interface KParameter : KAnnotatedElement {
|
||||
* 2. The parameter is declared in a member function and one of the corresponding parameters in the super functions is optional.
|
||||
*/
|
||||
public val isOptional: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this parameter is `vararg`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs)
|
||||
* for more information.
|
||||
*/
|
||||
public val isVararg: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this parameter is `noinline`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/inline-functions.html#noinline)
|
||||
* for more information.
|
||||
*/
|
||||
public val isNoinline: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this parameter is `crossinline`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns)
|
||||
* for more information.
|
||||
*/
|
||||
public val isCrossinline: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this parameter is `coroutine`.
|
||||
*/
|
||||
public val isCoroutine: Boolean
|
||||
}
|
||||
|
||||
@@ -25,6 +25,20 @@ package kotlin.reflect
|
||||
* @param R the type of the property.
|
||||
*/
|
||||
public interface KProperty<out R> : KCallable<R> {
|
||||
/**
|
||||
* `true` if this property is `lateinit`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties)
|
||||
* for more information.
|
||||
*/
|
||||
public val isLateinit: Boolean
|
||||
|
||||
/**
|
||||
* `true` if this property is `const`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/properties.html#compile-time-constants)
|
||||
* for more information.
|
||||
*/
|
||||
public val isConst: Boolean
|
||||
|
||||
/** The getter of this property, used to obtain the value of the property. */
|
||||
public val getter: Getter<R>
|
||||
|
||||
|
||||
@@ -40,4 +40,11 @@ public interface KTypeParameter : KClassifier {
|
||||
* for more information.
|
||||
*/
|
||||
public val variance: KVariance
|
||||
|
||||
/**
|
||||
* `true` if this type parameter is `reified`.
|
||||
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters)
|
||||
* for more information.
|
||||
*/
|
||||
public val isReified: Boolean
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import java.lang.reflect.Type
|
||||
import java.util.*
|
||||
@@ -62,6 +63,15 @@ internal interface KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl {
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = descriptor.typeParameters.map(::KTypeParameterImpl)
|
||||
|
||||
override val isFinal: Boolean
|
||||
get() = descriptor.modality == Modality.FINAL
|
||||
|
||||
override val isOpen: Boolean
|
||||
get() = descriptor.modality == Modality.OPEN
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = descriptor.modality == Modality.ABSTRACT
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun call(vararg args: Any?): R = reflectionCall {
|
||||
return caller.call(args) as R
|
||||
|
||||
@@ -170,6 +170,27 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
|
||||
}
|
||||
}
|
||||
|
||||
override val isFinal: Boolean
|
||||
get() = descriptor.modality == Modality.FINAL
|
||||
|
||||
override val isOpen: Boolean
|
||||
get() = descriptor.modality == Modality.OPEN
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = descriptor.modality == Modality.ABSTRACT
|
||||
|
||||
override val isSealed: Boolean
|
||||
get() = descriptor.modality == Modality.SEALED
|
||||
|
||||
override val isData: Boolean
|
||||
get() = descriptor.isData
|
||||
|
||||
override val isInner: Boolean
|
||||
get() = descriptor.isInner
|
||||
|
||||
override val isCompanion: Boolean
|
||||
get() = descriptor.isCompanionObject
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is KClassImpl<*> && jClass == other.jClass
|
||||
|
||||
|
||||
@@ -109,6 +109,24 @@ internal open class KFunctionImpl protected constructor(
|
||||
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
||||
}
|
||||
|
||||
override val isInline: Boolean
|
||||
get() = descriptor.isInline
|
||||
|
||||
override val isExternal: Boolean
|
||||
get() = descriptor.isExternal
|
||||
|
||||
override val isOperator: Boolean
|
||||
get() = descriptor.isOperator
|
||||
|
||||
override val isInfix: Boolean
|
||||
get() = descriptor.isInfix
|
||||
|
||||
override val isTailrec: Boolean
|
||||
get() = descriptor.isTailrec
|
||||
|
||||
override val isSuspend: Boolean
|
||||
get() = descriptor.isSuspend
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
val that = other.asKFunctionImpl() ?: return false
|
||||
return container == that.container && name == that.name && signature == that.signature
|
||||
|
||||
@@ -46,6 +46,18 @@ internal class KParameterImpl(
|
||||
override val isOptional: Boolean
|
||||
get() = (descriptor as? ValueParameterDescriptor)?.hasDefaultValue() ?: false
|
||||
|
||||
override val isVararg: Boolean
|
||||
get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null }
|
||||
|
||||
override val isNoinline: Boolean
|
||||
get() = descriptor.let { it is ValueParameterDescriptor && it.isNoinline }
|
||||
|
||||
override val isCrossinline: Boolean
|
||||
get() = descriptor.let { it is ValueParameterDescriptor && it.isCrossinline }
|
||||
|
||||
override val isCoroutine: Boolean
|
||||
get() = descriptor.let { it is ValueParameterDescriptor && it.isCoroutine }
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
|
||||
|
||||
|
||||
@@ -42,10 +42,40 @@ internal interface KPropertyImpl<out R> : KProperty<R>, KCallableImpl<R> {
|
||||
|
||||
override val defaultCaller: FunctionCaller<*>? get() = getter.defaultCaller
|
||||
|
||||
override val isLateinit: Boolean
|
||||
get() = descriptor.isLateInit
|
||||
|
||||
override val isConst: Boolean
|
||||
get() = descriptor.isConst
|
||||
|
||||
abstract class Accessor<out R> : KProperty.Accessor<R> {
|
||||
abstract override val property: KPropertyImpl<R>
|
||||
|
||||
internal abstract val descriptor: PropertyAccessorDescriptor
|
||||
|
||||
@Suppress("unused") // Used as an implementation of KFunction#isInline in subclasses
|
||||
val isInline: Boolean
|
||||
get() = descriptor.isInline
|
||||
|
||||
@Suppress("unused")
|
||||
val isExternal: Boolean
|
||||
get() = descriptor.isExternal
|
||||
|
||||
@Suppress("unused")
|
||||
val isOperator: Boolean
|
||||
get() = descriptor.isOperator
|
||||
|
||||
@Suppress("unused")
|
||||
val isInfix: Boolean
|
||||
get() = descriptor.isInfix
|
||||
|
||||
@Suppress("unused")
|
||||
val isTailrec: Boolean
|
||||
get() = descriptor.isTailrec
|
||||
|
||||
@Suppress("unused")
|
||||
val isSuspend: Boolean
|
||||
get() = descriptor.isSuspend
|
||||
}
|
||||
|
||||
abstract class Getter<out R> : Accessor<R>(), KProperty.Getter<R>, KCallableImpl<R> {
|
||||
|
||||
@@ -40,6 +40,9 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript
|
||||
Variance.OUT_VARIANCE -> KVariance.OUT
|
||||
}
|
||||
|
||||
override val isReified: Boolean
|
||||
get() = descriptor.isReified
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is KTypeParameterImpl && descriptor == other.descriptor
|
||||
|
||||
|
||||
@@ -99,6 +99,21 @@ public abstract class CallableReference implements KCallable {
|
||||
return getReflected().callBy(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return getReflected().isFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return getReflected().isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return getReflected().isAbstract();
|
||||
}
|
||||
|
||||
public KCallable compute() {
|
||||
if (reflected == null) {
|
||||
reflected = computeReflected();
|
||||
|
||||
@@ -48,6 +48,27 @@ class ClassReference(override val jClass: Class<*>) : KClass<Any>, ClassBasedDec
|
||||
override val supertypes: List<KType>
|
||||
get() = error()
|
||||
|
||||
override val isFinal: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isOpen: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isSealed: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isData: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isInner: Boolean
|
||||
get() = error()
|
||||
|
||||
override val isCompanion: Boolean
|
||||
get() = error()
|
||||
|
||||
private fun error(): Nothing = throw KotlinReflectionNotSupportedError()
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
|
||||
@@ -84,6 +84,51 @@ public class FunctionReference extends FunctionImpl implements KFunction {
|
||||
return getReflected().callBy(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return getReflected().isFinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return getReflected().isOpen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return getReflected().isAbstract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInline() {
|
||||
return getReflected().isInline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExternal() {
|
||||
return getReflected().isExternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOperator() {
|
||||
return getReflected().isOperator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfix() {
|
||||
return getReflected().isInfix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTailrec() {
|
||||
return getReflected().isTailrec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuspend() {
|
||||
return getReflected().isSuspend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
|
||||
@@ -19,6 +19,21 @@ package kotlin.jvm.internal;
|
||||
import kotlin.reflect.KProperty;
|
||||
|
||||
public abstract class PropertyReference extends CallableReference implements KProperty {
|
||||
@Override
|
||||
protected KProperty getReflected() {
|
||||
return (KProperty) super.getReflected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLateinit() {
|
||||
return getReflected().isLateinit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConst() {
|
||||
return getReflected().isConst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
|
||||
Reference in New Issue
Block a user