[FIR] Implement warnings for java nullability type mismatch
#KT-56989
This commit is contained in:
committed by
Space Team
parent
1ecbc094ec
commit
a6fdeeb7df
+37
-5
@@ -5,10 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java.enhancement
|
||||
|
||||
import org.jetbrains.kotlin.fir.types.ConeAttributeWithConeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeAttributes
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class EnhancedTypeForWarningAttribute(
|
||||
@@ -31,4 +30,37 @@ class EnhancedTypeForWarningAttribute(
|
||||
val ConeAttributes.enhancedTypeForWarning: EnhancedTypeForWarningAttribute? by ConeAttributes.attributeAccessor<EnhancedTypeForWarningAttribute>()
|
||||
|
||||
val ConeKotlinType.enhancedTypeForWarning: ConeKotlinType?
|
||||
get() = attributes.enhancedTypeForWarning?.coneType
|
||||
get() = attributes.enhancedTypeForWarning?.coneType
|
||||
|
||||
/**
|
||||
* Substitutor that substitutes types with their [ConeKotlinType.enhancedTypeForWarning] recursively.
|
||||
*/
|
||||
class EnhancedForWarningConeSubstitutor(typeContext: ConeTypeContext) : AbstractConeSubstitutor(typeContext) {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
// The attribute is usually taken from the lower bound of flexible types.
|
||||
// However, if the type has flexible mutability, we don't want to accidentally enhance the mutability to the lower bound.
|
||||
if (type is ConeFlexibleType && type.hasFlexibleMutability()) {
|
||||
val lowerSubstituted = substituteOrNull(type.lowerBound)
|
||||
|
||||
return if (lowerSubstituted is ConeSimpleKotlinType) {
|
||||
ConeFlexibleType(
|
||||
lowerBound = lowerSubstituted,
|
||||
upperBound = substituteOrNull(type.upperBound) as? ConeSimpleKotlinType ?: type.upperBound
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
// If the top-level type can be enhanced, this will only enhance the top-level type but not its arguments: Foo<Bar!>! -> Foo<Bar!>?
|
||||
// Otherwise, it will enhance recursively until the first possible enhancement.
|
||||
val enhancedTopLevel = type.enhancedTypeForWarning
|
||||
|
||||
// This will also enhance type arguments if the top-level type was enhanced, otherwise it will continue enhancing recursively.
|
||||
return enhancedTopLevel?.let(::substituteOrSelf)
|
||||
}
|
||||
|
||||
private fun ConeFlexibleType.hasFlexibleMutability(): Boolean {
|
||||
return JavaToKotlinClassMap.isMutable(lowerBound.classId) && JavaToKotlinClassMap.isReadOnly(upperBound.classId)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user