FIR checker: expose API to check if two types are compatible

This is useful for quickfixes offering casts. We don't want to offer
user to cast incompatible types.

Also, explicitly allow compare to `Nothing` and handle `Nothing` from intersection
This commit is contained in:
Tianyu Geng
2021-08-03 18:55:47 -07:00
committed by teamcityserver
parent 5b0ca06e95
commit d77db2cda6
13 changed files with 239 additions and 8 deletions
@@ -27,6 +27,8 @@ public abstract class KtTypeProvider : KtAnalysisSessionComponent() {
public abstract fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType?
public abstract fun withNullability(type: KtType, newNullability: KtTypeNullability): KtType
public abstract fun haveCommonSubtype(a: KtType, b: KtType): Boolean
}
public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
@@ -76,6 +78,9 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
public fun KtType.upperBoundIfFlexible(): KtType = (this as? KtFlexibleType)?.upperBound ?: this
public fun KtType.lowerBoundIfFlexible(): KtType = (this as? KtFlexibleType)?.lowerBound ?: this
/** Check whether this type is compatible with that type. If they are compatible, it means they can have a common subtype. */
public fun KtType.hasCommonSubTypeWith(that: KtType): Boolean = analysisSession.typeProvider.haveCommonSubtype(this, that)
}
@Suppress("PropertyName")
@@ -0,0 +1,9 @@
fun test() {
typesHaveCommonSubtype(listOf(1), listOf(1))
typesHaveCommonSubtype(listOf(1), setOf(1))
typesHaveCommonSubtype(listOf(1), mutableSetOf(1))
typesHaveNoCommonSubtype(listOf(1), listOf(""))
typesHaveNoCommonSubtype(listOf(1), setOf(""))
typesHaveNoCommonSubtype(listOf(1), mutableSetOf(""))
}
@@ -0,0 +1,14 @@
interface I
data class Foo(val i: Int) : I
data class Bar(val s: String)
fun test(f1: Foo, f2: Foo, f3: Foo?, b1: Bar, b2: Bar?, i: I) {
typesHaveCommonSubtype(f1, f2)
typesHaveCommonSubtype(f1, f3)
typesHaveCommonSubtype(f3, b2)
typesHaveCommonSubtype(f1, i)
typesHaveNoCommonSubtype(f1, b1)
typesHaveNoCommonSubtype(f1, b2)
typesHaveNoCommonSubtype(b1, i)
}
@@ -0,0 +1,15 @@
enum class A {
A1, A2
}
enum class B {
B1, B2
}
fun test(a1: A, a2: A, b: B) {
typesHaveCommonSubtype(a1, a2)
typesHaveCommonSubtype(a1, A.A1)
typesHaveNoCommonSubtype(a1, b)
typesHaveNoCommonSubtype(A.A1, b)
}
@@ -0,0 +1,10 @@
fun test() {
typesHaveCommonSubtype(1, 1)
typesHaveCommonSubtype("", "")
typesHaveCommonSubtype(null, null)
typesHaveNoCommonSubtype("", null)
typesHaveNoCommonSubtype(1, 1L)
typesHaveNoCommonSubtype(1, 1.0)
typesHaveNoCommonSubtype(1, "")
}