@@ -10,23 +10,39 @@ import org.jetbrains.kotlin.diagnostics.reportOn
1010import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
1111import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
1212import org.jetbrains.kotlin.fir.analysis.checkers.explicitReceiverIsNotSuperReference
13+ import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
14+ import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
1315import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
1416import org.jetbrains.kotlin.fir.declarations.getSingleMatchedExpectForActualOrNull
17+ import org.jetbrains.kotlin.fir.declarations.utils.isOverride
1518import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
1619import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
1720import org.jetbrains.kotlin.fir.references.toResolvedNamedFunctionSymbol
21+ import org.jetbrains.kotlin.fir.scopes.anyOverriddenOf
22+ import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
23+ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
1824import org.jetbrains.kotlin.fir.unwrapFakeOverridesOrDelegated
1925
2026object FirSuperCallWithDefaultsChecker : FirFunctionCallChecker(MppCheckerKind .Common ) {
2127 override fun check (expression : FirFunctionCall , context : CheckerContext , reporter : DiagnosticReporter ) {
2228 if (expression.explicitReceiverIsNotSuperReference()) return
2329
24- val functionSymbol = expression.calleeReference.toResolvedNamedFunctionSymbol() ? : return
25- val relevantFunctionSymbol = functionSymbol.unwrapFakeOverridesOrDelegated()
26- .let { it.getSingleMatchedExpectForActualOrNull() ? : it }
27- if (! relevantFunctionSymbol.valueParameterSymbols.any { it.hasDefaultValue }) return
30+ val functionSymbol = expression.calleeReference.toResolvedNamedFunctionSymbol()
31+ ?.unwrapFakeOverridesOrDelegated()
32+ ?.let { it.getSingleMatchedExpectForActualOrNull() ? : it } as ? FirNamedFunctionSymbol
33+ ? : return
34+ val containingClass = functionSymbol
35+ .getContainingClassSymbol() as ? FirClassSymbol <* >
36+ ? : return
37+
38+ fun FirNamedFunctionSymbol.hasDefaultValues (): Boolean =
39+ ! isOverride && valueParameterSymbols.any { it.hasDefaultValue }
40+
41+ val isCallWithDefaultValues = functionSymbol.hasDefaultValues()
42+ || containingClass.anyOverriddenOf(functionSymbol, context) { it.hasDefaultValues() }
2843 val arguments = expression.argumentList as ? FirResolvedArgumentList ? : return
29- if (arguments.arguments.size < functionSymbol.valueParameterSymbols.size) {
44+
45+ if (isCallWithDefaultValues && arguments.arguments.size < functionSymbol.valueParameterSymbols.size) {
3046 reporter.reportOn(
3147 expression.calleeReference.source,
3248 FirErrors .SUPER_CALL_WITH_DEFAULT_PARAMETERS ,
@@ -35,4 +51,16 @@ object FirSuperCallWithDefaultsChecker : FirFunctionCallChecker(MppCheckerKind.C
3551 )
3652 }
3753 }
54+
55+ private fun FirClassSymbol <* >.anyOverriddenOf (
56+ functionSymbol : FirNamedFunctionSymbol ,
57+ context : CheckerContext ,
58+ predicate : (FirNamedFunctionSymbol ) -> Boolean
59+ ): Boolean {
60+ val containingScope = unsubstitutedScope(context)
61+ // Without it, `LLReversedDiagnosticsFe10TestGenerated.testSuperCallsWithDefaultArguments` fails
62+ // because the maps in the scope are empty.
63+ containingScope.processFunctionsByName(functionSymbol.name) { }
64+ return containingScope.anyOverriddenOf(functionSymbol, predicate)
65+ }
3866}
0 commit comments