diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrTypeSystemContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrTypeSystemContext.kt index 2c2c7e90609..d54c3adc58f 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrTypeSystemContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrTypeSystemContext.kt @@ -5,7 +5,35 @@ package org.jetbrains.kotlin.backend.jvm +import org.jetbrains.kotlin.backend.jvm.ir.IrJvmFlexibleType +import org.jetbrains.kotlin.backend.jvm.ir.asJvmFlexibleType +import org.jetbrains.kotlin.backend.jvm.ir.isWithFlexibleNullability import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.types.IrSimpleType +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeSystemContext +import org.jetbrains.kotlin.types.model.FlexibleTypeMarker +import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.model.SimpleTypeMarker -class JvmIrTypeSystemContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext +class JvmIrTypeSystemContext(override val irBuiltIns: IrBuiltIns) : IrTypeSystemContext { + override fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? = + (this as IrType).asJvmFlexibleType(irBuiltIns) + + override fun FlexibleTypeMarker.upperBound(): SimpleTypeMarker { + return when (this) { + is IrJvmFlexibleType -> this.upperBound + else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") + } + } + + override fun FlexibleTypeMarker.lowerBound(): SimpleTypeMarker { + return when (this) { + is IrJvmFlexibleType -> this.lowerBound + else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") + } + } + + override fun KotlinTypeMarker.isMarkedNullable(): Boolean = + this is IrSimpleType && !isWithFlexibleNullability() && hasQuestionMark +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt index 1f6f2f49712..f244f94b518 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmSymbols import org.jetbrains.kotlin.backend.jvm.ir.isInlineClassType +import org.jetbrains.kotlin.backend.jvm.ir.isWithFlexibleNullability import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.TypeAnnotationCollector @@ -43,7 +44,10 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.model.KotlinTypeMarker -import org.jetbrains.org.objectweb.asm.* +import org.jetbrains.org.objectweb.asm.AnnotationVisitor +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.TypePath +import org.jetbrains.org.objectweb.asm.TypeReference import java.lang.annotation.RetentionPolicy abstract class AnnotationCodegen( @@ -156,9 +160,7 @@ abstract class AnnotationCodegen( } // A flexible type whose lower bound in not-null and upper bound is nullable, should not be annotated - if (type.isNullabilityFlexible()) { - return - } + if (type.isWithFlexibleNullability()) return val annotationClass = if (type.isNullable()) Nullable::class.java else NotNull::class.java @@ -451,9 +453,6 @@ private fun IrClass.getAnnotationRetention(): KotlinRetention? { return KotlinRetention.valueOf(retentionArgumentValue.name.asString()) } -private fun IrType.isNullabilityFlexible(): Boolean = - hasAnnotation(JvmSymbols.FLEXIBLE_NULLABILITY_ANNOTATION_FQ_NAME) - // To be generalized to IrMemberAccessExpression as soon as properties get symbols. private fun IrConstructorCall.getValueArgument(name: Name): IrExpression? { val index = symbol.owner.valueParameters.find { it.name == name }?.index ?: return null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrJvmFlexibleType.kt similarity index 82% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt rename to compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrJvmFlexibleType.kt index abcfddaa7f3..e3cc0899c98 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/IrJvmFlexibleType.kt @@ -3,21 +3,25 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package org.jetbrains.kotlin.ir.types +package org.jetbrains.kotlin.backend.jvm.ir +import org.jetbrains.kotlin.backend.jvm.JvmSymbols +import org.jetbrains.kotlin.backend.jvm.codegen.isRawType import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.types.IrSimpleType +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classFqName import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.ir.types.impl.buildSimpleType +import org.jetbrains.kotlin.ir.types.removeAnnotations import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.render -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.FlexibleTypeBoundsChecker import org.jetbrains.kotlin.types.model.FlexibleTypeMarker -// TODO: extract properly to JVM-specific modules internal interface IrJvmFlexibleType : FlexibleTypeMarker { val lowerBound: IrSimpleType val upperBound: IrSimpleType @@ -64,30 +68,25 @@ private class IrJvmFlexibleTypeImpl( } } -internal val FLEXIBLE_NULLABILITY_FQN = FqName("kotlin.internal.ir.FlexibleNullability") -internal val FLEXIBLE_MUTABILITY_FQN = FqName("kotlin.internal.ir.FlexibleMutability") -internal val RAW_TYPE_FQN = FqName("kotlin.internal.ir.RawType") - internal fun IrType.isWithFlexibleNullability(): Boolean = - hasAnnotation(FLEXIBLE_NULLABILITY_FQN) + hasAnnotation(JvmSymbols.FLEXIBLE_NULLABILITY_ANNOTATION_FQ_NAME) internal fun IrType.isWithFlexibleMutability(): Boolean = - hasAnnotation(FLEXIBLE_MUTABILITY_FQN) - -internal fun IrType.isRaw(): Boolean = - hasAnnotation(RAW_TYPE_FQN) + hasAnnotation(JvmSymbols.FLEXIBLE_MUTABILITY_ANNOTATION_FQ_NAME) internal fun IrType.asJvmFlexibleType(builtIns: IrBuiltIns): FlexibleTypeMarker? { if (this !is IrSimpleType || annotations.isEmpty()) return null val nullability = isWithFlexibleNullability() val mutability = isWithFlexibleMutability() - val raw = isRaw() + val raw = isRawType() if (!nullability && !mutability && !raw) return null val baseType = this.removeAnnotations { irCtorCall -> val fqName = irCtorCall.type.classFqName - fqName == FLEXIBLE_NULLABILITY_FQN || fqName == FLEXIBLE_MUTABILITY_FQN || fqName == RAW_TYPE_FQN + fqName == JvmSymbols.FLEXIBLE_NULLABILITY_ANNOTATION_FQ_NAME || + fqName == JvmSymbols.FLEXIBLE_MUTABILITY_ANNOTATION_FQ_NAME || + fqName == JvmSymbols.RAW_TYPE_ANNOTATION_FQ_NAME } as IrSimpleType return IrJvmFlexibleTypeImpl(baseType, builtIns, nullability, mutability, raw) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index b93c5099dde..a12e0ea91ab 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -36,11 +36,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun KotlinTypeMarker.asSimpleType() = this as? SimpleTypeMarker - override fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? = when (this) { - is FlexibleTypeMarker -> this - is IrType -> asJvmFlexibleType(irBuiltIns) - else -> null - } + override fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? = this as? FlexibleTypeMarker override fun KotlinTypeMarker.isError() = this is IrErrorType @@ -57,7 +53,6 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun FlexibleTypeMarker.upperBound(): SimpleTypeMarker { return when (this) { is IrDynamicType -> irBuiltIns.anyNType as IrSimpleType - is IrJvmFlexibleType -> this.upperBound else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") } } @@ -65,7 +60,6 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun FlexibleTypeMarker.lowerBound(): SimpleTypeMarker { return when (this) { is IrDynamicType -> irBuiltIns.nothingType as IrSimpleType - is IrJvmFlexibleType -> this.lowerBound else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") } } @@ -76,8 +70,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun SimpleTypeMarker.isMarkedNullable(): Boolean = (this as IrSimpleType).hasQuestionMark - override fun KotlinTypeMarker.isMarkedNullable(): Boolean = - this is IrSimpleType && !isWithFlexibleNullability() && hasQuestionMark + override fun KotlinTypeMarker.isMarkedNullable(): Boolean = this is IrSimpleType && hasQuestionMark override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker { val simpleType = this as IrSimpleType