[FIR] Reuse shouldReportAsPerRules1() in FirCastOperatorsChecker
This change better aligns the checker with the description in KT-57779. ^KT-57779
This commit is contained in:
committed by
Space Team
parent
4c0ec0fae4
commit
a4c33ee785
+21
@@ -115,3 +115,24 @@ internal fun FirExpression.toArgumentInfo(context: CheckerContext) =
|
||||
originalType = mostOriginalTypeIfSmartCast.fullyExpandedType(context.session).finalApproximationOrSelf(context),
|
||||
context.session,
|
||||
)
|
||||
|
||||
private fun TypeInfo.isSubtypeOf(other: TypeInfo, context: CheckerContext) =
|
||||
notNullType.isSubtypeOf(other.notNullType, context.session)
|
||||
|
||||
internal fun areUnrelated(a: TypeInfo, b: TypeInfo, context: CheckerContext): Boolean {
|
||||
return !a.isSubtypeOf(b, context) && !b.isSubtypeOf(a, context)
|
||||
}
|
||||
|
||||
internal fun areRelated(a: TypeInfo, b: TypeInfo, context: CheckerContext): Boolean = !areUnrelated(a, b, context)
|
||||
|
||||
/**
|
||||
* See [KT-57779](https://youtrack.jetbrains.com/issue/KT-57779) for more information.
|
||||
*/
|
||||
internal fun shouldReportAsPerRules1(l: TypeInfo, r: TypeInfo, context: CheckerContext): Boolean {
|
||||
val oneIsFinal = l.isFinal || r.isFinal
|
||||
|
||||
return when {
|
||||
oneIsFinal -> areUnrelated(l, r, context)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
+2
-9
@@ -53,7 +53,7 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker(MppCheckerKind.Commo
|
||||
|| l.type.isNullableNothing && !r.type.isNullable
|
||||
|
||||
return when {
|
||||
l.type.isNothing && r.type.isNothingOrNullableNothing -> Applicability.APPLICABLE
|
||||
l.type.isNothing -> Applicability.APPLICABLE
|
||||
r.type.isNothing -> Applicability.IMPOSSIBLE_CAST
|
||||
isNullableNothingWithNotNull -> when (expression.operation) {
|
||||
// (null as? WhatEver) == null
|
||||
@@ -71,23 +71,16 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker(MppCheckerKind.Commo
|
||||
useless: Applicability,
|
||||
context: CheckerContext,
|
||||
): Applicability {
|
||||
val oneIsFinal = l.isFinal || r.isFinal
|
||||
val oneIsNotNull = !l.type.isNullable || !r.type.isNullable
|
||||
|
||||
return when {
|
||||
isRefinementUseless(context, l.directType.upperBoundIfFlexible(), r.directType, expression) -> useless
|
||||
oneIsNotNull && oneIsFinal && areUnrelated(l, r, context) -> impossible
|
||||
oneIsNotNull && shouldReportAsPerRules1(l, r, context) -> impossible
|
||||
isCastErased(l.directType, r.directType, context) -> Applicability.CAST_ERASED
|
||||
else -> Applicability.APPLICABLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun areUnrelated(a: TypeInfo, b: TypeInfo, context: CheckerContext) =
|
||||
!a.isSubtypeOf(b, context) && !b.isSubtypeOf(a, context)
|
||||
|
||||
private fun TypeInfo.isSubtypeOf(other: TypeInfo, context: CheckerContext) =
|
||||
notNullType.isSubtypeOf(other.notNullType, context.session)
|
||||
|
||||
/**
|
||||
* K1 reports different diagnostics for different
|
||||
* cases, and this enum helps to replicate the K1's
|
||||
|
||||
+1
-14
@@ -105,19 +105,6 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker(MppCheck
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldReportAsPerRules1(l: TypeInfo, r: TypeInfo, context: CheckerContext): Boolean {
|
||||
val oneIsFinal = l.isFinal || r.isFinal
|
||||
|
||||
return when {
|
||||
l.type.isNothingOrNullableNothing || r.type.isNothingOrNullableNothing -> false
|
||||
oneIsFinal -> !l.isSubtypeOf(r, context) && !r.isSubtypeOf(l, context)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun TypeInfo.isSubtypeOf(other: TypeInfo, context: CheckerContext) =
|
||||
notNullType.isSubtypeOf(other.notNullType, context.session)
|
||||
|
||||
/**
|
||||
* K1 reports different diagnostics for different
|
||||
* cases, and this enum helps to replicate the K1's
|
||||
@@ -155,7 +142,7 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker(MppCheck
|
||||
val shouldProperlyReportError = context.languageVersionSettings.supportsFeature(LanguageFeature.ReportErrorsForComparisonOperators)
|
||||
|
||||
// In this case K1 reports nothing
|
||||
val shouldRelaxDiagnostic = (l.isPrimitive || r.isPrimitive) && (l.isSubtypeOf(r, context) || r.isSubtypeOf(l, context))
|
||||
val shouldRelaxDiagnostic = (l.isPrimitive || r.isPrimitive) && areRelated(l, r, context)
|
||||
&& !shouldProperlyReportError
|
||||
|
||||
return when {
|
||||
|
||||
Reference in New Issue
Block a user