From 9614404914f414782f6e67738c0da707fc325d0a Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Wed, 21 Dec 2016 22:00:31 +0300 Subject: [PATCH] Move all extensions from kotlin.reflect package to kotlin.reflect.full in order not to have kotlin-reflect package split between kotlin-stdlib and kotlin-reflect modules. Leave old API deprecated with a replacement provided and make those functions/properties inline pointing to moved ones. --- .../src/kotlin/reflect/KAnnotatedElements.kt | 1 + .../src/kotlin/reflect/KCallables.kt | 25 +- .../src/kotlin/reflect/KClasses.kt | 206 +++++++------- .../src/kotlin/reflect/KClassifiers.kt | 60 +--- .../src/kotlin/reflect/KTypes.kt | 30 +- .../kotlin/reflect/full/KAnnotatedElements.kt | 27 ++ .../src/kotlin/reflect/full/KCallables.kt | 51 ++++ .../src/kotlin/reflect/full/KClasses.kt | 267 ++++++++++++++++++ .../src/kotlin/reflect/full/KClassifiers.kt | 96 +++++++ .../src/kotlin/reflect/full/KTypes.kt | 57 ++++ .../kotlin/reflect/jvm/ReflectJvmMapping.kt | 3 + 11 files changed, 636 insertions(+), 187 deletions(-) create mode 100644 core/reflection.jvm/src/kotlin/reflect/full/KAnnotatedElements.kt create mode 100644 core/reflection.jvm/src/kotlin/reflect/full/KCallables.kt create mode 100644 core/reflection.jvm/src/kotlin/reflect/full/KClasses.kt create mode 100644 core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt create mode 100644 core/reflection.jvm/src/kotlin/reflect/full/KTypes.kt diff --git a/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt b/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt index 3c486def3e8..5b8a07f8fcb 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KAnnotatedElements.kt @@ -20,6 +20,7 @@ package kotlin.reflect /** * Returns an annotation of the given type on this element. */ +@Deprecated("Use 'findAnnotation' from kotlin.reflect.full package", ReplaceWith("this.findAnnotation()", "kotlin.reflect.full.findAnnotation"), level = DeprecationLevel.WARNING) @Suppress("UNCHECKED_CAST") inline fun KAnnotatedElement.findAnnotation(): T? = annotations.first { it is T } as T diff --git a/core/reflection.jvm/src/kotlin/reflect/KCallables.kt b/core/reflection.jvm/src/kotlin/reflect/KCallables.kt index ea3faaac5b6..4a0022b244f 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KCallables.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KCallables.kt @@ -17,33 +17,42 @@ @file:JvmName("KCallables") package kotlin.reflect +import kotlin.reflect.full.extensionReceiverParameter +import kotlin.reflect.full.findParameterByName +import kotlin.reflect.full.instanceParameter +import kotlin.reflect.full.valueParameters + /** * Returns a parameter representing the `this` instance needed to call this callable, * or `null` if this callable is not a member of a class and thus doesn't take such parameter. */ +@Deprecated("Use 'instanceParameter' from kotlin.reflect.full package", ReplaceWith("this.instanceParameter", "kotlin.reflect.full.instanceParameter"), level = DeprecationLevel.WARNING) @SinceKotlin("1.1") -val KCallable<*>.instanceParameter: KParameter? - get() = parameters.singleOrNull { it.kind == KParameter.Kind.INSTANCE } +inline val KCallable<*>.instanceParameter: KParameter? + get() = this.instanceParameter /** * Returns a parameter representing the extension receiver instance needed to call this callable, * or `null` if this callable is not an extension. */ +@Deprecated("Use 'extensionReceiverParameter' from kotlin.reflect.full package", ReplaceWith("this.extensionReceiverParameter", "kotlin.reflect.full.extensionReceiverParameter"), level = DeprecationLevel.WARNING) @SinceKotlin("1.1") -val KCallable<*>.extensionReceiverParameter: KParameter? - get() = parameters.singleOrNull { it.kind == KParameter.Kind.EXTENSION_RECEIVER } +inline val KCallable<*>.extensionReceiverParameter: KParameter? + get() = this.extensionReceiverParameter /** * Returns parameters of this callable, excluding the `this` instance and the extension receiver parameter. */ +@Deprecated("Use 'valueParameters' from kotlin.reflect.full package", ReplaceWith("this.valueParameters", "kotlin.reflect.full.valueParameters"), level = DeprecationLevel.WARNING) @SinceKotlin("1.1") -val KCallable<*>.valueParameters: List - get() = parameters.filter { it.kind == KParameter.Kind.VALUE } +inline val KCallable<*>.valueParameters: List + get() = this.valueParameters /** * Returns the parameter of this callable with the given name, or `null` if there's no such parameter. */ +@Deprecated("Use 'findParameterByName' from kotlin.reflect.full package", ReplaceWith("this.findParameterByName", "kotlin.reflect.full.findParameterByName"), level = DeprecationLevel.WARNING) @SinceKotlin("1.1") -fun KCallable<*>.findParameterByName(name: String): KParameter? { - return parameters.singleOrNull { it.name == name } +inline fun KCallable<*>.findParameterByName(name: String): KParameter? { + return this.findParameterByName(name) } diff --git a/core/reflection.jvm/src/kotlin/reflect/KClasses.kt b/core/reflection.jvm/src/kotlin/reflect/KClasses.kt index a65be582445..761dd927fa3 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClasses.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClasses.kt @@ -19,52 +19,66 @@ package kotlin.reflect -import org.jetbrains.kotlin.descriptors.ConstructorDescriptor -import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.utils.DFS -import kotlin.reflect.jvm.internal.KCallableImpl -import kotlin.reflect.jvm.internal.KClassImpl -import kotlin.reflect.jvm.internal.KFunctionImpl -import kotlin.reflect.jvm.internal.KTypeImpl +import kotlin.reflect.full.allSuperclasses +import kotlin.reflect.full.allSupertypes +import kotlin.reflect.full.cast +import kotlin.reflect.full.companionObject +import kotlin.reflect.full.companionObjectInstance +import kotlin.reflect.full.createInstance +import kotlin.reflect.full.declaredFunctions +import kotlin.reflect.full.declaredMemberExtensionFunctions +import kotlin.reflect.full.declaredMemberExtensionProperties +import kotlin.reflect.full.declaredMemberFunctions +import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.declaredMembers +import kotlin.reflect.full.defaultType +import kotlin.reflect.full.functions +import kotlin.reflect.full.isSubclassOf +import kotlin.reflect.full.isSuperclassOf +import kotlin.reflect.full.memberExtensionFunctions +import kotlin.reflect.full.memberExtensionProperties +import kotlin.reflect.full.memberFunctions +import kotlin.reflect.full.memberProperties +import kotlin.reflect.full.primaryConstructor +import kotlin.reflect.full.safeCast +import kotlin.reflect.full.staticFunctions +import kotlin.reflect.full.staticProperties +import kotlin.reflect.full.superclasses /** * Returns the primary constructor of this class, or `null` if this class has no primary constructor. * See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/classes.html#constructors) * for more information. */ -val KClass.primaryConstructor: KFunction? - get() = (this as KClassImpl).constructors.firstOrNull { - ((it as KFunctionImpl).descriptor as ConstructorDescriptor).isPrimary - } +@Deprecated("Use 'primaryConstructor' from kotlin.reflect.full package", ReplaceWith("this.primaryConstructor", "kotlin.reflect.full.primaryConstructor"), level = DeprecationLevel.WARNING) +inline val KClass.primaryConstructor: KFunction? + get() = this.primaryConstructor /** * Returns a [KClass] instance representing the companion object of a given class, * or `null` if the class doesn't have a companion object. */ -val KClass<*>.companionObject: KClass<*>? - get() = nestedClasses.firstOrNull { - (it as KClassImpl<*>).descriptor.isCompanionObject - } +@Deprecated("Use 'companionObject' from kotlin.reflect.full package", ReplaceWith("this.companionObject", "kotlin.reflect.full.companionObject"), level = DeprecationLevel.WARNING) +inline val KClass<*>.companionObject: KClass<*>? + get() = this.companionObject /** * Returns an instance of the companion object of a given class, * or `null` if the class doesn't have a companion object. */ -val KClass<*>.companionObjectInstance: Any? - get() = companionObject?.objectInstance +@Deprecated("Use 'companionObjectInstance' from kotlin.reflect.full package", ReplaceWith("this.companionObjectInstance", "kotlin.reflect.full.companionObjectInstance"), level = DeprecationLevel.WARNING) +inline val KClass<*>.companionObjectInstance: Any? + get() = this.companionObjectInstance /** * Returns a type corresponding to the given class with type parameters of that class substituted as the corresponding arguments. * For example, for class `MyMap` [defaultType] would return the type `MyMap`. */ -@Deprecated("This function creates a type which rarely makes sense for generic classes. " + - "For example, such type can only be used in signatures of members of that class. " + - "Use starProjectedType or createType() for clearer semantics.") -val KClass<*>.defaultType: KType - get() = KTypeImpl((this as KClassImpl<*>).descriptor.defaultType) { jClass } +@Deprecated("Use 'defaultType' from kotlin.reflect.full package", ReplaceWith("this.defaultType", "kotlin.reflect.full.defaultType"), level = DeprecationLevel.WARNING) +inline val KClass<*>.defaultType: KType + get() = this.defaultType /** @@ -72,158 +86,140 @@ val KClass<*>.defaultType: KType * Does not include members declared in supertypes. */ @SinceKotlin("1.1") -val KClass<*>.declaredMembers: Collection> - get() = (this as KClassImpl).data().declaredMembers +@Deprecated("Use 'declaredMembers' from kotlin.reflect.full package", ReplaceWith("this.declaredMembers", "kotlin.reflect.full.declaredMembers"), level = DeprecationLevel.WARNING) +inline val KClass<*>.declaredMembers: Collection> + get() = this.declaredMembers /** * Returns all functions declared in this class, including all non-static methods declared in the class * and the superclasses, as well as static methods declared in the class. */ -val KClass<*>.functions: Collection> - get() = members.filterIsInstance>() +@Deprecated("Use 'functions' from kotlin.reflect.full package", ReplaceWith("this.functions", "kotlin.reflect.full.functions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.functions: Collection> + get() = this.functions /** * Returns static functions declared in this class. */ -val KClass<*>.staticFunctions: Collection> - get() = (this as KClassImpl).data().allStaticMembers.filterIsInstance>() +@Deprecated("Use 'staticFunctions' from kotlin.reflect.full package", ReplaceWith("this.staticFunctions", "kotlin.reflect.full.staticFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.staticFunctions: Collection> + get() = this.staticFunctions /** * Returns non-extension non-static functions declared in this class and all of its superclasses. */ -val KClass<*>.memberFunctions: Collection> - get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isNotExtension && it is KFunction<*> } as Collection> +@Deprecated("Use 'memberFunctions' from kotlin.reflect.full package", ReplaceWith("this.memberFunctions", "kotlin.reflect.full.memberFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.memberFunctions: Collection> + get() = this.memberFunctions /** * Returns extension functions declared in this class and all of its superclasses. */ -val KClass<*>.memberExtensionFunctions: Collection> - get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isExtension && it is KFunction<*> } as Collection> +@Deprecated("Use 'memberExtensionFunctions' from kotlin.reflect.full package", ReplaceWith("this.memberExtensionFunctions", "kotlin.reflect.full.memberExtensionFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.memberExtensionFunctions: Collection> + get() = this.memberExtensionFunctions /** * Returns all functions declared in this class. * If this is a Java class, it includes all non-static methods (both extensions and non-extensions) * declared in the class and the superclasses, as well as static methods declared in the class. */ -val KClass<*>.declaredFunctions: Collection> - get() = (this as KClassImpl).data().declaredMembers.filterIsInstance>() +@Deprecated("Use 'declaredFunctions' from kotlin.reflect.full package", ReplaceWith("this.declaredFunctions", "kotlin.reflect.full.declaredFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.declaredFunctions: Collection> + get() = this.declaredFunctions /** * Returns non-extension non-static functions declared in this class. */ -val KClass<*>.declaredMemberFunctions: Collection> - get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isNotExtension && it is KFunction<*> } as Collection> +@Deprecated("Use 'declaredMemberFunctions' from kotlin.reflect.full package", ReplaceWith("this.declaredMemberFunctions", "kotlin.reflect.full.declaredMemberFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.declaredMemberFunctions: Collection> + get() = this.declaredMemberFunctions /** * Returns extension functions declared in this class. */ -val KClass<*>.declaredMemberExtensionFunctions: Collection> - get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isExtension && it is KFunction<*> } as Collection> +@Deprecated("Use 'declaredMemberExtensionFunctions' from kotlin.reflect.full package", ReplaceWith("this.declaredMemberExtensionFunctions", "kotlin.reflect.full.declaredMemberExtensionFunctions"), level = DeprecationLevel.WARNING) +inline val KClass<*>.declaredMemberExtensionFunctions: Collection> + get() = this.declaredMemberExtensionFunctions /** * Returns static properties declared in this class. * Only properties representing static fields of Java classes are considered static. */ -val KClass<*>.staticProperties: Collection> - get() = (this as KClassImpl).data().allStaticMembers.filter { it.isNotExtension && it is KProperty0<*> } as Collection> +@Deprecated("Use 'staticProperties' from kotlin.reflect.full package", ReplaceWith("this.staticProperties", "kotlin.reflect.full.staticProperties"), level = DeprecationLevel.WARNING) +inline val KClass<*>.staticProperties: Collection> + get() = this.staticProperties /** * Returns non-extension properties declared in this class and all of its superclasses. */ -val KClass.memberProperties: Collection> - get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isNotExtension && it is KProperty1<*, *> } as Collection> +@Deprecated("Use 'memberProperties' from kotlin.reflect.full package", ReplaceWith("this.memberProperties", "kotlin.reflect.full.memberProperties"), level = DeprecationLevel.WARNING) +inline val KClass.memberProperties: Collection> + get() = this.memberProperties /** * Returns extension properties declared in this class and all of its superclasses. */ -val KClass.memberExtensionProperties: Collection> - get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isExtension && it is KProperty2<*, *, *> } as Collection> +@Deprecated("Use 'memberExtensionProperties' from kotlin.reflect.full package", ReplaceWith("this.memberExtensionProperties", "kotlin.reflect.full.memberExtensionProperties"), level = DeprecationLevel.WARNING) +inline val KClass.memberExtensionProperties: Collection> + get() = this.memberExtensionProperties /** * Returns non-extension properties declared in this class. */ -val KClass.declaredMemberProperties: Collection> - get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isNotExtension && it is KProperty1<*, *> } as Collection> +@Deprecated("Use 'declaredMemberProperties' from kotlin.reflect.full package", ReplaceWith("this.declaredMemberProperties", "kotlin.reflect.full.declaredMemberProperties"), level = DeprecationLevel.WARNING) +inline val KClass.declaredMemberProperties: Collection> + get() = this.declaredMemberProperties /** * Returns extension properties declared in this class. */ -val KClass.declaredMemberExtensionProperties: Collection> - get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isExtension && it is KProperty2<*, *, *> } as Collection> +@Deprecated("Use 'declaredMemberExtensionProperties' from kotlin.reflect.full package", ReplaceWith("this.declaredMemberExtensionProperties", "kotlin.reflect.full.declaredMemberExtensionProperties"), level = DeprecationLevel.WARNING) +inline val KClass.declaredMemberExtensionProperties: Collection> + get() = this.declaredMemberExtensionProperties -private val KCallableImpl<*>.isExtension: Boolean - get() = descriptor.extensionReceiverParameter != null - -private val KCallableImpl<*>.isNotExtension: Boolean - get() = !isExtension - /** * Immediate superclasses of this class, in the order they are listed in the source code. * Includes superclasses and superinterfaces of the class, but does not include the class itself. */ @SinceKotlin("1.1") -val KClass<*>.superclasses: List> - get() = supertypes.mapNotNull { it.classifier as? KClass<*> } +@Deprecated("Use 'superclasses' from kotlin.reflect.full package", ReplaceWith("this.superclasses", "kotlin.reflect.full.superclasses"), level = DeprecationLevel.WARNING) +inline val KClass<*>.superclasses: List> + get() = this.superclasses /** * All supertypes of this class, including indirect ones, in no particular order. * There is not more than one type in the returned collection that has any given classifier. */ @SinceKotlin("1.1") -val KClass<*>.allSupertypes: Collection - get() = DFS.dfs( - supertypes, - DFS.Neighbors { current -> - val klass = current.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $current") - val supertypes = klass.supertypes - val typeArguments = current.arguments - if (typeArguments.isEmpty()) supertypes - else TypeSubstitutor.create((current as KTypeImpl).type).let { substitutor -> - supertypes.map { supertype -> - val substituted = substitutor.substitute((supertype as KTypeImpl).type, Variance.INVARIANT) - ?: throw KotlinReflectionInternalError("Type substitution failed: $supertype ($current)") - KTypeImpl(substituted) { - // TODO - TODO("Java type for supertype") - } - } - } - }, - DFS.VisitedWithSet(), - object : DFS.NodeHandlerWithListResult() { - override fun beforeChildren(current: KType): Boolean { - result.add(current) - return true - } - } - ) - +@Deprecated("Use 'allSupertypes' from kotlin.reflect.full package", ReplaceWith("this.allSupertypes", "kotlin.reflect.full.allSupertypes"), level = DeprecationLevel.WARNING) +inline val KClass<*>.allSupertypes: Collection + get() = this.allSupertypes /** * All superclasses of this class, including indirect ones, in no particular order. * Includes superclasses and superinterfaces of the class, but does not include the class itself. * The returned collection does not contain more than one instance of any given class. */ @SinceKotlin("1.1") -val KClass<*>.allSuperclasses: Collection> - get() = allSupertypes.map { supertype -> - supertype.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $supertype") - } - +@Deprecated("Use 'allSuperclasses' from kotlin.reflect.full package", ReplaceWith("this.allSuperclasses", "kotlin.reflect.full.allSuperclasses"), level = DeprecationLevel.WARNING) +inline val KClass<*>.allSuperclasses: Collection> + get() = this.allSuperclasses /** * Returns `true` if `this` class is the same or is a (possibly indirect) subclass of [base], `false` otherwise. */ @SinceKotlin("1.1") -fun KClass<*>.isSubclassOf(base: KClass<*>): Boolean = - this == base || - DFS.ifAny(listOf(this), KClass<*>::superclasses) { it == base } +@Deprecated("Use 'isSubclassOf' from kotlin.reflect.full package", ReplaceWith("this.isSubclassOf(base)", "kotlin.reflect.full.isSubclassOf"), level = DeprecationLevel.WARNING) +inline fun KClass<*>.isSubclassOf(base: KClass<*>): Boolean = + this.isSubclassOf(base) /** * Returns `true` if `this` class is the same or is a (possibly indirect) superclass of [derived], `false` otherwise. */ @SinceKotlin("1.1") -fun KClass<*>.isSuperclassOf(derived: KClass<*>): Boolean = - derived.isSubclassOf(this) +@Deprecated("Use 'isSuperclassOf' from kotlin.reflect.full package", ReplaceWith("this.isSuperclassOf(derived)", "kotlin.reflect.full.isSuperclassOf"), level = DeprecationLevel.WARNING) +inline fun KClass<*>.isSuperclassOf(derived: KClass<*>): Boolean = + this.isSuperclassOf(derived) /** @@ -234,9 +230,9 @@ fun KClass<*>.isSuperclassOf(derived: KClass<*>): Boolean = * @see [KClass.safeCast] */ @SinceKotlin("1.1") -fun KClass.cast(value: Any?): T { - if (!isInstance(value)) throw TypeCastException("Value cannot be cast to $qualifiedName") - return value as T +@Deprecated("Use 'cast' from kotlin.reflect.full package", ReplaceWith("this.cast(value)", "kotlin.reflect.full.cast"), level = DeprecationLevel.WARNING) +inline fun KClass.cast(value: Any?): T { + return this.cast(value) } /** @@ -247,8 +243,9 @@ fun KClass.cast(value: Any?): T { * @see [KClass.cast] */ @SinceKotlin("1.1") -fun KClass.safeCast(value: Any?): T? { - return if (isInstance(value)) value as T else null +@Deprecated("Use 'safeCast' from kotlin.reflect.full package", ReplaceWith("this.safeCast(value)", "kotlin.reflect.full.safeCast"), level = DeprecationLevel.WARNING) +inline fun KClass.safeCast(value: Any?): T? { + return this.safeCast(value) } @@ -257,10 +254,7 @@ fun KClass.safeCast(value: Any?): T? { * (see [KParameter.isOptional]). If there are no or many such constructors, an exception is thrown. */ @SinceKotlin("1.1") -fun KClass.createInstance(): T { - // TODO: throw a meaningful exception - val noArgsConstructor = constructors.singleOrNull { it.parameters.all(KParameter::isOptional) } - ?: throw IllegalArgumentException("Class should have a single no-arg constructor: $this") - - return noArgsConstructor.callBy(emptyMap()) +@Deprecated("Use 'createInstance' from kotlin.reflect.full package", ReplaceWith("this.createInstance()", "kotlin.reflect.full.createInstance"), level = DeprecationLevel.WARNING) +inline fun KClass.createInstance(): T { + return this.createInstance() } diff --git a/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt b/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt index 21dcb0ff7f3..247423cb895 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClassifiers.kt @@ -17,10 +17,8 @@ @file:JvmName("KClassifiers") package kotlin.reflect -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.types.* -import kotlin.reflect.jvm.internal.KClassifierImpl -import kotlin.reflect.jvm.internal.KTypeImpl +import kotlin.reflect.full.createType +import kotlin.reflect.full.starProjectedType /** * Creates a [KType] instance with the given classifier, type arguments, nullability and annotations. @@ -34,47 +32,12 @@ import kotlin.reflect.jvm.internal.KTypeImpl * not `inner`, or is declared on the top level. */ @SinceKotlin("1.1") -fun KClassifier.createType( +@Deprecated("Use 'createType' from kotlin.reflect.full package", ReplaceWith("this.createType(arguments, nullable, annotations)", "kotlin.reflect.full.createType"), level = DeprecationLevel.WARNING) +inline fun KClassifier.createType( arguments: List = emptyList(), nullable: Boolean = false, annotations: List = emptyList() -): KType { - val descriptor = (this as? KClassifierImpl)?.descriptor - ?: throw KotlinReflectionInternalError("Cannot create type for an unsupported classifier: $this (${this.javaClass})") - - val typeConstructor = descriptor.typeConstructor - val parameters = typeConstructor.parameters - if (parameters.size != arguments.size) { - throw IllegalArgumentException("Class declares ${parameters.size} type parameters, but ${arguments.size} were provided.") - } - - // TODO: throw exception if argument does not satisfy bounds - - val typeAnnotations = - if (annotations.isEmpty()) Annotations.EMPTY - else Annotations.EMPTY // TODO: support type annotations - - val kotlinType = createKotlinType(typeAnnotations, typeConstructor, arguments, nullable) - - return KTypeImpl(kotlinType) { - TODO("Java type is not yet supported for types created with createType (classifier = $this)") - } -} - -private fun createKotlinType( - typeAnnotations: Annotations, typeConstructor: TypeConstructor, arguments: List, nullable: Boolean -): SimpleType { - val parameters = typeConstructor.parameters - return KotlinTypeFactory.simpleType(typeAnnotations, typeConstructor, arguments.mapIndexed { index, typeProjection -> - val type = (typeProjection.type as KTypeImpl?)?.type - when (typeProjection.variance) { - KVariance.INVARIANT -> TypeProjectionImpl(Variance.INVARIANT, type!!) - KVariance.IN -> TypeProjectionImpl(Variance.IN_VARIANCE, type!!) - KVariance.OUT -> TypeProjectionImpl(Variance.OUT_VARIANCE, type!!) - null -> StarProjectionImpl(parameters[index]) - } - }, nullable) -} +): KType = this.createType(arguments, nullable, annotations) /** * Creates an instance of [KType] with the given classifier, substituting all its type parameters with star projections. @@ -83,13 +46,6 @@ private fun createKotlinType( * @see [KClassifier.createType] */ @SinceKotlin("1.1") -val KClassifier.starProjectedType: KType - get() { - val descriptor = (this as? KClassifierImpl)?.descriptor - ?: return createType() - - val typeParameters = descriptor.typeConstructor.parameters - if (typeParameters.isEmpty()) return createType() // TODO: optimize, get defaultType from ClassDescriptor - - return createType(typeParameters.map { KTypeProjection.STAR }) - } +@Deprecated("Use 'starProjectedType' from kotlin.reflect.full package", ReplaceWith("this.starProjectedType", "kotlin.reflect.full.starProjectedType"), level = DeprecationLevel.WARNING) +inline val KClassifier.starProjectedType: KType + get() = this.starProjectedType \ No newline at end of file diff --git a/core/reflection.jvm/src/kotlin/reflect/KTypes.kt b/core/reflection.jvm/src/kotlin/reflect/KTypes.kt index 69485c44b2b..08dc75cdf40 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KTypes.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KTypes.kt @@ -17,40 +17,28 @@ @file:JvmName("KTypes") package kotlin.reflect -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.isFlexible -import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf -import kotlin.reflect.jvm.internal.KTypeImpl +import kotlin.reflect.full.isSubtypeOf +import kotlin.reflect.full.isSupertypeOf +import kotlin.reflect.full.withNullability /** * Returns a new type with the same classifier, arguments and annotations as the given type, and with the given nullability. */ @SinceKotlin("1.1") -fun KType.withNullability(nullable: Boolean): KType { - if (isMarkedNullable) { - return if (nullable) this else KTypeImpl(TypeUtils.makeNotNullable((this as KTypeImpl).type)) { javaType } - } - - // If the type is not marked nullable, it's either a non-null type or a platform type. - val kotlinType = (this as KTypeImpl).type - if (kotlinType.isFlexible()) return KTypeImpl(TypeUtils.makeNullableAsSpecified(kotlinType, nullable)) { javaType } - - return if (!nullable) this else KTypeImpl(TypeUtils.makeNullable(kotlinType)) { javaType } -} +@Deprecated("Use 'withNullability' from kotlin.reflect.full package", ReplaceWith("this.withNullability(nullable)", "kotlin.reflect.full.withNullability"), level = DeprecationLevel.WARNING) +inline fun KType.withNullability(nullable: Boolean): KType = this.withNullability(nullable) /** * Returns `true` if `this` type is the same or is a subtype of [other], `false` otherwise. */ @SinceKotlin("1.1") -fun KType.isSubtypeOf(other: KType): Boolean { - return (this as KTypeImpl).type.isSubtypeOf((other as KTypeImpl).type) -} +@Deprecated("Use 'isSubtypeOf' from kotlin.reflect.full package", ReplaceWith("this.isSubtypeOf(other)", "kotlin.reflect.full.isSubtypeOf"), level = DeprecationLevel.WARNING) +inline fun KType.isSubtypeOf(other: KType): Boolean = this.isSubtypeOf(other) /** * Returns `true` if `this` type is the same or is a supertype of [other], `false` otherwise. */ @SinceKotlin("1.1") -fun KType.isSupertypeOf(other: KType): Boolean { - return other.isSubtypeOf(this) -} +@Deprecated("Use 'isSupertypeOf' from kotlin.reflect.full package", ReplaceWith("this.isSupertypeOf(other)", "kotlin.reflect.full.isSupertypeOf"), level = DeprecationLevel.WARNING) +inline fun KType.isSupertypeOf(other: KType): Boolean = this.isSupertypeOf(other) diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KAnnotatedElements.kt b/core/reflection.jvm/src/kotlin/reflect/full/KAnnotatedElements.kt new file mode 100644 index 00000000000..5b2dd07e879 --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/full/KAnnotatedElements.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2016 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. + */ + +@file:JvmName("KAnnotatedElements") +package kotlin.reflect.full + +import kotlin.reflect.* + +/** + * Returns an annotation of the given type on this element. + */ +@Suppress("UNCHECKED_CAST") +inline fun KAnnotatedElement.findAnnotation(): T? = + annotations.first { it is T } as T diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KCallables.kt b/core/reflection.jvm/src/kotlin/reflect/full/KCallables.kt new file mode 100644 index 00000000000..634371373ee --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/full/KCallables.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2016 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. + */ + +@file:JvmName("KCallables") +package kotlin.reflect.full + +import kotlin.reflect.* + +/** + * Returns a parameter representing the `this` instance needed to call this callable, + * or `null` if this callable is not a member of a class and thus doesn't take such parameter. + */ +@SinceKotlin("1.1") +val KCallable<*>.instanceParameter: KParameter? + get() = parameters.singleOrNull { it.kind == KParameter.Kind.INSTANCE } + +/** + * Returns a parameter representing the extension receiver instance needed to call this callable, + * or `null` if this callable is not an extension. + */ +@SinceKotlin("1.1") +val KCallable<*>.extensionReceiverParameter: KParameter? + get() = parameters.singleOrNull { it.kind == KParameter.Kind.EXTENSION_RECEIVER } + +/** + * Returns parameters of this callable, excluding the `this` instance and the extension receiver parameter. + */ +@SinceKotlin("1.1") +val KCallable<*>.valueParameters: List + get() = parameters.filter { it.kind == KParameter.Kind.VALUE } + +/** + * Returns the parameter of this callable with the given name, or `null` if there's no such parameter. + */ +@SinceKotlin("1.1") +fun KCallable<*>.findParameterByName(name: String): KParameter? { + return parameters.singleOrNull { it.name == name } +} diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KClasses.kt b/core/reflection.jvm/src/kotlin/reflect/full/KClasses.kt new file mode 100644 index 00000000000..e14110de089 --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/full/KClasses.kt @@ -0,0 +1,267 @@ +/* + * Copyright 2010-2016 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. + */ + +@file:JvmName("KClasses") +@file:Suppress("UNCHECKED_CAST") + +package kotlin.reflect.full + +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.types.TypeSubstitutor +import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.utils.DFS +import kotlin.reflect.* +import kotlin.reflect.jvm.internal.KCallableImpl +import kotlin.reflect.jvm.internal.KClassImpl +import kotlin.reflect.jvm.internal.KFunctionImpl +import kotlin.reflect.jvm.internal.KTypeImpl + +/** + * Returns the primary constructor of this class, or `null` if this class has no primary constructor. + * See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/classes.html#constructors) + * for more information. + */ +val KClass.primaryConstructor: KFunction? + get() = (this as KClassImpl).constructors.firstOrNull { + ((it as KFunctionImpl).descriptor as ConstructorDescriptor).isPrimary + } + + +/** + * Returns a [KClass] instance representing the companion object of a given class, + * or `null` if the class doesn't have a companion object. + */ +val KClass<*>.companionObject: KClass<*>? + get() = nestedClasses.firstOrNull { + (it as KClassImpl<*>).descriptor.isCompanionObject + } + +/** + * Returns an instance of the companion object of a given class, + * or `null` if the class doesn't have a companion object. + */ +val KClass<*>.companionObjectInstance: Any? + get() = companionObject?.objectInstance + + +/** + * Returns a type corresponding to the given class with type parameters of that class substituted as the corresponding arguments. + * For example, for class `MyMap` [defaultType] would return the type `MyMap`. + */ +@Deprecated("This function creates a type which rarely makes sense for generic classes. " + + "For example, such type can only be used in signatures of members of that class. " + + "Use starProjectedType or createType() for clearer semantics.") +val KClass<*>.defaultType: KType + get() = KTypeImpl((this as KClassImpl<*>).descriptor.defaultType) { jClass } + + +/** + * Returns all functions and properties declared in this class. + * Does not include members declared in supertypes. + */ +@SinceKotlin("1.1") +val KClass<*>.declaredMembers: Collection> + get() = (this as KClassImpl).data().declaredMembers + +/** + * Returns all functions declared in this class, including all non-static methods declared in the class + * and the superclasses, as well as static methods declared in the class. + */ +val KClass<*>.functions: Collection> + get() = members.filterIsInstance>() + +/** + * Returns static functions declared in this class. + */ +val KClass<*>.staticFunctions: Collection> + get() = (this as KClassImpl).data().allStaticMembers.filterIsInstance>() + +/** + * Returns non-extension non-static functions declared in this class and all of its superclasses. + */ +val KClass<*>.memberFunctions: Collection> + get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isNotExtension && it is KFunction<*> } as Collection> + +/** + * Returns extension functions declared in this class and all of its superclasses. + */ +val KClass<*>.memberExtensionFunctions: Collection> + get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isExtension && it is KFunction<*> } as Collection> + +/** + * Returns all functions declared in this class. + * If this is a Java class, it includes all non-static methods (both extensions and non-extensions) + * declared in the class and the superclasses, as well as static methods declared in the class. + */ +val KClass<*>.declaredFunctions: Collection> + get() = (this as KClassImpl).data().declaredMembers.filterIsInstance>() + +/** + * Returns non-extension non-static functions declared in this class. + */ +val KClass<*>.declaredMemberFunctions: Collection> + get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isNotExtension && it is KFunction<*> } as Collection> + +/** + * Returns extension functions declared in this class. + */ +val KClass<*>.declaredMemberExtensionFunctions: Collection> + get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isExtension && it is KFunction<*> } as Collection> + +/** + * Returns static properties declared in this class. + * Only properties representing static fields of Java classes are considered static. + */ +val KClass<*>.staticProperties: Collection> + get() = (this as KClassImpl).data().allStaticMembers.filter { it.isNotExtension && it is KProperty0<*> } as Collection> + +/** + * Returns non-extension properties declared in this class and all of its superclasses. + */ +val KClass.memberProperties: Collection> + get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isNotExtension && it is KProperty1<*, *> } as Collection> + +/** + * Returns extension properties declared in this class and all of its superclasses. + */ +val KClass.memberExtensionProperties: Collection> + get() = (this as KClassImpl).data().allNonStaticMembers.filter { it.isExtension && it is KProperty2<*, *, *> } as Collection> + +/** + * Returns non-extension properties declared in this class. + */ +val KClass.declaredMemberProperties: Collection> + get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isNotExtension && it is KProperty1<*, *> } as Collection> + +/** + * Returns extension properties declared in this class. + */ +val KClass.declaredMemberExtensionProperties: Collection> + get() = (this as KClassImpl).data().declaredNonStaticMembers.filter { it.isExtension && it is KProperty2<*, *, *> } as Collection> + + +private val KCallableImpl<*>.isExtension: Boolean + get() = descriptor.extensionReceiverParameter != null + +private val KCallableImpl<*>.isNotExtension: Boolean + get() = !isExtension + +/** + * Immediate superclasses of this class, in the order they are listed in the source code. + * Includes superclasses and superinterfaces of the class, but does not include the class itself. + */ +@SinceKotlin("1.1") +val KClass<*>.superclasses: List> + get() = supertypes.mapNotNull { it.classifier as? KClass<*> } + +/** + * All supertypes of this class, including indirect ones, in no particular order. + * There is not more than one type in the returned collection that has any given classifier. + */ +@SinceKotlin("1.1") +val KClass<*>.allSupertypes: Collection + get() = DFS.dfs( + supertypes, + DFS.Neighbors { current -> + val klass = current.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $current") + val supertypes = klass.supertypes + val typeArguments = current.arguments + if (typeArguments.isEmpty()) supertypes + else TypeSubstitutor.create((current as KTypeImpl).type).let { substitutor -> + supertypes.map { supertype -> + val substituted = substitutor.substitute((supertype as KTypeImpl).type, Variance.INVARIANT) + ?: throw KotlinReflectionInternalError("Type substitution failed: $supertype ($current)") + KTypeImpl(substituted) { + // TODO + TODO("Java type for supertype") + } + } + } + }, + DFS.VisitedWithSet(), + object : DFS.NodeHandlerWithListResult() { + override fun beforeChildren(current: KType): Boolean { + result.add(current) + return true + } + } + ) + +/** + * All superclasses of this class, including indirect ones, in no particular order. + * Includes superclasses and superinterfaces of the class, but does not include the class itself. + * The returned collection does not contain more than one instance of any given class. + */ +@SinceKotlin("1.1") +val KClass<*>.allSuperclasses: Collection> + get() = allSupertypes.map { supertype -> + supertype.classifier as? KClass<*> ?: throw KotlinReflectionInternalError("Supertype not a class: $supertype") + } + +/** + * Returns `true` if `this` class is the same or is a (possibly indirect) subclass of [base], `false` otherwise. + */ +@SinceKotlin("1.1") +fun KClass<*>.isSubclassOf(base: KClass<*>): Boolean = + this == base || + DFS.ifAny(listOf(this), KClass<*>::superclasses) { it == base } + +/** + * Returns `true` if `this` class is the same or is a (possibly indirect) superclass of [derived], `false` otherwise. + */ +@SinceKotlin("1.1") +fun KClass<*>.isSuperclassOf(derived: KClass<*>): Boolean = + derived.isSubclassOf(this) + + +/** + * Casts the given [value] to the class represented by this [KClass] object. + * Throws an exception if the value is `null` or if it is not an instance of this class. + * + * @see [KClass.isInstance] + * @see [KClass.safeCast] + */ +@SinceKotlin("1.1") +fun KClass.cast(value: Any?): T { + if (!isInstance(value)) throw TypeCastException("Value cannot be cast to $qualifiedName") + return value as T +} + +/** + * Casts the given [value] to the class represented by this [KClass] object. + * Returns `null` if the value is `null` or if it is not an instance of this class. + * + * @see [KClass.isInstance] + * @see [KClass.cast] + */ +@SinceKotlin("1.1") +fun KClass.safeCast(value: Any?): T? { + return if (isInstance(value)) value as T else null +} + + +/** + * Creates a new instance of the class, calling a constructor which either has no parameters or all parameters of which are optional + * (see [KParameter.isOptional]). If there are no or many such constructors, an exception is thrown. + */ +@SinceKotlin("1.1") +fun KClass.createInstance(): T { + // TODO: throw a meaningful exception + val noArgsConstructor = constructors.singleOrNull { it.parameters.all(KParameter::isOptional) } + ?: throw IllegalArgumentException("Class should have a single no-arg constructor: $this") + + return noArgsConstructor.callBy(emptyMap()) +} diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt b/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt new file mode 100644 index 00000000000..b2ec005474d --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/full/KClassifiers.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2016 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. + */ + +@file:JvmName("KClassifiers") +package kotlin.reflect.full + +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.types.* +import kotlin.reflect.* +import kotlin.reflect.jvm.internal.KClassifierImpl +import kotlin.reflect.jvm.internal.KTypeImpl + +/** + * Creates a [KType] instance with the given classifier, type arguments, nullability and annotations. + * If the number of passed type arguments is not equal to the total number of type parameters of a classifier, + * an exception is thrown. If any of the arguments does not satisfy the bounds of the corresponding type parameter, + * an exception is thrown. + * + * For classifiers representing type parameters, the type argument list must always be empty. + * For classes, the type argument list should contain arguments for the type parameters of the class. If the class is `inner`, + * the list should follow with arguments for the type parameters of its outer class, and so forth until a class is + * not `inner`, or is declared on the top level. + */ +@SinceKotlin("1.1") +fun KClassifier.createType( + arguments: List = emptyList(), + nullable: Boolean = false, + annotations: List = emptyList() +): KType { + val descriptor = (this as? KClassifierImpl)?.descriptor + ?: throw KotlinReflectionInternalError("Cannot create type for an unsupported classifier: $this (${this.javaClass})") + + val typeConstructor = descriptor.typeConstructor + val parameters = typeConstructor.parameters + if (parameters.size != arguments.size) { + throw IllegalArgumentException("Class declares ${parameters.size} type parameters, but ${arguments.size} were provided.") + } + + // TODO: throw exception if argument does not satisfy bounds + + val typeAnnotations = + if (annotations.isEmpty()) Annotations.EMPTY + else Annotations.EMPTY // TODO: support type annotations + + val kotlinType = createKotlinType(typeAnnotations, typeConstructor, arguments, nullable) + + return KTypeImpl(kotlinType) { + TODO("Java type is not yet supported for types created with createType (classifier = $this)") + } +} + +private fun createKotlinType( + typeAnnotations: Annotations, typeConstructor: TypeConstructor, arguments: List, nullable: Boolean +): SimpleType { + val parameters = typeConstructor.parameters + return KotlinTypeFactory.simpleType(typeAnnotations, typeConstructor, arguments.mapIndexed { index, typeProjection -> + val type = (typeProjection.type as KTypeImpl?)?.type + when (typeProjection.variance) { + KVariance.INVARIANT -> TypeProjectionImpl(Variance.INVARIANT, type!!) + KVariance.IN -> TypeProjectionImpl(Variance.IN_VARIANCE, type!!) + KVariance.OUT -> TypeProjectionImpl(Variance.OUT_VARIANCE, type!!) + null -> StarProjectionImpl(parameters[index]) + } + }, nullable) +} + +/** + * Creates an instance of [KType] with the given classifier, substituting all its type parameters with star projections. + * The resulting type is not marked as nullable and does not have any annotations. + * + * @see [KClassifier.createType] + */ +@SinceKotlin("1.1") +val KClassifier.starProjectedType: KType + get() { + val descriptor = (this as? KClassifierImpl)?.descriptor + ?: return createType() + + val typeParameters = descriptor.typeConstructor.parameters + if (typeParameters.isEmpty()) return createType() // TODO: optimize, get defaultType from ClassDescriptor + + return createType(typeParameters.map { KTypeProjection.STAR }) + } diff --git a/core/reflection.jvm/src/kotlin/reflect/full/KTypes.kt b/core/reflection.jvm/src/kotlin/reflect/full/KTypes.kt new file mode 100644 index 00000000000..7413b068f56 --- /dev/null +++ b/core/reflection.jvm/src/kotlin/reflect/full/KTypes.kt @@ -0,0 +1,57 @@ +/* + * Copyright 2010-2016 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. + */ + +@file:JvmName("KTypes") +package kotlin.reflect.full + +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.isFlexible +import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf +import kotlin.reflect.* +import kotlin.reflect.jvm.internal.KTypeImpl + +/** + * Returns a new type with the same classifier, arguments and annotations as the given type, and with the given nullability. + */ +@SinceKotlin("1.1") +fun KType.withNullability(nullable: Boolean): KType { + if (isMarkedNullable) { + return if (nullable) this else KTypeImpl(TypeUtils.makeNotNullable((this as KTypeImpl).type)) { javaType } + } + + // If the type is not marked nullable, it's either a non-null type or a platform type. + val kotlinType = (this as KTypeImpl).type + if (kotlinType.isFlexible()) return KTypeImpl(TypeUtils.makeNullableAsSpecified(kotlinType, nullable)) { javaType } + + return if (!nullable) this else KTypeImpl(TypeUtils.makeNullable(kotlinType)) { javaType } +} + + +/** + * Returns `true` if `this` type is the same or is a subtype of [other], `false` otherwise. + */ +@SinceKotlin("1.1") +fun KType.isSubtypeOf(other: KType): Boolean { + return (this as KTypeImpl).type.isSubtypeOf((other as KTypeImpl).type) +} + +/** + * Returns `true` if `this` type is the same or is a supertype of [other], `false` otherwise. + */ +@SinceKotlin("1.1") +fun KType.isSupertypeOf(other: KType): Boolean { + return other.isSubtypeOf(this) +} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt index 57053636e72..8e08d9d172e 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/ReflectJvmMapping.kt @@ -26,6 +26,9 @@ import java.lang.reflect.* import java.util.* import kotlin.jvm.internal.Reflection import kotlin.reflect.* +import kotlin.reflect.full.companionObject +import kotlin.reflect.full.functions +import kotlin.reflect.full.memberProperties import kotlin.reflect.jvm.internal.KTypeImpl import kotlin.reflect.jvm.internal.asKCallableImpl import kotlin.reflect.jvm.internal.asKPropertyImpl