[FIR, IR] 1/2 Minimize usages of ExpectActualCompatibility, MismatchOrIncompatible and MatchedOrCompatible
- Migrate ExpectActualCompatibility -> ExpectActualCheckingCompatibility where the "checker" is expect - Migrate ExpectActualCompatibility -> ExpectActualMatchingCompatibility where the "matching" is expect KT-62590 in progress. A lot of tests start to fail now. I will fix them in next commits Review: https://jetbrains.team/p/kt/reviews/12750/timeline
This commit is contained in:
+3
-6
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.expectForActual
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
|
|
||||||
internal class KtFirMultiplatformInfoProvider(
|
internal class KtFirMultiplatformInfoProvider(
|
||||||
override val analysisSession: KtFirAnalysisSession,
|
override val analysisSession: KtFirAnalysisSession,
|
||||||
@@ -31,10 +31,7 @@ internal class KtFirMultiplatformInfoProvider(
|
|||||||
}
|
}
|
||||||
if (status?.isActual != true) return emptyList()
|
if (status?.isActual != true) return emptyList()
|
||||||
|
|
||||||
return firSymbol.expectForActual.orEmpty().asSequence()
|
return firSymbol.expectForActual?.get(ExpectActualMatchingCompatibility.MatchedSuccessfully)
|
||||||
.filter { it.key.isCompatibleOrWeaklyIncompatible }
|
?.map { analysisSession.firSymbolBuilder.buildSymbol(it) as KtDeclarationSymbol }.orEmpty()
|
||||||
.flatMap { it.value }
|
|
||||||
.map { analysisSession.firSymbolBuilder.buildSymbol(it) as KtDeclarationSymbol }
|
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.areCompatibleExpectActualTypes
|
import org.jetbrains.kotlin.fir.types.areCompatibleExpectActualTypes
|
||||||
import org.jetbrains.kotlin.fir.types.createExpectActualTypeParameterSubstitutor
|
import org.jetbrains.kotlin.fir.types.createExpectActualTypeParameterSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
||||||
|
|
||||||
object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
||||||
@@ -60,7 +61,7 @@ object FirActualCallableDeclarationChecker : FirCallableDeclarationChecker() {
|
|||||||
callableDeclaration.source,
|
callableDeclaration.source,
|
||||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||||
actualFunctionSymbol,
|
actualFunctionSymbol,
|
||||||
actualFunctionSymbol.expectForActual as Map<ExpectActualCompatibility<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>,
|
actualFunctionSymbol.expectForActual as Map<ExpectActualMatchingCompatibility, Collection<FirBasedSymbol<*>>>,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
|
import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.compatible
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
|
|
||||||
internal object FirDefaultArgumentsInExpectActualizedByFakeOverrideChecker : FirRegularClassChecker() {
|
internal object FirDefaultArgumentsInExpectActualizedByFakeOverrideChecker : FirRegularClassChecker() {
|
||||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -77,7 +77,8 @@ internal object FirDefaultArgumentsInExpectActualizedByFakeOverrideChecker : Fir
|
|||||||
expectSymbol, actualSymbol, actualMember,
|
expectSymbol, actualSymbol, actualMember,
|
||||||
checkClassScopesCompatibility = false
|
checkClassScopesCompatibility = false
|
||||||
)
|
)
|
||||||
val expectMember: DeclarationSymbolMarker = potentialExpects.entries.singleOrNull { it.value.compatible }?.key
|
val expectMember: DeclarationSymbolMarker = potentialExpects.entries
|
||||||
|
.singleOrNull { it.value == ExpectActualMatchingCompatibility.MatchedSuccessfully }?.key
|
||||||
?: potentialExpects.keys.singleOrNull()
|
?: potentialExpects.keys.singleOrNull()
|
||||||
?: return null
|
?: return null
|
||||||
return expectMember as FirNamedFunctionSymbol
|
return expectMember as FirNamedFunctionSymbol
|
||||||
|
|||||||
+77
-31
@@ -9,8 +9,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.diagnostics.*
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
|
import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
@@ -19,22 +18,22 @@ import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isTailRec
|
import org.jetbrains.kotlin.fir.declarations.utils.isTailRec
|
||||||
import org.jetbrains.kotlin.fir.expectActualMatchingContextFactory
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.mpp.RegularClassSymbolMarker
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
|
|
||||||
|
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||||
@@ -120,20 +119,35 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
declaration: FirMemberDeclaration,
|
declaration: FirMemberDeclaration,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
checkActual: Boolean = true
|
checkActual: Boolean = true,
|
||||||
) {
|
) {
|
||||||
val symbol = declaration.symbol
|
val symbol = declaration.symbol
|
||||||
val compatibilityToMembersMap = symbol.expectForActual ?: return
|
val matchingCompatibilityToMembersMap = symbol.expectForActual ?: return
|
||||||
|
val expectedSingleCandidate =
|
||||||
|
matchingCompatibilityToMembersMap[ExpectActualMatchingCompatibility.MatchedSuccessfully]?.singleOrNull()
|
||||||
|
val checkingCompatibility = if (expectedSingleCandidate != null) {
|
||||||
|
val expectActualMatchingContext = context.session.expectActualMatchingContextFactory.create(
|
||||||
|
context.session, context.scopeSession,
|
||||||
|
allowedWritingMemberExpectForActualMapping = true,
|
||||||
|
)
|
||||||
|
val actualContainingClass = context.containingDeclarations.lastOrNull()?.symbol as? FirRegularClassSymbol
|
||||||
|
val expectContainingClass = actualContainingClass?.getSingleExpectForActualOrNull() as? FirRegularClassSymbol
|
||||||
|
getCheckingCompatibility(
|
||||||
|
symbol,
|
||||||
|
expectedSingleCandidate,
|
||||||
|
actualContainingClass,
|
||||||
|
expectContainingClass,
|
||||||
|
expectActualMatchingContext,
|
||||||
|
)
|
||||||
|
} else null
|
||||||
|
|
||||||
checkAmbiguousExpects(symbol, compatibilityToMembersMap, symbol, context, reporter)
|
checkAmbiguousExpects(symbol, matchingCompatibilityToMembersMap, symbol, context, reporter)
|
||||||
|
|
||||||
val source = declaration.source
|
val source = declaration.source
|
||||||
if (!declaration.isActual) {
|
if (!declaration.isActual) {
|
||||||
if (compatibilityToMembersMap.allMismatches()) return
|
if (matchingCompatibilityToMembersMap.allMismatches()) return
|
||||||
|
|
||||||
if (ExpectActualCheckingCompatibility.Compatible in compatibilityToMembersMap ||
|
if (ExpectActualMatchingCompatibility.MatchedSuccessfully in matchingCompatibilityToMembersMap) {
|
||||||
ExpectActualMatchingCompatibility.MatchedSuccessfully in compatibilityToMembersMap
|
|
||||||
) {
|
|
||||||
if (checkActual) {
|
if (checkActual) {
|
||||||
reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context)
|
reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context)
|
||||||
}
|
}
|
||||||
@@ -141,9 +155,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val singleIncompatibility = compatibilityToMembersMap.keys.singleOrNull()
|
|
||||||
when {
|
when {
|
||||||
singleIncompatibility is ExpectActualCheckingCompatibility.ClassScopes -> {
|
checkingCompatibility is ExpectActualCheckingCompatibility.ClassScopes -> {
|
||||||
require(symbol is FirRegularClassSymbol || symbol is FirTypeAliasSymbol) {
|
require(symbol is FirRegularClassSymbol || symbol is FirTypeAliasSymbol) {
|
||||||
"Incompatible.ClassScopes is only possible for a class or a typealias: $declaration"
|
"Incompatible.ClassScopes is only possible for a class or a typealias: $declaration"
|
||||||
}
|
}
|
||||||
@@ -153,7 +166,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
// This is needed only to reduce the number of errors. Incompatibility errors for those members will be reported
|
// 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
|
// later when this checker is called for them
|
||||||
fun hasSingleActualSuspect(
|
fun hasSingleActualSuspect(
|
||||||
expectedWithIncompatibility: Pair<FirBasedSymbol<*>, Map<out MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>
|
expectedWithIncompatibility: Pair<FirBasedSymbol<*>, Map<out ExpectActualCompatibility.MismatchOrIncompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val (expectedMember, incompatibility) = expectedWithIncompatibility
|
val (expectedMember, incompatibility) = expectedWithIncompatibility
|
||||||
val actualMember = incompatibility.values.singleOrNull()?.singleOrNull()
|
val actualMember = incompatibility.values.singleOrNull()?.singleOrNull()
|
||||||
@@ -163,8 +176,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
actualMember.fir.expectForActual?.values?.singleOrNull()?.singleOrNull() == expectedMember
|
actualMember.fir.expectForActual?.values?.singleOrNull()?.singleOrNull() == expectedMember
|
||||||
}
|
}
|
||||||
|
|
||||||
val nonTrivialIncompatibleMembers = singleIncompatibility.incompatibleMembers.filterNot(::hasSingleActualSuspect)
|
val nonTrivialIncompatibleMembers = checkingCompatibility.incompatibleMembers.filterNot(::hasSingleActualSuspect)
|
||||||
val nonTrivialMismatchedMembers = singleIncompatibility.mismatchedMembers.filterNot(::hasSingleActualSuspect)
|
val nonTrivialMismatchedMembers = checkingCompatibility.mismatchedMembers.filterNot(::hasSingleActualSuspect)
|
||||||
|
|
||||||
if (nonTrivialIncompatibleMembers.isNotEmpty()) {
|
if (nonTrivialIncompatibleMembers.isNotEmpty()) {
|
||||||
reporter.reportOn(source, FirErrors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, symbol, nonTrivialIncompatibleMembers, context)
|
reporter.reportOn(source, FirErrors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, symbol, nonTrivialIncompatibleMembers, context)
|
||||||
@@ -173,17 +186,28 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectActualCheckingCompatibility.Compatible !in compatibilityToMembersMap &&
|
ExpectActualMatchingCompatibility.MatchedSuccessfully !in matchingCompatibilityToMembersMap &&
|
||||||
ExpectActualMatchingCompatibility.MatchedSuccessfully !in compatibilityToMembersMap -> {
|
requireActualModifier(declaration.symbol, context.session) -> {
|
||||||
|
reporter.reportOn(
|
||||||
|
source,
|
||||||
|
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||||
|
symbol,
|
||||||
|
matchingCompatibilityToMembersMap,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkingCompatibility != null && checkingCompatibility != ExpectActualCheckingCompatibility.Compatible -> {
|
||||||
|
check(expectedSingleCandidate != null) // It can't be null, because checkingCompatibility is not null
|
||||||
// A nicer diagnostic for functions with default params
|
// A nicer diagnostic for functions with default params
|
||||||
if (declaration is FirFunction && compatibilityToMembersMap.keys.any { it is ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters }) {
|
if (declaration is FirFunction && checkingCompatibility == ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters) {
|
||||||
reporter.reportOn(declaration.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
reporter.reportOn(declaration.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context)
|
||||||
} else if (requireActualModifier(declaration.symbol, context.session)) {
|
} else if (requireActualModifier(declaration.symbol, context.session)) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
source,
|
source,
|
||||||
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
FirErrors.ACTUAL_WITHOUT_EXPECT,
|
||||||
symbol,
|
symbol,
|
||||||
compatibilityToMembersMap,
|
mapOf(checkingCompatibility to listOf(expectedSingleCandidate)),
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -191,27 +215,49 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
// We want to report errors even if a candidate is incompatible, but it's single
|
|
||||||
val expectedSingleCandidate = symbol.getSingleExpectForActualOrNull()
|
|
||||||
if (expectedSingleCandidate != null) {
|
if (expectedSingleCandidate != null) {
|
||||||
checkOptInAnnotation(declaration, expectedSingleCandidate, context, reporter)
|
checkOptInAnnotation(declaration, expectedSingleCandidate, context, reporter)
|
||||||
checkAnnotationsMatch(expectedSingleCandidate, symbol, context, reporter)
|
checkAnnotationsMatch(expectedSingleCandidate, symbol, context, reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getCheckingCompatibility(
|
||||||
|
actualSymbol: FirBasedSymbol<*>,
|
||||||
|
expectSymbol: FirBasedSymbol<*>,
|
||||||
|
actualContainingClass: FirRegularClassSymbol?,
|
||||||
|
expectContainingClass: FirRegularClassSymbol?,
|
||||||
|
context: FirExpectActualMatchingContext,
|
||||||
|
): ExpectActualCompatibility<FirBasedSymbol<*>> =
|
||||||
|
when {
|
||||||
|
actualSymbol is FirCallableSymbol<*> && expectSymbol is FirCallableSymbol<*> -> {
|
||||||
|
AbstractExpectActualChecker.getCallablesCompatibility(
|
||||||
|
expectSymbol,
|
||||||
|
actualSymbol,
|
||||||
|
expectContainingClass,
|
||||||
|
actualContainingClass,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
actualSymbol is FirClassLikeSymbol<*> && expectSymbol is RegularClassSymbolMarker -> {
|
||||||
|
AbstractExpectActualChecker.getClassifiersCompatibility(
|
||||||
|
expectSymbol,
|
||||||
|
actualSymbol,
|
||||||
|
checkClassScopesCompatibility = true,
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> error("These expect/actual shouldn't have been matched by FirExpectActualResolver")
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkAmbiguousExpects(
|
private fun checkAmbiguousExpects(
|
||||||
actualDeclaration: FirBasedSymbol<*>,
|
actualDeclaration: FirBasedSymbol<*>,
|
||||||
compatibility: Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>,
|
compatibility: Map<ExpectActualMatchingCompatibility, List<FirBasedSymbol<*>>>,
|
||||||
symbol: FirBasedSymbol<*>,
|
symbol: FirBasedSymbol<*>,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
) {
|
) {
|
||||||
val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence()
|
val filesWithAtLeastWeaklyCompatibleExpects = compatibility[ExpectActualMatchingCompatibility.MatchedSuccessfully]
|
||||||
.filter { (compatibility, _) ->
|
.orEmpty()
|
||||||
compatibility.isCompatibleOrWeaklyIncompatible
|
|
||||||
}
|
|
||||||
.map { (_, members) -> members }
|
|
||||||
.flatten()
|
|
||||||
.map { it.moduleData }
|
.map { it.moduleData }
|
||||||
.sortedBy { it.name.asString() }
|
.sortedBy { it.name.asString() }
|
||||||
.toList()
|
.toList()
|
||||||
|
|||||||
+4
-4
@@ -451,7 +451,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
|||||||
return symbol.source == null && symbol.origin !is FirDeclarationOrigin.Plugin
|
return symbol.source == null && symbol.origin !is FirDeclarationOrigin.Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatchedOrCompatibleMembers(
|
override fun onMatchedMembers(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbol: DeclarationSymbolMarker,
|
actualSymbol: DeclarationSymbolMarker,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
@@ -469,7 +469,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
|||||||
|
|
||||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbolsByIncompatibility: Map<out ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
containingActualClassSymbol: RegularClassSymbolMarker?
|
containingActualClassSymbol: RegularClassSymbolMarker?
|
||||||
) {
|
) {
|
||||||
@@ -489,7 +489,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
|||||||
|
|
||||||
private fun FirRegularClassSymbol.addMemberExpectForActualMapping(
|
private fun FirRegularClassSymbol.addMemberExpectForActualMapping(
|
||||||
expectMember: FirBasedSymbol<*>, actualMember: FirBasedSymbol<*>,
|
expectMember: FirBasedSymbol<*>, actualMember: FirBasedSymbol<*>,
|
||||||
expectClassSymbol: FirRegularClassSymbol, compatibility: ExpectActualCompatibility<*>,
|
expectClassSymbol: FirRegularClassSymbol, compatibility: ExpectActualMatchingCompatibility,
|
||||||
) {
|
) {
|
||||||
check(allowedWritingMemberExpectForActualMapping) { "Writing memberExpectForActual is not allowed in this context" }
|
check(allowedWritingMemberExpectForActualMapping) { "Writing memberExpectForActual is not allowed in this context" }
|
||||||
val fir = fir
|
val fir = fir
|
||||||
@@ -524,7 +524,7 @@ class FirExpectActualMatchingContextImpl private constructor(
|
|||||||
actualClass: RegularClassSymbolMarker,
|
actualClass: RegularClassSymbolMarker,
|
||||||
actualMember: DeclarationSymbolMarker,
|
actualMember: DeclarationSymbolMarker,
|
||||||
checkClassScopesCompatibility: Boolean,
|
checkClassScopesCompatibility: Boolean,
|
||||||
): Map<FirBasedSymbol<*>, ExpectActualCompatibility<*>> {
|
): Map<FirBasedSymbol<*>, ExpectActualMatchingCompatibility> {
|
||||||
val mapping = actualClass.asSymbol().fir.memberExpectForActual
|
val mapping = actualClass.asSymbol().fir.memberExpectForActual
|
||||||
return mapping?.get(actualMember to expectClass) ?: emptyMap()
|
return mapping?.get(actualMember to expectClass) ?: emptyMap()
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-18
@@ -7,19 +7,20 @@ package org.jetbrains.kotlin.fir.resolve.transformers.mpp
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirExpectActualMatchingContext
|
import org.jetbrains.kotlin.fir.FirExpectActualMatchingContext
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.ExpectForActualMatchingData
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
import org.jetbrains.kotlin.mpp.CallableSymbolMarker
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.getMatchedAndChecked
|
|
||||||
|
|
||||||
object FirExpectActualResolver {
|
object FirExpectActualResolver {
|
||||||
fun findExpectForActual(
|
fun findExpectForActual(
|
||||||
@@ -27,9 +28,9 @@ object FirExpectActualResolver {
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
context: FirExpectActualMatchingContext,
|
context: FirExpectActualMatchingContext,
|
||||||
): ExpectForActualData {
|
): ExpectForActualMatchingData {
|
||||||
with(context) {
|
with(context) {
|
||||||
val result = when (actualSymbol) {
|
val result: Map<ExpectActualMatchingCompatibility, List<FirBasedSymbol<*>>> = when (actualSymbol) {
|
||||||
is FirCallableSymbol<*> -> {
|
is FirCallableSymbol<*> -> {
|
||||||
val callableId = actualSymbol.callableId
|
val callableId = actualSymbol.callableId
|
||||||
val classId = callableId.classId
|
val classId = callableId.classId
|
||||||
@@ -60,7 +61,7 @@ object FirExpectActualResolver {
|
|||||||
candidates.filter { expectSymbol ->
|
candidates.filter { expectSymbol ->
|
||||||
actualSymbol != expectSymbol && expectSymbol.isExpect
|
actualSymbol != expectSymbol && expectSymbol.isExpect
|
||||||
}.groupBy { expectDeclaration ->
|
}.groupBy { expectDeclaration ->
|
||||||
AbstractExpectActualChecker.getCallablesCompatibility(
|
AbstractExpectActualMatcher.getCallablesMatchingCompatibility(
|
||||||
expectDeclaration,
|
expectDeclaration,
|
||||||
actualSymbol as CallableSymbolMarker,
|
actualSymbol as CallableSymbolMarker,
|
||||||
expectContainingClass,
|
expectContainingClass,
|
||||||
@@ -69,21 +70,16 @@ object FirExpectActualResolver {
|
|||||||
)
|
)
|
||||||
}.let {
|
}.let {
|
||||||
// If there is a compatible entry, return a map only containing it
|
// If there is a compatible entry, return a map only containing it
|
||||||
when (val compatibleSymbols = it.getMatchedAndChecked()) {
|
when (val compatibleSymbols = it[ExpectActualMatchingCompatibility.MatchedSuccessfully]) {
|
||||||
null -> it
|
null -> it
|
||||||
else -> mapOf<ExpectActualCompatibility<FirBasedSymbol<*>>, _>(ExpectActualMatchingCompatibility.MatchedSuccessfully to compatibleSymbols)
|
else -> mapOf(ExpectActualMatchingCompatibility.MatchedSuccessfully to compatibleSymbols)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirClassLikeSymbol<*> -> {
|
is FirClassLikeSymbol<*> -> {
|
||||||
val expectClassSymbol = useSiteSession.dependenciesSymbolProvider
|
val expectClassSymbol = useSiteSession.dependenciesSymbolProvider
|
||||||
.getClassLikeSymbolByClassId(actualSymbol.classId) as? FirRegularClassSymbol ?: return emptyMap()
|
.getClassLikeSymbolByClassId(actualSymbol.classId) as? FirRegularClassSymbol ?: return emptyMap()
|
||||||
val compatibility = AbstractExpectActualChecker.getClassifiersCompatibility(
|
val compatibility = AbstractExpectActualMatcher.matchClassifiers(expectClassSymbol, actualSymbol, context)
|
||||||
expectClassSymbol,
|
|
||||||
actualSymbol,
|
|
||||||
checkClassScopesCompatibility = true,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
mapOf(compatibility to listOf(expectClassSymbol))
|
mapOf(compatibility to listOf(expectClassSymbol))
|
||||||
}
|
}
|
||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
|
|||||||
+7
-12
@@ -10,12 +10,11 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
|
|
||||||
|
|
||||||
private object ExpectForActualAttributeKey : FirDeclarationDataKey()
|
private object ExpectForActualAttributeKey : FirDeclarationDataKey()
|
||||||
|
|
||||||
typealias ExpectForActualData = Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>
|
typealias ExpectForActualMatchingData = Map<ExpectActualMatchingCompatibility, List<FirBasedSymbol<*>>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actual declaration -> (many) expect declaration mapping. For top-level declarations.
|
* Actual declaration -> (many) expect declaration mapping. For top-level declarations.
|
||||||
@@ -27,7 +26,7 @@ typealias ExpectForActualData = Map<ExpectActualCompatibility<FirBasedSymbol<*>>
|
|||||||
* See `/docs/fir/k2_kmp.md`
|
* See `/docs/fir/k2_kmp.md`
|
||||||
*/
|
*/
|
||||||
@SymbolInternals
|
@SymbolInternals
|
||||||
var FirDeclaration.expectForActual: ExpectForActualData? by FirDeclarationDataRegistry.data(ExpectForActualAttributeKey)
|
var FirDeclaration.expectForActual: ExpectForActualMatchingData? by FirDeclarationDataRegistry.data(ExpectForActualAttributeKey)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see expectForActual
|
* @see expectForActual
|
||||||
@@ -38,17 +37,13 @@ fun FirFunctionSymbol<*>.getSingleExpectForActualOrNull(): FirFunctionSymbol<*>?
|
|||||||
/**
|
/**
|
||||||
* @see expectForActual
|
* @see expectForActual
|
||||||
*/
|
*/
|
||||||
fun FirBasedSymbol<*>.getSingleExpectForActualOrNull(): FirBasedSymbol<*>? {
|
fun FirBasedSymbol<*>.getSingleExpectForActualOrNull(): FirBasedSymbol<*>? =
|
||||||
val expectForActual = expectForActual ?: return null
|
expectForActual?.get(ExpectActualMatchingCompatibility.MatchedSuccessfully)?.singleOrNull()
|
||||||
val compatibleOrWeakCompatible: List<FirBasedSymbol<*>> =
|
|
||||||
expectForActual.entries.singleOrNull { it.key.isCompatibleOrWeaklyIncompatible }?.value ?: return null
|
|
||||||
return compatibleOrWeakCompatible.singleOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see expectForActual
|
* @see expectForActual
|
||||||
*/
|
*/
|
||||||
val FirBasedSymbol<*>.expectForActual: ExpectForActualData?
|
val FirBasedSymbol<*>.expectForActual: ExpectForActualMatchingData?
|
||||||
get() {
|
get() {
|
||||||
lazyResolveToPhase(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
lazyResolveToPhase(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
||||||
return fir.expectForActual
|
return fir.expectForActual
|
||||||
@@ -61,7 +56,7 @@ private object MemberExpectForActualAttributeKey : FirDeclarationDataKey()
|
|||||||
// in case when two `actual typealias` point to the same class.
|
// in case when two `actual typealias` point to the same class.
|
||||||
typealias MemberExpectForActualData =
|
typealias MemberExpectForActualData =
|
||||||
Map<Pair</* actual member */ FirBasedSymbol<*>, /* expect class */ FirRegularClassSymbol>,
|
Map<Pair</* actual member */ FirBasedSymbol<*>, /* expect class */ FirRegularClassSymbol>,
|
||||||
Map</* expect member */ FirBasedSymbol<*>, ExpectActualCompatibility<*>>>
|
Map</* expect member */ FirBasedSymbol<*>, ExpectActualMatchingCompatibility>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actual class + expect class + actual member declaration -> (many) expect member declaration mapping.
|
* Actual class + expect class + actual member declaration -> (many) expect member declaration mapping.
|
||||||
|
|||||||
+7
-6
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
import org.jetbrains.kotlin.ir.util.callableId
|
import org.jetbrains.kotlin.ir.util.callableId
|
||||||
@@ -20,8 +22,8 @@ import org.jetbrains.kotlin.mpp.DeclarationSymbolMarker
|
|||||||
import org.jetbrains.kotlin.mpp.RegularClassSymbolMarker
|
import org.jetbrains.kotlin.mpp.RegularClassSymbolMarker
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,11 +221,10 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
|||||||
actualSymbols: List<IrSymbol>,
|
actualSymbols: List<IrSymbol>,
|
||||||
context: MatchingContext
|
context: MatchingContext
|
||||||
) {
|
) {
|
||||||
AbstractExpectActualChecker.checkSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||||
expectSymbol,
|
expectSymbol,
|
||||||
actualSymbols,
|
actualSymbols,
|
||||||
context,
|
context,
|
||||||
checkClassScopesCompatibility = true
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +261,7 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
|
|||||||
|
|
||||||
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
override fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbolsByIncompatibility: Map<out ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||||
) {
|
) {
|
||||||
|
|||||||
+2
-3
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
|||||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualChecker
|
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualMatcher
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||||
@@ -45,11 +45,10 @@ internal fun collectActualCallablesMatchingToSpecificExpect(
|
|||||||
matchingActuals += actualSymbol
|
matchingActuals += actualSymbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AbstractExpectActualChecker.checkSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||||
expectSymbol,
|
expectSymbol,
|
||||||
actualSymbols,
|
actualSymbols,
|
||||||
context,
|
context,
|
||||||
checkClassScopesCompatibility = false
|
|
||||||
)
|
)
|
||||||
return matchingActuals
|
return matchingActuals
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCom
|
|||||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
|
||||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
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.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
@@ -480,7 +480,7 @@ internal abstract class IrExpectActualMatchingContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMatchedOrCompatibleMembers(
|
override fun onMatchedMembers(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbol: DeclarationSymbolMarker,
|
actualSymbol: DeclarationSymbolMarker,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
@@ -558,7 +558,7 @@ internal abstract class IrExpectActualMatchingContext(
|
|||||||
actualClass: RegularClassSymbolMarker,
|
actualClass: RegularClassSymbolMarker,
|
||||||
actualMember: DeclarationSymbolMarker,
|
actualMember: DeclarationSymbolMarker,
|
||||||
checkClassScopesCompatibility: Boolean,
|
checkClassScopesCompatibility: Boolean,
|
||||||
): Map<out DeclarationSymbolMarker, ExpectActualCompatibility<*>> = error("Should not be called")
|
): Map<out DeclarationSymbolMarker, ExpectActualMatchingCompatibility> = error("Should not be called")
|
||||||
|
|
||||||
// It's a stub, because not needed anywhere
|
// It's a stub, because not needed anywhere
|
||||||
private object IrSourceElementStub : SourceElementMarker
|
private object IrSourceElementStub : SourceElementMarker
|
||||||
|
|||||||
+2
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.name.StandardClassIds
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||||
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
||||||
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType as IncompatibilityType
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType as IncompatibilityType
|
||||||
|
|
||||||
object AbstractExpectActualAnnotationMatchChecker {
|
object AbstractExpectActualAnnotationMatchChecker {
|
||||||
@@ -316,7 +317,7 @@ object AbstractExpectActualAnnotationMatchChecker {
|
|||||||
checkClassScopesCompatibility = false,
|
checkClassScopesCompatibility = false,
|
||||||
)
|
)
|
||||||
val expectMember = expectToCompatibilityMap
|
val expectMember = expectToCompatibilityMap
|
||||||
.filter { it.value is ExpectActualCompatibility.MatchedOrCompatible }.keys.singleOrNull()
|
.filter { it.value == ExpectActualMatchingCompatibility.MatchedSuccessfully }.keys.singleOrNull()
|
||||||
// Check also incompatible members if only one is found
|
// Check also incompatible members if only one is found
|
||||||
?: expectToCompatibilityMap.keys.singleOrNull()
|
?: expectToCompatibilityMap.keys.singleOrNull()
|
||||||
?: continue
|
?: continue
|
||||||
|
|||||||
+43
-43
@@ -13,8 +13,6 @@ import org.jetbrains.kotlin.mpp.*
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCheckingCompatibility
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.MismatchOrIncompatible
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
@@ -37,12 +35,17 @@ object AbstractExpectActualChecker {
|
|||||||
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
||||||
checkClassScopesCompatibility: Boolean,
|
checkClassScopesCompatibility: Boolean,
|
||||||
context: ExpectActualMatchingContext<T>,
|
context: ExpectActualMatchingContext<T>,
|
||||||
): ExpectActualCompatibility<T> {
|
): ExpectActualCheckingCompatibility<T> {
|
||||||
val result = with(context) {
|
val result = with(context) {
|
||||||
getClassifiersCompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor = null, checkClassScopesCompatibility)
|
getClassifiersCompatibility(
|
||||||
|
expectClassSymbol,
|
||||||
|
actualClassLikeSymbol,
|
||||||
|
parentSubstitutor = null,
|
||||||
|
checkClassScopesCompatibility,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return result as ExpectActualCompatibility<T>
|
return result as ExpectActualCheckingCompatibility<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : DeclarationSymbolMarker> getCallablesCompatibility(
|
fun <T : DeclarationSymbolMarker> getCallablesCompatibility(
|
||||||
@@ -51,7 +54,7 @@ object AbstractExpectActualChecker {
|
|||||||
expectContainingClass: RegularClassSymbolMarker?,
|
expectContainingClass: RegularClassSymbolMarker?,
|
||||||
actualContainingClass: RegularClassSymbolMarker?,
|
actualContainingClass: RegularClassSymbolMarker?,
|
||||||
context: ExpectActualMatchingContext<T>,
|
context: ExpectActualMatchingContext<T>,
|
||||||
): ExpectActualCompatibility<T> = with (context) {
|
): ExpectActualCheckingCompatibility<T> = with (context) {
|
||||||
val expectTypeParameters = expectContainingClass?.typeParameters.orEmpty()
|
val expectTypeParameters = expectContainingClass?.typeParameters.orEmpty()
|
||||||
val actualTypeParameters = actualContainingClass?.typeParameters.orEmpty()
|
val actualTypeParameters = actualContainingClass?.typeParameters.orEmpty()
|
||||||
val parentSubstitutor = (expectTypeParameters zipIfSizesAreEqual actualTypeParameters)
|
val parentSubstitutor = (expectTypeParameters zipIfSizesAreEqual actualTypeParameters)
|
||||||
@@ -61,10 +64,10 @@ object AbstractExpectActualChecker {
|
|||||||
actualDeclaration,
|
actualDeclaration,
|
||||||
parentSubstitutor,
|
parentSubstitutor,
|
||||||
expectContainingClass,
|
expectContainingClass,
|
||||||
actualContainingClass
|
actualContainingClass,
|
||||||
)
|
)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
result as ExpectActualCompatibility<T>
|
result as ExpectActualCheckingCompatibility<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : DeclarationSymbolMarker> checkSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
fun <T : DeclarationSymbolMarker> checkSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||||
@@ -93,7 +96,12 @@ object AbstractExpectActualChecker {
|
|||||||
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
actualClassLikeSymbol: ClassLikeSymbolMarker,
|
||||||
parentSubstitutor: TypeSubstitutorMarker?,
|
parentSubstitutor: TypeSubstitutorMarker?,
|
||||||
checkClassScopes: Boolean,
|
checkClassScopes: Boolean,
|
||||||
): ExpectActualCheckingCompatibility<*> = getClassifiersIncompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor, checkClassScopes)
|
): ExpectActualCheckingCompatibility<*> = getClassifiersIncompatibility(
|
||||||
|
expectClassSymbol,
|
||||||
|
actualClassLikeSymbol,
|
||||||
|
parentSubstitutor,
|
||||||
|
checkClassScopes,
|
||||||
|
)
|
||||||
?: ExpectActualCheckingCompatibility.Compatible
|
?: ExpectActualCheckingCompatibility.Compatible
|
||||||
|
|
||||||
context(ExpectActualMatchingContext<*>)
|
context(ExpectActualMatchingContext<*>)
|
||||||
@@ -301,27 +309,17 @@ object AbstractExpectActualChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val mismatchedOrIncompatibleMap = mutableMapOf<MismatchOrIncompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
val incompatibilityMap = mutableMapOf<ExpectActualCheckingCompatibility.Incompatible<*>, MutableList<DeclarationSymbolMarker>>()
|
||||||
for ((actualMember, compatibility) in mapping) {
|
for ((actualMember, compatibility) in mapping) {
|
||||||
when (compatibility) {
|
when (compatibility) {
|
||||||
is ExpectActualCompatibility.MatchedOrCompatible<*> -> {
|
ExpectActualCheckingCompatibility.Compatible -> return
|
||||||
onMatchedOrCompatibleMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
is ExpectActualCheckingCompatibility.Incompatible<*> -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
is MismatchOrIncompatible<*> -> mismatchedOrIncompatibleMap.getOrPut(compatibility) { SmartList() }.add(actualMember)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo it's temporary code. KT-62590 in progress
|
incompatibleMembers?.add(expectMember to incompatibilityMap)
|
||||||
val incompatibilities = mismatchedOrIncompatibleMap
|
// Temporarily comment out reporting checking incompatibilities to backend. KT-62590 is in progress
|
||||||
.mapNotNull { (key, value) ->
|
//onMismatchedOrIncompatibleMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
|
||||||
(key as? ExpectActualCheckingCompatibility.Incompatible)?.let { it to value }
|
|
||||||
}
|
|
||||||
.toMap()
|
|
||||||
|
|
||||||
incompatibleMembers?.add(expectMember to incompatibilities)
|
|
||||||
onMismatchedOrIncompatibleMembersFromClassScope(expectMember, mismatchedOrIncompatibleMap, expectClassSymbol, actualClassSymbol)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context(ExpectActualMatchingContext<*>)
|
context(ExpectActualMatchingContext<*>)
|
||||||
@@ -331,7 +329,7 @@ object AbstractExpectActualChecker {
|
|||||||
parentSubstitutor: TypeSubstitutorMarker?,
|
parentSubstitutor: TypeSubstitutorMarker?,
|
||||||
expectContainingClass: RegularClassSymbolMarker?,
|
expectContainingClass: RegularClassSymbolMarker?,
|
||||||
actualContainingClass: RegularClassSymbolMarker?,
|
actualContainingClass: RegularClassSymbolMarker?,
|
||||||
): ExpectActualCompatibility<*> {
|
): ExpectActualCheckingCompatibility<*> {
|
||||||
require(
|
require(
|
||||||
(expectDeclaration is ConstructorSymbolMarker && actualDeclaration is ConstructorSymbolMarker) ||
|
(expectDeclaration is ConstructorSymbolMarker && actualDeclaration is ConstructorSymbolMarker) ||
|
||||||
expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName
|
expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName
|
||||||
@@ -352,18 +350,15 @@ object AbstractExpectActualChecker {
|
|||||||
return ExpectActualCheckingCompatibility.Compatible
|
return ExpectActualCheckingCompatibility.Compatible
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must prioritize to return STRONG incompatible over WEAK incompatible (because STRONG incompatibility allows to search for overloads)
|
|
||||||
val annotationMode = expectContainingClass?.classKind == ClassKind.ANNOTATION_CLASS
|
val annotationMode = expectContainingClass?.classKind == ClassKind.ANNOTATION_CLASS
|
||||||
return getCallablesStrongIncompatibility(expectDeclaration, actualDeclaration, annotationMode, parentSubstitutor)
|
return getCallablesCheckingIncompatibility(
|
||||||
?: getCallablesWeakIncompatibility(
|
expectDeclaration,
|
||||||
expectDeclaration,
|
actualDeclaration,
|
||||||
actualDeclaration,
|
annotationMode,
|
||||||
annotationMode,
|
parentSubstitutor,
|
||||||
parentSubstitutor,
|
expectContainingClass,
|
||||||
expectContainingClass,
|
actualContainingClass,
|
||||||
actualContainingClass
|
) ?: ExpectActualCheckingCompatibility.Compatible
|
||||||
)
|
|
||||||
?: ExpectActualCheckingCompatibility.Compatible
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context(ExpectActualMatchingContext<*>)
|
context(ExpectActualMatchingContext<*>)
|
||||||
@@ -423,14 +418,14 @@ object AbstractExpectActualChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context(ExpectActualMatchingContext<*>)
|
context(ExpectActualMatchingContext<*>)
|
||||||
private fun getCallablesWeakIncompatibility(
|
private fun getCallablesCheckingIncompatibility(
|
||||||
expectDeclaration: CallableSymbolMarker,
|
expectDeclaration: CallableSymbolMarker,
|
||||||
actualDeclaration: CallableSymbolMarker,
|
actualDeclaration: CallableSymbolMarker,
|
||||||
insideAnnotationClass: Boolean,
|
insideAnnotationClass: Boolean,
|
||||||
parentSubstitutor: TypeSubstitutorMarker?,
|
parentSubstitutor: TypeSubstitutorMarker?,
|
||||||
expectContainingClass: RegularClassSymbolMarker?,
|
expectContainingClass: RegularClassSymbolMarker?,
|
||||||
actualContainingClass: RegularClassSymbolMarker?,
|
actualContainingClass: RegularClassSymbolMarker?,
|
||||||
): ExpectActualCheckingCompatibility<*>? {
|
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||||
val expectedTypeParameters = expectDeclaration.typeParameters
|
val expectedTypeParameters = expectDeclaration.typeParameters
|
||||||
val actualTypeParameters = actualDeclaration.typeParameters
|
val actualTypeParameters = actualDeclaration.typeParameters
|
||||||
val expectedValueParameters = expectDeclaration.valueParameters
|
val expectedValueParameters = expectDeclaration.valueParameters
|
||||||
@@ -679,7 +674,7 @@ object AbstractExpectActualChecker {
|
|||||||
private fun getFunctionsIncompatibility(
|
private fun getFunctionsIncompatibility(
|
||||||
expectFunction: CallableSymbolMarker,
|
expectFunction: CallableSymbolMarker,
|
||||||
actualFunction: CallableSymbolMarker,
|
actualFunction: CallableSymbolMarker,
|
||||||
): ExpectActualCheckingCompatibility<*>? {
|
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||||
if (!equalBy(expectFunction, actualFunction) { f -> f.isSuspend }) {
|
if (!equalBy(expectFunction, actualFunction) { f -> f.isSuspend }) {
|
||||||
return ExpectActualCheckingCompatibility.FunctionModifiersDifferent
|
return ExpectActualCheckingCompatibility.FunctionModifiersDifferent
|
||||||
}
|
}
|
||||||
@@ -699,12 +694,13 @@ object AbstractExpectActualChecker {
|
|||||||
private fun getPropertiesIncompatibility(
|
private fun getPropertiesIncompatibility(
|
||||||
expected: PropertySymbolMarker,
|
expected: PropertySymbolMarker,
|
||||||
actual: PropertySymbolMarker,
|
actual: PropertySymbolMarker,
|
||||||
): ExpectActualCheckingCompatibility<*>? {
|
): ExpectActualCheckingCompatibility.Incompatible<*>? {
|
||||||
return when {
|
return when {
|
||||||
!equalBy(expected, actual) { p -> p.isVar } -> ExpectActualCheckingCompatibility.PropertyKind
|
!equalBy(expected, actual) { p -> p.isVar } -> ExpectActualCheckingCompatibility.PropertyKind
|
||||||
!equalBy(expected, actual) { p -> p.isLateinit } -> ExpectActualCheckingCompatibility.PropertyLateinitModifier
|
!equalBy(expected, actual) { p -> p.isLateinit } -> ExpectActualCheckingCompatibility.PropertyLateinitModifier
|
||||||
expected.isConst && !actual.isConst -> ExpectActualCheckingCompatibility.PropertyConstModifier
|
expected.isConst && !actual.isConst -> ExpectActualCheckingCompatibility.PropertyConstModifier
|
||||||
!arePropertySettersWithCompatibleVisibilities(expected, actual) -> ExpectActualCheckingCompatibility.PropertySetterVisibility
|
!arePropertySettersWithCompatibleVisibilities(expected, actual) ->
|
||||||
|
ExpectActualCheckingCompatibility.PropertySetterVisibility
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -716,7 +712,11 @@ object AbstractExpectActualChecker {
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
val expectedSetter = expected.setter ?: return true
|
val expectedSetter = expected.setter ?: return true
|
||||||
val actualSetter = actual.setter ?: return true
|
val actualSetter = actual.setter ?: return true
|
||||||
return areCompatibleCallableVisibilities(expectedSetter.visibility, expectedSetter.modality, actualSetter.visibility)
|
return areCompatibleCallableVisibilities(
|
||||||
|
expectedSetter.visibility,
|
||||||
|
expectedSetter.modality,
|
||||||
|
actualSetter.visibility,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------- Utils ----------------------------------------
|
// ---------------------------------------- Utils ----------------------------------------
|
||||||
|
|||||||
+7
-10
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.mpp.*
|
import org.jetbrains.kotlin.mpp.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
@@ -27,26 +26,24 @@ import org.jetbrains.kotlin.utils.zipIfSizesAreEqual
|
|||||||
* See `/docs/fir/k2_kmp.md` for details
|
* See `/docs/fir/k2_kmp.md` for details
|
||||||
*/
|
*/
|
||||||
object AbstractExpectActualMatcher {
|
object AbstractExpectActualMatcher {
|
||||||
fun <T : DeclarationSymbolMarker> getCallablesCompatibility(
|
fun getCallablesMatchingCompatibility(
|
||||||
expectDeclaration: CallableSymbolMarker,
|
expectDeclaration: CallableSymbolMarker,
|
||||||
actualDeclaration: CallableSymbolMarker,
|
actualDeclaration: CallableSymbolMarker,
|
||||||
expectContainingClass: RegularClassSymbolMarker?,
|
expectContainingClass: RegularClassSymbolMarker?,
|
||||||
actualContainingClass: RegularClassSymbolMarker?,
|
actualContainingClass: RegularClassSymbolMarker?,
|
||||||
context: ExpectActualMatchingContext<T>,
|
context: ExpectActualMatchingContext<*>,
|
||||||
): ExpectActualCompatibility<T> = with (context) {
|
): ExpectActualMatchingCompatibility = with (context) {
|
||||||
val expectTypeParameters = expectContainingClass?.typeParameters.orEmpty()
|
val expectTypeParameters = expectContainingClass?.typeParameters.orEmpty()
|
||||||
val actualTypeParameters = actualContainingClass?.typeParameters.orEmpty()
|
val actualTypeParameters = actualContainingClass?.typeParameters.orEmpty()
|
||||||
val parentSubstitutor = (expectTypeParameters zipIfSizesAreEqual actualTypeParameters)
|
val parentSubstitutor = (expectTypeParameters zipIfSizesAreEqual actualTypeParameters)
|
||||||
?.let { createExpectActualTypeParameterSubstitutor(it, parentSubstitutor = null) }
|
?.let { createExpectActualTypeParameterSubstitutor(it, parentSubstitutor = null) }
|
||||||
val result = getCallablesCompatibility(
|
getCallablesCompatibility(
|
||||||
expectDeclaration,
|
expectDeclaration,
|
||||||
actualDeclaration,
|
actualDeclaration,
|
||||||
parentSubstitutor,
|
parentSubstitutor,
|
||||||
expectContainingClass,
|
expectContainingClass,
|
||||||
actualContainingClass
|
actualContainingClass
|
||||||
)
|
)
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
result as ExpectActualCompatibility<T>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : DeclarationSymbolMarker> matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
fun <T : DeclarationSymbolMarker> matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
|
||||||
@@ -147,7 +144,7 @@ object AbstractExpectActualMatcher {
|
|||||||
for ((actualMember, compatibility) in mapping) {
|
for ((actualMember, compatibility) in mapping) {
|
||||||
when (compatibility) {
|
when (compatibility) {
|
||||||
ExpectActualMatchingCompatibility.MatchedSuccessfully -> {
|
ExpectActualMatchingCompatibility.MatchedSuccessfully -> {
|
||||||
onMatchedOrCompatibleMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
onMatchedMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
|
||||||
return actualMember
|
return actualMember
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,12 +186,12 @@ object AbstractExpectActualMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val annotationMode = expectContainingClass?.classKind == ClassKind.ANNOTATION_CLASS
|
val annotationMode = expectContainingClass?.classKind == ClassKind.ANNOTATION_CLASS
|
||||||
return getCallablesStrongIncompatibility(expectDeclaration, actualDeclaration, annotationMode, parentSubstitutor)
|
return getCallablesMatchingIncompatibility(expectDeclaration, actualDeclaration, annotationMode, parentSubstitutor)
|
||||||
?: ExpectActualMatchingCompatibility.MatchedSuccessfully
|
?: ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||||
}
|
}
|
||||||
|
|
||||||
context(ExpectActualMatchingContext<*>)
|
context(ExpectActualMatchingContext<*>)
|
||||||
private fun getCallablesStrongIncompatibility(
|
private fun getCallablesMatchingIncompatibility(
|
||||||
expectDeclaration: CallableSymbolMarker,
|
expectDeclaration: CallableSymbolMarker,
|
||||||
actualDeclaration: CallableSymbolMarker,
|
actualDeclaration: CallableSymbolMarker,
|
||||||
insideAnnotationClass: Boolean,
|
insideAnnotationClass: Boolean,
|
||||||
|
|||||||
+4
-4
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.mpp.*
|
|||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMatchingCompatibility
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
@@ -165,7 +165,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
|||||||
|
|
||||||
val CallableSymbolMarker.hasStableParameterNames: Boolean
|
val CallableSymbolMarker.hasStableParameterNames: Boolean
|
||||||
|
|
||||||
fun onMatchedOrCompatibleMembers(
|
fun onMatchedMembers(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbol: DeclarationSymbolMarker,
|
actualSymbol: DeclarationSymbolMarker,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
@@ -174,7 +174,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
|||||||
|
|
||||||
fun onMismatchedOrIncompatibleMembersFromClassScope(
|
fun onMismatchedOrIncompatibleMembersFromClassScope(
|
||||||
expectSymbol: DeclarationSymbolMarker,
|
expectSymbol: DeclarationSymbolMarker,
|
||||||
actualSymbolsByIncompatibility: Map<out ExpectActualCompatibility.MismatchOrIncompatible<*>, List<DeclarationSymbolMarker>>,
|
actualSymbolsByIncompatibility: Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker>>,
|
||||||
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
containingExpectClassSymbol: RegularClassSymbolMarker?,
|
||||||
containingActualClassSymbol: RegularClassSymbolMarker?,
|
containingActualClassSymbol: RegularClassSymbolMarker?,
|
||||||
) {}
|
) {}
|
||||||
@@ -217,7 +217,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
|||||||
actualClass: RegularClassSymbolMarker,
|
actualClass: RegularClassSymbolMarker,
|
||||||
actualMember: DeclarationSymbolMarker,
|
actualMember: DeclarationSymbolMarker,
|
||||||
checkClassScopesCompatibility: Boolean,
|
checkClassScopesCompatibility: Boolean,
|
||||||
): Map<out DeclarationSymbolMarker, ExpectActualCompatibility<*>>
|
): Map<out DeclarationSymbolMarker, ExpectActualMatchingCompatibility>
|
||||||
|
|
||||||
fun DeclarationSymbolMarker.getSourceElement(): SourceElementMarker
|
fun DeclarationSymbolMarker.getSourceElement(): SourceElementMarker
|
||||||
|
|
||||||
|
|||||||
+2
-16
@@ -20,9 +20,6 @@ sealed interface ExpectActualCompatibility<out D> {
|
|||||||
sealed interface MismatchOrIncompatible<out D> : ExpectActualCompatibility<D> {
|
sealed interface MismatchOrIncompatible<out D> : ExpectActualCompatibility<D> {
|
||||||
val reason: String?
|
val reason: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's temporary class. KT-62590 is in progress
|
|
||||||
sealed interface MatchedOrCompatible<out D> : ExpectActualCompatibility<D>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +38,7 @@ sealed class ExpectActualMatchingCompatibility : ExpectActualCompatibility<Nothi
|
|||||||
object FunctionTypeParameterCount : Mismatch(TYPE_PARAMETER_COUNT)
|
object FunctionTypeParameterCount : Mismatch(TYPE_PARAMETER_COUNT)
|
||||||
object ParameterTypes : Mismatch("parameter types are different")
|
object ParameterTypes : Mismatch("parameter types are different")
|
||||||
object FunctionTypeParameterUpperBounds : Mismatch("upper bounds of type parameters are different")
|
object FunctionTypeParameterUpperBounds : Mismatch("upper bounds of type parameters are different")
|
||||||
object MatchedSuccessfully : ExpectActualMatchingCompatibility(), ExpectActualCompatibility.MatchedOrCompatible<Nothing>
|
object MatchedSuccessfully : ExpectActualMatchingCompatibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,16 +93,5 @@ sealed class ExpectActualCheckingCompatibility<out D> : ExpectActualCompatibilit
|
|||||||
object ClassTypeParameterUpperBounds : Incompatible<Nothing>(ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds.reason)
|
object ClassTypeParameterUpperBounds : Incompatible<Nothing>(ExpectActualMatchingCompatibility.FunctionTypeParameterUpperBounds.reason)
|
||||||
object TypeParameterVariance : Incompatible<Nothing>("declaration-site variances of type parameters are different")
|
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 TypeParameterReified : Incompatible<Nothing>("some type parameter is reified in one declaration and non-reified in the other")
|
||||||
object Compatible : ExpectActualCheckingCompatibility<Nothing>(), ExpectActualCompatibility.MatchedOrCompatible<Nothing>
|
object Compatible : ExpectActualCheckingCompatibility<Nothing>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val ExpectActualCompatibility<*>.isCompatibleOrWeaklyIncompatible: Boolean
|
|
||||||
get() = this is ExpectActualCompatibility.MatchedOrCompatible || this is ExpectActualCheckingCompatibility
|
|
||||||
|
|
||||||
val ExpectActualCompatibility<*>.compatible: Boolean
|
|
||||||
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() }
|
|
||||||
|
|||||||
+1
-10
@@ -56,16 +56,7 @@ data class ExpectActualMemberDiff<out M, out C>(val kind: Kind, val actualMember
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ExpectActualCompatibility.MismatchOrIncompatible<*>.toMemberDiffKind(): ExpectActualMemberDiff.Kind? = when (this) {
|
fun ExpectActualCheckingCompatibility.Incompatible<*>.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")
|
|
||||||
|
|
||||||
ExpectActualCheckingCompatibility.ReturnType -> ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride
|
ExpectActualCheckingCompatibility.ReturnType -> ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride
|
||||||
ExpectActualCheckingCompatibility.ClassTypeParameterCount -> error("Not applicable because ExpectActualMemberDiff is about members")
|
ExpectActualCheckingCompatibility.ClassTypeParameterCount -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||||
ExpectActualCheckingCompatibility.ClassTypeParameterUpperBounds -> error("Not applicable because ExpectActualMemberDiff is about members")
|
ExpectActualCheckingCompatibility.ClassTypeParameterUpperBounds -> error("Not applicable because ExpectActualMemberDiff is about members")
|
||||||
|
|||||||
Reference in New Issue
Block a user