Reflection: add API for declaration modifiers
#KT-10447 Fixed
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
interface Interface {
|
||||
open fun openFun() {}
|
||||
abstract fun abstractFun()
|
||||
}
|
||||
|
||||
abstract class AbstractClass {
|
||||
final val finalVal = Unit
|
||||
open val openVal = Unit
|
||||
abstract var abstractVar: Unit
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertFalse(Interface::openFun.isFinal)
|
||||
assertTrue(Interface::openFun.isOpen)
|
||||
assertFalse(Interface::openFun.isAbstract)
|
||||
|
||||
assertFalse(Interface::abstractFun.isFinal)
|
||||
assertFalse(Interface::abstractFun.isOpen)
|
||||
assertTrue(Interface::abstractFun.isAbstract)
|
||||
|
||||
assertTrue(AbstractClass::finalVal.isFinal)
|
||||
assertFalse(AbstractClass::finalVal.isOpen)
|
||||
assertFalse(AbstractClass::finalVal.isAbstract)
|
||||
assertTrue(AbstractClass::finalVal.getter.isFinal)
|
||||
assertFalse(AbstractClass::finalVal.getter.isOpen)
|
||||
assertFalse(AbstractClass::finalVal.getter.isAbstract)
|
||||
|
||||
assertFalse(AbstractClass::openVal.isFinal)
|
||||
assertTrue(AbstractClass::openVal.isOpen)
|
||||
assertFalse(AbstractClass::openVal.isAbstract)
|
||||
assertFalse(AbstractClass::openVal.getter.isFinal)
|
||||
assertTrue(AbstractClass::openVal.getter.isOpen)
|
||||
assertFalse(AbstractClass::openVal.getter.isAbstract)
|
||||
|
||||
assertFalse(AbstractClass::abstractVar.isFinal)
|
||||
assertFalse(AbstractClass::abstractVar.isOpen)
|
||||
assertTrue(AbstractClass::abstractVar.isAbstract)
|
||||
assertFalse(AbstractClass::abstractVar.getter.isFinal)
|
||||
assertFalse(AbstractClass::abstractVar.getter.isOpen)
|
||||
assertTrue(AbstractClass::abstractVar.getter.isAbstract)
|
||||
assertFalse(AbstractClass::abstractVar.setter.isFinal)
|
||||
assertFalse(AbstractClass::abstractVar.setter.isOpen)
|
||||
assertTrue(AbstractClass::abstractVar.setter.isAbstract)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
class FinalClass {
|
||||
companion object Companion
|
||||
}
|
||||
open class OpenClass
|
||||
abstract class AbstractClass
|
||||
interface Interface
|
||||
enum class EnumClass
|
||||
enum class EnumClassWithAbstractMember { ; abstract fun foo() }
|
||||
annotation class AnnotationClass
|
||||
object Object
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(FinalClass::class.isFinal)
|
||||
assertFalse(FinalClass::class.isOpen)
|
||||
assertFalse(FinalClass::class.isAbstract)
|
||||
|
||||
assertTrue(FinalClass.Companion::class.isFinal)
|
||||
assertFalse(FinalClass.Companion::class.isOpen)
|
||||
assertFalse(FinalClass.Companion::class.isAbstract)
|
||||
|
||||
assertFalse(OpenClass::class.isFinal)
|
||||
assertTrue(OpenClass::class.isOpen)
|
||||
assertFalse(OpenClass::class.isAbstract)
|
||||
|
||||
assertFalse(AbstractClass::class.isFinal)
|
||||
assertFalse(AbstractClass::class.isOpen)
|
||||
assertTrue(AbstractClass::class.isAbstract)
|
||||
|
||||
assertFalse(Interface::class.isFinal)
|
||||
assertFalse(Interface::class.isOpen)
|
||||
assertTrue(Interface::class.isAbstract)
|
||||
|
||||
assertTrue(EnumClass::class.isFinal)
|
||||
assertFalse(EnumClass::class.isOpen)
|
||||
assertFalse(EnumClass::class.isAbstract)
|
||||
|
||||
assertTrue(EnumClassWithAbstractMember::class.isFinal)
|
||||
assertFalse(EnumClassWithAbstractMember::class.isOpen)
|
||||
assertFalse(EnumClassWithAbstractMember::class.isAbstract)
|
||||
|
||||
// Note that unlike in JVM, annotation classes are final in Kotlin
|
||||
assertTrue(AnnotationClass::class.isFinal)
|
||||
assertFalse(AnnotationClass::class.isOpen)
|
||||
assertFalse(AnnotationClass::class.isAbstract)
|
||||
|
||||
assertTrue(Object::class.isFinal)
|
||||
assertFalse(Object::class.isOpen)
|
||||
assertFalse(Object::class.isAbstract)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
sealed class S {
|
||||
data class DataClass(val x: Int) : S()
|
||||
inner class InnerClass
|
||||
companion object
|
||||
object NonCompanionObject
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(S::class.isSealed)
|
||||
assertFalse(S::class.isFinal)
|
||||
assertFalse(S::class.isOpen)
|
||||
assertFalse(S::class.isAbstract)
|
||||
assertFalse(S::class.isData)
|
||||
assertFalse(S::class.isInner)
|
||||
assertFalse(S::class.isCompanion)
|
||||
|
||||
assertFalse(S.DataClass::class.isSealed)
|
||||
assertTrue(S.DataClass::class.isData)
|
||||
assertFalse(S.DataClass::class.isInner)
|
||||
assertFalse(S.DataClass::class.isCompanion)
|
||||
|
||||
assertFalse(S.InnerClass::class.isSealed)
|
||||
assertFalse(S.InnerClass::class.isData)
|
||||
assertTrue(S.InnerClass::class.isInner)
|
||||
assertFalse(S.InnerClass::class.isCompanion)
|
||||
|
||||
assertFalse(S.Companion::class.isSealed)
|
||||
assertFalse(S.Companion::class.isData)
|
||||
assertFalse(S.Companion::class.isInner)
|
||||
assertTrue(S.Companion::class.isCompanion)
|
||||
|
||||
assertFalse(S.NonCompanionObject::class.isSealed)
|
||||
assertFalse(S.NonCompanionObject::class.isData)
|
||||
assertFalse(S.NonCompanionObject::class.isInner)
|
||||
assertFalse(S.NonCompanionObject::class.isCompanion)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
inline fun inline() {}
|
||||
class External { external fun external() }
|
||||
operator fun Unit.invoke() {}
|
||||
infix fun Unit.infix(unit: Unit) {}
|
||||
tailrec fun tailrec() { tailrec() }
|
||||
class Suspend { suspend fun suspend(c: Continuation<Unit>) {} }
|
||||
|
||||
val externalGetter = Unit
|
||||
external get
|
||||
|
||||
inline var inlineProperty: Unit
|
||||
get() = Unit
|
||||
set(value) {}
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(::inline.isInline)
|
||||
assertFalse(::inline.isExternal)
|
||||
assertFalse(::inline.isOperator)
|
||||
assertFalse(::inline.isInfix)
|
||||
assertFalse(::inline.isTailrec)
|
||||
assertFalse(::inline.isSuspend)
|
||||
|
||||
assertFalse(External::external.isInline)
|
||||
assertTrue(External::external.isExternal)
|
||||
assertFalse(External::external.isOperator)
|
||||
assertFalse(External::external.isInfix)
|
||||
assertFalse(External::external.isTailrec)
|
||||
assertFalse(External::external.isSuspend)
|
||||
|
||||
assertFalse(Unit::invoke.isInline)
|
||||
assertFalse(Unit::invoke.isExternal)
|
||||
assertTrue(Unit::invoke.isOperator)
|
||||
assertFalse(Unit::invoke.isInfix)
|
||||
assertFalse(Unit::invoke.isTailrec)
|
||||
assertFalse(Unit::invoke.isSuspend)
|
||||
|
||||
assertFalse(Unit::infix.isInline)
|
||||
assertFalse(Unit::infix.isExternal)
|
||||
assertFalse(Unit::infix.isOperator)
|
||||
assertTrue(Unit::infix.isInfix)
|
||||
assertFalse(Unit::infix.isTailrec)
|
||||
assertFalse(Unit::infix.isSuspend)
|
||||
|
||||
assertFalse(::tailrec.isInline)
|
||||
assertFalse(::tailrec.isExternal)
|
||||
assertFalse(::tailrec.isOperator)
|
||||
assertFalse(::tailrec.isInfix)
|
||||
assertTrue(::tailrec.isTailrec)
|
||||
assertFalse(::tailrec.isSuspend)
|
||||
|
||||
assertFalse(Suspend::suspend.isInline)
|
||||
assertFalse(Suspend::suspend.isExternal)
|
||||
assertFalse(Suspend::suspend.isOperator)
|
||||
assertFalse(Suspend::suspend.isInfix)
|
||||
assertFalse(Suspend::suspend.isTailrec)
|
||||
assertTrue(Suspend::suspend.isSuspend)
|
||||
|
||||
assertTrue(::externalGetter.getter.isExternal)
|
||||
assertFalse(::externalGetter.getter.isInline)
|
||||
|
||||
assertFalse(::inlineProperty.getter.isExternal)
|
||||
assertTrue(::inlineProperty.getter.isInline)
|
||||
assertTrue(::inlineProperty.setter.isInline)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
inline fun Unit.foo(
|
||||
crossinline crossinline: () -> Unit,
|
||||
noinline coroutine x: Unit.() -> Continuation<Unit>,
|
||||
vararg vararg: Unit
|
||||
) {}
|
||||
|
||||
fun box(): String {
|
||||
val p = Unit::foo.parameters
|
||||
|
||||
assertFalse(p[0].isNoinline)
|
||||
assertFalse(p[0].isCrossinline)
|
||||
assertFalse(p[0].isVararg)
|
||||
assertFalse(p[0].isCoroutine)
|
||||
|
||||
assertFalse(p[1].isNoinline)
|
||||
assertTrue(p[1].isCrossinline)
|
||||
assertFalse(p[1].isVararg)
|
||||
assertFalse(p[1].isCoroutine)
|
||||
|
||||
assertTrue(p[2].isNoinline)
|
||||
assertFalse(p[2].isCrossinline)
|
||||
assertFalse(p[2].isVararg)
|
||||
assertTrue(p[2].isCoroutine)
|
||||
|
||||
assertFalse(p[3].isNoinline)
|
||||
assertFalse(p[3].isCrossinline)
|
||||
assertTrue(p[3].isVararg)
|
||||
assertFalse(p[3].isCoroutine)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
const val const = "const"
|
||||
val nonConst = "nonConst"
|
||||
|
||||
class A {
|
||||
lateinit var lateinit: Unit
|
||||
var nonLateinit = Unit
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(::const.isConst)
|
||||
assertFalse(::nonConst.isConst)
|
||||
|
||||
assertTrue(A::lateinit.isLateinit)
|
||||
assertFalse(A::nonLateinit.isLateinit)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
class A {
|
||||
fun <T> nonReified(): T = null!!
|
||||
inline fun <reified U> reified(): U = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertFalse(A::class.members.single { it.name == "nonReified" }.typeParameters.single().isReified)
|
||||
assertTrue(A::class.members.single { it.name == "reified" }.typeParameters.single().isReified)
|
||||
return "OK"
|
||||
}
|
||||
@@ -12619,6 +12619,57 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/modifiers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Modifiers extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInModifiers() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/modifiers"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableModality.kt")
|
||||
public void testCallableModality() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/callableModality.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classModality.kt")
|
||||
public void testClassModality() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/classModality.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classes.kt")
|
||||
public void testClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/classes.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("functions.kt")
|
||||
public void testFunctions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/functions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parameters.kt")
|
||||
public void testParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/parameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/properties.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameters.kt")
|
||||
public void testTypeParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/modifiers/typeParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/multifileClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -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