Support Nothing type in typeOf
The proper support will come in KT-15518, but that would be a breaking change even for stable Kotlin without kotlin-reflect. Before that issue is fixed, represent Nothing in types with the Void class, and use a flag in the no-reflect implementation to remember that it's not actually the Void class itself. #KT-39166 Fixed
This commit is contained in:
@@ -195,4 +195,9 @@ public class Reflection {
|
||||
public static KType mutableCollectionType(KType type) {
|
||||
return factory.mutableCollectionType(type);
|
||||
}
|
||||
|
||||
@SinceKotlin(version = "1.6")
|
||||
public static KType nothingType(KType type) {
|
||||
return factory.nothingType(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,18 +97,26 @@ public class ReflectionFactory {
|
||||
@SinceKotlin(version = "1.6")
|
||||
public KType platformType(KType lowerBound, KType upperBound) {
|
||||
return new TypeReference(
|
||||
lowerBound.getClassifier(), lowerBound.getArguments(), lowerBound.isMarkedNullable(),
|
||||
upperBound,
|
||||
((TypeReference) lowerBound).getMutableCollectionType$kotlin_stdlib()
|
||||
lowerBound.getClassifier(), lowerBound.getArguments(), upperBound,
|
||||
((TypeReference) lowerBound).getFlags$kotlin_stdlib()
|
||||
);
|
||||
}
|
||||
|
||||
@SinceKotlin(version = "1.6")
|
||||
public KType mutableCollectionType(KType type) {
|
||||
TypeReference typeRef = (TypeReference) type;
|
||||
return new TypeReference(
|
||||
type.getClassifier(), type.getArguments(), type.isMarkedNullable(),
|
||||
((TypeReference) type).getPlatformTypeUpperBound$kotlin_stdlib(),
|
||||
true
|
||||
type.getClassifier(), type.getArguments(), typeRef.getPlatformTypeUpperBound$kotlin_stdlib(),
|
||||
typeRef.getFlags$kotlin_stdlib() | TypeReference.IS_MUTABLE_COLLECTION_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
@SinceKotlin(version = "1.6")
|
||||
public KType nothingType(KType type) {
|
||||
TypeReference typeRef = (TypeReference) type;
|
||||
return new TypeReference(
|
||||
type.getClassifier(), type.getArguments(), typeRef.getPlatformTypeUpperBound$kotlin_stdlib(),
|
||||
typeRef.getFlags$kotlin_stdlib() | TypeReference.IS_NOTHING_TYPE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,26 +13,28 @@ import kotlin.reflect.*
|
||||
public class TypeReference /* @SinceKotlin("1.6") constructor */(
|
||||
override val classifier: KClassifier,
|
||||
override val arguments: List<KTypeProjection>,
|
||||
override val isMarkedNullable: Boolean,
|
||||
internal val platformTypeUpperBound: KType?,
|
||||
internal val mutableCollectionType: Boolean,
|
||||
/* @SinceKotlin("1.6") */ internal val platformTypeUpperBound: KType?,
|
||||
/* @SinceKotlin("1.6") */ internal val flags: Int,
|
||||
) : KType {
|
||||
constructor(
|
||||
classifier: KClassifier,
|
||||
arguments: List<KTypeProjection>,
|
||||
isMarkedNullable: Boolean,
|
||||
) : this(classifier, arguments, isMarkedNullable, null, false)
|
||||
) : this(classifier, arguments, null, if (isMarkedNullable) IS_MARKED_NULLABLE else 0)
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = emptyList()
|
||||
|
||||
override val isMarkedNullable: Boolean
|
||||
get() = flags and IS_MARKED_NULLABLE != 0
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is TypeReference &&
|
||||
classifier == other.classifier && arguments == other.arguments && isMarkedNullable == other.isMarkedNullable &&
|
||||
platformTypeUpperBound == other.platformTypeUpperBound && mutableCollectionType == other.mutableCollectionType
|
||||
classifier == other.classifier && arguments == other.arguments && platformTypeUpperBound == other.platformTypeUpperBound &&
|
||||
flags == other.flags
|
||||
|
||||
override fun hashCode(): Int =
|
||||
(classifier.hashCode() * 31 + arguments.hashCode()) * 31 + isMarkedNullable.hashCode()
|
||||
(classifier.hashCode() * 31 + arguments.hashCode()) * 31 + flags.hashCode()
|
||||
|
||||
override fun toString(): String =
|
||||
asString(false) + Reflection.REFLECTION_NOT_AVAILABLE
|
||||
@@ -41,6 +43,7 @@ public class TypeReference /* @SinceKotlin("1.6") constructor */(
|
||||
val javaClass = (classifier as? KClass<*>)?.java
|
||||
val klass = when {
|
||||
javaClass == null -> classifier.toString()
|
||||
flags and IS_NOTHING_TYPE != 0 -> "kotlin.Nothing"
|
||||
javaClass.isArray -> javaClass.arrayClassName
|
||||
convertPrimitiveToWrapper && javaClass.isPrimitive -> (classifier as KClass<*>).javaObjectType.name
|
||||
else -> javaClass.name
|
||||
@@ -78,4 +81,11 @@ public class TypeReference /* @SinceKotlin("1.6") constructor */(
|
||||
KVariance.OUT -> "out $typeString"
|
||||
}
|
||||
}
|
||||
|
||||
// @SinceKotlin("1.6")
|
||||
internal companion object {
|
||||
internal const val IS_MARKED_NULLABLE = 1 shl 0
|
||||
internal const val IS_MUTABLE_COLLECTION_TYPE = 1 shl 1
|
||||
internal const val IS_NOTHING_TYPE = 1 shl 2
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user