[FE] Type-safety refactoring: extract main logic of areCompatibleCallables into two functions

Review: https://jetbrains.team/p/kt/reviews/11039/timeline

Extract main logic of `areCompatibleCallables` into two functions:
`areStrongIncompatibleCallables` and `areWeakIncompatibleCallables`.

The main point is that `areStrongIncompatibleCallables` &
`areWeakIncompatibleCallables` have very specific return types.

This commit doesn't change any logic. The commit makes the API more
type-safe ensuring that bugs like in previous commit (KT-60902) won't
happen again
This commit is contained in:
Nikita Bobko
2023-08-02 18:27:54 +02:00
committed by teamcity
parent eac4b81b11
commit 98ec13b51a
4 changed files with 85 additions and 75 deletions
@@ -9,90 +9,83 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
sealed class ExpectActualCompatibility<out D> {
// For IncompatibilityKind.STRONG `actual` declaration is considered as overload and error reports on expected declaration
enum class IncompatibilityKind {
WEAK, STRONG
}
// Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer
sealed class Incompatible<out D>(
val reason: String?,
val kind: IncompatibilityKind = IncompatibilityKind.WEAK
) : ExpectActualCompatibility<D>() {
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 : Incompatible<Nothing>(
"callable kinds are different (function vs property)",
IncompatibilityKind.STRONG
)
object CallableKind : StrongIncompatible<Nothing>("callable kinds are different (function vs property)")
object ParameterShape : Incompatible<Nothing>(
"parameter shapes are different (extension vs non-extension)",
IncompatibilityKind.STRONG
)
object ParameterShape : StrongIncompatible<Nothing>("parameter shapes are different (extension vs non-extension)")
object ParameterCount : Incompatible<Nothing>("number of value parameters is different", IncompatibilityKind.STRONG)
object TypeParameterCount : Incompatible<Nothing>("number of type parameters is different", IncompatibilityKind.STRONG)
object ParameterCount : StrongIncompatible<Nothing>("number of value parameters is different")
object TypeParameterCount : StrongIncompatible<Nothing>("number of type parameters is different")
object ParameterTypes : Incompatible<Nothing>("parameter types are different", IncompatibilityKind.STRONG)
object ReturnType : Incompatible<Nothing>("return type is different", IncompatibilityKind.STRONG)
object ParameterTypes : StrongIncompatible<Nothing>("parameter types are different")
object ReturnType : StrongIncompatible<Nothing>("return type is different")
object ParameterNames : Incompatible<Nothing>("parameter names are different")
object TypeParameterNames : Incompatible<Nothing>("names of type parameters are different")
object ParameterNames : WeakIncompatible<Nothing>("parameter names are different")
object TypeParameterNames : WeakIncompatible<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>(
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 : Incompatible<Nothing>(
object ValueParameterCrossinline : WeakIncompatible<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>(
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 :
Incompatible<Nothing>("actual function cannot have default argument values, they should be declared in the expected function")
WeakIncompatible<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")
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 : Incompatible<Nothing>("class kinds are different (class, interface, object, enum, annotation)")
object ClassKind : WeakIncompatible<Nothing>("class kinds are different (class, interface, object, enum, annotation)")
object ClassModifiers : Incompatible<Nothing>("modifiers are different (companion, inner, inline)")
object ClassModifiers : WeakIncompatible<Nothing>("modifiers are different (companion, inner, inline)")
object FunInterfaceModifier : Incompatible<Nothing>("actual declaration for fun expect interface is not a functional interface")
object FunInterfaceModifier : WeakIncompatible<Nothing>("actual declaration for fun expect interface is not a functional interface")
object Supertypes : Incompatible<Nothing>("some supertypes are missing in the actual declaration")
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>>>>
) : Incompatible<D>("some expected members have no actual ones")
) : WeakIncompatible<D>("some expected members have no actual ones")
object EnumEntries : Incompatible<Nothing>("some entries from expected enum are missing in the actual enum")
object EnumEntries : WeakIncompatible<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 Modality : WeakIncompatible<Nothing>("modality is different")
object Visibility : WeakIncompatible<Nothing>("visibility is different")
object TypeParameterUpperBounds : Incompatible<Nothing>("upper bounds of type parameters are different", IncompatibilityKind.STRONG)
object TypeParameterVariance : Incompatible<Nothing>("declaration-site variances of type parameters are different")
object TypeParameterReified : Incompatible<Nothing>(
object TypeParameterUpperBounds : StrongIncompatible<Nothing>("upper bounds of type parameters are different")
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"
)
object Unknown : Incompatible<Nothing>(null)
object Unknown : WeakIncompatible<Nothing>(null)
}
object Compatible : ExpectActualCompatibility<Nothing>()