[FIR, IR] Convert FirDefaultArgumentsInExpectActualizedByFakeOverrideChecker into ExpectActualCheckingCompatibility
FirDefaultArgumentsInExpectActualizedByFakeOverrideChecker is an adhoc checker which can be converted to ExpectActualCheckingCompatibility to reuse common expect-actual checking infrastructure. ^KT-62913 Fixed Review: https://jetbrains.team/p/kt/reviews/13094/timeline Tests that were broken by one of my previous commits are now fixed: - actualFakeOverride_paramsAreCompatibleViaSharedMethodWithDefaultParams.kt - inheritedJavaMembers.kt DEFAULT_ARGUMENTS_IN_EXPECT_ACTUALIZED_BY_FAKE_OVERRIDE diagnostic disappeared in delegation.fir.kt because only one AbstractExpectActualChecker incompatibility can be reported at a time (DEFAULT_ARGUMENTS_IN_EXPECT_ACTUALIZED_BY_FAKE_OVERRIDE is now reported not by adhoc checker but by common AbstractExpectActualChecker). It would be nice to report both of them, but it's a separate issue KT-62631 delegation2 test makes sure that DEFAULT_ARGUMENTS_IN_EXPECT_ACTUALIZED_BY_FAKE_OVERRIDE is reported when NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS is fixed
This commit is contained in:
+25
-13
@@ -369,19 +369,31 @@ object AbstractExpectActualChecker {
|
||||
|
||||
getTypeParametersVarianceOrReifiedIncompatibility(expectedTypeParameters, actualTypeParameters)?.let { return it }
|
||||
|
||||
if (shouldCheckAbsenceOfDefaultParamsInActual) {
|
||||
// "Default parameters in actual" check is required only for functions, because only functions can have parameters
|
||||
if (actualDeclaration is FunctionSymbolMarker && expectDeclaration is FunctionSymbolMarker) {
|
||||
// Actual annotation constructors can have default argument values; their consistency with arguments in the expected annotation
|
||||
// is checked in ExpectedActualDeclarationChecker.checkAnnotationConstructors
|
||||
if (!actualDeclaration.isAnnotationConstructor() &&
|
||||
// If default params came from common supertypes of actual class and expect class then it's a valid code.
|
||||
// Here we filter out such default params.
|
||||
(actualDeclaration.allOverriddenDeclarationsRecursive() - expectDeclaration.allOverriddenDeclarationsRecursive().toSet())
|
||||
.flatMap { it.valueParameters }.any { it.hasDefaultValue }
|
||||
) {
|
||||
return ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters
|
||||
}
|
||||
if (shouldCheckDefaultParams &&
|
||||
// "parameters" checks are required only for functions, because only functions can have parameters
|
||||
actualDeclaration is FunctionSymbolMarker && expectDeclaration is FunctionSymbolMarker
|
||||
) {
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitDefaultArgumentsInExpectActualizedByFakeOverride) &&
|
||||
(actualDeclaration.isFakeOverride(actualContainingClass) || actualDeclaration.isDelegatedMember) &&
|
||||
// If default params came from common supertypes of actual class and expect class then it's a valid code.
|
||||
// Here we filter out such default params.
|
||||
(expectDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf() -
|
||||
actualDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf().toSet())
|
||||
.flatMap { it.valueParameters }.any { it.hasDefaultValueNonRecursive }
|
||||
) {
|
||||
return ExpectActualCheckingCompatibility.DefaultArgumentsInExpectActualizedByFakeOverride
|
||||
}
|
||||
|
||||
// Actual annotation constructors can have default argument values; their consistency with arguments in the expected annotation
|
||||
// is checked in ExpectedActualDeclarationChecker.checkAnnotationConstructors
|
||||
if (!actualDeclaration.isAnnotationConstructor() &&
|
||||
// If default params came from common supertypes of actual class and expect class then it's a valid code.
|
||||
// Here we filter out such default params.
|
||||
(actualDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf() -
|
||||
expectDeclaration.allRecursivelyOverriddenDeclarationsIncludingSelf().toSet())
|
||||
.flatMap { it.valueParameters }.any { it.hasDefaultValue }
|
||||
) {
|
||||
return ExpectActualCheckingCompatibility.ActualFunctionWithDefaultParameters
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-30
@@ -74,36 +74,6 @@ object AbstractExpectActualMatcher {
|
||||
ExpectActualMatchingCompatibility.MatchedSuccessfully
|
||||
}
|
||||
|
||||
fun recursivelyMatchClassScopes( // todo drop KT-62913
|
||||
expectClassSymbol: RegularClassSymbolMarker,
|
||||
actualClassSymbol: RegularClassSymbolMarker,
|
||||
context: ExpectActualMatchingContext<*>,
|
||||
): Unit = with(context) {
|
||||
val expectTypeParameterSymbols = expectClassSymbol.typeParameters
|
||||
val actualTypeParameterSymbols = actualClassSymbol.typeParameters
|
||||
val substitutor = createExpectActualTypeParameterSubstitutor(
|
||||
(expectTypeParameterSymbols zipIfSizesAreEqual actualTypeParameterSymbols) ?: return,
|
||||
parentSubstitutor = null,
|
||||
)
|
||||
|
||||
val actualMembersByName = actualClassSymbol.collectAllMembers(isActualDeclaration = true).groupBy { it.name }
|
||||
|
||||
outer@ for (expectMember in expectClassSymbol.collectAllMembers(isActualDeclaration = false)) {
|
||||
val actualMembers = getPossibleActualsByExpectName(expectMember, actualMembersByName)
|
||||
|
||||
matchSingleExpectAgainstPotentialActuals(
|
||||
expectMember,
|
||||
actualMembers,
|
||||
substitutor,
|
||||
expectClassSymbol,
|
||||
actualClassSymbol,
|
||||
mismatchedMembers = null,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: check static scope?
|
||||
}
|
||||
|
||||
/**
|
||||
* Besides returning the matched declaration
|
||||
*
|
||||
|
||||
+6
-3
@@ -40,7 +40,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
// Known clients that do suppress:
|
||||
// - stdlib
|
||||
// - coroutines
|
||||
val shouldCheckAbsenceOfDefaultParamsInActual: Boolean
|
||||
val shouldCheckDefaultParams: Boolean
|
||||
|
||||
/**
|
||||
* This flag determines, how visibilities for classes/typealiases will be matched
|
||||
@@ -123,9 +123,9 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
val FunctionSymbolMarker.valueParameters: List<ValueParameterSymbolMarker>
|
||||
|
||||
/**
|
||||
* Returns all symbols that are overridden by [this] symbol
|
||||
* Returns all symbols that are overridden by [this] symbol, including self
|
||||
*/
|
||||
fun FunctionSymbolMarker.allOverriddenDeclarationsRecursive(): Sequence<CallableSymbolMarker>
|
||||
fun FunctionSymbolMarker.allRecursivelyOverriddenDeclarationsIncludingSelf(): Sequence<CallableSymbolMarker>
|
||||
|
||||
val CallableSymbolMarker.valueParameters: List<ValueParameterSymbolMarker>
|
||||
get() = (this as? FunctionSymbolMarker)?.valueParameters ?: emptyList()
|
||||
@@ -134,6 +134,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
val ValueParameterSymbolMarker.isNoinline: Boolean
|
||||
val ValueParameterSymbolMarker.isCrossinline: Boolean
|
||||
val ValueParameterSymbolMarker.hasDefaultValue: Boolean
|
||||
val ValueParameterSymbolMarker.hasDefaultValueNonRecursive: Boolean
|
||||
|
||||
fun CallableSymbolMarker.isAnnotationConstructor(): Boolean
|
||||
|
||||
@@ -158,6 +159,8 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
|
||||
|
||||
fun CallableSymbolMarker.isFakeOverride(containingExpectClass: RegularClassSymbolMarker?): Boolean
|
||||
|
||||
val CallableSymbolMarker.isDelegatedMember: Boolean
|
||||
|
||||
val CallableSymbolMarker.hasStableParameterNames: Boolean
|
||||
|
||||
fun onMatchedMembers(
|
||||
|
||||
Reference in New Issue
Block a user