Support flexible types internally in typeOf
#KT-45066 Fixed
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@ import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
|
||||
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class PsiInlineIntrinsicsSupport(private val state: GenerationState) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||
class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||
DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.generateAsCast
|
||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
@@ -63,6 +64,8 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||
}
|
||||
|
||||
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
||||
val state: GenerationState
|
||||
|
||||
fun putClassInstance(v: InstructionAdapter, type: KT)
|
||||
|
||||
fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker)
|
||||
|
||||
@@ -89,6 +89,15 @@ fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||
}
|
||||
|
||||
v.invokestatic(REFLECTION, methodName, signature, false)
|
||||
|
||||
if (type.isFlexible() && intrinsicsSupport.state.stableTypeOf) {
|
||||
// If this is a flexible type, we've just generated its lower bound and have it on the stack.
|
||||
// Let's generate the upper bound now and call the method that takes lower and upper bound and constructs a flexible KType.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
generateTypeOf(v, type.upperBoundIfFlexible() as KT, intrinsicsSupport)
|
||||
|
||||
v.invokestatic(REFLECTION, "platformType", Type.getMethodDescriptor(K_TYPE, K_TYPE, K_TYPE), false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateNonReifiedTypeParameter(
|
||||
|
||||
@@ -260,6 +260,10 @@ class GenerationState private constructor(
|
||||
val useKotlinNothingValueException =
|
||||
languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4 &&
|
||||
!configuration.getBoolean(JVMConfigurationKeys.NO_KOTLIN_NOTHING_VALUE_EXCEPTION)
|
||||
|
||||
// In 1.6, `typeOf` became stable and started to rely on a few internal stdlib functions which were missing before 1.6.
|
||||
val stableTypeOf = languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_6
|
||||
|
||||
val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
val globalInlineContext: GlobalInlineContext = GlobalInlineContext(diagnostics)
|
||||
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||
|
||||
+21
-3
@@ -37404,9 +37404,15 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleType.kt")
|
||||
public void testFlexibleType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -37458,6 +37464,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
public void testInlineClasses() throws Exception {
|
||||
|
||||
+4
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.SignatureString
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
@@ -29,6 +30,9 @@ class IrInlineIntrinsicsSupport(
|
||||
private val context: JvmBackendContext,
|
||||
private val typeMapper: IrTypeMapper
|
||||
) : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||
override val state: GenerationState
|
||||
get() = context.state
|
||||
|
||||
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
||||
ExpressionCodegen.generateClassInstance(v, type, typeMapper)
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
// FILE: box.kt
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
fun box(): String {
|
||||
val v = returnTypeOf { J.get() }.toString()
|
||||
if (v != "J") return "Fail: $v"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <reified T: Any> returnTypeOf(block: () -> T) =
|
||||
typeOf<T>()
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
public class J {
|
||||
public static J get() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// !API_VERSION: LATEST
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
// FILE: box.kt
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
fun box(): String {
|
||||
val v1 = returnTypeOf { J.nullabilityFlexible() }.toString()
|
||||
if (v1 != "kotlin.String!") return "Fail 1: $v1"
|
||||
|
||||
val v2 = returnTypeOf { J.mutabilityFlexible() }.toString()
|
||||
// TODO: should be (Mutable)List after KT-35877.
|
||||
if (v2 != "kotlin.collections.List<kotlin.String!>") return "Fail 2: $v2"
|
||||
|
||||
val v3 = returnTypeOf { J.bothFlexible() }.toString()
|
||||
// TODO: should be (Mutable)List after KT-35877.
|
||||
if (v3 != "kotlin.collections.List<kotlin.String!>!") return "Fail 3: $v3"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> returnTypeOf(block: () -> T) =
|
||||
typeOf<T>()
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public class J {
|
||||
public static String nullabilityFlexible() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> mutabilityFlexible() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<String> bothFlexible() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// !API_VERSION: 1.5
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
// FILE: box.kt
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
fun box(): String {
|
||||
val v1 = returnTypeOf { J.nullabilityFlexible() }.toString()
|
||||
if (v1 != "kotlin.String") return "Fail 1: $v1"
|
||||
|
||||
val v2 = returnTypeOf { J.mutabilityFlexible() }.toString()
|
||||
if (v2 != "kotlin.collections.List<kotlin.String>") return "Fail 2: $v2"
|
||||
|
||||
val v3 = returnTypeOf { J.bothFlexible() }.toString()
|
||||
if (v3 != "kotlin.collections.List<kotlin.String>") return "Fail 3: $v3"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> returnTypeOf(block: () -> T) =
|
||||
typeOf<T>()
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public class J {
|
||||
public static String nullabilityFlexible() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> mutabilityFlexible() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<String> bothFlexible() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// !API_VERSION: LATEST
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: box.kt
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun check(expected: String, actual: KType) {
|
||||
assertEquals(expected + " (Kotlin reflection is not available)", actual.toString())
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
// String representation of platform types does not differ from non-nullable types in the stdlib implementation (without reflect).
|
||||
check("java.lang.String", returnTypeOf { J.nullabilityFlexible() })
|
||||
check("java.util.List<java.lang.String>", returnTypeOf { J.mutabilityFlexible() })
|
||||
check("java.util.List<java.lang.String>", returnTypeOf { J.bothFlexible() })
|
||||
|
||||
// However, type flexibility affects equality! Platform type is neither nullable nor non-nullable.
|
||||
val platform = returnTypeOf { J.nullabilityFlexible() }
|
||||
if (platform == returnTypeOf { J.nullable() }) return "Fail: platform type should not be equal to nullable type"
|
||||
if (platform == returnTypeOf { J.notNull() }) return "Fail: platform type should not be equal to non-nullable type"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <reified T> returnTypeOf(block: () -> T) =
|
||||
typeOf<T>()
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class J {
|
||||
public static String nullabilityFlexible() { return null; }
|
||||
|
||||
@NotNull
|
||||
public static List<String> mutabilityFlexible() { return null; }
|
||||
|
||||
public static List<String> bothFlexible() { return null; }
|
||||
|
||||
@Nullable
|
||||
public static String nullable() { return null; }
|
||||
|
||||
@NotNull
|
||||
public static String notNull() { return null; }
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// !API_VERSION: 1.5
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_RUNTIME
|
||||
// FILE: box.kt
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
fun check(expected: String, actual: KType) {
|
||||
assertEquals(expected + " (Kotlin reflection is not available)", actual.toString())
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
check("java.lang.String", returnTypeOf { J.nullabilityFlexible() })
|
||||
check("java.util.List<java.lang.String>", returnTypeOf { J.mutabilityFlexible() })
|
||||
check("java.util.List<java.lang.String>", returnTypeOf { J.bothFlexible() })
|
||||
|
||||
// Before 1.6, typeOf of a flexible type was represented as non-nullable type in stdlib implementation (without reflect).
|
||||
val platform = returnTypeOf { J.nullabilityFlexible() }
|
||||
if (platform == returnTypeOf { J.nullable() }) return "Fail: platform type should not be equal to nullable type"
|
||||
if (platform != returnTypeOf { J.notNull() }) return "Fail: platform type should be equal to non-nullable type"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
inline fun <reified T> returnTypeOf(block: () -> T) =
|
||||
typeOf<T>()
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class J {
|
||||
public static String nullabilityFlexible() { return null; }
|
||||
|
||||
@NotNull
|
||||
public static List<String> mutabilityFlexible() { return null; }
|
||||
|
||||
public static List<String> bothFlexible() { return null; }
|
||||
|
||||
@Nullable
|
||||
public static String nullable() { return null; }
|
||||
|
||||
@NotNull
|
||||
public static String notNull() { return null; }
|
||||
}
|
||||
+21
-3
@@ -37362,9 +37362,15 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleType.kt")
|
||||
public void testFlexibleType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -37416,6 +37422,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
public void testInlineClasses() throws Exception {
|
||||
|
||||
+21
-3
@@ -37404,9 +37404,15 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleType.kt")
|
||||
public void testFlexibleType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -37458,6 +37464,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
public void testInlineClasses() throws Exception {
|
||||
|
||||
+18
-3
@@ -29737,9 +29737,14 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/classes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("flexibleType.kt")
|
||||
public void testFlexibleType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
@@ -29792,6 +29797,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("flexibleTypes_after.kt")
|
||||
public void testFlexibleTypes_after() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("flexibleTypes_before.kt")
|
||||
public void testFlexibleTypes_before() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/flexibleTypes_before.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClasses.kt")
|
||||
public void testInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/inlineClasses.kt");
|
||||
|
||||
@@ -58,6 +58,9 @@ class ApiVersion private constructor(
|
||||
@JvmField
|
||||
val KOTLIN_1_5 = createByLanguageVersion(LanguageVersion.KOTLIN_1_5)
|
||||
|
||||
@JvmField
|
||||
val KOTLIN_1_6 = createByLanguageVersion(LanguageVersion.KOTLIN_1_6)
|
||||
|
||||
@JvmField
|
||||
val LATEST: ApiVersion = createByLanguageVersion(LanguageVersion.values().last())
|
||||
|
||||
|
||||
@@ -146,6 +146,11 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
|
||||
// Do nothing. KTypeParameterImpl implementation will load upper bounds from the metadata.
|
||||
}
|
||||
|
||||
// @Override // JPS
|
||||
public KType platformType(KType lowerBound, KType upperBound) {
|
||||
return TypeOfImplKt.createPlatformKType(lowerBound, upperBound);
|
||||
}
|
||||
|
||||
// Misc
|
||||
|
||||
public static void clearCaches() {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import kotlin.reflect.KType
|
||||
|
||||
internal fun createPlatformKType(lowerBound: KType, upperBound: KType): KType {
|
||||
// lowerBound/upperBound are guaranteed to be KTypeImpl over SimpleType, as long as this function is only used from the bytecode
|
||||
// generated by the compiler for `typeOf`.
|
||||
return KTypeImpl(
|
||||
KotlinTypeFactory.flexibleType(
|
||||
(lowerBound as KTypeImpl).type as SimpleType,
|
||||
(upperBound as KTypeImpl).type as SimpleType,
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -183,4 +183,11 @@ public class Reflection {
|
||||
public static void setUpperBounds(KTypeParameter typeParameter, KType... bounds) {
|
||||
factory.setUpperBounds(typeParameter, ArraysKt.toList(bounds));
|
||||
}
|
||||
|
||||
// Features of stable typeOf
|
||||
|
||||
@SinceKotlin(version = "1.6")
|
||||
public static KType platformType(KType lowerBound, KType upperBound) {
|
||||
return factory.platformType(lowerBound, upperBound);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +93,9 @@ public class ReflectionFactory {
|
||||
public void setUpperBounds(KTypeParameter typeParameter, List<KType> bounds) {
|
||||
((TypeParameterReference) typeParameter).setUpperBounds(bounds);
|
||||
}
|
||||
|
||||
@SinceKotlin(version = "1.6")
|
||||
public KType platformType(KType lowerBound, KType upperBound) {
|
||||
return new TypeReference(lowerBound.getClassifier(), lowerBound.getArguments(), lowerBound.isMarkedNullable(), upperBound);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,32 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("NEWER_VERSION_IN_SINCE_KOTLIN")
|
||||
|
||||
package kotlin.jvm.internal
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
@SinceKotlin("1.4")
|
||||
public class TypeReference(
|
||||
public class TypeReference /* @SinceKotlin("1.6") constructor */(
|
||||
override val classifier: KClassifier,
|
||||
override val arguments: List<KTypeProjection>,
|
||||
override val isMarkedNullable: Boolean
|
||||
override val isMarkedNullable: Boolean,
|
||||
private val platformTypeUpperBound: KType?,
|
||||
) : KType {
|
||||
constructor(
|
||||
classifier: KClassifier,
|
||||
arguments: List<KTypeProjection>,
|
||||
isMarkedNullable: Boolean,
|
||||
) : this(classifier, arguments, isMarkedNullable, null)
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = emptyList()
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is TypeReference &&
|
||||
classifier == other.classifier && arguments == other.arguments && isMarkedNullable == other.isMarkedNullable
|
||||
classifier == other.classifier && arguments == other.arguments && isMarkedNullable == other.isMarkedNullable &&
|
||||
platformTypeUpperBound == other.platformTypeUpperBound
|
||||
|
||||
override fun hashCode(): Int =
|
||||
(classifier.hashCode() * 31 + arguments.hashCode()) * 31 + isMarkedNullable.hashCode()
|
||||
|
||||
+3
@@ -3995,6 +3995,7 @@ public class kotlin/jvm/internal/Reflection {
|
||||
public static fun nullableTypeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||
public static fun nullableTypeOf (Ljava/lang/Class;[Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||
public static fun nullableTypeOf (Lkotlin/reflect/KClassifier;)Lkotlin/reflect/KType;
|
||||
public static fun platformType (Lkotlin/reflect/KType;Lkotlin/reflect/KType;)Lkotlin/reflect/KType;
|
||||
public static fun property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
||||
public static fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
||||
public static fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
||||
@@ -4021,6 +4022,7 @@ public class kotlin/jvm/internal/ReflectionFactory {
|
||||
public fun mutableProperty0 (Lkotlin/jvm/internal/MutablePropertyReference0;)Lkotlin/reflect/KMutableProperty0;
|
||||
public fun mutableProperty1 (Lkotlin/jvm/internal/MutablePropertyReference1;)Lkotlin/reflect/KMutableProperty1;
|
||||
public fun mutableProperty2 (Lkotlin/jvm/internal/MutablePropertyReference2;)Lkotlin/reflect/KMutableProperty2;
|
||||
public fun platformType (Lkotlin/reflect/KType;Lkotlin/reflect/KType;)Lkotlin/reflect/KType;
|
||||
public fun property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
||||
public fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
||||
public fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
||||
@@ -4120,6 +4122,7 @@ public final class kotlin/jvm/internal/TypeParameterReference$Companion {
|
||||
|
||||
public final class kotlin/jvm/internal/TypeReference : kotlin/reflect/KType {
|
||||
public fun <init> (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)V
|
||||
public fun <init> (Lkotlin/reflect/KClassifier;Ljava/util/List;ZLkotlin/reflect/KType;)V
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun getAnnotations ()Ljava/util/List;
|
||||
public fun getArguments ()Ljava/util/List;
|
||||
|
||||
Reference in New Issue
Block a user