[FIR] Implement EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE

^KT-60367 Fixed
KT review: https://jetbrains.team/p/kt/reviews/14064/timeline
IJ review: https://jetbrains.team/p/ij/reviews/124657/timeline
This commit is contained in:
Nikita Bobko
2024-01-17 19:36:28 +01:00
committed by teamcity
parent b317a88536
commit c214c5445a
25 changed files with 254 additions and 36 deletions
@@ -3042,6 +3042,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE) { firDiagnostic ->
ExpectAndActualInTheSameModuleImpl(
firSymbolBuilder.buildSymbol(firDiagnostic.a),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE) { firDiagnostic -> add(FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE) { firDiagnostic ->
MethodOfAnyImplementedInInterfaceImpl( MethodOfAnyImplementedInInterfaceImpl(
firDiagnostic as KtPsiDiagnostic, firDiagnostic as KtPsiDiagnostic,
@@ -2151,6 +2151,11 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
val conflictingDeclarations: List<KtSymbol> val conflictingDeclarations: List<KtSymbol>
} }
interface ExpectAndActualInTheSameModule : KtFirDiagnostic<KtNamedDeclaration> {
override val diagnosticClass get() = ExpectAndActualInTheSameModule::class
val declaration: KtSymbol
}
interface MethodOfAnyImplementedInInterface : KtFirDiagnostic<PsiElement> { interface MethodOfAnyImplementedInInterface : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = MethodOfAnyImplementedInInterface::class override val diagnosticClass get() = MethodOfAnyImplementedInInterface::class
} }
@@ -2577,6 +2577,12 @@ internal class PackageOrClassifierRedeclarationImpl(
token: KtLifetimeToken, token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.PackageOrClassifierRedeclaration ) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.PackageOrClassifierRedeclaration
internal class ExpectAndActualInTheSameModuleImpl(
override val declaration: KtSymbol,
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtNamedDeclaration>(firDiagnostic, token), KtFirDiagnostic.ExpectAndActualInTheSameModule
internal class MethodOfAnyImplementedInInterfaceImpl( internal class MethodOfAnyImplementedInInterfaceImpl(
firDiagnostic: KtPsiDiagnostic, firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken, token: KtLifetimeToken,
@@ -24854,6 +24854,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt"); runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt");
} }
@Test
@TestMetadata("expectActualInTheSameModule.kt")
public void testExpectActualInTheSameModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModule.kt");
}
@Test
@TestMetadata("expectActualInTheSameModuleDifferentFiles.kt")
public void testExpectActualInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModuleDifferentFiles.kt");
}
@Test
@TestMetadata("expectActualMainInTheSameModuleDifferentFiles.kt")
public void testExpectActualMainInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualMainInTheSameModuleDifferentFiles.kt");
}
@Test @Test
@TestMetadata("expectDataObject.kt") @TestMetadata("expectDataObject.kt")
public void testExpectDataObject() throws Exception { public void testExpectDataObject() throws Exception {
@@ -24854,6 +24854,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt"); runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt");
} }
@Test
@TestMetadata("expectActualInTheSameModule.kt")
public void testExpectActualInTheSameModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModule.kt");
}
@Test
@TestMetadata("expectActualInTheSameModuleDifferentFiles.kt")
public void testExpectActualInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModuleDifferentFiles.kt");
}
@Test
@TestMetadata("expectActualMainInTheSameModuleDifferentFiles.kt")
public void testExpectActualMainInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualMainInTheSameModuleDifferentFiles.kt");
}
@Test @Test
@TestMetadata("expectDataObject.kt") @TestMetadata("expectDataObject.kt")
public void testExpectDataObject() throws Exception { public void testExpectDataObject() throws Exception {
@@ -139,6 +139,24 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt"); runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt");
} }
@Test
@TestMetadata("expectActualInTheSameModule.kt")
public void testExpectActualInTheSameModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModule.kt");
}
@Test
@TestMetadata("expectActualInTheSameModuleDifferentFiles.kt")
public void testExpectActualInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModuleDifferentFiles.kt");
}
@Test
@TestMetadata("expectActualMainInTheSameModuleDifferentFiles.kt")
public void testExpectActualMainInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualMainInTheSameModuleDifferentFiles.kt");
}
@Test @Test
@TestMetadata("expectDataObject.kt") @TestMetadata("expectDataObject.kt")
public void testExpectDataObject() throws Exception { public void testExpectDataObject() throws Exception {
@@ -139,6 +139,24 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt"); runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt");
} }
@Test
@TestMetadata("expectActualInTheSameModule.kt")
public void testExpectActualInTheSameModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModule.kt");
}
@Test
@TestMetadata("expectActualInTheSameModuleDifferentFiles.kt")
public void testExpectActualInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModuleDifferentFiles.kt");
}
@Test
@TestMetadata("expectActualMainInTheSameModuleDifferentFiles.kt")
public void testExpectActualMainInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualMainInTheSameModuleDifferentFiles.kt");
}
@Test @Test
@TestMetadata("expectDataObject.kt") @TestMetadata("expectDataObject.kt")
public void testExpectDataObject() throws Exception { public void testExpectDataObject() throws Exception {
@@ -1079,6 +1079,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val PACKAGE_OR_CLASSIFIER_REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) { val PACKAGE_OR_CLASSIFIER_REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
parameter<Collection<Symbol>>("conflictingDeclarations") parameter<Collection<Symbol>>("conflictingDeclarations")
} }
val EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
parameter<Symbol>("declaration")
}
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>() val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>()
} }
@@ -552,6 +552,7 @@ object FirErrors {
val CONFLICTING_OVERLOADS: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) val CONFLICTING_OVERLOADS: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val REDECLARATION: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.NAME_IDENTIFIER) val REDECLARATION: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val PACKAGE_OR_CLASSIFIER_REDECLARATION: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME) val PACKAGE_OR_CLASSIFIER_REDECLARATION: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE: KtDiagnosticFactory1<FirBasedSymbol<*>> by error1<KtNamedDeclaration, FirBasedSymbol<*>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE: KtDiagnosticFactory0 by error0<PsiElement>() val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE: KtDiagnosticFactory0 by error0<PsiElement>()
// Invalid local declarations // Invalid local declarations
@@ -361,6 +361,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
"CONFLICTING_OVERLOADS", "CONFLICTING_OVERLOADS",
"REDECLARATION", "REDECLARATION",
"PACKAGE_OR_CLASSIFIER_REDECLARATION", "PACKAGE_OR_CLASSIFIER_REDECLARATION",
"EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE",
"METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE", "METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE",
"LOCAL_OBJECT_NOT_ALLOWED", "LOCAL_OBJECT_NOT_ALLOWED",
"LOCAL_INTERFACE_NOT_ALLOWED", "LOCAL_INTERFACE_NOT_ALLOWED",
@@ -93,7 +93,7 @@ private val FirBasedSymbol<*>.resolvedStatus
else -> null else -> null
} }
private fun isExpectAndActual(declaration1: FirBasedSymbol<*>, declaration2: FirBasedSymbol<*>): Boolean { internal fun isExpectAndActual(declaration1: FirBasedSymbol<*>, declaration2: FirBasedSymbol<*>): Boolean {
val status1 = declaration1.resolvedStatus ?: return false val status1 = declaration1.resolvedStatus ?: return false
val status2 = declaration2.resolvedStatus ?: return false val status2 = declaration2.resolvedStatus ?: return false
return (status1.isExpect && status2.isActual) || (status1.isActual && status2.isExpect) return (status1.isExpect && status2.isActual) || (status1.isActual && status2.isExpect)
@@ -496,7 +496,7 @@ private fun FirDeclarationCollector<*>.areNonConflictingCallables(
declaration: FirBasedSymbol<*>, declaration: FirBasedSymbol<*>,
conflicting: FirBasedSymbol<*>, conflicting: FirBasedSymbol<*>,
): Boolean { ): Boolean {
if (isExpectAndActual(declaration, conflicting)) return true if (isExpectAndActual(declaration, conflicting) && declaration.moduleData != conflicting.moduleData) return true
val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations) val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations)
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations) val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
@@ -90,19 +90,22 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKin
conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor } conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor }
) return@forEach ) return@forEach
val factory = when {
if (conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol) { symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true -> {
FirErrors.CONFLICTING_OVERLOADS reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
} else if (conflictingDeclaration is FirClassLikeSymbol<*> &&
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
} else {
FirErrors.REDECLARATION
} }
conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol -> {
reporter.reportOn(source, factory, symbols, context) reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
}
conflictingDeclaration is FirClassLikeSymbol<*> &&
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> } -> {
reporter.reportOn(source, FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION, symbols, context)
}
else -> {
reporter.reportOn(source, FirErrors.REDECLARATION, symbols, context)
}
}
} }
} }
@@ -501,6 +501,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PLATFORM_CLASS_MAPPED_TO_KOTLIN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PLATFORM_CLASS_MAPPED_TO_KOTLIN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPILER_REQUIRED_ANNOTATION_AMBIGUITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPILER_REQUIRED_ANNOTATION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.POTENTIALLY_NON_REPORTED_ANNOTATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.POTENTIALLY_NON_REPORTED_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRE_RELEASE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRE_RELEASE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
@@ -1800,6 +1801,8 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", SYMBOLS) map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", SYMBOLS)
map.put(REDECLARATION, "Conflicting declarations: {0}", SYMBOLS) map.put(REDECLARATION, "Conflicting declarations: {0}", SYMBOLS)
map.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", SYMBOLS) map.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", SYMBOLS)
map.put(EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, "{0}: expect and corresponding actual are declared in the same module", DECLARATION_NAME)
map.put(METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE, "Interfaces cannot implement a method of 'Any'.") map.put(METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE, "Interfaces cannot implement a method of 'Any'.")
// Invalid local declarations // Invalid local declarations
@@ -1,4 +1,10 @@
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-1.kt:1:21: error: base: expect and corresponding actual are declared in the same module
expect sealed class Base
^
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-2.kt:1:21: error: 'actual class Base : Any' has no corresponding expected declaration compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-2.kt:1:21: error: 'actual class Base : Any' has no corresponding expected declaration
actual sealed class Base
^
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-2.kt:1:21: error: base: expect and corresponding actual are declared in the same module
actual sealed class Base actual sealed class Base
^ ^
compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-3.kt:1:17: error: unresolved reference '<init>'. compiler/testData/cli/metadata/inheritorOfExpectSealedClass/common-3.kt:1:17: error: unresolved reference '<init>'.
@@ -0,0 +1,11 @@
// MODULE: m1-common
// FILE: common.kt
expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>A<!>
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>A<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>B<!>
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>B<!>
@@ -0,0 +1,11 @@
// MODULE: m1-common
// FILE: common.kt
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class A<!>
actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class A<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class B<!>
actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class B<!>
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect class A
// FILE: common2.kt
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>A<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>B<!>
// FILE: jvm2.kt
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>B<!>
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class A<!>
// FILE: common2.kt
actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class A<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class B<!>
// FILE: jvm2.kt
actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class B<!>
@@ -0,0 +1,15 @@
// MODULE: m1-common
// FILE: common.kt
expect class A
// FILE: common2.kt
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>A<!>
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect class B
// FILE: jvm2.kt
actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>B<!>
@@ -0,0 +1,13 @@
// MODULE: m1-common
// FILE: common.kt
expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>()
// FILE: common2.kt
actual fun <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>() {}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>()
// FILE: jvm2.kt
actual fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>() {}
@@ -0,0 +1,13 @@
// MODULE: m1-common
// FILE: common.kt
expect fun <!AMBIGUOUS_ACTUALS{JVM}, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>()
// FILE: common2.kt
actual fun <!AMBIGUOUS_EXPECTS{JVM}, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE{JVM}!>main<!>() {}
// MODULE: m1-jvm()()(m1-common)
// FILE: jvm.kt
expect fun <!AMBIGUOUS_ACTUALS, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>()
// FILE: jvm2.kt
actual fun <!AMBIGUOUS_EXPECTS, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>main<!>() {}
@@ -1,67 +1,67 @@
// MODULE: common // MODULE: common
// TARGET_PLATFORM: Common // TARGET_PLATFORM: Common
expect class CommonClass { expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>CommonClass<!> {
fun memberFun() fun memberFun()
val memberProp: Int val memberProp: Int
class Nested class Nested
inner class Inner inner class Inner
} }
actual class <!ACTUAL_WITHOUT_EXPECT!>CommonClass<!> { actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>CommonClass<!> {
actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {}
actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42 actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42
actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!> actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!>
actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!> actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!>
} }
expect fun commonFun() expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>commonFun<!>()
actual fun <!ACTUAL_WITHOUT_EXPECT!>commonFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>commonFun<!>() {}
expect val commonProperty: String expect val <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>commonProperty<!>: String
actual val <!ACTUAL_WITHOUT_EXPECT!>commonProperty<!>: String actual val <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>commonProperty<!>: String
get() = "hello" get() = "hello"
// MODULE: intermediate()()(common) // MODULE: intermediate()()(common)
// TARGET_PLATFORM: Common // TARGET_PLATFORM: Common
expect class IntermediateClass { expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>IntermediateClass<!> {
fun memberFun() fun memberFun()
val memberProp: Int val memberProp: Int
class Nested class Nested
inner class Inner inner class Inner
} }
actual class <!ACTUAL_WITHOUT_EXPECT!>IntermediateClass<!> { actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>IntermediateClass<!> {
actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {}
actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42 actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42
actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!> actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!>
actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!> actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!>
} }
expect fun intermediateFun() expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>intermediateFun<!>()
actual fun <!ACTUAL_WITHOUT_EXPECT!>intermediateFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>intermediateFun<!>() {}
expect val intermediateProperty: String expect val <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>intermediateProperty<!>: String
actual val <!ACTUAL_WITHOUT_EXPECT!>intermediateProperty<!>: String actual val <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>intermediateProperty<!>: String
get() = "hello" get() = "hello"
// MODULE: main()()(intermediate) // MODULE: main()()(intermediate)
expect class PlatformClass { expect class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>PlatformClass<!> {
fun memberFun() fun memberFun()
val memberProp: Int val memberProp: Int
class Nested class Nested
inner class Inner inner class Inner
} }
actual class <!ACTUAL_WITHOUT_EXPECT!>PlatformClass<!> { actual class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>PlatformClass<!> {
actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT!>memberFun<!>() {}
actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42 actual val <!ACTUAL_WITHOUT_EXPECT!>memberProp<!>: Int = 42
actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!> actual class <!ACTUAL_WITHOUT_EXPECT!>Nested<!>
actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!> actual inner class <!ACTUAL_WITHOUT_EXPECT!>Inner<!>
} }
expect fun platformFun() expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>platformFun<!>()
actual fun <!ACTUAL_WITHOUT_EXPECT!>platformFun<!>() {} actual fun <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>platformFun<!>() {}
expect val platformProperty: String expect val <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>platformProperty<!>: String
actual val <!ACTUAL_WITHOUT_EXPECT!>platformProperty<!>: String actual val <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>platformProperty<!>: String
get() = "hello" get() = "hello"
@@ -13,10 +13,10 @@ val callableKind: Int = 1
expect fun <T> typeParameterCount() expect fun <T> typeParameterCount()
fun typeParameterCount() {} fun typeParameterCount() {}
expect enum class EnumEntries { expect enum class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>EnumEntries<!> {
ONE, TWO; ONE, TWO;
} }
actual enum class <!ACTUAL_WITHOUT_EXPECT!>EnumEntries<!> { actual enum class <!ACTUAL_WITHOUT_EXPECT, EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>EnumEntries<!> {
ONE; ONE;
} }
@@ -1,6 +1,6 @@
<!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> fun foo1() <!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> fun foo1()
<!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> val bar1 = <!EXPECTED_PROPERTY_INITIALIZER!>42<!> <!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> val bar1 = <!EXPECTED_PROPERTY_INITIALIZER!>42<!>
<!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> class ImplicitExpect { <!NOT_A_MULTIPLATFORM_COMPILATION!>expect<!> class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>ImplicitExpect<!> {
fun foo() fun foo()
val x: Int val x: Int
class Inner class Inner
@@ -16,7 +16,7 @@
<!MUST_BE_INITIALIZED!><!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> val bar2: Int<!> <!MUST_BE_INITIALIZED!><!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> val bar2: Int<!>
<!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> interface Baz2 <!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> interface Baz2
<!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> class ImplicitExpect { <!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> class <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>ImplicitExpect<!> {
<!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> fun foo() { <!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> fun foo() {
} }
<!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> val x: Int = 0 <!NOT_A_MULTIPLATFORM_COMPILATION!>actual<!> val x: Int = 0
@@ -24854,6 +24854,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt"); runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualClassesAreInBeta_suppressWarningWithLv.kt");
} }
@Test
@TestMetadata("expectActualInTheSameModule.kt")
public void testExpectActualInTheSameModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModule.kt");
}
@Test
@TestMetadata("expectActualInTheSameModuleDifferentFiles.kt")
public void testExpectActualInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualInTheSameModuleDifferentFiles.kt");
}
@Test
@TestMetadata("expectActualMainInTheSameModuleDifferentFiles.kt")
public void testExpectActualMainInTheSameModuleDifferentFiles() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/expectActualMainInTheSameModuleDifferentFiles.kt");
}
@Test @Test
@TestMetadata("expectDataObject.kt") @TestMetadata("expectDataObject.kt")
public void testExpectDataObject() throws Exception { public void testExpectDataObject() throws Exception {