From ce0c0ad2e362413837035149bcbcdb1501d94511 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 31 Mar 2021 19:30:30 +0200 Subject: [PATCH] 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. --- .../kotlin/codegen/state/KotlinTypeMapper.kt | 4 +-- .../jvm/codegen/MethodSignatureMapper.kt | 5 ++-- .../genericConstructorReference.kt | 4 +-- .../genericLocalClassConstructorReference.kt | 4 +-- .../load/kotlin/TypeMappingModeExtensions.kt | 26 +++++++++-------- .../kotlin/load/kotlin/inlineClassMapping.kt | 28 ++++++++----------- .../kotlin/kapt3/stubs/ErrorTypeCorrector.kt | 11 ++++---- 7 files changed, 37 insertions(+), 45 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt index 67118204301..f4bfaedc02e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt @@ -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) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index 44ff7423357..a2a986d16b3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -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) } } diff --git a/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt b/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt index 3b3b633a62e..2e014bfe5a8 100644 --- a/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt +++ b/compiler/testData/codegen/box/callableReference/genericConstructorReference.kt @@ -1,7 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: BINDING_RECEIVERS - -// IGNORE_BACKEND_FIR: JVM_IR // KT-42025 open class L(val ll: LL) @@ -98,4 +96,4 @@ fun box(): String { val ipl = i.readP(Rec("OK")) return ipl.ll -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/callableReference/genericLocalClassConstructorReference.kt b/compiler/testData/codegen/box/callableReference/genericLocalClassConstructorReference.kt index 0311bf04fca..1b656b0ba80 100644 --- a/compiler/testData/codegen/box/callableReference/genericLocalClassConstructorReference.kt +++ b/compiler/testData/codegen/box/callableReference/genericLocalClassConstructorReference.kt @@ -1,7 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: BINDING_RECEIVERS - -// IGNORE_BACKEND_FIR: JVM_IR // KT-42025 open class L(val ll: LL) @@ -22,4 +20,4 @@ val Rec.p: L fun foo2(t1: T1, t2: T2, bb: (T1, T2) -> R): R = bb(t1, t2) fun box(): String = - Rec("O").fn().ll + Rec("K").p.ll \ No newline at end of file + Rec("O").fn().ll + Rec("K").p.ll diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingModeExtensions.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingModeExtensions.kt index 7ae951e94de..56dd5d1d6e4 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingModeExtensions.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingModeExtensions.kt @@ -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 ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/inlineClassMapping.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/inlineClassMapping.kt index 1586934a6b9..99df989378b 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/inlineClassMapping.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/inlineClassMapping.kt @@ -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()) } diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt index 390abb04542..248970557ef 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ErrorTypeCorrector.kt @@ -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 ->