[FIR, IR] Refactor: restructure ExpectActualCompatibility class hierarchy
KT-62590 is in progress This commit is pure refactoring. - No tests changed their behaviour - Semantics isn't changed Review: https://jetbrains.team/p/kt/reviews/12750/timeline
This commit is contained in:
+93
-92
@@ -5,103 +5,104 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.multiplatform
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
private const val TYPE_PARAMETER_COUNT = "number of type parameters is different"
|
||||
|
||||
sealed class ExpectActualCompatibility<out D> {
|
||||
|
||||
// Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer
|
||||
sealed class Incompatible<out D>(val reason: String?) : ExpectActualCompatibility<D>() {
|
||||
|
||||
sealed class WeakIncompatible<out D>(reason: String?) : Incompatible<D>(reason)
|
||||
|
||||
// For StrongIncompatible `actual` declaration is considered as overload and error reports on expected declaration
|
||||
sealed class StrongIncompatible<out D>(reason: String?) : Incompatible<D>(reason)
|
||||
|
||||
// Callables
|
||||
|
||||
object CallableKind : StrongIncompatible<Nothing>("callable kinds are different (function vs property)")
|
||||
|
||||
object ParameterShape : StrongIncompatible<Nothing>("parameter shapes are different (extension vs non-extension)")
|
||||
|
||||
object ParameterCount : StrongIncompatible<Nothing>("number of value parameters is different")
|
||||
|
||||
// FunctionTypeParameterCount is strong because functions can be overloaded by type parameter count
|
||||
object FunctionTypeParameterCount : StrongIncompatible<Nothing>("number of type parameters is different")
|
||||
|
||||
// ClassTypeParameterCount is weak because classes cannot be overloaded
|
||||
object ClassTypeParameterCount : WeakIncompatible<Nothing>(FunctionTypeParameterCount.reason)
|
||||
|
||||
object ParameterTypes : StrongIncompatible<Nothing>("parameter types are different")
|
||||
object ReturnType : WeakIncompatible<Nothing>("return type is different")
|
||||
|
||||
object ParameterNames : WeakIncompatible<Nothing>("parameter names are different")
|
||||
object TypeParameterNames : WeakIncompatible<Nothing>("names of type parameters are different")
|
||||
|
||||
object ValueParameterVararg : WeakIncompatible<Nothing>("some value parameter is vararg in one declaration and non-vararg in the other")
|
||||
object ValueParameterNoinline : WeakIncompatible<Nothing>(
|
||||
"some value parameter is noinline in one declaration and not noinline in the other"
|
||||
)
|
||||
|
||||
object ValueParameterCrossinline : WeakIncompatible<Nothing>(
|
||||
"some value parameter is crossinline in one declaration and not crossinline in the other"
|
||||
)
|
||||
|
||||
// Functions
|
||||
|
||||
object FunctionModifiersDifferent : WeakIncompatible<Nothing>("modifiers are different (suspend)")
|
||||
object FunctionModifiersNotSubset : WeakIncompatible<Nothing>(
|
||||
"some modifiers on expected declaration are missing on the actual one (infix, inline, operator)"
|
||||
)
|
||||
object ActualFunctionWithDefaultParameters :
|
||||
WeakIncompatible<Nothing>("actual function cannot have default argument values, they should be declared in the expected function")
|
||||
|
||||
// Properties
|
||||
|
||||
object PropertyKind : WeakIncompatible<Nothing>("property kinds are different (val vs var)")
|
||||
object PropertyLateinitModifier : WeakIncompatible<Nothing>("modifiers are different (lateinit)")
|
||||
object PropertyConstModifier : WeakIncompatible<Nothing>("modifiers are different (const)")
|
||||
object PropertySetterVisibility : WeakIncompatible<Nothing>("setter visibility is different")
|
||||
|
||||
// Classifiers
|
||||
|
||||
object ClassKind : WeakIncompatible<Nothing>("class kinds are different (class, interface, object, enum, annotation)")
|
||||
|
||||
object ClassModifiers : WeakIncompatible<Nothing>("modifiers are different (companion, inner, inline, value)")
|
||||
|
||||
object FunInterfaceModifier : WeakIncompatible<Nothing>("actual declaration for fun expect interface is not a functional interface")
|
||||
|
||||
object Supertypes : WeakIncompatible<Nothing>("some supertypes are missing in the actual declaration")
|
||||
|
||||
class ClassScopes<D>(
|
||||
val unfulfilled: List<Pair<D, Map<Incompatible<D>, Collection<D>>>>
|
||||
) : WeakIncompatible<D>("some expected members have no actual ones")
|
||||
|
||||
object EnumEntries : WeakIncompatible<Nothing>("some entries from expected enum are missing in the actual enum")
|
||||
|
||||
// Common
|
||||
|
||||
object Modality : WeakIncompatible<Nothing>("modality is different")
|
||||
object Visibility : WeakIncompatible<Nothing>("visibility is different")
|
||||
|
||||
// FunctionTypeParameterUpperBounds is weak because functions can be overloaded by type parameter upper bounds
|
||||
object FunctionTypeParameterUpperBounds : StrongIncompatible<Nothing>("upper bounds of type parameters are different")
|
||||
|
||||
// ClassTypeParameterUpperBounds is strong because classes cannot be overloaded
|
||||
object ClassTypeParameterUpperBounds : WeakIncompatible<Nothing>(FunctionTypeParameterUpperBounds.reason)
|
||||
|
||||
object TypeParameterVariance : WeakIncompatible<Nothing>("declaration-site variances of type parameters are different")
|
||||
object TypeParameterReified : WeakIncompatible<Nothing>(
|
||||
"some type parameter is reified in one declaration and non-reified in the other"
|
||||
)
|
||||
// Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer
|
||||
/**
|
||||
* DON'T USE THIS CLASS. This class is currently used only in diagnostics. Eventually, it will go away KT-62631
|
||||
*/
|
||||
sealed interface ExpectActualCompatibility<out D> {
|
||||
/**
|
||||
* DON'T USE THIS CLASS. This class is currently used only in diagnostics. Eventually, it will go away KT-62631
|
||||
*/
|
||||
sealed interface MismatchOrIncompatible<out D> : ExpectActualCompatibility<D> {
|
||||
val reason: String?
|
||||
}
|
||||
|
||||
object Compatible : ExpectActualCompatibility<Nothing>()
|
||||
// It's temporary class. KT-62590 is in progress
|
||||
sealed interface MatchedOrCompatible<out D> : ExpectActualCompatibility<D>
|
||||
}
|
||||
|
||||
/**
|
||||
* All mismatches that can be fixed by introducing an overload without this mismatch.
|
||||
* In other words: "overloadable" mismatches
|
||||
*
|
||||
* @see ExpectActualCheckingCompatibility
|
||||
*/
|
||||
sealed class ExpectActualMatchingCompatibility : ExpectActualCompatibility<Nothing> {
|
||||
sealed class Mismatch(override val reason: String?) : ExpectActualMatchingCompatibility(),
|
||||
ExpectActualCompatibility.MismatchOrIncompatible<Nothing>
|
||||
|
||||
object CallableKind : Mismatch("callable kinds are different (function vs property)")
|
||||
object ParameterShape : Mismatch("parameter shapes are different (extension vs non-extension)")
|
||||
object ParameterCount : Mismatch("number of value parameters is different")
|
||||
object FunctionTypeParameterCount : Mismatch(TYPE_PARAMETER_COUNT)
|
||||
object ParameterTypes : Mismatch("parameter types are different")
|
||||
object FunctionTypeParameterUpperBounds : Mismatch("upper bounds of type parameters are different")
|
||||
object MatchedSuccessfully : ExpectActualMatchingCompatibility(), ExpectActualCompatibility.MatchedOrCompatible<Nothing>
|
||||
}
|
||||
|
||||
/**
|
||||
* "Non-overloadable" compatibilities
|
||||
*
|
||||
* @see ExpectActualMatchingCompatibility
|
||||
*/
|
||||
sealed class ExpectActualCheckingCompatibility<out D> : ExpectActualCompatibility<D> {
|
||||
sealed class Incompatible<out D>(override val reason: String?) : ExpectActualCheckingCompatibility<D>(),
|
||||
ExpectActualCompatibility.MismatchOrIncompatible<D>
|
||||
|
||||
object ClassTypeParameterCount : Incompatible<Nothing>(TYPE_PARAMETER_COUNT)
|
||||
|
||||
// Callables
|
||||
object ReturnType : Incompatible<Nothing>("return type is different")
|
||||
object ParameterNames : Incompatible<Nothing>("parameter names are different")
|
||||
object TypeParameterNames : Incompatible<Nothing>("names of type parameters are different")
|
||||
object ValueParameterVararg : Incompatible<Nothing>("some value parameter is vararg in one declaration and non-vararg in the other")
|
||||
object ValueParameterNoinline :
|
||||
Incompatible<Nothing>("some value parameter is noinline in one declaration and not noinline in the other")
|
||||
object ValueParameterCrossinline :
|
||||
Incompatible<Nothing>("some value parameter is crossinline in one declaration and not crossinline in the other")
|
||||
|
||||
// Functions
|
||||
object FunctionModifiersDifferent : Incompatible<Nothing>("modifiers are different (suspend)")
|
||||
object FunctionModifiersNotSubset :
|
||||
Incompatible<Nothing>("some modifiers on expected declaration are missing on the actual one (infix, inline, operator)")
|
||||
object ActualFunctionWithDefaultParameters :
|
||||
Incompatible<Nothing>("actual function cannot have default argument values, they should be declared in the expected function")
|
||||
|
||||
// Properties
|
||||
object PropertyKind : Incompatible<Nothing>("property kinds are different (val vs var)")
|
||||
object PropertyLateinitModifier : Incompatible<Nothing>("modifiers are different (lateinit)")
|
||||
object PropertyConstModifier : Incompatible<Nothing>("modifiers are different (const)")
|
||||
object PropertySetterVisibility : Incompatible<Nothing>("setter visibility is different")
|
||||
|
||||
// Classifiers
|
||||
object ClassKind : Incompatible<Nothing>("class kinds are different (class, interface, object, enum, annotation)")
|
||||
object ClassModifiers : Incompatible<Nothing>("modifiers are different (companion, inner, inline, value)")
|
||||
object FunInterfaceModifier : Incompatible<Nothing>("actual declaration for fun expect interface is not a functional interface")
|
||||
object Supertypes : Incompatible<Nothing>("some supertypes are missing in the actual declaration")
|
||||
class ClassScopes<D>(
|
||||
val unfulfilled: List<Pair<D, Map<out ExpectActualCompatibility.MismatchOrIncompatible<D>, Collection<D>>>>
|
||||
) : Incompatible<D>("some expected members have no actual ones")
|
||||
object EnumEntries : Incompatible<Nothing>("some entries from expected enum are missing in the actual enum")
|
||||
|
||||
// Common
|
||||
object Modality : Incompatible<Nothing>("modality is different")
|
||||
object Visibility : Incompatible<Nothing>("visibility is different")
|
||||
|
||||
object ClassTypeParameterUpperBounds : Incompatible<Nothing>(ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds.reason)
|
||||
object TypeParameterVariance : Incompatible<Nothing>("declaration-site variances of type parameters are different")
|
||||
object TypeParameterReified : Incompatible<Nothing>("some type parameter is reified in one declaration and non-reified in the other")
|
||||
object Compatible : ExpectActualCheckingCompatibility<Nothing>(), ExpectActualCompatibility.MatchedOrCompatible<Nothing>
|
||||
}
|
||||
|
||||
val ExpectActualCompatibility<*>.isCompatibleOrWeaklyIncompatible: Boolean
|
||||
get() = this is ExpectActualCompatibility.Compatible
|
||||
|| this is ExpectActualCompatibility.Incompatible.WeakIncompatible
|
||||
get() = this is ExpectActualCompatibility.MatchedOrCompatible || this is ExpectActualCheckingCompatibility
|
||||
|
||||
val ExpectActualCompatibility<*>.compatible: Boolean
|
||||
get() = this == ExpectActualCompatibility.Compatible
|
||||
get() = this is ExpectActualCompatibility.MatchedOrCompatible
|
||||
|
||||
// It's temporary function. KT-62590 is in progress
|
||||
fun <T, R> Map<ExpectActualCompatibility<R>, List<T>>.getMatchedAndChecked(): List<T>? =
|
||||
(get(ExpectActualMatchingCompatibility.MatchedSuccessfully).orEmpty() + get(ExpectActualCheckingCompatibility.Compatible).orEmpty())
|
||||
.takeIf { it.isNotEmpty() }
|
||||
|
||||
+32
-32
@@ -56,39 +56,39 @@ data class ExpectActualMemberDiff<out M, out C>(val kind: Kind, val actualMember
|
||||
}
|
||||
}
|
||||
|
||||
fun ExpectActualCompatibility.Incompatible<*>.toMemberDiffKind(): ExpectActualMemberDiff.Kind? = when (this) {
|
||||
ExpectActualCompatibility.Incompatible.CallableKind,
|
||||
ExpectActualCompatibility.Incompatible.ParameterCount,
|
||||
ExpectActualCompatibility.Incompatible.ParameterShape,
|
||||
ExpectActualCompatibility.Incompatible.ParameterTypes,
|
||||
ExpectActualCompatibility.Incompatible.FunctionTypeParameterCount,
|
||||
ExpectActualCompatibility.Incompatible.FunctionTypeParameterUpperBounds,
|
||||
fun ExpectActualCompatibility.MismatchOrIncompatible<*>.toMemberDiffKind(): ExpectActualMemberDiff.Kind? = when (this) {
|
||||
ExpectActualMatchingCompatibility.CallableKind,
|
||||
ExpectActualMatchingCompatibility.ParameterCount,
|
||||
ExpectActualMatchingCompatibility.ParameterShape,
|
||||
ExpectActualMatchingCompatibility.ParameterTypes,
|
||||
ExpectActualMatchingCompatibility.FunctionTypeParameterCount,
|
||||
ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds,
|
||||
// It's an awful API. It will be fixed in KT-62752
|
||||
-> error("It's not allowed to call this function with receiver: $this")
|
||||
|
||||
ExpectActualCompatibility.Incompatible.ReturnType -> ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.ClassTypeParameterCount -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.ClassTypeParameterUpperBounds -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.ActualFunctionWithDefaultParameters -> null // It's not possible to add default parameters in override
|
||||
ExpectActualCompatibility.Incompatible.ClassKind -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.ClassModifiers -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
is ExpectActualCompatibility.Incompatible.ClassScopes -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.EnumEntries -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.FunInterfaceModifier -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent -> null // It's not possible to override with different function modifier (suspend)
|
||||
ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset -> null // It's not possible to override with different function modifier (infix, inline, operator)
|
||||
ExpectActualCompatibility.Incompatible.Modality -> ExpectActualMemberDiff.Kind.ModalityChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.ParameterNames -> ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.PropertyConstModifier -> null // const fun can't be overridden
|
||||
ExpectActualCompatibility.Incompatible.PropertyKind -> ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.PropertyLateinitModifier -> ExpectActualMemberDiff.Kind.LateinitChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.PropertySetterVisibility -> ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.Supertypes -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCompatibility.Incompatible.TypeParameterNames -> ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.TypeParameterReified -> null // inline fun can't be overridden
|
||||
ExpectActualCompatibility.Incompatible.TypeParameterVariance -> null // Members are not allowed to have variance
|
||||
ExpectActualCompatibility.Incompatible.ValueParameterCrossinline -> null // inline fun can't be overridden
|
||||
ExpectActualCompatibility.Incompatible.ValueParameterNoinline -> null // inline fun can't be overridden
|
||||
ExpectActualCompatibility.Incompatible.ValueParameterVararg -> ExpectActualMemberDiff.Kind.VarargChangedInOverride
|
||||
ExpectActualCompatibility.Incompatible.Visibility -> ExpectActualMemberDiff.Kind.VisibilityChangedInOverride
|
||||
ExpectActualCheckingCompatibility.ReturnType -> ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride
|
||||
ExpectActualCheckingCompatibility.ClassTypeParameterCount -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.ClassTypeParameterUpperBounds -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters -> null // It's not possible to add default parameters in override
|
||||
ExpectActualCheckingCompatibility.ClassKind -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.ClassModifiers -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
is ExpectActualCheckingCompatibility.ClassScopes -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.EnumEntries -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.FunInterfaceModifier -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.FunctionModifiersDifferent -> null // It's not possible to override with different function modifier (suspend)
|
||||
ExpectActualCheckingCompatibility.FunctionModifiersNotSubset -> null // It's not possible to override with different function modifier (infix, inline, operator)
|
||||
ExpectActualCheckingCompatibility.Modality -> ExpectActualMemberDiff.Kind.ModalityChangedInOverride
|
||||
ExpectActualCheckingCompatibility.ParameterNames -> ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride
|
||||
ExpectActualCheckingCompatibility.PropertyConstModifier -> null // const fun can't be overridden
|
||||
ExpectActualCheckingCompatibility.PropertyKind -> ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride
|
||||
ExpectActualCheckingCompatibility.PropertyLateinitModifier -> ExpectActualMemberDiff.Kind.LateinitChangedInOverride
|
||||
ExpectActualCheckingCompatibility.PropertySetterVisibility -> ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride
|
||||
ExpectActualCheckingCompatibility.Supertypes -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||
ExpectActualCheckingCompatibility.TypeParameterNames -> ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride
|
||||
ExpectActualCheckingCompatibility.TypeParameterReified -> null // inline fun can't be overridden
|
||||
ExpectActualCheckingCompatibility.TypeParameterVariance -> null // Members are not allowed to have variance
|
||||
ExpectActualCheckingCompatibility.ValueParameterCrossinline -> null // inline fun can't be overridden
|
||||
ExpectActualCheckingCompatibility.ValueParameterNoinline -> null // inline fun can't be overridden
|
||||
ExpectActualCheckingCompatibility.ValueParameterVararg -> ExpectActualMemberDiff.Kind.VarargChangedInOverride
|
||||
ExpectActualCheckingCompatibility.Visibility -> ExpectActualMemberDiff.Kind.VisibilityChangedInOverride
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user