redeclaration
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");