IR: move JVM-specific flexible types to backend.jvm

This commit is contained in:
Alexander Udalov
2021-06-30 23:03:49 +02:00
parent 2834c22a85
commit e2f462095d
4 changed files with 50 additions and 31 deletions
@@ -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
}
@@ -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
@@ -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)
@@ -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