[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:
+1
-1
@@ -373,7 +373,7 @@ internal object FirToKtConversionCreator {
|
||||
ClassId::class,
|
||||
FirModuleData::class,
|
||||
ExpectActualCompatibility::class,
|
||||
ExpectActualCompatibility.Incompatible::class,
|
||||
ExpectActualCompatibility.MismatchOrIncompatible::class,
|
||||
ExpectActualAnnotationsIncompatibilityType::class,
|
||||
DeprecationInfo::class,
|
||||
ApiVersion::class,
|
||||
|
||||
+2
-2
@@ -3763,8 +3763,8 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
NoActualClassMemberForExpectedClassImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a),
|
||||
firDiagnostic.b.map { pair ->
|
||||
firSymbolBuilder.buildSymbol(pair.first) to pair.second.mapKeys { (incompatible, _) ->
|
||||
incompatible
|
||||
firSymbolBuilder.buildSymbol(pair.first) to pair.second.mapKeys { (mismatchOrIncompatible, _) ->
|
||||
mismatchOrIncompatible
|
||||
}.mapValues { (_, collection) ->
|
||||
collection.map { firBasedSymbol ->
|
||||
firSymbolBuilder.buildSymbol(firBasedSymbol)
|
||||
|
||||
+2
-2
@@ -84,7 +84,7 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
@@ -2630,7 +2630,7 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
interface NoActualClassMemberForExpectedClass : KtFirDiagnostic<KtNamedDeclaration> {
|
||||
override val diagnosticClass get() = NoActualClassMemberForExpectedClass::class
|
||||
val declaration: KtSymbol
|
||||
val members: List<Pair<KtSymbol, Map<Incompatible<FirBasedSymbol<*>>, List<KtSymbol>>>>
|
||||
val members: List<Pair<KtSymbol, Map<MismatchOrIncompatible<FirBasedSymbol<*>>, List<KtSymbol>>>>
|
||||
}
|
||||
|
||||
interface ActualMissing : KtFirDiagnostic<KtNamedDeclaration> {
|
||||
|
||||
+2
-2
@@ -85,7 +85,7 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
@@ -3166,7 +3166,7 @@ internal class AmbiguousExpectsImpl(
|
||||
|
||||
internal class NoActualClassMemberForExpectedClassImpl(
|
||||
override val declaration: KtSymbol,
|
||||
override val members: List<Pair<KtSymbol, Map<Incompatible<FirBasedSymbol<*>>, List<KtSymbol>>>>,
|
||||
override val members: List<Pair<KtSymbol, Map<MismatchOrIncompatible<FirBasedSymbol<*>>, List<KtSymbol>>>>,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.NoActualClassMemberForExpectedClass
|
||||
|
||||
+2
-3
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.PrivateForInline
|
||||
@@ -1270,7 +1269,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val ACTUAL_WITHOUT_EXPECT by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME_ONLY) {
|
||||
parameter<Symbol>("declaration")
|
||||
parameter<Map<ExpectActualCompatibility<Symbol>, Collection<Symbol>>>("compatibility")
|
||||
parameter<Map<out ExpectActualCompatibility<Symbol>, Collection<Symbol>>>("compatibility")
|
||||
}
|
||||
|
||||
val AMBIGUOUS_ACTUALS by error<KtNamedDeclaration>(PositioningStrategy.INCOMPATIBLE_DECLARATION) {
|
||||
@@ -1285,7 +1284,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
|
||||
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
|
||||
parameter<Symbol>("declaration")
|
||||
parameter<List<Pair<Symbol, Map<Incompatible<Symbol>, Collection<Symbol>>>>>("members")
|
||||
parameter<List<Pair<Symbol, Map<out ExpectActualCompatibility.MismatchOrIncompatible<Symbol>, Collection<Symbol>>>>>("members")
|
||||
}
|
||||
|
||||
val ACTUAL_MISSING by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME)
|
||||
|
||||
+3
-3
@@ -110,7 +110,7 @@ import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
@@ -663,10 +663,10 @@ object FirErrors {
|
||||
val DEFAULT_ARGUMENTS_IN_EXPECT_ACTUALIZED_BY_FAKE_OVERRIDE by error2<KtClass, FirRegularClassSymbol, Collection<FirNamedFunctionSymbol>>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
||||
val EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND by error0<PsiElement>()
|
||||
val NO_ACTUAL_FOR_EXPECT by error3<KtNamedDeclaration, FirBasedSymbol<*>, FirModuleData, Map<ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
|
||||
val ACTUAL_WITHOUT_EXPECT by error2<KtNamedDeclaration, FirBasedSymbol<*>, Map<ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY)
|
||||
val ACTUAL_WITHOUT_EXPECT by error2<KtNamedDeclaration, FirBasedSymbol<*>, Map<out ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>(SourceElementPositioningStrategies.DECLARATION_NAME_ONLY)
|
||||
val AMBIGUOUS_ACTUALS by error2<KtNamedDeclaration, FirBasedSymbol<*>, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
|
||||
val AMBIGUOUS_EXPECTS by error2<KtNamedDeclaration, FirBasedSymbol<*>, Collection<FirModuleData>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
|
||||
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error2<KtNamedDeclaration, FirBasedSymbol<*>, List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error2<KtNamedDeclaration, FirBasedSymbol<*>, List<Pair<FirBasedSymbol<*>, Map<out MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||
val ACTUAL_MISSING by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
|
||||
val EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING by warning0<KtClassLikeDeclaration>(SourceElementPositioningStrategies.EXPECT_ACTUAL_MODIFIER)
|
||||
val NOT_A_MULTIPLATFORM_COMPILATION by error0<PsiElement>()
|
||||
|
||||
+15
-11
@@ -30,9 +30,10 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Compatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
@@ -128,9 +129,11 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
|
||||
val source = declaration.source
|
||||
if (!declaration.isActual) {
|
||||
if (compatibilityToMembersMap.allStrongIncompatibilities()) return
|
||||
if (compatibilityToMembersMap.allMismatches()) return
|
||||
|
||||
if (Compatible in compatibilityToMembersMap) {
|
||||
if (ExpectActualCheckingCompatibility.Compatible in compatibilityToMembersMap ||
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully in compatibilityToMembersMap
|
||||
) {
|
||||
if (checkActual) {
|
||||
reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context)
|
||||
}
|
||||
@@ -140,7 +143,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
|
||||
val singleIncompatibility = compatibilityToMembersMap.keys.singleOrNull()
|
||||
when {
|
||||
singleIncompatibility is Incompatible.ClassScopes -> {
|
||||
singleIncompatibility is ExpectActualCheckingCompatibility.ClassScopes -> {
|
||||
require(symbol is FirRegularClassSymbol || symbol is FirTypeAliasSymbol) {
|
||||
"Incompatible.ClassScopes is only possible for a class or a typealias: $declaration"
|
||||
}
|
||||
@@ -150,13 +153,13 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
// This is needed only to reduce the number of errors. Incompatibility errors for those members will be reported
|
||||
// later when this checker is called for them
|
||||
fun hasSingleActualSuspect(
|
||||
expectedWithIncompatibility: Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>
|
||||
expectedWithIncompatibility: Pair<FirBasedSymbol<*>, Map<out MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>
|
||||
): Boolean {
|
||||
val (expectedMember, incompatibility) = expectedWithIncompatibility
|
||||
val actualMember = incompatibility.values.singleOrNull()?.singleOrNull()
|
||||
@OptIn(SymbolInternals::class)
|
||||
return actualMember != null &&
|
||||
!incompatibility.allStrongIncompatibilities() &&
|
||||
!incompatibility.allMismatches() &&
|
||||
actualMember.fir.expectForActual?.values?.singleOrNull()?.singleOrNull() == expectedMember
|
||||
}
|
||||
|
||||
@@ -167,9 +170,10 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
Compatible !in compatibilityToMembersMap -> {
|
||||
ExpectActualCheckingCompatibility.Compatible !in compatibilityToMembersMap &&
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully !in compatibilityToMembersMap -> {
|
||||
// A nicer diagnostic for functions with default params
|
||||
if (declaration is FirFunction && compatibilityToMembersMap.keys.any { it is Incompatible.ActualFunctionWithDefaultParameters }) {
|
||||
if (declaration is FirFunction && compatibilityToMembersMap.keys.any { it is ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters }) {
|
||||
reporter.reportOn(declaration.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
||||
} else if (requireActualModifier(declaration.symbol, context.session)) {
|
||||
reporter.reportOn(
|
||||
@@ -247,8 +251,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
)
|
||||
}
|
||||
|
||||
fun Map<out ExpectActualCompatibility<*>, *>.allStrongIncompatibilities(): Boolean {
|
||||
return keys.all { it is Incompatible.StrongIncompatible }
|
||||
fun Map<out ExpectActualCompatibility<*>, *>.allMismatches(): Boolean {
|
||||
return keys.all { it is ExpectActualMatchingCompatibility.Mismatch }
|
||||
}
|
||||
|
||||
// we don't require `actual` modifier on
|
||||
|
||||
+8
-7
@@ -18,14 +18,15 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.ContextIndependentParameterRenderer
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
|
||||
class FirPlatformIncompatibilityDiagnosticRenderer(
|
||||
private val mode: MultiplatformDiagnosticRenderingMode
|
||||
) : ContextIndependentParameterRenderer<Map<ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>> {
|
||||
) : ContextIndependentParameterRenderer<Map<out ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>> {
|
||||
override fun render(
|
||||
obj: Map<ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>,
|
||||
obj: Map<out ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>,
|
||||
): String {
|
||||
if (obj.isEmpty()) return ""
|
||||
|
||||
@@ -43,9 +44,9 @@ class FirPlatformIncompatibilityDiagnosticRenderer(
|
||||
|
||||
class FirIncompatibleExpectedActualClassScopesRenderer(
|
||||
private val mode: MultiplatformDiagnosticRenderingMode
|
||||
) : ContextIndependentParameterRenderer<List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>> {
|
||||
) : ContextIndependentParameterRenderer<List<Pair<FirBasedSymbol<*>, Map<out MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>> {
|
||||
override fun render(
|
||||
obj: List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>
|
||||
obj: List<Pair<FirBasedSymbol<*>, Map<out MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>
|
||||
): String {
|
||||
if (obj.isEmpty()) return ""
|
||||
|
||||
@@ -90,14 +91,14 @@ private fun StringBuilder.renderIncompatibilityInformation(
|
||||
append("The following declaration")
|
||||
if (descriptors.size == 1) append(" is") else append("s are")
|
||||
append(" incompatible")
|
||||
(compatibility as? Incompatible)?.reason?.let { append(" because $it") }
|
||||
(compatibility as? MismatchOrIncompatible)?.reason?.let { append(" because $it") }
|
||||
append(":")
|
||||
|
||||
mode.renderList(this, descriptors.map { descriptor ->
|
||||
{ mode.renderSymbol(this, descriptor, indent) }
|
||||
})
|
||||
|
||||
if (compatibility is Incompatible.ClassScopes) {
|
||||
if (compatibility is ExpectActualCheckingCompatibility.ClassScopes) {
|
||||
append(indent)
|
||||
append("No actual members are found for expected members listed below:")
|
||||
mode.newLine(this)
|
||||
|
||||
+5
-4
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -450,7 +451,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
return symbol.source == null && symbol.origin !is FirDeclarationOrigin.Plugin
|
||||
}
|
||||
|
||||
override fun onMatchedMembers(
|
||||
override fun onMatchedOrCompatibleMembers(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbol: DeclarationSymbolMarker,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
@@ -462,13 +463,13 @@ class FirExpectActualMatchingContextImpl private constructor(
|
||||
expectSymbol.asSymbol(),
|
||||
actualSymbol.asSymbol(),
|
||||
containingExpectClassSymbol.asSymbol(),
|
||||
ExpectActualCompatibility.Compatible
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMismatchedMembersFromClassScope(
|
||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?
|
||||
) {
|
||||
|
||||
+4
-2
@@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.getMatchedAndChecked
|
||||
|
||||
object FirExpectActualResolver {
|
||||
fun findExpectForActual(
|
||||
@@ -67,9 +69,9 @@ object FirExpectActualResolver {
|
||||
)
|
||||
}.let {
|
||||
// If there is a compatible entry, return a map only containing it
|
||||
when (val compatibleSymbols = it[ExpectActualCompatibility.Compatible]) {
|
||||
when (val compatibleSymbols = it.getMatchedAndChecked()) {
|
||||
null -> it
|
||||
else -> mapOf<ExpectActualCompatibility<FirBasedSymbol<*>>, _>(ExpectActualCompatibility.Compatible to compatibleSymbols)
|
||||
else -> mapOf<ExpectActualCompatibility<FirBasedSymbol<*>>, _>(ExpectActualMatchingCompatibility.MatchedSuccessfully to compatibleSymbols)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
|
||||
object CommonBackendErrors {
|
||||
val NO_ACTUAL_FOR_EXPECT by error2<PsiElement, String, ModuleDescriptor>()
|
||||
val INCOMPATIBLE_MATCHING by error3<PsiElement, String, String, ExpectActualCompatibility.Incompatible<*>>()
|
||||
val INCOMPATIBLE_MATCHING by error3<PsiElement, String, String, ExpectActualCompatibility.MismatchOrIncompatible<*>>()
|
||||
val ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT by warning3<PsiElement, IrSymbol, IrSymbol, ExpectActualAnnotationsIncompatibilityType<IrConstructorCall>>()
|
||||
val EVALUATION_ERROR by error1<PsiElement, String>()
|
||||
val ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE by error1<PsiElement, IrValueParameter>()
|
||||
@@ -76,7 +76,7 @@ object KtDefaultCommonBackendErrorMessages : BaseDiagnosticRendererFactory() {
|
||||
}
|
||||
|
||||
object BackendDiagnosticRenderers {
|
||||
val INCOMPATIBILITY = Renderer<ExpectActualCompatibility.Incompatible<*>> {
|
||||
val INCOMPATIBILITY = Renderer<ExpectActualCompatibility.MismatchOrIncompatible<*>> {
|
||||
it.reason ?: "<unknown>"
|
||||
}
|
||||
val SYMBOL_OWNER_DECLARATION_FQ_NAME = Renderer<IrSymbol> {
|
||||
|
||||
+2
-2
@@ -258,9 +258,9 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
||||
recordActualForExpectDeclaration(expectSymbol, actualSymbol, destination)
|
||||
}
|
||||
|
||||
override fun onMismatchedMembersFromClassScope(
|
||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||
) {
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportMissingActual(
|
||||
internal fun KtDiagnosticReporterWithImplicitIrBasedContext.reportIncompatibleExpectActual(
|
||||
expectSymbol: IrSymbol,
|
||||
actualSymbol: IrSymbol,
|
||||
incompatibility: ExpectActualCompatibility.Incompatible<*>
|
||||
incompatibility: ExpectActualCompatibility.MismatchOrIncompatible<*>
|
||||
) {
|
||||
val expectDeclaration = expectSymbol.owner as IrDeclaration
|
||||
val actualDeclaration = actualSymbol.owner as IrDeclaration
|
||||
|
||||
+1
-1
@@ -480,7 +480,7 @@ internal abstract class IrExpectActualMatchingContext(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMatchedMembers(
|
||||
override fun onMatchedOrCompatibleMembers(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbol: DeclarationSymbolMarker,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
|
||||
+2
-1
@@ -315,7 +315,8 @@ object AbstractExpectActualAnnotationMatchChecker {
|
||||
// so we are sure that we found the right member.
|
||||
checkClassScopesCompatibility = false,
|
||||
)
|
||||
val expectMember = expectToCompatibilityMap.filter { it.value == ExpectActualCompatibility.Compatible }.keys.singleOrNull()
|
||||
val expectMember = expectToCompatibilityMap
|
||||
.filter { it.value is ExpectActualCompatibility.MatchedOrCompatible }.keys.singleOrNull()
|
||||
// Check also incompatible members if only one is found
|
||||
?: expectToCompatibilityMap.keys.singleOrNull()
|
||||
?: continue
|
||||
|
||||
+54
-52
@@ -12,8 +12,10 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.mpp.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
@@ -91,8 +93,8 @@ object AbstractExpectActualChecker {
|
||||
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
checkClassScopes: Boolean,
|
||||
): ExpectActualCompatibility<*> = getClassifiersIncompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor, checkClassScopes)
|
||||
?: ExpectActualCompatibility.Compatible
|
||||
): ExpectActualCheckingCompatibility<*> = getClassifiersIncompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor, checkClassScopes)
|
||||
?: ExpectActualCheckingCompatibility.Compatible
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@Suppress("warnings")
|
||||
@@ -101,7 +103,7 @@ object AbstractExpectActualChecker {
|
||||
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
checkClassScopesCompatibility: Boolean,
|
||||
): ExpectActualCompatibility.Incompatible.WeakIncompatible<*>? {
|
||||
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||
// Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name
|
||||
require(expectClassSymbol.name == actualClassLikeSymbol.name) {
|
||||
"This function should be invoked only for declarations with the same name: $expectClassSymbol, $actualClassLikeSymbol"
|
||||
@@ -114,28 +116,28 @@ object AbstractExpectActualChecker {
|
||||
else -> error("Incorrect actual classifier for $expectClassSymbol: $actualClassLikeSymbol")
|
||||
}
|
||||
|
||||
if (!areCompatibleClassKinds(expectClassSymbol, actualClass)) return Incompatible.ClassKind
|
||||
if (!areCompatibleClassKinds(expectClassSymbol, actualClass)) return ExpectActualCheckingCompatibility.ClassKind
|
||||
|
||||
if (!equalBy(expectClassSymbol, actualClass) { listOf(it.isCompanion, it.isInner, it.isInline || it.isValue) }) {
|
||||
return Incompatible.ClassModifiers
|
||||
return ExpectActualCheckingCompatibility.ClassModifiers
|
||||
}
|
||||
|
||||
if (expectClassSymbol.isFun && !actualClass.isFun && actualClass.isNotSamInterface()) {
|
||||
return Incompatible.FunInterfaceModifier
|
||||
return ExpectActualCheckingCompatibility.FunInterfaceModifier
|
||||
}
|
||||
|
||||
val expectTypeParameterSymbols = expectClassSymbol.typeParameters
|
||||
val actualTypeParameterSymbols = actualClass.typeParameters
|
||||
if (expectTypeParameterSymbols.size != actualTypeParameterSymbols.size) {
|
||||
return Incompatible.ClassTypeParameterCount
|
||||
return ExpectActualCheckingCompatibility.ClassTypeParameterCount
|
||||
}
|
||||
|
||||
if (!areCompatibleModalities(expectClassSymbol.modality, actualClass.modality)) {
|
||||
return Incompatible.Modality
|
||||
return ExpectActualCheckingCompatibility.Modality
|
||||
}
|
||||
|
||||
if (!areCompatibleClassVisibilities(expectClassSymbol, actualClass)) {
|
||||
return Incompatible.Visibility
|
||||
return ExpectActualCheckingCompatibility.Visibility
|
||||
}
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
@@ -145,14 +147,14 @@ object AbstractExpectActualChecker {
|
||||
)
|
||||
|
||||
if (!areCompatibleTypeParameterUpperBounds(expectTypeParameterSymbols, actualTypeParameterSymbols, substitutor)) {
|
||||
return Incompatible.ClassTypeParameterUpperBounds
|
||||
return ExpectActualCheckingCompatibility.ClassTypeParameterUpperBounds
|
||||
}
|
||||
|
||||
getTypeParametersVarianceOrReifiedIncompatibility(expectTypeParameterSymbols, actualTypeParameterSymbols)
|
||||
?.let { return it }
|
||||
|
||||
if (!areCompatibleSupertypes(expectClassSymbol, actualClass, substitutor)) {
|
||||
return Incompatible.Supertypes
|
||||
return ExpectActualCheckingCompatibility.Supertypes
|
||||
}
|
||||
|
||||
if (checkClassScopesCompatibility) {
|
||||
@@ -213,8 +215,8 @@ object AbstractExpectActualChecker {
|
||||
expectClassSymbol: RegularClassSymbolMarker,
|
||||
actualClassSymbol: RegularClassSymbolMarker,
|
||||
substitutor: TypeSubstitutorMarker,
|
||||
): Incompatible.WeakIncompatible<*>? {
|
||||
val unfulfilled = arrayListOf<Pair<DeclarationSymbolMarker, Map<Incompatible<*>, List<DeclarationSymbolMarker?>>>>()
|
||||
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||
val unfulfilled = arrayListOf<Pair<DeclarationSymbolMarker, Map<MismatchOrIncompatible<*>, List<DeclarationSymbolMarker?>>>>()
|
||||
|
||||
val actualMembersByName = actualClassSymbol.collectAllMembers(isActualDeclaration = true).groupBy { it.name }
|
||||
|
||||
@@ -241,14 +243,14 @@ object AbstractExpectActualChecker {
|
||||
val aEntries = expectClassSymbol.collectEnumEntryNames()
|
||||
val bEntries = actualClassSymbol.collectEnumEntryNames()
|
||||
|
||||
if (!bEntries.containsAll(aEntries)) return Incompatible.EnumEntries
|
||||
if (!bEntries.containsAll(aEntries)) return ExpectActualCheckingCompatibility.EnumEntries
|
||||
}
|
||||
|
||||
// TODO: check static scope?
|
||||
|
||||
if (unfulfilled.isEmpty()) return null
|
||||
|
||||
return Incompatible.ClassScopes(unfulfilled)
|
||||
return ExpectActualCheckingCompatibility.ClassScopes(unfulfilled)
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -258,7 +260,7 @@ object AbstractExpectActualChecker {
|
||||
substitutor: TypeSubstitutorMarker?,
|
||||
expectClassSymbol: RegularClassSymbolMarker?,
|
||||
actualClassSymbol: RegularClassSymbolMarker?,
|
||||
unfulfilled: MutableList<Pair<DeclarationSymbolMarker, Map<Incompatible<*>, List<DeclarationSymbolMarker?>>>>?,
|
||||
unfulfilled: MutableList<Pair<DeclarationSymbolMarker, Map<MismatchOrIncompatible<*>, List<DeclarationSymbolMarker?>>>>?,
|
||||
checkClassScopesCompatibility: Boolean,
|
||||
) {
|
||||
val mapping = actualMembers.keysToMap { actualMember ->
|
||||
@@ -284,20 +286,20 @@ object AbstractExpectActualChecker {
|
||||
}
|
||||
}
|
||||
|
||||
val incompatibilityMap = mutableMapOf<Incompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
||||
val incompatibilityMap = mutableMapOf<MismatchOrIncompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
||||
for ((actualMember, compatibility) in mapping) {
|
||||
when (compatibility) {
|
||||
ExpectActualCompatibility.Compatible -> {
|
||||
onMatchedMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
||||
is ExpectActualCompatibility.MatchedOrCompatible<*> -> {
|
||||
onMatchedOrCompatibleMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
||||
return
|
||||
}
|
||||
|
||||
is Incompatible -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
||||
is MismatchOrIncompatible<*> -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
||||
}
|
||||
}
|
||||
|
||||
unfulfilled?.add(expectMember to incompatibilityMap)
|
||||
onMismatchedMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
onMismatchedOrIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -325,7 +327,7 @@ object AbstractExpectActualChecker {
|
||||
expectDeclaration is ConstructorSymbolMarker &&
|
||||
actualDeclaration is ConstructorSymbolMarker
|
||||
) {
|
||||
return ExpectActualCompatibility.Compatible
|
||||
return ExpectActualCheckingCompatibility.Compatible
|
||||
}
|
||||
|
||||
// We must prioritize to return STRONG incompatible over WEAK incompatible (because STRONG incompatibility allows to search for overloads)
|
||||
@@ -339,7 +341,7 @@ object AbstractExpectActualChecker {
|
||||
expectContainingClass,
|
||||
actualContainingClass
|
||||
)
|
||||
?: ExpectActualCompatibility.Compatible
|
||||
?: ExpectActualCheckingCompatibility.Compatible
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -348,27 +350,27 @@ object AbstractExpectActualChecker {
|
||||
actualDeclaration: CallableSymbolMarker,
|
||||
insideAnnotationClass: Boolean,
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
): Incompatible.StrongIncompatible<*>? {
|
||||
): ExpectActualMatchingCompatibility.Mismatch? {
|
||||
if (expectDeclaration is FunctionSymbolMarker != actualDeclaration is FunctionSymbolMarker) {
|
||||
return Incompatible.CallableKind
|
||||
return ExpectActualMatchingCompatibility.CallableKind
|
||||
}
|
||||
|
||||
val expectedReceiverType = expectDeclaration.extensionReceiverType
|
||||
val actualReceiverType = actualDeclaration.extensionReceiverType
|
||||
if ((expectedReceiverType != null) != (actualReceiverType != null)) {
|
||||
return Incompatible.ParameterShape
|
||||
return ExpectActualMatchingCompatibility.ParameterShape
|
||||
}
|
||||
|
||||
val expectedValueParameters = expectDeclaration.valueParameters
|
||||
val actualValueParameters = actualDeclaration.valueParameters
|
||||
if (!valueParametersCountCompatible(expectDeclaration, actualDeclaration, expectedValueParameters, actualValueParameters)) {
|
||||
return Incompatible.ParameterCount
|
||||
return ExpectActualMatchingCompatibility.ParameterCount
|
||||
}
|
||||
|
||||
val expectedTypeParameters = expectDeclaration.typeParameters
|
||||
val actualTypeParameters = actualDeclaration.typeParameters
|
||||
if (expectedTypeParameters.size != actualTypeParameters.size) {
|
||||
return Incompatible.FunctionTypeParameterCount
|
||||
return ExpectActualMatchingCompatibility.FunctionTypeParameterCount
|
||||
}
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
@@ -388,11 +390,11 @@ object AbstractExpectActualChecker {
|
||||
parameterOfAnnotationComparisonMode = false
|
||||
)
|
||||
) {
|
||||
return Incompatible.ParameterTypes
|
||||
return ExpectActualMatchingCompatibility.ParameterTypes
|
||||
}
|
||||
|
||||
if (!areCompatibleTypeParameterUpperBounds(expectedTypeParameters, actualTypeParameters, substitutor)) {
|
||||
return Incompatible.FunctionTypeParameterUpperBounds
|
||||
return ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -406,7 +408,7 @@ object AbstractExpectActualChecker {
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
expectContainingClass: RegularClassSymbolMarker?,
|
||||
actualContainingClass: RegularClassSymbolMarker?,
|
||||
): Incompatible.WeakIncompatible<*>? {
|
||||
): ExpectActualCheckingCompatibility<*>? {
|
||||
val expectedTypeParameters = expectDeclaration.typeParameters
|
||||
val actualTypeParameters = actualDeclaration.typeParameters
|
||||
val expectedValueParameters = expectDeclaration.valueParameters
|
||||
@@ -425,16 +427,16 @@ object AbstractExpectActualChecker {
|
||||
parameterOfAnnotationComparisonMode = insideAnnotationClass
|
||||
)
|
||||
) {
|
||||
return Incompatible.ReturnType
|
||||
return ExpectActualCheckingCompatibility.ReturnType
|
||||
}
|
||||
}
|
||||
|
||||
if (actualDeclaration.hasStableParameterNames && !equalsBy(expectedValueParameters, actualValueParameters) { it.name }) {
|
||||
return Incompatible.ParameterNames
|
||||
return ExpectActualCheckingCompatibility.ParameterNames
|
||||
}
|
||||
|
||||
if (!equalsBy(expectedTypeParameters, actualTypeParameters) { it.name }) {
|
||||
return Incompatible.TypeParameterNames
|
||||
return ExpectActualCheckingCompatibility.TypeParameterNames
|
||||
}
|
||||
|
||||
val expectModality = expectDeclaration.modality
|
||||
@@ -447,11 +449,11 @@ object AbstractExpectActualChecker {
|
||||
actualContainingClass?.modality
|
||||
)
|
||||
) {
|
||||
return Incompatible.Modality
|
||||
return ExpectActualCheckingCompatibility.Modality
|
||||
}
|
||||
|
||||
if (!areCompatibleCallableVisibilities(expectDeclaration.visibility, expectModality, actualDeclaration.visibility)) {
|
||||
return Incompatible.Visibility
|
||||
return ExpectActualCheckingCompatibility.Visibility
|
||||
}
|
||||
|
||||
getTypeParametersVarianceOrReifiedIncompatibility(expectedTypeParameters, actualTypeParameters)?.let { return it }
|
||||
@@ -467,22 +469,22 @@ object AbstractExpectActualChecker {
|
||||
(actualDeclaration.allOverriddenDeclarationsRecursive() - expectDeclaration.allOverriddenDeclarationsRecursive().toSet())
|
||||
.flatMap { it.valueParameters }.any { it.hasDefaultValue }
|
||||
) {
|
||||
return Incompatible.ActualFunctionWithDefaultParameters
|
||||
return ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!equalsBy(expectedValueParameters, actualValueParameters) { it.isVararg }) {
|
||||
return Incompatible.ValueParameterVararg
|
||||
return ExpectActualCheckingCompatibility.ValueParameterVararg
|
||||
}
|
||||
|
||||
// Adding noinline/crossinline to parameters is disallowed, except if the expected declaration was not inline at all
|
||||
if (expectDeclaration is SimpleFunctionSymbolMarker && expectDeclaration.isInline) {
|
||||
if (expectedValueParameters.indices.any { i -> !expectedValueParameters[i].isNoinline && actualValueParameters[i].isNoinline }) {
|
||||
return Incompatible.ValueParameterNoinline
|
||||
return ExpectActualCheckingCompatibility.ValueParameterNoinline
|
||||
}
|
||||
if (expectedValueParameters.indices.any { i -> !expectedValueParameters[i].isCrossinline && actualValueParameters[i].isCrossinline }) {
|
||||
return Incompatible.ValueParameterCrossinline
|
||||
return ExpectActualCheckingCompatibility.ValueParameterCrossinline
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,9 +636,9 @@ object AbstractExpectActualChecker {
|
||||
private fun getTypeParametersVarianceOrReifiedIncompatibility(
|
||||
expectTypeParameterSymbols: List<TypeParameterSymbolMarker>,
|
||||
actualTypeParameterSymbols: List<TypeParameterSymbolMarker>,
|
||||
): Incompatible.WeakIncompatible<*>? {
|
||||
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||
if (!equalsBy(expectTypeParameterSymbols, actualTypeParameterSymbols) { it.variance }) {
|
||||
return Incompatible.TypeParameterVariance
|
||||
return ExpectActualCheckingCompatibility.TypeParameterVariance
|
||||
}
|
||||
|
||||
// Removing "reified" from an expected function's type parameter is fine
|
||||
@@ -645,7 +647,7 @@ object AbstractExpectActualChecker {
|
||||
!expectTypeParameterSymbols[i].isReified && actualTypeParameterSymbols[i].isReified
|
||||
}
|
||||
) {
|
||||
return Incompatible.TypeParameterReified
|
||||
return ExpectActualCheckingCompatibility.TypeParameterReified
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -655,9 +657,9 @@ object AbstractExpectActualChecker {
|
||||
private fun getFunctionsIncompatibility(
|
||||
expectFunction: CallableSymbolMarker,
|
||||
actualFunction: CallableSymbolMarker,
|
||||
): Incompatible.WeakIncompatible<*>? {
|
||||
): ExpectActualCheckingCompatibility<*>? {
|
||||
if (!equalBy(expectFunction, actualFunction) { f -> f.isSuspend }) {
|
||||
return Incompatible.FunctionModifiersDifferent
|
||||
return ExpectActualCheckingCompatibility.FunctionModifiersDifferent
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -665,7 +667,7 @@ object AbstractExpectActualChecker {
|
||||
expectFunction.isInline && !actualFunction.isInline ||
|
||||
expectFunction.isOperator && !actualFunction.isOperator
|
||||
) {
|
||||
return Incompatible.FunctionModifiersNotSubset
|
||||
return ExpectActualCheckingCompatibility.FunctionModifiersNotSubset
|
||||
}
|
||||
|
||||
return null
|
||||
@@ -675,12 +677,12 @@ object AbstractExpectActualChecker {
|
||||
private fun getPropertiesIncompatibility(
|
||||
expected: PropertySymbolMarker,
|
||||
actual: PropertySymbolMarker,
|
||||
): Incompatible.WeakIncompatible<*>? {
|
||||
): ExpectActualCheckingCompatibility<*>? {
|
||||
return when {
|
||||
!equalBy(expected, actual) { p -> p.isVar } -> Incompatible.PropertyKind
|
||||
!equalBy(expected, actual) { p -> p.isLateinit } -> Incompatible.PropertyLateinitModifier
|
||||
expected.isConst && !actual.isConst -> Incompatible.PropertyConstModifier
|
||||
!arePropertySettersWithCompatibleVisibilities(expected, actual) -> Incompatible.PropertySetterVisibility
|
||||
!equalBy(expected, actual) { p -> p.isVar } -> ExpectActualCheckingCompatibility.PropertyKind
|
||||
!equalBy(expected, actual) { p -> p.isLateinit } -> ExpectActualCheckingCompatibility.PropertyLateinitModifier
|
||||
expected.isConst && !actual.isConst -> ExpectActualCheckingCompatibility.PropertyConstModifier
|
||||
!arePropertySettersWithCompatibleVisibilities(expected, actual) -> ExpectActualCheckingCompatibility.PropertySetterVisibility
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+22
-21
@@ -10,7 +10,8 @@ import org.jetbrains.kotlin.mpp.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
@@ -66,11 +67,11 @@ object AbstractExpectActualMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : DeclarationSymbolMarker> matchClassifiers(
|
||||
fun matchClassifiers(
|
||||
expectClassSymbol: RegularClassSymbolMarker,
|
||||
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
||||
context: ExpectActualMatchingContext<T>,
|
||||
): ExpectActualCompatibility<T> = with(context) {
|
||||
context: ExpectActualMatchingContext<*>,
|
||||
): ExpectActualMatchingCompatibility = with(context) {
|
||||
// Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name
|
||||
check(expectClassSymbol.name == actualClassLikeSymbol.name) {
|
||||
"This function should be invoked only for declarations with the same name: $expectClassSymbol, $actualClassLikeSymbol"
|
||||
@@ -78,7 +79,7 @@ object AbstractExpectActualMatcher {
|
||||
check(actualClassLikeSymbol is RegularClassSymbolMarker || actualClassLikeSymbol is TypeAliasSymbolMarker) {
|
||||
"Incorrect actual classifier for $expectClassSymbol: $actualClassLikeSymbol"
|
||||
}
|
||||
ExpectActualCompatibility.Compatible
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -117,7 +118,7 @@ object AbstractExpectActualMatcher {
|
||||
substitutor: TypeSubstitutorMarker?,
|
||||
expectClassSymbol: RegularClassSymbolMarker?,
|
||||
actualClassSymbol: RegularClassSymbolMarker?,
|
||||
unfulfilled: MutableList<Pair<DeclarationSymbolMarker, Map<Incompatible<*>, List<DeclarationSymbolMarker?>>>>?,
|
||||
unfulfilled: MutableList<Pair<DeclarationSymbolMarker, Map<MismatchOrIncompatible<*>, List<DeclarationSymbolMarker?>>>>?,
|
||||
) {
|
||||
val mapping = actualMembers.keysToMap { actualMember ->
|
||||
when (expectMember) {
|
||||
@@ -136,20 +137,20 @@ object AbstractExpectActualMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
val incompatibilityMap = mutableMapOf<Incompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
||||
val incompatibilityMap = mutableMapOf<MismatchOrIncompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
||||
for ((actualMember, compatibility) in mapping) {
|
||||
when (compatibility) {
|
||||
ExpectActualCompatibility.Compatible -> {
|
||||
onMatchedMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully -> {
|
||||
onMatchedOrCompatibleMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
||||
return
|
||||
}
|
||||
|
||||
is Incompatible -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
||||
is ExpectActualMatchingCompatibility.Mismatch -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
||||
}
|
||||
}
|
||||
|
||||
unfulfilled?.add(expectMember to incompatibilityMap)
|
||||
onMismatchedMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
onMismatchedOrIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -159,7 +160,7 @@ object AbstractExpectActualMatcher {
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
expectContainingClass: RegularClassSymbolMarker?,
|
||||
actualContainingClass: RegularClassSymbolMarker?,
|
||||
): ExpectActualCompatibility<*> {
|
||||
): ExpectActualMatchingCompatibility {
|
||||
require(
|
||||
(expectDeclaration is ConstructorSymbolMarker && actualDeclaration is ConstructorSymbolMarker) ||
|
||||
expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName
|
||||
@@ -177,12 +178,12 @@ object AbstractExpectActualMatcher {
|
||||
expectDeclaration is ConstructorSymbolMarker &&
|
||||
actualDeclaration is ConstructorSymbolMarker
|
||||
) {
|
||||
return ExpectActualCompatibility.Compatible
|
||||
return ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||
}
|
||||
|
||||
val annotationMode = expectContainingClass?.classKind == ClassKind.ANNOTATION_CLASS
|
||||
return getCallablesStrongIncompatibility(expectDeclaration, actualDeclaration, annotationMode, parentSubstitutor)
|
||||
?: ExpectActualCompatibility.Compatible
|
||||
?: ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||
}
|
||||
|
||||
context(ExpectActualMatchingContext<*>)
|
||||
@@ -191,27 +192,27 @@ object AbstractExpectActualMatcher {
|
||||
actualDeclaration: CallableSymbolMarker,
|
||||
insideAnnotationClass: Boolean,
|
||||
parentSubstitutor: TypeSubstitutorMarker?,
|
||||
): Incompatible.StrongIncompatible<*>? {
|
||||
): ExpectActualMatchingCompatibility.Mismatch? {
|
||||
if (expectDeclaration is FunctionSymbolMarker != actualDeclaration is FunctionSymbolMarker) {
|
||||
return Incompatible.CallableKind
|
||||
return ExpectActualMatchingCompatibility.CallableKind
|
||||
}
|
||||
|
||||
val expectedReceiverType = expectDeclaration.extensionReceiverType
|
||||
val actualReceiverType = actualDeclaration.extensionReceiverType
|
||||
if ((expectedReceiverType != null) != (actualReceiverType != null)) {
|
||||
return Incompatible.ParameterShape
|
||||
return ExpectActualMatchingCompatibility.ParameterShape
|
||||
}
|
||||
|
||||
val expectedValueParameters = expectDeclaration.valueParameters
|
||||
val actualValueParameters = actualDeclaration.valueParameters
|
||||
if (!valueParametersCountCompatible(expectDeclaration, actualDeclaration, expectedValueParameters, actualValueParameters)) {
|
||||
return Incompatible.ParameterCount
|
||||
return ExpectActualMatchingCompatibility.ParameterCount
|
||||
}
|
||||
|
||||
val expectedTypeParameters = expectDeclaration.typeParameters
|
||||
val actualTypeParameters = actualDeclaration.typeParameters
|
||||
if (expectedTypeParameters.size != actualTypeParameters.size) {
|
||||
return Incompatible.FunctionTypeParameterCount
|
||||
return ExpectActualMatchingCompatibility.FunctionTypeParameterCount
|
||||
}
|
||||
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
@@ -231,11 +232,11 @@ object AbstractExpectActualMatcher {
|
||||
parameterOfAnnotationComparisonMode = false
|
||||
)
|
||||
) {
|
||||
return Incompatible.ParameterTypes
|
||||
return ExpectActualMatchingCompatibility.ParameterTypes
|
||||
}
|
||||
|
||||
if (!areCompatibleTypeParameterUpperBounds(expectedTypeParameters, actualTypeParameters, substitutor)) {
|
||||
return Incompatible.FunctionTypeParameterUpperBounds
|
||||
return ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
+3
-3
@@ -165,16 +165,16 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
|
||||
val CallableSymbolMarker.hasStableParameterNames: Boolean
|
||||
|
||||
fun onMatchedMembers(
|
||||
fun onMatchedOrCompatibleMembers(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbol: DeclarationSymbolMarker,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||
) {}
|
||||
|
||||
fun onMismatchedMembersFromClassScope(
|
||||
fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||
expectSymbol: DeclarationSymbolMarker,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||
) {}
|
||||
|
||||
+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