@@ -10,23 +10,39 @@ import org.jetbrains.kotlin.diagnostics.reportOn
10
10
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
11
11
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
12
12
import 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
13
15
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
14
16
import org.jetbrains.kotlin.fir.declarations.getSingleMatchedExpectForActualOrNull
17
+ import org.jetbrains.kotlin.fir.declarations.utils.isOverride
15
18
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
16
19
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
17
20
import 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
18
24
import org.jetbrains.kotlin.fir.unwrapFakeOverridesOrDelegated
19
25
20
26
object FirSuperCallWithDefaultsChecker : FirFunctionCallChecker(MppCheckerKind .Common ) {
21
27
override fun check (expression : FirFunctionCall , context : CheckerContext , reporter : DiagnosticReporter ) {
22
28
if (expression.explicitReceiverIsNotSuperReference()) return
23
29
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() }
28
43
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) {
30
46
reporter.reportOn(
31
47
expression.calleeReference.source,
32
48
FirErrors .SUPER_CALL_WITH_DEFAULT_PARAMETERS ,
@@ -35,4 +51,16 @@ object FirSuperCallWithDefaultsChecker : FirFunctionCallChecker(MppCheckerKind.C
35
51
)
36
52
}
37
53
}
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
+ }
38
66
}
0 commit comments