Report warnings by enhanced base types

This commit is contained in:
Victor Petukhov
2021-05-13 13:02:26 +03:00
parent 2239404085
commit b78c645fb0
12 changed files with 76 additions and 37 deletions
@@ -35,11 +35,9 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.checker.*
import org.jetbrains.kotlin.types.expressions.SenselessComparisonChecker
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : AdditionalTypeChecker {
@@ -233,31 +231,21 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
) {
if (TypeUtils.noExpectedType(expectedType)) return
val doesExpectedTypeContainsEnhancement = expectedType.contains { it is TypeWithEnhancement }
val doesExpressionTypeContainsEnhancement = expressionType.contains { it is TypeWithEnhancement }
@Suppress("NAME_SHADOWING")
val expressionType = exactedExpressionTypeByDataFlowNullability(expressionType, expressionTypeDataFlowValue, dataFlowInfo)
if (!doesExpectedTypeContainsEnhancement && !doesExpressionTypeContainsEnhancement) return
val enhancedExpectedType = if (doesExpectedTypeContainsEnhancement) expectedType.unwrapEnhancementDeeply() else expectedType
val enhancedExpressionType = enhanceExpressionTypeByDataFlowNullability(
if (doesExpressionTypeContainsEnhancement) expressionType.unwrapEnhancementDeeply() else expressionType,
expressionTypeDataFlowValue,
dataFlowInfo
)
val isEnhancedExpectedTypeSubtypeOfExpressionType =
KotlinTypeChecker.DEFAULT.isSubtypeOf(enhancedExpressionType, enhancedExpectedType)
val isEnhancedExpectedTypeSubtypeOfExpressionType = typeCheckerForEnhancedTypes.isSubtypeOf(expressionType, expectedType)
if (isEnhancedExpectedTypeSubtypeOfExpressionType) return
val isExpectedTypeSubtypeOfExpressionType = KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, expectedType)
val isExpectedTypeSubtypeOfExpressionType = typeCheckerForBaseTypes.isSubtypeOf(expressionType, expectedType)
if (!isEnhancedExpectedTypeSubtypeOfExpressionType && isExpectedTypeSubtypeOfExpressionType) {
reportWarning(enhancedExpectedType, enhancedExpressionType)
reportWarning(expectedType.unwrapEnhancementDeeply(), expressionType.unwrapEnhancementDeeply())
}
}
private fun enhanceExpressionTypeByDataFlowNullability(
private fun exactedExpressionTypeByDataFlowNullability(
expressionType: KotlinType,
expressionTypeDataFlowValue: () -> DataFlowValue,
dataFlowInfo: DataFlowInfo,
@@ -276,6 +264,17 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
} else {
null
}
companion object {
val typeCheckerForEnhancedTypes = NewKotlinTypeCheckerImpl(
kotlinTypeRefiner = KotlinTypeRefiner.Default,
kotlinTypePreparator = object : KotlinTypePreparator() {
override fun prepareType(type: KotlinTypeMarker): UnwrappedType =
super.prepareType(type).let { it.getEnhancementDeeply() ?: it }.unwrap()
}
)
val typeCheckerForBaseTypes = NewKotlinTypeCheckerImpl(KotlinTypeRefiner.Default)
}
}
class EnhancedNullabilityInfo(val enhancedType: KotlinType, val isFromJava: Boolean) {