[FIR] Consider expect declarations in defaults arguments inheritance checker

Actual functions cannot declare default values for parameters
Corresponding expect function should be checked instead
This commit is contained in:
Dmitriy Novozhilov
2024-01-10 14:08:54 +02:00
committed by Nikolay Lunyak
parent 2982f548d4
commit e8f5e35a86
2 changed files with 14 additions and 6 deletions
@@ -11,11 +11,14 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
import org.jetbrains.kotlin.fir.analysis.checkers.collectOverriddenFunctionsWhere
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.processOverriddenFunctions
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.getSingleMatchedExpectForActualOrNull
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.isSubstitutionOverride
@@ -58,9 +61,14 @@ sealed class FirMultipleDefaultsInheritedFromSupertypesChecker(mppKind: MppCheck
context: CheckerContext,
reporter: DiagnosticReporter,
) {
val overriddenFunctions = function.collectOverriddenFunctionsWhere(mutableSetOf(), context) { overridden ->
val overriddenFunctions = mutableSetOf<FirNamedFunctionSymbol>()
function.processOverriddenFunctions(context) { overridden ->
// default values of actual functions are located in corresponding expect functions
val overriddenWithDefaults = overridden.getSingleMatchedExpectForActualOrNull() as? FirNamedFunctionSymbol ?: overridden
// Substitution overrides copy default values from originals
!overridden.isSubstitutionOverride && overridden.valueParameterSymbols.any { it.hasDefaultValue }
if (!overriddenWithDefaults.isSubstitutionOverride && overriddenWithDefaults.valueParameterSymbols.any { it.hasDefaultValue }) {
overriddenFunctions += overriddenWithDefaults
}
}
val isExplicitOverride = function.origin == FirDeclarationOrigin.Source
@@ -16,8 +16,8 @@ expect interface I2 {
override fun foo(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES!>x: Int<!>)
}
interface CommonInterface : I1, I2 {
override fun foo(x: Int)
<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE!>interface CommonInterface<!> : I1, I2 {
override fun foo(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES!>x: Int<!>)
}
// MODULE: m1-jvm()()(m1-common)
@@ -33,6 +33,6 @@ actual interface I2 {
actual fun bar(x: Int)
}
actual interface ExpectInterface : I1, I2 {
actual override fun foo(x: Int)
<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE!>actual interface ExpectInterface<!> : I1, I2 {
actual override fun foo(<!MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES!>x: Int<!>)
}