redeclaration Related tests: - MultiPlatformIntegrationTestGenerated.testSimpleNoImplKeywordOnTopLevelFunction - MultiPlatformIntegrationTestGenerated.testWeakIncompatibilityWithoutActualModifier - FirPsiJsKlibDiagnosticsTestGenerated.testSignatureClash_MPP - LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated$ResolveWithStdlib$MultiModule.testFakeOverrides - DiagnosticCompilerTestFE10TestdataTestGenerated$Tests$Multiplatform: - LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated$Tests$Multiplatform - FirOldFrontendMPPDiagnosticsWithPsiTestGenerated - FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated - FirLibraryModuleDeclarationResolveTestGenerated.testDataClass - org.jetbrains.kotlin.idea.k2.highlighting.K2HighlightingMetaInfoTestGenerated$Diagnostics.testDataClassFromLibrary - org.jetbrains.fir.uast.test.FirLightClassBehaviorTest.testContainingFile - org.jetbrains.fir.uast.test.FirLightClassBehaviorTest.testAnnotationParameterReference - org.jetbrains.uast.test.kotlin.org.jetbrains.uast.test.kotlin.comparison.FE1LightClassBehaviorTest.testContainingFile
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 8a019d9..7456ccb 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java
@@ -26600,6 +26600,18 @@ } @Test + @TestMetadata("hmppRedeclaration.kt") + public void testHmppRedeclaration() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt"); + } + + @Test + @TestMetadata("hmppRedeclarationWithExpectActualPair.kt") + public void testHmppRedeclarationWithExpectActualPair() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt"); + } + + @Test @TestMetadata("intermediateActualHasAdditionalSupertypes.kt") public void testIntermediateActualHasAdditionalSupertypes() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateActualHasAdditionalSupertypes.kt");
diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index a4a0d99..e04e665 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java
@@ -26600,6 +26600,18 @@ } @Test + @TestMetadata("hmppRedeclaration.kt") + public void testHmppRedeclaration() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt"); + } + + @Test + @TestMetadata("hmppRedeclarationWithExpectActualPair.kt") + public void testHmppRedeclarationWithExpectActualPair() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt"); + } + + @Test @TestMetadata("intermediateActualHasAdditionalSupertypes.kt") public void testIntermediateActualHasAdditionalSupertypes() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateActualHasAdditionalSupertypes.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 5cb4db0..74bbea1 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
@@ -1741,6 +1741,18 @@ } @Test + @TestMetadata("hmppRedeclaration.kt") + public void testHmppRedeclaration() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt"); + } + + @Test + @TestMetadata("hmppRedeclarationWithExpectActualPair.kt") + public void testHmppRedeclarationWithExpectActualPair() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt"); + } + + @Test @TestMetadata("intermediateActualHasAdditionalSupertypes.kt") public void testIntermediateActualHasAdditionalSupertypes() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateActualHasAdditionalSupertypes.kt");
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 39e06ab..024a55e 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
@@ -1741,6 +1741,18 @@ } @Test + @TestMetadata("hmppRedeclaration.kt") + public void testHmppRedeclaration() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt"); + } + + @Test + @TestMetadata("hmppRedeclarationWithExpectActualPair.kt") + public void testHmppRedeclarationWithExpectActualPair() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt"); + } + + @Test @TestMetadata("intermediateActualHasAdditionalSupertypes.kt") public void testIntermediateActualHasAdditionalSupertypes() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateActualHasAdditionalSupertypes.kt");
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt index 1f8db2a..6d42094 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isEffectivelyFinal import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION import org.jetbrains.kotlin.fir.declarations.impl.modifiersRepresentation @@ -93,12 +92,21 @@ else -> null } -internal fun isExpectAndActual(declaration1: FirBasedSymbol<*>, declaration2: FirBasedSymbol<*>): Boolean { +internal fun isExpectAndActualPair(declaration1: FirBasedSymbol<*>, declaration2: FirBasedSymbol<*>): Boolean { val status1 = declaration1.resolvedStatus ?: return false val status2 = declaration2.resolvedStatus ?: return false return (status1.isExpect && status2.isActual) || (status1.isActual && status2.isExpect) } +private fun FirBasedSymbol<*>.isExpectOrActual(): Boolean = + resolvedStatus?.let { it.isActual || it.isExpect } == true + +private val FirBasedSymbol<*>.isExpectSymbol: Boolean + get() = resolvedStatus?.isExpect == true + +private val FirBasedSymbol<*>.isActualSymbol: Boolean + get() = resolvedStatus?.isActual == true + private class DeclarationBuckets { val simpleFunctions = mutableListOf<Pair<FirNamedFunctionSymbol, String>>() val constructors = mutableListOf<Pair<FirConstructorSymbol, String>>() @@ -439,6 +447,10 @@ } } +private fun shouldCheckForMultiplatformRedeclaration(dependency: FirBasedSymbol<*>, dependent: FirBasedSymbol<*>): Boolean = + dependent.moduleData.allDependsOnDependencies.contains(dependency.moduleData) && + dependency.resolvedStatus?.isExpect != true // ACTUAL_MISSING takes care of this case + private fun FirDeclarationCollector<FirBasedSymbol<*>>.collectTopLevelConflict( declaration: FirBasedSymbol<*>, declarationPresentation: String, @@ -448,7 +460,11 @@ conflictingFile: FirFile? = null, ) { conflictingSymbol.lazyResolveToPhase(FirResolvePhase.STATUS) - if (conflictingSymbol == declaration || declaration.moduleData != conflictingSymbol.moduleData) return + if (conflictingSymbol == declaration) return + if ( + declaration.moduleData != conflictingSymbol.moduleData && + !shouldCheckForMultiplatformRedeclaration(declaration, conflictingSymbol) + ) return val actualConflictingPresentation = conflictingPresentation ?: FirRedeclarationPresenter.represent(conflictingSymbol) if (actualConflictingPresentation != declarationPresentation) return val actualConflictingFile = @@ -496,7 +512,7 @@ declaration: FirBasedSymbol<*>, conflicting: FirBasedSymbol<*>, ): Boolean { - if (isExpectAndActual(declaration, conflicting) && declaration.moduleData != conflicting.moduleData) return true + if (isExpectAndActualPair(declaration, conflicting) && declaration.moduleData != conflicting.moduleData) return true val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations) val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt index b7d2de6..1da336c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt
@@ -123,7 +123,7 @@ conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor } ) return@forEach - if (symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true) { + if (symbols.singleOrNull()?.let { isExpectAndActualPair(conflictingDeclaration, it) } == true) { reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context) return@forEach }
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.fir.kt new file mode 100644 index 0000000..7c4656c --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.fir.kt
@@ -0,0 +1,19 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +class A + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> + +// MODULE: main()()(common, intermediate) + +class B + +class C
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt new file mode 100644 index 0000000..5632adf --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt
@@ -0,0 +1,19 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION{COMMON}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>A<!> + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>C<!> + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>A<!> + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>B<!> + +// MODULE: main()()(common, intermediate) + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.ll.kt new file mode 100644 index 0000000..6a8158d --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.ll.kt
@@ -0,0 +1,19 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +class A + +class C + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +class A + +class B + +// MODULE: main()()(common, intermediate) + +class B + +class C
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.fir.kt new file mode 100644 index 0000000..1aa8d96 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.fir.kt
@@ -0,0 +1,25 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +expect class A + +expect class B + +class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +actual class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> + +class <!ACTUAL_MISSING, PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> + +expect class C + +// MODULE: main()()(common, intermediate) + +class A + +actual class <!ACTUAL_WITHOUT_EXPECT!>B<!> + +actual class C
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt new file mode 100644 index 0000000..e49df4e --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt
@@ -0,0 +1,25 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE{COMMON}!>class <!AMBIGUOUS_ACTUALS{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>A<!><!> + +expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE{COMMON}!>class <!AMBIGUOUS_ACTUALS{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>B<!><!> + +<!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE{COMMON}!>class <!ACTUAL_MISSING{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>C<!><!> + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class <!PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>A<!><!> + +<!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class <!ACTUAL_MISSING{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>B<!><!> + +expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class <!AMBIGUOUS_ACTUALS{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>C<!><!> + +// MODULE: main()()(common, intermediate) + +class <!ACTUAL_MISSING, PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> + +actual class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> + +actual class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
diff --git a/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.ll.kt new file mode 100644 index 0000000..366f844 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.ll.kt
@@ -0,0 +1,25 @@ +// MODULE: common +// TARGET_PLATFORM: Common + +expect class A + +expect class B + +class C + +// MODULE: intermediate()()(common) +// TARGET_PLATFORM: Common + +actual class A + +class <!ACTUAL_MISSING!>B<!> + +expect class C + +// MODULE: main()()(common, intermediate) + +class A + +actual class <!ACTUAL_WITHOUT_EXPECT!>B<!> + +actual class C
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 f6ed928..96dbf5a 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
@@ -26600,6 +26600,18 @@ } @Test + @TestMetadata("hmppRedeclaration.kt") + public void testHmppRedeclaration() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclaration.kt"); + } + + @Test + @TestMetadata("hmppRedeclarationWithExpectActualPair.kt") + public void testHmppRedeclarationWithExpectActualPair() throws Exception { + runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/hmppRedeclarationWithExpectActualPair.kt"); + } + + @Test @TestMetadata("intermediateActualHasAdditionalSupertypes.kt") public void testIntermediateActualHasAdditionalSupertypes() throws Exception { runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateActualHasAdditionalSupertypes.kt");