[FIR] Properly reports about conflicts in MPP setup
Checker for conflicting declarations will now check for the following scenarios too - two expect declarations in different modules - actual and non-expect declarations in different modules ^KT-63826 Fixed
This commit is contained in:
committed by
Space Team
parent
2febc807a1
commit
6cfe81de50
+6
@@ -25332,6 +25332,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("platformRedeclarationOfExpect.kt")
|
||||
public void testPlatformRedeclarationOfExpect() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/platformRedeclarationOfExpect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateTopLevelDeclarations.kt")
|
||||
public void testPrivateTopLevelDeclarations() {
|
||||
|
||||
+6
@@ -25332,6 +25332,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("platformRedeclarationOfExpect.kt")
|
||||
public void testPlatformRedeclarationOfExpect() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/platformRedeclarationOfExpect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateTopLevelDeclarations.kt")
|
||||
public void testPrivateTopLevelDeclarations() {
|
||||
|
||||
+6
@@ -349,6 +349,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("platformRedeclarationOfExpect.kt")
|
||||
public void testPlatformRedeclarationOfExpect() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/platformRedeclarationOfExpect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateTopLevelDeclarations.kt")
|
||||
public void testPrivateTopLevelDeclarations() {
|
||||
|
||||
+6
@@ -349,6 +349,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("platformRedeclarationOfExpect.kt")
|
||||
public void testPlatformRedeclarationOfExpect() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/platformRedeclarationOfExpect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateTopLevelDeclarations.kt")
|
||||
public void testPrivateTopLevelDeclarations() {
|
||||
|
||||
+23
-8
@@ -92,10 +92,19 @@ private val FirBasedSymbol<*>.resolvedStatus
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun isExpectAndActual(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)
|
||||
internal fun isExpectAndNonExpect(first: FirBasedSymbol<*>, second: FirBasedSymbol<*>): Boolean {
|
||||
val firstIsExpect = first.resolvedStatus?.isExpect == true
|
||||
val secondIsExpect = second.resolvedStatus?.isExpect == true
|
||||
/*
|
||||
* this `xor` is equivalent to the following check:
|
||||
* when {
|
||||
* !firstIsExpect && secondIsExpect -> true
|
||||
* firstIsExpect && !secondIsExpect -> true
|
||||
* else -> false
|
||||
* }
|
||||
*/
|
||||
|
||||
return firstIsExpect xor secondIsExpect
|
||||
}
|
||||
|
||||
private class DeclarationBuckets {
|
||||
@@ -438,9 +447,15 @@ private fun FirClassLikeSymbol<*>.expandedClassWithConstructorsScope(context: Ch
|
||||
}
|
||||
}
|
||||
|
||||
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 shouldCheckForMultiplatformRedeclaration(dependency: FirBasedSymbol<*>, dependent: FirBasedSymbol<*>): Boolean {
|
||||
if (dependency.moduleData !in dependent.moduleData.allDependsOnDependencies) return false
|
||||
|
||||
/*
|
||||
* If one of declarations is expect and the other is not expect, ExpectActualChecker will handle this case
|
||||
* All other cases (both are expect or both are not expect) should be reported as declarations conflict
|
||||
*/
|
||||
return !isExpectAndNonExpect(dependency, dependent)
|
||||
}
|
||||
|
||||
private fun FirDeclarationCollector<FirBasedSymbol<*>>.collectTopLevelConflict(
|
||||
declaration: FirBasedSymbol<*>,
|
||||
@@ -503,7 +518,7 @@ private fun FirDeclarationCollector<*>.areNonConflictingCallables(
|
||||
declaration: FirBasedSymbol<*>,
|
||||
conflicting: FirBasedSymbol<*>,
|
||||
): Boolean {
|
||||
if (isExpectAndActual(declaration, conflicting) && declaration.moduleData != conflicting.moduleData) return true
|
||||
if (isExpectAndNonExpect(declaration, conflicting) && declaration.moduleData != conflicting.moduleData) return true
|
||||
|
||||
val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations)
|
||||
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
@@ -123,7 +122,7 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKin
|
||||
conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor }
|
||||
) return@forEach
|
||||
|
||||
if (symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true) {
|
||||
if (symbols.singleOrNull()?.let { isExpectAndNonExpect(conflictingDeclaration, it) } == true) {
|
||||
reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
|
||||
return@forEach
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// MODULE: m1-common
|
||||
// FILE: common.kt
|
||||
expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>()
|
||||
<!CONFLICTING_OVERLOADS!>expect fun main()<!>
|
||||
|
||||
// FILE: common2.kt
|
||||
<!CONFLICTING_OVERLOADS!>actual fun <!ACTUAL_WITHOUT_EXPECT!>main<!>()<!> {}
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// MODULE: common
|
||||
// FILE: common.kt
|
||||
expect class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Foo<!>
|
||||
|
||||
// MODULE: main()()(common)
|
||||
// FILE: test.kt
|
||||
expect class Foo
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// MODULE: common
|
||||
// FILE: common.kt
|
||||
expect class <!NO_ACTUAL_FOR_EXPECT, NO_ACTUAL_FOR_EXPECT{JVM}, PACKAGE_OR_CLASSIFIER_REDECLARATION{JVM}!>Foo<!>
|
||||
|
||||
// MODULE: main()()(common)
|
||||
// FILE: test.kt
|
||||
expect class <!NO_ACTUAL_FOR_EXPECT, PACKAGE_OR_CLASSIFIER_REDECLARATION!>Foo<!>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// MODULE: common
|
||||
// FILE: common.kt
|
||||
expect class Foo
|
||||
|
||||
// MODULE: main()()(common)
|
||||
// FILE: test.kt
|
||||
expect class Foo
|
||||
Generated
+6
@@ -25332,6 +25332,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/optionalExpectationDiagnostics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("platformRedeclarationOfExpect.kt")
|
||||
public void testPlatformRedeclarationOfExpect() {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/platformRedeclarationOfExpect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateTopLevelDeclarations.kt")
|
||||
public void testPrivateTopLevelDeclarations() {
|
||||
|
||||
Reference in New Issue
Block a user