[FIR] Unify checks for is and as
This commit is contained in:
committed by
Space Team
parent
88ff93df7f
commit
4cdddb1b08
+19
-15
@@ -45,26 +45,14 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker(MppCheckerKind.Commo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIsApplicability(l: TypeInfo, r: TypeInfo, expression: FirTypeOperatorCall, context: CheckerContext): Applicability {
|
private fun checkIsApplicability(l: TypeInfo, r: TypeInfo, expression: FirTypeOperatorCall, context: CheckerContext): Applicability =
|
||||||
val oneIsFinal = l.isFinal || r.isFinal
|
checkAnyApplicability(l, r, expression, Applicability.IMPOSSIBLE_IS_CHECK, Applicability.USELESS_IS_CHECK, context)
|
||||||
val oneIsNotNull = !l.type.isNullable || !r.type.isNullable
|
|
||||||
|
|
||||||
return when {
|
|
||||||
isRefinementUseless(context, l.directType.upperBoundIfFlexible(), r.directType, expression) -> Applicability.USELESS_IS_CHECK
|
|
||||||
isCastErased(l.directType, r.directType, context) -> Applicability.CAST_ERASED
|
|
||||||
oneIsNotNull && oneIsFinal && areUnrelated(l, r, context) -> Applicability.IMPOSSIBLE_IS_CHECK
|
|
||||||
else -> Applicability.APPLICABLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkAsApplicability(l: TypeInfo, r: TypeInfo, expression: FirTypeOperatorCall, context: CheckerContext): Applicability {
|
private fun checkAsApplicability(l: TypeInfo, r: TypeInfo, expression: FirTypeOperatorCall, context: CheckerContext): Applicability {
|
||||||
val oneIsFinal = l.isFinal || r.isFinal
|
|
||||||
val oneIsNotNull = !l.type.isNullable || !r.type.isNullable
|
|
||||||
val isNullableNothingWithNotNull = !l.type.isNullable && r.type.isNullableNothing
|
val isNullableNothingWithNotNull = !l.type.isNullable && r.type.isNullableNothing
|
||||||
|| l.type.isNullableNothing && !r.type.isNullable
|
|| l.type.isNullableNothing && !r.type.isNullable
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
isRefinementUseless(context, l.directType.upperBoundIfFlexible(), r.directType, expression) -> Applicability.USELESS_CAST
|
|
||||||
l.type.isNothing && r.type.isNothingOrNullableNothing -> Applicability.APPLICABLE
|
l.type.isNothing && r.type.isNothingOrNullableNothing -> Applicability.APPLICABLE
|
||||||
r.type.isNothing -> Applicability.IMPOSSIBLE_CAST
|
r.type.isNothing -> Applicability.IMPOSSIBLE_CAST
|
||||||
isNullableNothingWithNotNull -> when (expression.operation) {
|
isNullableNothingWithNotNull -> when (expression.operation) {
|
||||||
@@ -72,7 +60,23 @@ object FirCastOperatorsChecker : FirTypeOperatorCallChecker(MppCheckerKind.Commo
|
|||||||
FirOperation.SAFE_AS -> Applicability.USELESS_CAST
|
FirOperation.SAFE_AS -> Applicability.USELESS_CAST
|
||||||
else -> Applicability.IMPOSSIBLE_CAST
|
else -> Applicability.IMPOSSIBLE_CAST
|
||||||
}
|
}
|
||||||
oneIsNotNull && oneIsFinal && areUnrelated(l, r, context) -> Applicability.IMPOSSIBLE_CAST
|
else -> checkAnyApplicability(l, r, expression, Applicability.IMPOSSIBLE_CAST, Applicability.USELESS_CAST, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkAnyApplicability(
|
||||||
|
l: TypeInfo, r: TypeInfo,
|
||||||
|
expression: FirTypeOperatorCall,
|
||||||
|
impossible: Applicability,
|
||||||
|
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
|
||||||
isCastErased(l.directType, r.directType, context) -> Applicability.CAST_ERASED
|
isCastErased(l.directType, r.directType, context) -> Applicability.CAST_ERASED
|
||||||
else -> Applicability.APPLICABLE
|
else -> Applicability.APPLICABLE
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user