Support mutable collection types in typeOf

flexibleTypes_1_6.kt is fixed for JVM IR in a subsequent commit.

 #KT-35877 Fixed
This commit is contained in:
Alexander Udalov
2021-05-21 20:39:29 +02:00
parent 6e975b3498
commit 0cb905a4b1
19 changed files with 327 additions and 15 deletions
@@ -5,12 +5,14 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.model.TypeParameterMarker
@@ -56,5 +58,10 @@ class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedT
)
}
override fun isMutableCollectionType(type: KotlinType): Boolean {
val classifier = type.constructor.declarationDescriptor
return classifier is ClassDescriptor && JavaToKotlinClassMap.isMutable(classifier.fqNameUnsafe)
}
override fun toKotlinType(type: KotlinType): KotlinType = type
}
@@ -70,6 +70,8 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker)
fun isMutableCollectionType(type: KT): Boolean
fun toKotlinType(type: KT): KotlinType
}
@@ -90,13 +90,19 @@ 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)
if (intrinsicsSupport.state.stableTypeOf) {
if (intrinsicsSupport.isMutableCollectionType(type)) {
v.invokestatic(REFLECTION, "mutableCollectionType", Type.getMethodDescriptor(K_TYPE, K_TYPE), false)
}
v.invokestatic(REFLECTION, "platformType", Type.getMethodDescriptor(K_TYPE, K_TYPE, K_TYPE), false)
if (type.isFlexible()) {
// 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)
}
}
}