Rework nullability in IR
This commit is contained in:
@@ -1131,12 +1131,13 @@ private fun getContainingDeclaration(declaration: IrDeclaration): DeclarationDes
|
||||
|
||||
fun IrType.toIrBasedKotlinType(): KotlinType = when (this) {
|
||||
is IrSimpleType ->
|
||||
makeKotlinType(classifier, arguments, hasQuestionMark)
|
||||
is IrDefinitelyNotNullType -> {
|
||||
val kotlinType = this.original.toIrBasedKotlinType()
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(kotlinType.unwrap())
|
||||
?: kotlinType
|
||||
}
|
||||
makeKotlinType(classifier, arguments, isMarkedNullable()).let {
|
||||
if (classifier is IrTypeParameterSymbol && nullability == SimpleTypeNullability.DEFINITELY_NOT_NULL) {
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(it.unwrap()) ?: it
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
else ->
|
||||
throw AssertionError("Unexpected type: $this = ${this.render()}")
|
||||
}
|
||||
|
||||
+4
-5
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder
|
||||
@@ -186,14 +185,14 @@ class IrBuiltInsOverDescriptors(
|
||||
val returnIrType = IrSimpleTypeBuilder().run {
|
||||
classifier = typeParameterSymbol
|
||||
kotlinType = returnKotlinType
|
||||
hasQuestionMark = false
|
||||
nullability = SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
buildSimpleType()
|
||||
}
|
||||
|
||||
val valueIrType = IrSimpleTypeBuilder().run {
|
||||
classifier = typeParameterSymbol
|
||||
kotlinType = valueKotlinType
|
||||
hasQuestionMark = true
|
||||
nullability = SimpleTypeNullability.MARKED_NULLABLE
|
||||
buildSimpleType()
|
||||
}
|
||||
|
||||
@@ -232,7 +231,7 @@ class IrBuiltInsOverDescriptors(
|
||||
val any = builtIns.anyType
|
||||
override val anyType = any.toIrType()
|
||||
override val anyClass = builtIns.any.toIrSymbol()
|
||||
override val anyNType = anyType.withHasQuestionMark(true)
|
||||
override val anyNType = anyType.makeNullable()
|
||||
|
||||
val bool = builtIns.booleanType
|
||||
override val booleanType = bool.toIrType()
|
||||
@@ -273,7 +272,7 @@ class IrBuiltInsOverDescriptors(
|
||||
val nothing = builtIns.nothingType
|
||||
override val nothingType = nothing.toIrType()
|
||||
override val nothingClass = builtIns.nothing.toIrSymbol()
|
||||
override val nothingNType = nothingType.withHasQuestionMark(true)
|
||||
override val nothingNType = nothingType.makeNullable()
|
||||
|
||||
val unit = builtIns.unitType
|
||||
override val unitType = unit.toIrType()
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -329,7 +330,7 @@ class IrDescriptorBasedFunctionFactory(
|
||||
return with(IrSimpleTypeBuilder()) {
|
||||
classifier =
|
||||
symbolTable.referenceClassifier(kotlinType.constructor.declarationDescriptor ?: error("No classifier for type $kotlinType"))
|
||||
hasQuestionMark = kotlinType.isMarkedNullable
|
||||
nullability = SimpleTypeNullability.fromHasQuestionMark(kotlinType.isMarkedNullable)
|
||||
arguments = kotlinType.arguments.map {
|
||||
if (it.isStarProjection) IrStarProjectionImpl
|
||||
else makeTypeProjection(toIrType(it.type), it.projectionKind)
|
||||
|
||||
+1
-5
@@ -52,11 +52,7 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParamet
|
||||
|
||||
return when (val substitutedType = typeArguments[type.classifier]) {
|
||||
is IrDynamicType -> substitutedType
|
||||
is IrDefinitelyNotNullType -> substitutedType
|
||||
is IrSimpleType -> substitutedType.buildSimpleType {
|
||||
kotlinType = null
|
||||
hasQuestionMark = type.hasQuestionMark or substitutedType.isMarkedNullable()
|
||||
}
|
||||
is IrSimpleType -> substitutedType.mergeNullability(type)
|
||||
else -> type.buildSimpleType {
|
||||
kotlinType = null
|
||||
classifier = symbolRemapper.getReferencedClassifier(type.classifier)
|
||||
|
||||
@@ -32,15 +32,56 @@ abstract class IrErrorType(kotlinType: KotlinType?) : IrTypeBase(kotlinType)
|
||||
|
||||
abstract class IrDynamicType(kotlinType: KotlinType?) : IrTypeBase(kotlinType), DynamicTypeMarker
|
||||
|
||||
abstract class IrDefinitelyNotNullType(kotlinType: KotlinType?) : IrTypeBase(kotlinType), DefinitelyNotNullTypeMarker {
|
||||
abstract val original: IrType
|
||||
enum class SimpleTypeNullability {
|
||||
MARKED_NULLABLE,
|
||||
NOT_SPECIFIED,
|
||||
DEFINITELY_NOT_NULL;
|
||||
|
||||
companion object {
|
||||
fun fromHasQuestionMark(hasQuestionMark: Boolean) = if (hasQuestionMark) MARKED_NULLABLE else NOT_SPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrSimpleType(kotlinType: KotlinType?) : IrTypeBase(kotlinType), SimpleTypeMarker, TypeArgumentListMarker {
|
||||
abstract val classifier: IrClassifierSymbol
|
||||
abstract val hasQuestionMark: Boolean
|
||||
|
||||
/**
|
||||
* If type is explicitly marked as nullable, [nullability] is [SimpleTypeNullability.MARKED_NULLABLE]
|
||||
*
|
||||
* If classifier is type parameter, not marked as nullable, but can store null values,
|
||||
* if corresponding argument would be nullable, [nullability] is [SimpleTypeNullability.NOT_SPECIFIED]
|
||||
*
|
||||
* If type can't store null values, [nullability] is [SimpleTypeNullability.DEFINITELY_NOT_NULL]
|
||||
*
|
||||
* Direct usages of this property should be avoided in most cases. Use relevant util functions instead.
|
||||
*
|
||||
* In most cases one of following is needed:
|
||||
*
|
||||
* Use [IrType.isNullable] to check if null value is possible for this type
|
||||
*
|
||||
* Use [IrType.isMarkedNullable] to check if type is marked with question mark in code
|
||||
*
|
||||
* Use [IrType.mergeNullability] to apply nullability of type parameter to actual type argument in type substitutions
|
||||
*
|
||||
* Use [IrType.makeNotNull] or [IrType.makeNullable] to transfer nullability from one type to another
|
||||
*/
|
||||
abstract val nullability: SimpleTypeNullability
|
||||
abstract val arguments: List<IrTypeArgument>
|
||||
abstract val abbreviation: IrTypeAbbreviation?
|
||||
|
||||
/**
|
||||
* This property was deprecated and replaced with [nullability] property.
|
||||
*
|
||||
* Anyway, in most cases one of utils function would be more suitable, than direct usage.
|
||||
*
|
||||
* Check [nullability] property documentation for details
|
||||
*/
|
||||
@Deprecated(
|
||||
level = DeprecationLevel.WARNING,
|
||||
message = "hasQuestionMark has ambiguous meaning. Use isNullable() or isMarkedNullable() instead.",
|
||||
)
|
||||
val hasQuestionMark: Boolean
|
||||
get() = nullability == SimpleTypeNullability.MARKED_NULLABLE
|
||||
}
|
||||
|
||||
interface IrTypeArgument : TypeArgumentMarker {
|
||||
|
||||
@@ -43,8 +43,6 @@ abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : T
|
||||
arguments = irType.arguments.map { substituteTypeArgument(it) }
|
||||
buildSimpleType()
|
||||
}
|
||||
is IrDefinitelyNotNullType ->
|
||||
IrDefinitelyNotNullTypeImpl(null, substituteType(irType.original))
|
||||
is IrDynamicType,
|
||||
is IrErrorType ->
|
||||
irType
|
||||
|
||||
@@ -28,6 +28,9 @@ import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.ir.types.makeNotNull as irMakeNotNull
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable as irMakeNullable
|
||||
import org.jetbrains.kotlin.ir.types.isMarkedNullable as irIsMarkedNullable
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType as irTypePredicates_isPrimitiveType
|
||||
|
||||
@@ -71,20 +74,18 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
|
||||
override fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker? = null
|
||||
|
||||
override fun SimpleTypeMarker.isMarkedNullable(): Boolean = this is IrSimpleType && hasQuestionMark
|
||||
override fun SimpleTypeMarker.isMarkedNullable(): Boolean = this is IrSimpleType && this.irIsMarkedNullable()
|
||||
|
||||
override fun KotlinTypeMarker.isMarkedNullable(): Boolean = this is IrSimpleType && hasQuestionMark
|
||||
override fun KotlinTypeMarker.isMarkedNullable(): Boolean = this is IrSimpleType && this.irIsMarkedNullable()
|
||||
|
||||
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
|
||||
val simpleType = this as IrSimpleType
|
||||
return if (simpleType.hasQuestionMark == nullable) simpleType
|
||||
else simpleType.run { IrSimpleTypeImpl(classifier, nullable, arguments, annotations) }
|
||||
return (if (nullable) simpleType.irMakeNullable() else simpleType.irMakeNotNull()) as IrSimpleType
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker = when (this) {
|
||||
is IrCapturedType -> constructor
|
||||
is IrSimpleType -> classifier
|
||||
is IrDefinitelyNotNullType -> original.typeConstructor()
|
||||
else -> error("Unknown type constructor")
|
||||
}
|
||||
|
||||
@@ -290,7 +291,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
}
|
||||
}
|
||||
|
||||
return IrSimpleTypeImpl(type.classifier, type.hasQuestionMark, newArguments, type.annotations)
|
||||
return IrSimpleTypeImpl(type.classifier, type.nullability, newArguments, type.annotations)
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.asArgumentList() = this as IrSimpleType
|
||||
@@ -341,7 +342,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
require(ourAnnotations?.size == attributes?.size)
|
||||
return IrSimpleTypeImpl(
|
||||
constructor as IrClassifierSymbol,
|
||||
nullable,
|
||||
if (nullable) SimpleTypeNullability.MARKED_NULLABLE else SimpleTypeNullability.DEFINITELY_NOT_NULL,
|
||||
arguments.map { it as IrTypeArgument },
|
||||
ourAnnotations ?: emptyList()
|
||||
)
|
||||
@@ -556,7 +557,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
error("Captured type is unsupported in IR")
|
||||
|
||||
override fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker =
|
||||
(this as IrDefinitelyNotNullType).original as IrSimpleType
|
||||
error("DefinitelyNotNullTypeMarker.original() type is unsupported in IR")
|
||||
|
||||
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
||||
error("makeDefinitelyNotNullOrNotNull is not supported in IR")
|
||||
|
||||
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.ir.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
|
||||
@@ -37,10 +34,15 @@ fun IrType.isSubtypeOf(superType: IrType, typeSystem: IrTypeSystemContext): Bool
|
||||
|
||||
fun IrType.isNullable(): Boolean =
|
||||
when (this) {
|
||||
is IrDefinitelyNotNullType -> false
|
||||
is IrSimpleType -> when (val classifier = classifier) {
|
||||
is IrClassSymbol -> hasQuestionMark
|
||||
is IrTypeParameterSymbol -> hasQuestionMark || classifier.owner.superTypes.any(IrType::isNullable)
|
||||
is IrClassSymbol -> nullability == SimpleTypeNullability.MARKED_NULLABLE
|
||||
is IrTypeParameterSymbol -> when (nullability) {
|
||||
SimpleTypeNullability.MARKED_NULLABLE -> true
|
||||
// here is a bug, there should be .all check (not .any),
|
||||
// but fixing it is a breaking change, see KT-31545 for details
|
||||
SimpleTypeNullability.NOT_SPECIFIED -> classifier.owner.superTypes.any(IrType::isNullable)
|
||||
SimpleTypeNullability.DEFINITELY_NOT_NULL -> false
|
||||
}
|
||||
else -> error("Unsupported classifier: $classifier")
|
||||
}
|
||||
is IrDynamicType -> true
|
||||
@@ -73,9 +75,3 @@ fun IrType.toArrayOrPrimitiveArrayType(irBuiltIns: IrBuiltIns): IrType =
|
||||
} else {
|
||||
irBuiltIns.arrayClass.typeWith(this)
|
||||
}
|
||||
|
||||
fun IrType.unwrapDefinitelyNotNullType(): IrType =
|
||||
if (this is IrDefinitelyNotNullType)
|
||||
this.original.unwrapDefinitelyNotNullType()
|
||||
else
|
||||
this
|
||||
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.IrDefinitelyNotNullType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class IrDefinitelyNotNullTypeImpl(
|
||||
kotlinType: KotlinType?,
|
||||
override val original: IrType,
|
||||
) : IrDefinitelyNotNullType(kotlinType) {
|
||||
|
||||
override val annotations: List<IrConstructorCall>
|
||||
get() = original.annotations
|
||||
|
||||
override val variance: Variance
|
||||
get() = Variance.INVARIANT
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is IrDefinitelyNotNullType &&
|
||||
this.original == other.original
|
||||
|
||||
override fun hashCode(): Int =
|
||||
original.hashCode()
|
||||
}
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.types.impl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -18,7 +19,7 @@ abstract class IrAbstractSimpleType(kotlinType: KotlinType?) : IrSimpleType(kotl
|
||||
get() = Variance.INVARIANT
|
||||
|
||||
abstract override val classifier: IrClassifierSymbol
|
||||
abstract override val hasQuestionMark: Boolean
|
||||
abstract override val nullability: SimpleTypeNullability
|
||||
abstract override val arguments: List<IrTypeArgument>
|
||||
abstract override val annotations: List<IrConstructorCall>
|
||||
abstract override val abbreviation: IrTypeAbbreviation?
|
||||
@@ -26,12 +27,12 @@ abstract class IrAbstractSimpleType(kotlinType: KotlinType?) : IrSimpleType(kotl
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is IrAbstractSimpleType &&
|
||||
FqNameEqualityChecker.areEqual(classifier, other.classifier) &&
|
||||
hasQuestionMark == other.hasQuestionMark &&
|
||||
nullability == other.nullability &&
|
||||
arguments == other.arguments
|
||||
|
||||
override fun hashCode(): Int =
|
||||
(FqNameEqualityChecker.getHashCode(classifier) * 31 +
|
||||
hasQuestionMark.hashCode()) * 31 +
|
||||
nullability.hashCode()) * 31 +
|
||||
arguments.hashCode()
|
||||
}
|
||||
|
||||
@@ -41,8 +42,8 @@ abstract class IrDelegatedSimpleType(kotlinType: KotlinType? = null) : IrAbstrac
|
||||
|
||||
override val classifier: IrClassifierSymbol
|
||||
get() = delegate.classifier
|
||||
override val hasQuestionMark: Boolean
|
||||
get() = delegate.hasQuestionMark
|
||||
override val nullability: SimpleTypeNullability
|
||||
get() = delegate.nullability
|
||||
override val arguments: List<IrTypeArgument>
|
||||
get() = delegate.arguments
|
||||
override val abbreviation: IrTypeAbbreviation?
|
||||
@@ -54,25 +55,40 @@ abstract class IrDelegatedSimpleType(kotlinType: KotlinType? = null) : IrAbstrac
|
||||
class IrSimpleTypeImpl(
|
||||
kotlinType: KotlinType?,
|
||||
override val classifier: IrClassifierSymbol,
|
||||
override val hasQuestionMark: Boolean,
|
||||
nullability: SimpleTypeNullability,
|
||||
override val arguments: List<IrTypeArgument>,
|
||||
override val annotations: List<IrConstructorCall>,
|
||||
override val abbreviation: IrTypeAbbreviation? = null
|
||||
) : IrAbstractSimpleType(kotlinType) {
|
||||
|
||||
override val nullability =
|
||||
if (classifier !is IrTypeParameterSymbol && nullability == SimpleTypeNullability.NOT_SPECIFIED)
|
||||
SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
else
|
||||
nullability
|
||||
|
||||
|
||||
constructor(
|
||||
classifier: IrClassifierSymbol,
|
||||
nullability: SimpleTypeNullability,
|
||||
arguments: List<IrTypeArgument>,
|
||||
annotations: List<IrConstructorCall>,
|
||||
abbreviation: IrTypeAbbreviation? = null
|
||||
) : this(null, classifier, nullability, arguments, annotations, abbreviation)
|
||||
|
||||
constructor(
|
||||
classifier: IrClassifierSymbol,
|
||||
hasQuestionMark: Boolean,
|
||||
arguments: List<IrTypeArgument>,
|
||||
annotations: List<IrConstructorCall>,
|
||||
abbreviation: IrTypeAbbreviation? = null
|
||||
) : this(null, classifier, hasQuestionMark, arguments, annotations, abbreviation)
|
||||
) : this(null, classifier, SimpleTypeNullability.fromHasQuestionMark(hasQuestionMark), arguments, annotations, abbreviation)
|
||||
}
|
||||
|
||||
class IrSimpleTypeBuilder {
|
||||
var kotlinType: KotlinType? = null
|
||||
var classifier: IrClassifierSymbol? = null
|
||||
var hasQuestionMark = false
|
||||
var nullability = SimpleTypeNullability.NOT_SPECIFIED
|
||||
var arguments: List<IrTypeArgument> = emptyList()
|
||||
var annotations: List<IrConstructorCall> = emptyList()
|
||||
var abbreviation: IrTypeAbbreviation? = null
|
||||
@@ -83,7 +99,7 @@ fun IrSimpleType.toBuilder() =
|
||||
IrSimpleTypeBuilder().also { b ->
|
||||
b.kotlinType = originalKotlinType
|
||||
b.classifier = classifier
|
||||
b.hasQuestionMark = hasQuestionMark
|
||||
b.nullability = nullability
|
||||
b.arguments = arguments
|
||||
b.annotations = annotations
|
||||
b.abbreviation = abbreviation
|
||||
@@ -93,7 +109,7 @@ fun IrSimpleTypeBuilder.buildSimpleType() =
|
||||
IrSimpleTypeImpl(
|
||||
kotlinType,
|
||||
classifier ?: throw AssertionError("Classifier not provided"),
|
||||
hasQuestionMark,
|
||||
nullability,
|
||||
arguments,
|
||||
annotations,
|
||||
abbreviation
|
||||
@@ -122,7 +138,6 @@ class IrTypeProjectionImpl internal constructor(
|
||||
fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection =
|
||||
when {
|
||||
type is IrCapturedType -> IrTypeProjectionImpl(type, variance)
|
||||
type is IrDefinitelyNotNullType -> IrTypeProjectionImpl(type, variance)
|
||||
type is IrTypeProjection && type.variance == variance -> type
|
||||
type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection()
|
||||
type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance)
|
||||
|
||||
@@ -103,7 +103,7 @@ class IrCapturedType(
|
||||
override val classifier: IrClassifierSymbol get() = error("Captured Type does not have a classifier")
|
||||
override val arguments: List<IrTypeArgument> get() = emptyList()
|
||||
override val abbreviation: IrTypeAbbreviation? get () = null
|
||||
override val hasQuestionMark: Boolean get() = false
|
||||
override val nullability: SimpleTypeNullability get() = SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
override val annotations: List<IrConstructorCall> get() = emptyList()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -48,15 +48,15 @@ object IdSignatureValues {
|
||||
@JvmField val sequence = IdSignature.CommonSignature("kotlin.sequences", "Sequence", null, 0)
|
||||
}
|
||||
|
||||
private fun IrType.isNotNullClassType(signature: IdSignature.CommonSignature) = isClassType(signature, hasQuestionMark = false)
|
||||
private fun IrType.isNullableClassType(signature: IdSignature.CommonSignature) = isClassType(signature, hasQuestionMark = true)
|
||||
private fun IrType.isNotNullClassType(signature: IdSignature.CommonSignature) = isClassType(signature, nullable = false)
|
||||
private fun IrType.isNullableClassType(signature: IdSignature.CommonSignature) = isClassType(signature, nullable = true)
|
||||
|
||||
fun getPublicSignature(packageFqName: FqName, name: String) =
|
||||
IdSignature.CommonSignature(packageFqName.asString(), name, null, 0)
|
||||
|
||||
private fun IrType.isClassType(signature: IdSignature.CommonSignature, hasQuestionMark: Boolean? = null): Boolean {
|
||||
private fun IrType.isClassType(signature: IdSignature.CommonSignature, nullable: Boolean? = null): Boolean {
|
||||
if (this !is IrSimpleType) return false
|
||||
if (hasQuestionMark != null && this.hasQuestionMark != hasQuestionMark) return false
|
||||
if (nullable != null && this.isMarkedNullable() != nullable) return false
|
||||
return signature == classifier.signature ||
|
||||
classifier.owner.let { it is IrClass && it.hasFqNameEqualToSignature(signature) }
|
||||
}
|
||||
@@ -109,16 +109,16 @@ fun IrType.isCollection(): Boolean = isNotNullClassType(IdSignatureValues.collec
|
||||
fun IrType.isNothing(): Boolean = isNotNullClassType(IdSignatureValues.nothing)
|
||||
fun IrType.isNullableNothing(): Boolean = isNullableClassType(IdSignatureValues.nothing)
|
||||
|
||||
fun IrType.isPrimitiveType(hasQuestionMark: Boolean = false): Boolean =
|
||||
this is IrSimpleType && hasQuestionMark == this.hasQuestionMark && getPrimitiveType() != null
|
||||
fun IrType.isPrimitiveType(nullable: Boolean = false): Boolean =
|
||||
nullable == this.isMarkedNullable() && getPrimitiveType() != null
|
||||
|
||||
fun IrType.isNullablePrimitiveType(): Boolean = isPrimitiveType(true)
|
||||
|
||||
fun IrType.getPrimitiveType(): PrimitiveType? =
|
||||
getPrimitiveOrUnsignedType(idSignatureToPrimitiveType, shortNameToPrimitiveType)
|
||||
|
||||
fun IrType.isUnsignedType(hasQuestionMark: Boolean = false): Boolean =
|
||||
this is IrSimpleType && hasQuestionMark == this.hasQuestionMark && getUnsignedType() != null
|
||||
fun IrType.isUnsignedType(nullable: Boolean = false): Boolean =
|
||||
nullable == this.isMarkedNullable() && getUnsignedType() != null
|
||||
|
||||
fun IrType.getUnsignedType(): UnsignedType? =
|
||||
getPrimitiveOrUnsignedType(idSignatureToUnsignedType, shortNameToUnsignedType)
|
||||
@@ -134,7 +134,8 @@ fun <T : Enum<T>> IrType.getPrimitiveOrUnsignedType(byIdSignature: Map<IdSignatu
|
||||
return byShortName[klass.name]
|
||||
}
|
||||
|
||||
fun IrType.isMarkedNullable() = (this as? IrSimpleType)?.hasQuestionMark ?: false
|
||||
fun IrType.isMarkedNullable() = (this as? IrSimpleType)?.nullability == SimpleTypeNullability.MARKED_NULLABLE
|
||||
fun IrSimpleType.isMarkedNullable() = nullability == SimpleTypeNullability.MARKED_NULLABLE
|
||||
|
||||
fun IrType.isUnit() = isNotNullClassType(IdSignatureValues.unit)
|
||||
|
||||
@@ -152,8 +153,8 @@ fun IrType.isFloat(): Boolean = isNotNullClassType(IdSignatureValues._float)
|
||||
fun IrType.isDouble(): Boolean = isNotNullClassType(IdSignatureValues._double)
|
||||
fun IrType.isNumber(): Boolean = isNotNullClassType(IdSignatureValues.number)
|
||||
fun IrType.isDoubleOrFloatWithoutNullability(): Boolean {
|
||||
return isClassType(IdSignatureValues._double, hasQuestionMark = null) ||
|
||||
isClassType(IdSignatureValues._float, hasQuestionMark = null)
|
||||
return isClassType(IdSignatureValues._double, nullable = null) ||
|
||||
isClassType(IdSignatureValues._float, nullable = null)
|
||||
}
|
||||
|
||||
fun IrType.isComparable(): Boolean = isNotNullClassType(IdSignatureValues.comparable)
|
||||
@@ -170,9 +171,9 @@ fun IrType.isLongArray(): Boolean = isNotNullClassType(primitiveArrayTypesSignat
|
||||
fun IrType.isFloatArray(): Boolean = isNotNullClassType(primitiveArrayTypesSignatures[PrimitiveType.FLOAT]!!)
|
||||
fun IrType.isDoubleArray(): Boolean = isNotNullClassType(primitiveArrayTypesSignatures[PrimitiveType.DOUBLE]!!)
|
||||
|
||||
fun IrType.isClassType(fqName: FqNameUnsafe, hasQuestionMark: Boolean): Boolean {
|
||||
fun IrType.isClassType(fqName: FqNameUnsafe, nullable: Boolean): Boolean {
|
||||
if (this !is IrSimpleType) return false
|
||||
if (this.hasQuestionMark != hasQuestionMark) return false
|
||||
if (this.isMarkedNullable() != nullable) return false
|
||||
return classifier.isClassWithFqName(fqName)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,27 +20,29 @@ import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType =
|
||||
private fun IrType.withNullability(newNullability: Boolean): IrType =
|
||||
when (this) {
|
||||
is IrSimpleType -> withHasQuestionMark(newHasQuestionMark)
|
||||
is IrSimpleType -> withNullability(newNullability)
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun IrSimpleType.withHasQuestionMark(newHasQuestionMark: Boolean): IrSimpleType =
|
||||
if (this.hasQuestionMark == newHasQuestionMark)
|
||||
private fun IrSimpleType.withNullability(newNullability: Boolean): IrSimpleType {
|
||||
val requiredNullability = if (newNullability) SimpleTypeNullability.MARKED_NULLABLE else SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
return if (nullability == requiredNullability)
|
||||
this
|
||||
else
|
||||
buildSimpleType {
|
||||
hasQuestionMark = newHasQuestionMark
|
||||
nullability = requiredNullability
|
||||
kotlinType = originalKotlinType?.run {
|
||||
if (newHasQuestionMark) makeNullable() else makeNotNullable()
|
||||
if (newNullability) {
|
||||
TypeUtils.makeNullable(this)
|
||||
} else {
|
||||
DefinitelyNotNullType.makeDefinitelyNotNull(this.unwrap()) ?: TypeUtils.makeNotNullable(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrType.addAnnotations(newAnnotations: List<IrConstructorCall>): IrType =
|
||||
if (newAnnotations.isEmpty())
|
||||
@@ -86,7 +88,6 @@ val IrType.classifierOrFail: IrClassifierSymbol
|
||||
val IrType.classifierOrNull: IrClassifierSymbol?
|
||||
get() = when (this) {
|
||||
is IrSimpleType -> classifier
|
||||
is IrDefinitelyNotNullType -> original.classifierOrNull
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -103,34 +104,18 @@ val IrType.classFqName: FqName?
|
||||
|
||||
val IrTypeArgument.typeOrNull: IrType? get() = (this as? IrTypeProjection)?.type
|
||||
|
||||
fun IrType.makeNotNull() =
|
||||
if (this is IrSimpleType && this.hasQuestionMark) {
|
||||
buildSimpleType {
|
||||
kotlinType = originalKotlinType?.makeNotNullable()
|
||||
hasQuestionMark = false
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
fun IrType.makeNotNull() = withNullability(false)
|
||||
|
||||
fun IrType.makeNullable(): IrType =
|
||||
when (this) {
|
||||
is IrSimpleType -> {
|
||||
if (this.hasQuestionMark)
|
||||
this
|
||||
else
|
||||
buildSimpleType {
|
||||
kotlinType = originalKotlinType?.makeNullable()
|
||||
hasQuestionMark = true
|
||||
}
|
||||
}
|
||||
is IrDefinitelyNotNullType -> {
|
||||
// '{ T & Any }?' => 'T?'
|
||||
this.original.makeNullable()
|
||||
}
|
||||
else ->
|
||||
this
|
||||
fun IrType.makeNullable() = withNullability(true)
|
||||
|
||||
fun IrType.mergeNullability(other: IrType) = when (other) {
|
||||
is IrSimpleType -> when (other.nullability) {
|
||||
SimpleTypeNullability.MARKED_NULLABLE -> makeNullable()
|
||||
SimpleTypeNullability.NOT_SPECIFIED -> this
|
||||
SimpleTypeNullability.DEFINITELY_NOT_NULL -> makeNotNull()
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
|
||||
@ObsoleteDescriptorBasedAPI
|
||||
fun IrType.toKotlinType(): KotlinType {
|
||||
@@ -139,7 +124,7 @@ fun IrType.toKotlinType(): KotlinType {
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is IrSimpleType -> makeKotlinType(classifier, arguments, hasQuestionMark)
|
||||
is IrSimpleType -> makeKotlinType(classifier, arguments, nullability == SimpleTypeNullability.MARKED_NULLABLE)
|
||||
else -> TODO(toString())
|
||||
}
|
||||
}
|
||||
@@ -181,7 +166,7 @@ val IrClassifierSymbol.defaultType: IrType
|
||||
val IrTypeParameter.defaultType: IrType
|
||||
get() = IrSimpleTypeImpl(
|
||||
symbol,
|
||||
hasQuestionMark = false,
|
||||
SimpleTypeNullability.NOT_SPECIFIED,
|
||||
arguments = emptyList(),
|
||||
annotations = emptyList()
|
||||
)
|
||||
@@ -189,7 +174,7 @@ val IrTypeParameter.defaultType: IrType
|
||||
val IrClassSymbol.starProjectedType: IrSimpleType
|
||||
get() = IrSimpleTypeImpl(
|
||||
this,
|
||||
hasQuestionMark = false,
|
||||
SimpleTypeNullability.NOT_SPECIFIED,
|
||||
arguments = owner.typeConstructorParameters.map { IrStarProjectionImpl }.toList(),
|
||||
annotations = emptyList()
|
||||
)
|
||||
@@ -230,13 +215,13 @@ fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWi
|
||||
fun IrClassifierSymbol.typeWith(arguments: List<IrType>): IrSimpleType =
|
||||
IrSimpleTypeImpl(
|
||||
this,
|
||||
false,
|
||||
SimpleTypeNullability.NOT_SPECIFIED,
|
||||
arguments.map { makeTypeProjection(it, Variance.INVARIANT) },
|
||||
emptyList()
|
||||
)
|
||||
|
||||
fun IrClassifierSymbol.typeWithArguments(arguments: List<IrTypeArgument>): IrSimpleType =
|
||||
IrSimpleTypeImpl(this, false, arguments, emptyList())
|
||||
IrSimpleTypeImpl(this, SimpleTypeNullability.NOT_SPECIFIED, arguments, emptyList())
|
||||
|
||||
fun IrClass.typeWith(arguments: List<IrType>) = this.symbol.typeWith(arguments)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.util
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrDefinitelyNotNullTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
@@ -29,11 +28,10 @@ class DeepCopyTypeRemapper(
|
||||
|
||||
override fun remapType(type: IrType): IrType {
|
||||
return when (type) {
|
||||
is IrDefinitelyNotNullType -> IrDefinitelyNotNullTypeImpl(null, remapType(type.original))
|
||||
is IrSimpleType -> IrSimpleTypeImpl(
|
||||
null,
|
||||
symbolRemapper.getReferencedClassifier(type.classifier),
|
||||
type.hasQuestionMark,
|
||||
type.nullability,
|
||||
type.arguments.map { remapTypeArgument(it) },
|
||||
type.annotations.map { it.transform(deepCopy, null) as IrConstructorCall },
|
||||
type.abbreviation?.remapTypeAbbreviation()
|
||||
|
||||
@@ -29,7 +29,7 @@ class IrTypeParameterRemapper(
|
||||
IrSimpleTypeImpl(
|
||||
null,
|
||||
type.classifier.remap(),
|
||||
type.hasQuestionMark,
|
||||
type.nullability,
|
||||
type.arguments.map { it.remap() },
|
||||
type.annotations,
|
||||
type.abbreviation?.remap()
|
||||
|
||||
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
|
||||
@@ -113,9 +110,9 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false, privat
|
||||
|
||||
is IrErrorType -> "IrErrorType(${if (verboseErrorTypes) originalKotlinType else null})"
|
||||
|
||||
is IrDefinitelyNotNullType -> "{${original.render()} & Any}"
|
||||
|
||||
is IrSimpleType -> buildTrimEnd {
|
||||
val isDefinitelyNotNullType = classifier is IrTypeParameterSymbol && nullability == SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
if (isDefinitelyNotNullType) append("{")
|
||||
append(classifier.renderClassifierFqn())
|
||||
if (arguments.isNotEmpty()) {
|
||||
append(
|
||||
@@ -124,7 +121,9 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false, privat
|
||||
}
|
||||
)
|
||||
}
|
||||
if (hasQuestionMark) {
|
||||
if (isDefinitelyNotNullType) {
|
||||
append(" & Any}")
|
||||
} else if (isMarkedNullable()) {
|
||||
append('?')
|
||||
}
|
||||
abbreviation?.let {
|
||||
|
||||
@@ -33,7 +33,7 @@ class SimpleTypeRemapper(
|
||||
IrSimpleTypeImpl(
|
||||
null,
|
||||
symbol,
|
||||
type.hasQuestionMark,
|
||||
type.nullability,
|
||||
arguments,
|
||||
type.annotations,
|
||||
type.abbreviation?.remapTypeAbbreviation()
|
||||
|
||||
@@ -17,9 +17,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBasedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeAbbreviation
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
|
||||
@@ -101,7 +99,7 @@ abstract class TypeTranslator(
|
||||
approximatedType.isDynamic() ->
|
||||
return IrDynamicTypeImpl(approximatedType, translateTypeAnnotations(approximatedType), variance)
|
||||
supportDefinitelyNotNullTypes && approximatedType is DefinitelyNotNullType ->
|
||||
return makeTypeProjection(IrDefinitelyNotNullTypeImpl(approximatedType, translateType(approximatedType.original)), variance)
|
||||
return makeTypeProjection(translateType(approximatedType.original).makeNotNull(), variance)
|
||||
}
|
||||
|
||||
val upperType = approximatedType.upperIfFlexible()
|
||||
@@ -121,7 +119,7 @@ abstract class TypeTranslator(
|
||||
|
||||
return IrSimpleTypeBuilder().apply {
|
||||
this.kotlinType = approximatedType
|
||||
this.hasQuestionMark = upperType.isMarkedNullable
|
||||
this.nullability = SimpleTypeNullability.fromHasQuestionMark(upperType.isMarkedNullable)
|
||||
this.variance = variance
|
||||
this.abbreviation = upperType.getAbbreviation()?.toIrTypeAbbreviation()
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -422,14 +423,14 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
// TODO don't print `Any?` as upper bound?
|
||||
printAnnotationsWithNoIndent()
|
||||
when (this) {
|
||||
is IrDefinitelyNotNullType -> {
|
||||
p.printWithNoIndent("(")
|
||||
original.printTypeWithNoIndent()
|
||||
p.printWithNoIndent(" & Any)")
|
||||
}
|
||||
is IrSimpleType -> {
|
||||
// TODO abbreviation
|
||||
|
||||
val dnn = classifier is IrTypeParameterSymbol && nullability == SimpleTypeNullability.DEFINITELY_NOT_NULL
|
||||
if (dnn) {
|
||||
p.printWithNoIndent("(")
|
||||
}
|
||||
|
||||
p.printWithNoIndent((classifier.owner as IrDeclarationWithName).name.asString())
|
||||
|
||||
if (arguments.isNotEmpty()) {
|
||||
@@ -442,7 +443,11 @@ private class KotlinLikeDumper(val p: Printer, val options: KotlinLikeDumpOption
|
||||
p.printWithNoIndent(">")
|
||||
}
|
||||
|
||||
if (hasQuestionMark) p.printWithNoIndent("?")
|
||||
if (dnn) {
|
||||
p.printWithNoIndent(" & Any)")
|
||||
}
|
||||
|
||||
if (isMarkedNullable()) p.printWithNoIndent("?")
|
||||
}
|
||||
is IrDynamicType ->
|
||||
p.printWithNoIndent("dynamic")
|
||||
|
||||
Reference in New Issue
Block a user