[FIR, IR] 1/2 Refactoring: propogate LanguageVersionSettings to areCompatibleCallableVisibilities

This refactoring is needed for KT-61955
This commit is contained in:
Nikita Bobko
2023-11-06 15:18:52 +01:00
committed by Space Team
parent dfe048a96a
commit e13ebe8474
3 changed files with 42 additions and 10 deletions
@@ -138,6 +138,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
actualContainingClass, actualContainingClass,
expectContainingClass, expectContainingClass,
expectActualMatchingContext, expectActualMatchingContext,
context,
) )
} else null } else null
@@ -220,7 +221,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
expectSymbol: FirBasedSymbol<*>, expectSymbol: FirBasedSymbol<*>,
actualContainingClass: FirRegularClassSymbol?, actualContainingClass: FirRegularClassSymbol?,
expectContainingClass: FirRegularClassSymbol?, expectContainingClass: FirRegularClassSymbol?,
context: FirExpectActualMatchingContext, expectActualMatchingContext: FirExpectActualMatchingContext,
context: CheckerContext,
): ExpectActualCompatibility<FirBasedSymbol<*>> = ): ExpectActualCompatibility<FirBasedSymbol<*>> =
when { when {
actualSymbol is FirCallableSymbol<*> && expectSymbol is FirCallableSymbol<*> -> { actualSymbol is FirCallableSymbol<*> && expectSymbol is FirCallableSymbol<*> -> {
@@ -229,14 +231,16 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
actualSymbol, actualSymbol,
expectContainingClass, expectContainingClass,
actualContainingClass, actualContainingClass,
context, expectActualMatchingContext,
context.languageVersionSettings
) )
} }
actualSymbol is FirClassLikeSymbol<*> && expectSymbol is RegularClassSymbolMarker -> { actualSymbol is FirClassLikeSymbol<*> && expectSymbol is RegularClassSymbolMarker -> {
AbstractExpectActualChecker.getClassifiersCompatibility( AbstractExpectActualChecker.getClassifiersCompatibility(
expectSymbol, expectSymbol,
actualSymbol, actualSymbol,
context, expectActualMatchingContext,
context.languageVersionSettings
) )
} }
else -> error("These expect/actual shouldn't have been matched by FirExpectActualResolver") else -> error("These expect/actual shouldn't have been matched by FirExpectActualResolver")
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.common.actualizer package org.jetbrains.kotlin.backend.common.actualizer
import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext import org.jetbrains.kotlin.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker 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
@@ -206,7 +207,7 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
matchAndCheckExpectDeclaration( matchAndCheckExpectDeclaration(
declaration.symbol, declaration.symbol,
context.classActualizationInfo.actualTopLevels[callableId].orEmpty(), context.classActualizationInfo.actualTopLevels[callableId].orEmpty(),
context context,
) )
} }
@@ -221,7 +222,7 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
private fun matchAndCheckExpectDeclaration( private fun matchAndCheckExpectDeclaration(
expectSymbol: IrSymbol, expectSymbol: IrSymbol,
actualSymbols: List<IrSymbol>, actualSymbols: List<IrSymbol>,
context: MatchingContext context: MatchingContext,
) { ) {
val matched = AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals( val matched = AbstractExpectActualMatcher.matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
expectSymbol, expectSymbol,
@@ -233,6 +234,7 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
expectSymbol, expectSymbol,
matched, matched,
context, context,
context.languageVersionSettings,
) )
} }
} }
@@ -252,6 +254,8 @@ private class ExpectActualLinkCollector : IrElementVisitor<Unit, ExpectActualLin
private val currentExpectIoFile by lazy(LazyThreadSafetyMode.PUBLICATION) { currentExpectFile?.toIoFile() } private val currentExpectIoFile by lazy(LazyThreadSafetyMode.PUBLICATION) { currentExpectFile?.toIoFile() }
internal val languageVersionSettings: LanguageVersionSettings get() = diagnosticsReporter.languageVersionSettings
fun withNewCurrentFile(newCurrentFile: IrFile) = fun withNewCurrentFile(newCurrentFile: IrFile) =
MatchingContext( MatchingContext(
typeContext, destination, diagnosticsReporter, expectActualTracker, classActualizationInfo, newCurrentFile typeContext, destination, diagnosticsReporter, expectActualTracker, classActualizationInfo, newCurrentFile
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.calls.mpp package org.jetbrains.kotlin.resolve.calls.mpp
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -31,12 +32,14 @@ object AbstractExpectActualChecker {
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassLikeSymbol: ClassLikeSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker,
context: ExpectActualMatchingContext<T>, context: ExpectActualMatchingContext<T>,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility<T> { ): ExpectActualCheckingCompatibility<T> {
val result = with(context) { val result = with(context) {
getClassifiersCompatibility( getClassifiersCompatibility(
expectClassSymbol, expectClassSymbol,
actualClassLikeSymbol, actualClassLikeSymbol,
parentSubstitutor = null, parentSubstitutor = null,
languageVersionSettings,
) )
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@@ -49,6 +52,7 @@ object AbstractExpectActualChecker {
expectContainingClass: RegularClassSymbolMarker?, expectContainingClass: RegularClassSymbolMarker?,
actualContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?,
context: ExpectActualMatchingContext<T>, context: ExpectActualMatchingContext<T>,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility<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()
@@ -60,6 +64,7 @@ object AbstractExpectActualChecker {
parentSubstitutor, parentSubstitutor,
expectContainingClass, expectContainingClass,
actualContainingClass, actualContainingClass,
languageVersionSettings,
) )
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
result as ExpectActualCheckingCompatibility<T> result as ExpectActualCheckingCompatibility<T>
@@ -69,6 +74,7 @@ object AbstractExpectActualChecker {
expectDeclaration: DeclarationSymbolMarker, expectDeclaration: DeclarationSymbolMarker,
actualDeclaration: DeclarationSymbolMarker, actualDeclaration: DeclarationSymbolMarker,
context: ExpectActualMatchingContext<T>, context: ExpectActualMatchingContext<T>,
languageVersionSettings: LanguageVersionSettings,
) { ) {
with(context) { with(context) {
checkSingleExpectAgainstMatchedActual( checkSingleExpectAgainstMatchedActual(
@@ -78,6 +84,7 @@ object AbstractExpectActualChecker {
expectClassSymbol = null, expectClassSymbol = null,
actualClassSymbol = null, actualClassSymbol = null,
incompatibleMembers = null, incompatibleMembers = null,
languageVersionSettings,
) )
} }
} }
@@ -88,6 +95,7 @@ object AbstractExpectActualChecker {
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassLikeSymbol: ClassLikeSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker,
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility<*> { ): ExpectActualCheckingCompatibility<*> {
// Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name // 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) { require(expectClassSymbol.name == actualClassLikeSymbol.name) {
@@ -142,7 +150,7 @@ object AbstractExpectActualChecker {
return ExpectActualCheckingCompatibility.Supertypes return ExpectActualCheckingCompatibility.Supertypes
} }
getClassScopesIncompatibility(expectClassSymbol, actualClass, substitutor)?.let { return it } getClassScopesIncompatibility(expectClassSymbol, actualClass, substitutor, languageVersionSettings)?.let { return it }
return ExpectActualCheckingCompatibility.Compatible return ExpectActualCheckingCompatibility.Compatible
} }
@@ -198,6 +206,7 @@ object AbstractExpectActualChecker {
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility.Incompatible<*>? { ): ExpectActualCheckingCompatibility.Incompatible<*>? {
val mismatchedMembers = val mismatchedMembers =
arrayListOf<Pair<DeclarationSymbolMarker, Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker?>>>>() arrayListOf<Pair<DeclarationSymbolMarker, Map<ExpectActualMatchingCompatibility.Mismatch, List<DeclarationSymbolMarker?>>>>()
@@ -228,6 +237,7 @@ object AbstractExpectActualChecker {
expectClassSymbol, expectClassSymbol,
actualClassSymbol, actualClassSymbol,
incompatibleMembers, incompatibleMembers,
languageVersionSettings,
) )
} }
} }
@@ -255,6 +265,7 @@ object AbstractExpectActualChecker {
expectClassSymbol: RegularClassSymbolMarker?, expectClassSymbol: RegularClassSymbolMarker?,
actualClassSymbol: RegularClassSymbolMarker?, actualClassSymbol: RegularClassSymbolMarker?,
incompatibleMembers: MutableList<Pair<DeclarationSymbolMarker, Map<ExpectActualCheckingCompatibility.Incompatible<*>, List<DeclarationSymbolMarker?>>>>?, incompatibleMembers: MutableList<Pair<DeclarationSymbolMarker, Map<ExpectActualCheckingCompatibility.Incompatible<*>, List<DeclarationSymbolMarker?>>>>?,
languageVersionSettings: LanguageVersionSettings,
) { ) {
val compatibility = when (expectMember) { val compatibility = when (expectMember) {
is CallableSymbolMarker -> getCallablesCompatibility( is CallableSymbolMarker -> getCallablesCompatibility(
@@ -262,7 +273,8 @@ object AbstractExpectActualChecker {
actualMember as CallableSymbolMarker, actualMember as CallableSymbolMarker,
substitutor, substitutor,
expectClassSymbol, expectClassSymbol,
actualClassSymbol actualClassSymbol,
languageVersionSettings,
) )
is RegularClassSymbolMarker -> { is RegularClassSymbolMarker -> {
@@ -271,6 +283,7 @@ object AbstractExpectActualChecker {
expectMember, expectMember,
actualMember as ClassLikeSymbolMarker, actualMember as ClassLikeSymbolMarker,
parentSubstitutor, parentSubstitutor,
languageVersionSettings,
) )
} }
else -> error("Unsupported declaration: $expectMember ($actualMember)") else -> error("Unsupported declaration: $expectMember ($actualMember)")
@@ -293,6 +306,7 @@ object AbstractExpectActualChecker {
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
expectContainingClass: RegularClassSymbolMarker?, expectContainingClass: RegularClassSymbolMarker?,
actualContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility<*> { ): ExpectActualCheckingCompatibility<*> {
checkCallablesInvariants(expectDeclaration, actualDeclaration) checkCallablesInvariants(expectDeclaration, actualDeclaration)
@@ -343,7 +357,13 @@ object AbstractExpectActualChecker {
return ExpectActualCheckingCompatibility.Modality return ExpectActualCheckingCompatibility.Modality
} }
if (!areCompatibleCallableVisibilities(expectDeclaration.visibility, expectModality, actualDeclaration.visibility)) { if (!areCompatibleCallableVisibilities(
expectDeclaration.visibility,
expectModality,
actualDeclaration.visibility,
languageVersionSettings
)
) {
return ExpectActualCheckingCompatibility.Visibility return ExpectActualCheckingCompatibility.Visibility
} }
@@ -384,7 +404,7 @@ object AbstractExpectActualChecker {
getFunctionsIncompatibility(expectDeclaration, actualDeclaration)?.let { return it } getFunctionsIncompatibility(expectDeclaration, actualDeclaration)?.let { return it }
expectDeclaration is PropertySymbolMarker && actualDeclaration is PropertySymbolMarker -> expectDeclaration is PropertySymbolMarker && actualDeclaration is PropertySymbolMarker ->
getPropertiesIncompatibility(expectDeclaration, actualDeclaration)?.let { return it } getPropertiesIncompatibility(expectDeclaration, actualDeclaration, languageVersionSettings)?.let { return it }
expectDeclaration is EnumEntrySymbolMarker && actualDeclaration is EnumEntrySymbolMarker -> { expectDeclaration is EnumEntrySymbolMarker && actualDeclaration is EnumEntrySymbolMarker -> {
// do nothing, entries are matched only by name // do nothing, entries are matched only by name
@@ -446,6 +466,7 @@ object AbstractExpectActualChecker {
expectVisibility: Visibility, expectVisibility: Visibility,
expectModality: Modality?, expectModality: Modality?,
actualVisibility: Visibility, actualVisibility: Visibility,
languageVersionSettings: LanguageVersionSettings,
): Boolean { ): Boolean {
val compare = Visibilities.compare(expectVisibility, actualVisibility) val compare = Visibilities.compare(expectVisibility, actualVisibility)
return if (expectModality != Modality.FINAL) { return if (expectModality != Modality.FINAL) {
@@ -515,12 +536,13 @@ object AbstractExpectActualChecker {
private fun getPropertiesIncompatibility( private fun getPropertiesIncompatibility(
expected: PropertySymbolMarker, expected: PropertySymbolMarker,
actual: PropertySymbolMarker, actual: PropertySymbolMarker,
languageVersionSettings: LanguageVersionSettings,
): ExpectActualCheckingCompatibility.Incompatible<*>? { ): 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) -> !arePropertySettersWithCompatibleVisibilities(expected, actual, languageVersionSettings) ->
ExpectActualCheckingCompatibility.PropertySetterVisibility ExpectActualCheckingCompatibility.PropertySetterVisibility
else -> null else -> null
} }
@@ -530,6 +552,7 @@ object AbstractExpectActualChecker {
private fun arePropertySettersWithCompatibleVisibilities( private fun arePropertySettersWithCompatibleVisibilities(
expected: PropertySymbolMarker, expected: PropertySymbolMarker,
actual: PropertySymbolMarker, actual: PropertySymbolMarker,
languageVersionSettings: LanguageVersionSettings,
): 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
@@ -537,6 +560,7 @@ object AbstractExpectActualChecker {
expectedSetter.visibility, expectedSetter.visibility,
expectedSetter.modality, expectedSetter.modality,
actualSetter.visibility, actualSetter.visibility,
languageVersionSettings
) )
} }