From 883102c4c68d1b73216c6ebebed0b288f0fa7978 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Wed, 5 Jul 2023 14:24:51 +0200 Subject: [PATCH] [FIR] Always run expect actual matching for actual annotation/inline class primary constructor Previously, we didn't run it when the primary constructor itself didn't have the actual modifier even though the modifier is optional. #KT-60120 Fixed --- ...PPDiagnosticsWithLightTreeTestGenerated.java | 6 ++++++ ...ntendMPPDiagnosticsWithPsiTestGenerated.java | 6 ++++++ .../mpp/FirExpectActualMatcherTransformer.kt | 17 ++++++++++++++--- ...otationAndInlineClassWithDefaultValue.fir.kt | 17 +++++++++++++++++ ...tAnnotationAndInlineClassWithDefaultValue.kt | 17 +++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.fir.kt create mode 100644 compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java index 2b66b475c74..b2c7a185f36 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated.java @@ -250,6 +250,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt"); } + @Test + @TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt") + public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt"); + } + @Test @TestMetadata("expectedDeclaresDefaultArguments.kt") public void testExpectedDeclaresDefaultArguments() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java index 8c2a5393ae3..0e5b572d170 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendMPPDiagnosticsWithPsiTestGenerated.java @@ -250,6 +250,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt"); } + @Test + @TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt") + public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt"); + } + @Test @TestMetadata("expectedDeclaresDefaultArguments.kt") public void testExpectedDeclaresDefaultArguments() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt index 6af0b78aa6a..f47f6a1e25f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualMatcherTransformer.kt @@ -6,19 +6,23 @@ package org.jetbrains.kotlin.fir.resolve.transformers.mpp import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.utils.isActual +import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractTreeTransformer import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor import org.jetbrains.kotlin.fir.visitors.FirTransformer class FirExpectActualMatcherProcessor( session: FirSession, - scopeSession: ScopeSession + scopeSession: ScopeSession, ) : FirTransformerBasedResolveProcessor(session, scopeSession, FirResolvePhase.EXPECT_ACTUAL_MATCHING) { private val enabled = session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) @@ -32,7 +36,7 @@ class FirExpectActualMatcherProcessor( open class FirExpectActualMatcherTransformer( override val session: FirSession, - private val scopeSession: ScopeSession + private val scopeSession: ScopeSession, ) : FirAbstractTreeTransformer(FirResolvePhase.EXPECT_ACTUAL_MATCHING) { // --------------------------- classifiers --------------------------- @@ -76,7 +80,7 @@ open class FirExpectActualMatcherTransformer( // ------------------------------------------------------ fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) { - if (!memberDeclaration.isActual) return + if (!memberDeclaration.isActual && !memberDeclaration.isImplicitlyActual()) return val actualSymbol = memberDeclaration.symbol // Regardless of whether any `expect` symbols are found for `memberDeclaration`, it must be assigned an `expectForActual` map. @@ -89,4 +93,11 @@ open class FirExpectActualMatcherTransformer( ) ?: mapOf() memberDeclaration.expectForActual = expectForActualData } + + // TODO KT-60139 Remove special handling when implicitly actual elements have the actual flag set. + private fun FirMemberDeclaration.isImplicitlyActual(): Boolean { + if (this !is FirPrimaryConstructor) return false + val klass = getContainingClass(session) ?: return false + return klass.isActual && (klass.isInline || klass.classKind == ClassKind.ANNOTATION_CLASS) + } } diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.fir.kt new file mode 100644 index 00000000000..23c20974e06 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.fir.kt @@ -0,0 +1,17 @@ +// WITH_STDLIB + +// MODULE: m1-common +// FILE: common.kt +expect annotation class Measurement(val iterations: Int = -1) +expect value class Inline(val value: String = "") + + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +actual annotation class Measurement(actual val iterations: Int) +@JvmInline actual value class Inline(val value: String) + +@Measurement() +fun test() { + Inline() // KT-60476 Fixed in K2 +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt new file mode 100644 index 00000000000..5cfa0922061 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt @@ -0,0 +1,17 @@ +// WITH_STDLIB + +// MODULE: m1-common +// FILE: common.kt +expect annotation class Measurement(val iterations: Int = -1) +expect value class Inline(val value: String = "") + + +// MODULE: m2-jvm()()(m1-common) +// FILE: jvm.kt +actual annotation class Measurement(actual val iterations: Int) +@JvmInline actual value class Inline(val value: String) + +@Measurement() +fun test() { + Inline() // KT-60476 Fixed in K2 +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 5f227d5b478..42175e8ec51 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -22777,6 +22777,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/constructorDefaultArgsViaActualTypealias.kt"); } + @Test + @TestMetadata("expectAnnotationAndInlineClassWithDefaultValue.kt") + public void testExpectAnnotationAndInlineClassWithDefaultValue() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/defaultArguments/expectAnnotationAndInlineClassWithDefaultValue.kt"); + } + @Test @TestMetadata("expectedDeclaresDefaultArguments.kt") public void testExpectedDeclaresDefaultArguments() throws Exception {