diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeInfoProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeInfoProvider.kt index 821a9b85e06..f1d52d085bd 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeInfoProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeInfoProvider.kt @@ -25,7 +25,7 @@ public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn { public val KtType.canBeNull: Boolean get() = analysisSession.typeInfoProvider.canBeNull(this) /** Returns true if the type is explicitly marked as nullable. This means it's safe to assign `null` to a variable with this type. */ - public val KtType.isMarkedNullable: Boolean get() = (this as? KtTypeWithNullability)?.nullability == KtTypeNullability.NULLABLE + public val KtType.isMarkedNullable: Boolean get() = this.nullability == KtTypeNullability.NULLABLE public val KtType.isUnit: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.UNIT) public val KtType.isInt: Boolean get() = isClassTypeWithClassId(DefaultTypeClassIds.INT) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt index c8c3fa8501b..40ff0083878 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt @@ -13,15 +13,14 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name public sealed interface KtType : ValidityTokenOwner { + public val nullability: KtTypeNullability public fun asStringForDebugging(): String } -public interface KtTypeWithNullability : KtType { - public val nullability: KtTypeNullability -} - public enum class KtTypeNullability(public val isNullable: Boolean) { - NULLABLE(true), NON_NULLABLE(false); + NULLABLE(true), + NON_NULLABLE(false), + UNKNOWN(false); public companion object { public fun create(isNullable: Boolean): KtTypeNullability = if (isNullable) NULLABLE else NON_NULLABLE @@ -32,7 +31,7 @@ public sealed class KtClassType : KtType { override fun toString(): String = asStringForDebugging() } -public sealed class KtNonErrorClassType : KtClassType(), KtTypeWithNullability { +public sealed class KtNonErrorClassType : KtClassType() { public abstract val classId: ClassId public abstract val classSymbol: KtClassLikeSymbol public abstract val typeArguments: List @@ -53,7 +52,7 @@ public abstract class KtClassErrorType : KtClassType() { public abstract val error: String } -public abstract class KtTypeParameterType : KtTypeWithNullability { +public abstract class KtTypeParameterType : KtType { public abstract val name: Name public abstract val symbol: KtTypeParameterSymbol } @@ -62,7 +61,7 @@ public abstract class KtCapturedType : KtType { override fun toString(): String = asStringForDebugging() } -public abstract class KtDefinitelyNotNullType : KtType, KtTypeWithNullability { +public abstract class KtDefinitelyNotNullType : KtType { public abstract val original: KtType final override val nullability: KtTypeNullability get() = KtTypeNullability.NON_NULLABLE diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt index 9880673337c..a0c5dbeb040 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt @@ -33,7 +33,6 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotatio import org.jetbrains.kotlin.idea.frontend.api.types.KtNonErrorClassType import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability -import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeWithNullability import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.SpecialNames @@ -71,11 +70,13 @@ internal enum class NullabilityType { Unknown } +//todo get rid of NullabilityType as it corresponds to KtTypeNullability internal val KtType.nullabilityType: NullabilityType - get() = - (this as? KtTypeWithNullability)?.let { - if (it.nullability == KtTypeNullability.NULLABLE) NullabilityType.Nullable else NullabilityType.NotNull - } ?: NullabilityType.Unknown + get() = when (nullability) { + KtTypeNullability.NULLABLE -> NullabilityType.Nullable + KtTypeNullability.NON_NULLABLE -> NullabilityType.NotNull + KtTypeNullability.UNKNOWN -> NullabilityType.Unknown + } internal fun FirMemberDeclaration.computeSimpleModality(): Set { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt index d03e21f1004..93a7c1e76c8 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt @@ -54,7 +54,7 @@ internal class KtFirUsualClassType( } } - override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.canBeNull) } + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() @@ -79,7 +79,7 @@ internal class KtFirFunctionalType( } } - override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.canBeNull) } + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } override val isSuspend: Boolean get() = withValidityAssertion { coneType.isSuspendFunctionType(builder.rootSession) } override val arity: Int @@ -120,6 +120,7 @@ internal class KtFirClassErrorType( override val coneType by weakRef(_coneType) override val error: String get() = withValidityAssertion { coneType.diagnostic.reason } + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() @@ -130,6 +131,7 @@ internal class KtFirCapturedType( override val token: ValidityToken, ) : KtCapturedType(), KtFirType { override val coneType by weakRef(_coneType) + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() @@ -164,7 +166,8 @@ internal class KtFirTypeParameterType( ?: error("Type parameter ${coneType.lookupTag} was not found") } - override val nullability: KtTypeNullability get() = withValidityAssertion { KtTypeNullability.create(coneType.canBeNull) } + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } + override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() @@ -180,6 +183,9 @@ internal class KtFirFlexibleType( override val lowerBound: KtType by cached { builder.typeBuilder.buildKtType(coneType.lowerBound) } override val upperBound: KtType by cached { builder.typeBuilder.buildKtType(coneType.upperBound) } + + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } + override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() @@ -197,7 +203,15 @@ internal class KtFirIntersectionType( coneType.intersectedTypes.map { conjunct -> builder.typeBuilder.buildKtType(conjunct) } } + override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } + override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() } + +private fun ConeNullability.asKtNullability(): KtTypeNullability = when (this) { + ConeNullability.NULLABLE -> KtTypeNullability.NULLABLE + ConeNullability.UNKNOWN -> KtTypeNullability.UNKNOWN + ConeNullability.NOT_NULL -> KtTypeNullability.NON_NULLABLE +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt index 172c4ef657c..803b1e0192f 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt @@ -95,4 +95,5 @@ internal fun FirExpression.convertConstantExpression(): KtConstantValue = internal fun KtTypeNullability.toConeNullability() = when (this) { KtTypeNullability.NULLABLE -> ConeNullability.NULLABLE KtTypeNullability.NON_NULLABLE -> ConeNullability.NOT_NULL + KtTypeNullability.UNKNOWN -> ConeNullability.UNKNOWN }