From c418a7a7bf0ce11e8569cf95dc52e826c27f419a Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sat, 11 Feb 2023 22:10:02 +0100 Subject: [PATCH] [FIR] Support of ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS diagnostic ^KT-56522 Fixed --- .../FirActualDeclarationChecker.kt | 75 +++++++++++-------- .../defaultArguments/constructor.fir.kt | 22 ------ .../defaultArguments/constructor.kt | 1 + .../expectedDeclaresDefaultArguments.fir.kt | 40 ---------- .../expectedDeclaresDefaultArguments.kt | 1 + .../expectedInheritsDefaultArguments.fir.kt | 6 +- .../expectedInheritsDefaultArguments.kt | 2 +- 7 files changed, 51 insertions(+), 96 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt index 4b2a2640455..5e365fa4f3d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirActualDeclarationChecker.kt @@ -22,38 +22,53 @@ object FirActualDeclarationChecker : FirBasicDeclarationChecker() { if (declaration !is FirMemberDeclaration || !declaration.isActual) return if (declaration is FirCallableDeclaration) { - val actualFunctionSymbol = declaration.symbol - val expectFunctionSymbol = actualFunctionSymbol.getSingleCompatibleExpectForActualOrNull() as? FirCallableSymbol ?: return + if (declaration is FirFunction) { + checkActualFunctionWithDefaultArguments(declaration, reporter, context) + } + checkReturnTypes(declaration, context, reporter) + } + } - val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session) - ?.typeParameterSymbols.orEmpty() - val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty() - val parentSubstitutor = - createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session) - - val substitutor = createExpectActualTypeParameterSubstitutor( - expectFunctionSymbol.typeParameterSymbols, - actualFunctionSymbol.typeParameterSymbols, - context.session, - parentSubstitutor - ) - - if (!areCompatibleExpectActualTypes( - substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type), - actualFunctionSymbol.resolvedReturnType.type, - expectFunctionSymbol.moduleData.session, - context.session - ) - ) { - @Suppress("UNCHECKED_CAST") - reporter.reportOn( - declaration.source, - FirErrors.ACTUAL_WITHOUT_EXPECT, - actualFunctionSymbol, - actualFunctionSymbol.expectForActual as Map>, Collection>>, - context - ) + private fun checkActualFunctionWithDefaultArguments(function: FirFunction, reporter: DiagnosticReporter, context: CheckerContext) { + for (valueParameter in function.valueParameters) { + if (valueParameter.defaultValue != null) { + reporter.reportOn(valueParameter.source, FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, context) } } } + + private fun checkReturnTypes(callableDeclaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + val actualFunctionSymbol = callableDeclaration.symbol + val expectFunctionSymbol = actualFunctionSymbol.getSingleCompatibleExpectForActualOrNull() as? FirCallableSymbol ?: return + + val expectTypeParameters = expectFunctionSymbol.getContainingClassSymbol(expectFunctionSymbol.moduleData.session) + ?.typeParameterSymbols.orEmpty() + val actualClassTypeParameters = actualFunctionSymbol.getContainingClassSymbol(context.session)?.typeParameterSymbols.orEmpty() + val parentSubstitutor = + createExpectActualTypeParameterSubstitutor(expectTypeParameters, actualClassTypeParameters, context.session) + + val substitutor = createExpectActualTypeParameterSubstitutor( + expectFunctionSymbol.typeParameterSymbols, + actualFunctionSymbol.typeParameterSymbols, + context.session, + parentSubstitutor + ) + + if (!areCompatibleExpectActualTypes( + substitutor.substituteOrSelf(expectFunctionSymbol.resolvedReturnType.type), + actualFunctionSymbol.resolvedReturnType.type, + expectFunctionSymbol.moduleData.session, + context.session + ) + ) { + @Suppress("UNCHECKED_CAST") + reporter.reportOn( + callableDeclaration.source, + FirErrors.ACTUAL_WITHOUT_EXPECT, + actualFunctionSymbol, + actualFunctionSymbol.expectForActual as Map>, Collection>>, + context + ) + } + } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.fir.kt deleted file mode 100644 index 6d59cac4299..00000000000 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// MODULE: m1-common -// FILE: common.kt - -expect class Ok(x: Int, y: String = "") - -expect class FailX(x: Int, y: String = "") - -expect class FailY(x: Int, y: String = "") - -fun test() { - Ok(42) - Ok(42, "OK") -} - -// MODULE: m2-jvm()()(m1-common) -// FILE: jvm.kt - -actual class Ok actual constructor(x: Int, y: String) - -actual class FailX actual constructor(x: Int = 0, y: String) - -actual class FailY actual constructor(x: Int, y: String = "") diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt index 256191aa96a..6e4b00c432e 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructor.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.fir.kt deleted file mode 100644 index 4d8310d3b80..00000000000 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.fir.kt +++ /dev/null @@ -1,40 +0,0 @@ -// MODULE: m1-common -// FILE: common.kt - -expect fun ok(x: Int, y: String = "") - -expect fun failX(x: Int, y: String = "") - -expect fun failY(x: Int, y: String = "") - -expect open class Foo { - fun ok(x: Int, y: String = "") - - fun failX(x: Int, y: String = "") - - fun failY(x: Int, y: String = "") -} - -fun test(foo: Foo) { - ok(42) - ok(42, "OK") - foo.ok(42) - foo.ok(42, "OK") -} - -// MODULE: m2-jvm()()(m1-common) -// FILE: jvm.kt - -actual fun ok(x: Int, y: String) {} - -actual fun failX(x: Int = 0, y: String) {} - -actual fun failY(x: Int, y: String = "") {} - -actual open class Foo { - actual fun ok(x: Int, y: String) {} - - actual fun failX(x: Int = 0, y: String) {} - - actual fun failY(x: Int, y: String = "") {} -} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt index 0f17b475376..2f0683cf3d4 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedDeclaresDefaultArguments.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // MODULE: m1-common // FILE: common.kt diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt index fdf60804e4f..2028994eaa1 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.fir.kt @@ -29,8 +29,8 @@ fun test(foo: Foo, bar: Bar) { actual class Bar : Foo { actual override fun ok(x: Int, y: String) {} - - actual override fun failX(x: Int = 0, y: String) {} - actual override fun failY(x: Int, y: String = "") {} + actual override fun failX(x: Int = 0, y: String) {} + + actual override fun failY(x: Int, y: String = "") {} } diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt index 83933c7e73b..2db6594a13d 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectedInheritsDefaultArguments.kt @@ -29,7 +29,7 @@ fun test(foo: Foo, bar: Bar) { actual class Bar : Foo { actual override fun ok(x: Int, y: String) {} - + actual override fun failX(x: Int = 0, y: String) {} actual override fun failY(x: Int, y: String = "") {}