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.Type.VOID_TYPE
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
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) {
|
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||||
DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
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.generateIsCheck
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
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.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
@@ -63,6 +64,8 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
||||||
|
val state: GenerationState
|
||||||
|
|
||||||
fun putClassInstance(v: InstructionAdapter, type: KT)
|
fun putClassInstance(v: InstructionAdapter, type: KT)
|
||||||
|
|
||||||
fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker)
|
fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker)
|
||||||
|
|||||||
@@ -89,6 +89,15 @@ fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
|||||||
}
|
}
|
||||||
|
|
||||||
v.invokestatic(REFLECTION, methodName, signature, false)
|
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(
|
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateNonReifiedTypeParameter(
|
||||||
|
|||||||
@@ -260,6 +260,10 @@ class GenerationState private constructor(
|
|||||||
val useKotlinNothingValueException =
|
val useKotlinNothingValueException =
|
||||||
languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4 &&
|
languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4 &&
|
||||||
!configuration.getBoolean(JVMConfigurationKeys.NO_KOTLIN_NOTHING_VALUE_EXCEPTION)
|
!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 samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||||
val globalInlineContext: GlobalInlineContext = GlobalInlineContext(diagnostics)
|
val globalInlineContext: GlobalInlineContext = GlobalInlineContext(diagnostics)
|
||||||
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
val mappingsClassesForWhenByEnum: MappingsClassesForWhenByEnum = MappingsClassesForWhenByEnum(this)
|
||||||
|
|||||||
+21
-3
@@ -37404,9 +37404,15 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("flexibleType.kt")
|
@TestMetadata("flexibleTypes_after.kt")
|
||||||
public void testFlexibleType() throws Exception {
|
public void testFlexibleTypes_after() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
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
|
@Test
|
||||||
@@ -37458,6 +37464,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineClasses.kt")
|
@TestMetadata("inlineClasses.kt")
|
||||||
public void testInlineClasses() throws Exception {
|
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.backend.jvm.lower.FunctionReferenceLowering
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
@@ -29,6 +30,9 @@ class IrInlineIntrinsicsSupport(
|
|||||||
private val context: JvmBackendContext,
|
private val context: JvmBackendContext,
|
||||||
private val typeMapper: IrTypeMapper
|
private val typeMapper: IrTypeMapper
|
||||||
) : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
) : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||||
|
override val state: GenerationState
|
||||||
|
get() = context.state
|
||||||
|
|
||||||
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
||||||
ExpressionCodegen.generateClassInstance(v, type, typeMapper)
|
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
|
@Test
|
||||||
@TestMetadata("flexibleType.kt")
|
@TestMetadata("flexibleTypes_after.kt")
|
||||||
public void testFlexibleType() throws Exception {
|
public void testFlexibleTypes_after() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
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
|
@Test
|
||||||
@@ -37416,6 +37422,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineClasses.kt")
|
@TestMetadata("inlineClasses.kt")
|
||||||
public void testInlineClasses() throws Exception {
|
public void testInlineClasses() throws Exception {
|
||||||
|
|||||||
+21
-3
@@ -37404,9 +37404,15 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("flexibleType.kt")
|
@TestMetadata("flexibleTypes_after.kt")
|
||||||
public void testFlexibleType() throws Exception {
|
public void testFlexibleTypes_after() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
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
|
@Test
|
||||||
@@ -37458,6 +37464,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
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
|
@Test
|
||||||
@TestMetadata("inlineClasses.kt")
|
@TestMetadata("inlineClasses.kt")
|
||||||
public void testInlineClasses() throws Exception {
|
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");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/classes.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("flexibleType.kt")
|
@TestMetadata("flexibleTypes_after.kt")
|
||||||
public void testFlexibleType() throws Exception {
|
public void testFlexibleTypes_after() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/flexibleType.kt");
|
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")
|
@TestMetadata("inlineClasses.kt")
|
||||||
@@ -29792,6 +29797,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/classes.kt");
|
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")
|
@TestMetadata("inlineClasses.kt")
|
||||||
public void testInlineClasses() throws Exception {
|
public void testInlineClasses() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/inlineClasses.kt");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/inlineClasses.kt");
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ class ApiVersion private constructor(
|
|||||||
@JvmField
|
@JvmField
|
||||||
val KOTLIN_1_5 = createByLanguageVersion(LanguageVersion.KOTLIN_1_5)
|
val KOTLIN_1_5 = createByLanguageVersion(LanguageVersion.KOTLIN_1_5)
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val KOTLIN_1_6 = createByLanguageVersion(LanguageVersion.KOTLIN_1_6)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val LATEST: ApiVersion = createByLanguageVersion(LanguageVersion.values().last())
|
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.
|
// 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
|
// Misc
|
||||||
|
|
||||||
public static void clearCaches() {
|
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) {
|
public static void setUpperBounds(KTypeParameter typeParameter, KType... bounds) {
|
||||||
factory.setUpperBounds(typeParameter, ArraysKt.toList(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) {
|
public void setUpperBounds(KTypeParameter typeParameter, List<KType> bounds) {
|
||||||
((TypeParameterReference) typeParameter).setUpperBounds(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.
|
* 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
|
package kotlin.jvm.internal
|
||||||
|
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
|
|
||||||
@SinceKotlin("1.4")
|
@SinceKotlin("1.4")
|
||||||
public class TypeReference(
|
public class TypeReference /* @SinceKotlin("1.6") constructor */(
|
||||||
override val classifier: KClassifier,
|
override val classifier: KClassifier,
|
||||||
override val arguments: List<KTypeProjection>,
|
override val arguments: List<KTypeProjection>,
|
||||||
override val isMarkedNullable: Boolean
|
override val isMarkedNullable: Boolean,
|
||||||
|
private val platformTypeUpperBound: KType?,
|
||||||
) : KType {
|
) : KType {
|
||||||
|
constructor(
|
||||||
|
classifier: KClassifier,
|
||||||
|
arguments: List<KTypeProjection>,
|
||||||
|
isMarkedNullable: Boolean,
|
||||||
|
) : this(classifier, arguments, isMarkedNullable, null)
|
||||||
|
|
||||||
override val annotations: List<Annotation>
|
override val annotations: List<Annotation>
|
||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
other is TypeReference &&
|
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 =
|
override fun hashCode(): Int =
|
||||||
(classifier.hashCode() * 31 + arguments.hashCode()) * 31 + isMarkedNullable.hashCode()
|
(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/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
public static fun nullableTypeOf (Ljava/lang/Class;[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 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 property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
||||||
public static fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
public static fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
||||||
public static fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
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 mutableProperty0 (Lkotlin/jvm/internal/MutablePropertyReference0;)Lkotlin/reflect/KMutableProperty0;
|
||||||
public fun mutableProperty1 (Lkotlin/jvm/internal/MutablePropertyReference1;)Lkotlin/reflect/KMutableProperty1;
|
public fun mutableProperty1 (Lkotlin/jvm/internal/MutablePropertyReference1;)Lkotlin/reflect/KMutableProperty1;
|
||||||
public fun mutableProperty2 (Lkotlin/jvm/internal/MutablePropertyReference2;)Lkotlin/reflect/KMutableProperty2;
|
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 property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
||||||
public fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
public fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
||||||
public fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
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 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;Z)V
|
||||||
|
public fun <init> (Lkotlin/reflect/KClassifier;Ljava/util/List;ZLkotlin/reflect/KType;)V
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
public fun getAnnotations ()Ljava/util/List;
|
public fun getAnnotations ()Ljava/util/List;
|
||||||
public fun getArguments ()Ljava/util/List;
|
public fun getArguments ()Ljava/util/List;
|
||||||
|
|||||||
Reference in New Issue
Block a user