JVM IR: get rid of toIrBasedKotlinType in MethodSignatureMapper

Commonize (in terms of TypeSystemCommonBackendContext implementations
for KotlinType/IrType) code that computes optimal TypeMappingMode to
apply to different positions where inline class types can be present.
This commit is contained in:
Alexander Udalov
2021-03-31 19:30:30 +02:00
parent b59ac5d8f6
commit ce0c0ad2e3
7 changed files with 37 additions and 45 deletions
@@ -218,7 +218,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
return mapType(returnType, sw, typeMappingModeFromAnnotation)
}
val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType, isAnnotationMethod)
val mappingMode = typeSystem.getOptimalModeForReturnType(returnType, isAnnotationMethod)
return mapType(returnType, sw, mappingMode)
}
@@ -1084,7 +1084,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
?: if (callableDescriptor.isMethodWithDeclarationSiteWildcards && type.arguments.isNotEmpty()) {
TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards
} else {
TypeMappingMode.getOptimalModeForValueParameter(type)
typeSystem.getOptimalModeForValueParameter(type)
}
mapType(type, sw, typeMappingMode)
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunctionBase
import org.jetbrains.kotlin.ir.descriptors.IrBasedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
@@ -190,7 +189,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
return typeMapper.mapType(returnType, typeMappingModeFromAnnotation, sw)
}
val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType.toIrBasedKotlinType(), isAnnotationMethod)
val mappingMode = typeSystem.getOptimalModeForReturnType(returnType, isAnnotationMethod)
return typeMapper.mapType(returnType, mappingMode, sw)
}
@@ -358,7 +357,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
?: if (declaration.isMethodWithDeclarationSiteWildcards && type.argumentsCount() != 0) {
TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards
} else {
TypeMappingMode.getOptimalModeForValueParameter(type.toIrBasedKotlinType())
typeSystem.getOptimalModeForValueParameter(type)
}
}
@@ -1,7 +1,5 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: BINDING_RECEIVERS
// IGNORE_BACKEND_FIR: JVM_IR
// KT-42025
open class L<LL>(val ll: LL)
@@ -98,4 +96,4 @@ fun box(): String {
val ipl = i.readP(Rec("OK"))
return ipl.ll
}
}
@@ -1,7 +1,5 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: BINDING_RECEIVERS
// IGNORE_BACKEND_FIR: JVM_IR
// KT-42025
open class L<LL>(val ll: LL)
@@ -22,4 +20,4 @@ val <PT> Rec<PT>.p: L<PT>
fun <T1, T2, R> foo2(t1: T1, t2: T2, bb: (T1, T2) -> R): R = bb(t1, t2)
fun box(): String =
Rec("O").fn().ll + Rec("K").p.ll
Rec("O").fn().ll + Rec("K").p.ll
@@ -5,28 +5,32 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
fun TypeMappingMode.Companion.getOptimalModeForValueParameter(
type: KotlinType
fun TypeSystemCommonBackendContext.getOptimalModeForValueParameter(
type: KotlinTypeMarker
): TypeMappingMode = getOptimalModeForSignaturePart(type, canBeUsedInSupertypePosition = true)
fun TypeMappingMode.Companion.getOptimalModeForReturnType(
type: KotlinType,
fun TypeSystemCommonBackendContext.getOptimalModeForReturnType(
type: KotlinTypeMarker,
isAnnotationMethod: Boolean
): TypeMappingMode {
return if (isAnnotationMethod)
VALUE_FOR_ANNOTATION
TypeMappingMode.VALUE_FOR_ANNOTATION
else
getOptimalModeForSignaturePart(type, canBeUsedInSupertypePosition = false)
}
@OptIn(TypeMappingModeInternals::class)
private fun getOptimalModeForSignaturePart(type: KotlinType, canBeUsedInSupertypePosition: Boolean): TypeMappingMode {
if (type.arguments.isEmpty()) return TypeMappingMode.DEFAULT
private fun TypeSystemCommonBackendContext.getOptimalModeForSignaturePart(
type: KotlinTypeMarker,
canBeUsedInSupertypePosition: Boolean
): TypeMappingMode {
if (type.argumentsCount() == 0) return TypeMappingMode.DEFAULT
if (type.isInlineClassType() && shouldUseUnderlyingType(type)) {
val isInlineClassType = type.typeConstructor().isInlineClass()
if (isInlineClassType && shouldUseUnderlyingType(type)) {
val underlyingType = computeUnderlyingType(type)
if (underlyingType != null) {
return getOptimalModeForSignaturePart(underlyingType, canBeUsedInSupertypePosition).dontWrapInlineClassesMode()
@@ -50,6 +54,6 @@ private fun getOptimalModeForSignaturePart(type: KotlinType, canBeUsedInSupertyp
skipDeclarationSiteWildcardsIfPossible = true,
genericContravariantArgumentMode = contravariantArgumentMode,
genericInvariantArgumentMode = invariantArgumentMode,
needInlineClassWrapping = !type.isInlineClassType()
needInlineClassWrapping = !isInlineClassType
)
}
@@ -5,27 +5,21 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
internal fun computeUnderlyingType(inlineClassType: KotlinType): KotlinType? {
internal fun TypeSystemCommonBackendContext.computeUnderlyingType(inlineClassType: KotlinTypeMarker): KotlinTypeMarker? {
if (!shouldUseUnderlyingType(inlineClassType)) return null
val descriptor = inlineClassType.unsubstitutedUnderlyingType()?.constructor?.declarationDescriptor ?: return null
return if (descriptor is TypeParameterDescriptor)
descriptor.representativeUpperBound
else
inlineClassType.substitutedUnderlyingType()
val underlyingType = inlineClassType.getUnsubstitutedUnderlyingType() ?: return null
return underlyingType.typeConstructor().getTypeParameterClassifier()?.getRepresentativeUpperBound()
?: inlineClassType.getSubstitutedUnderlyingType()
}
internal fun shouldUseUnderlyingType(inlineClassType: KotlinType): Boolean {
val underlyingType = inlineClassType.unsubstitutedUnderlyingType() ?: return false
internal fun TypeSystemCommonBackendContext.shouldUseUnderlyingType(inlineClassType: KotlinTypeMarker): Boolean {
val underlyingType = inlineClassType.getUnsubstitutedUnderlyingType() ?: return false
return !inlineClassType.isMarkedNullable ||
!TypeUtils.isNullableType(underlyingType) && !KotlinBuiltIns.isPrimitiveType(underlyingType)
return !inlineClassType.isMarkedNullable() ||
!underlyingType.isNullableType() && !(underlyingType is SimpleTypeMarker && underlyingType.isPrimitiveType())
}
@@ -25,9 +25,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.kapt3.base.javac.kaptError
import org.jetbrains.kotlin.kapt3.base.mapJList
import org.jetbrains.kotlin.kapt3.base.mapJListIndexed
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.METHOD_PARAMETER_TYPE
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.RETURN_TYPE
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.SUPER_TYPE
import org.jetbrains.kotlin.kapt3.stubs.ErrorTypeCorrector.TypeKind.*
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.load.kotlin.getOptimalModeForReturnType
import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
@@ -143,12 +141,13 @@ class ErrorTypeCorrector(
val typeReference = PsiTreeUtil.getParentOfType(type, KtTypeReference::class.java, true)
val kotlinType = bindingContext[BindingContext.TYPE, typeReference] ?: ErrorUtils.createErrorType("Kapt error type")
val typeSystem = SimpleClassicTypeSystemContext
val typeMappingMode = when (typeKind) {
//TODO figure out if the containing method is an annotation method
RETURN_TYPE -> TypeMappingMode.getOptimalModeForReturnType(kotlinType, false)
METHOD_PARAMETER_TYPE -> TypeMappingMode.getOptimalModeForValueParameter(kotlinType)
RETURN_TYPE -> typeSystem.getOptimalModeForReturnType(kotlinType, false)
METHOD_PARAMETER_TYPE -> typeSystem.getOptimalModeForValueParameter(kotlinType)
SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
}.updateArgumentModeFromAnnotations(kotlinType, SimpleClassicTypeSystemContext)
}.updateArgumentModeFromAnnotations(kotlinType, typeSystem)
val typeParameters = (target as? ClassifierDescriptor)?.typeConstructor?.parameters
return treeMaker.TypeApply(baseExpression, mapJListIndexed(arguments) { index, projection ->