[FE 1.0] Deprecate declaration of expect and actual in the same module
^KT-40904 Fixed ^KT-55177 Fixed
This commit is contained in:
committed by
Space Team
parent
71a80c5e36
commit
b09561c3c3
+6
@@ -21228,6 +21228,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectAndActualInSameModule.kt")
|
||||
public void testExpectAndActualInSameModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectAndActualInSameModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectDataObject.kt")
|
||||
public void testExpectDataObject() throws Exception {
|
||||
|
||||
+6
@@ -21234,6 +21234,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectAndActualInSameModule.kt")
|
||||
public void testExpectAndActualInSameModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectAndActualInSameModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectDataObject.kt")
|
||||
public void testExpectDataObject() throws Exception {
|
||||
|
||||
+6
@@ -21228,6 +21228,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectAndActualInSameModule.kt")
|
||||
public void testExpectAndActualInSameModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectAndActualInSameModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectDataObject.kt")
|
||||
public void testExpectDataObject() throws Exception {
|
||||
|
||||
@@ -805,6 +805,8 @@ public interface Errors {
|
||||
DiagnosticFactory2.create(ERROR, ACTUAL_DECLARATION_NAME);
|
||||
DiagnosticFactory0<KtNamedDeclaration> ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, ACTUAL_DECLARATION_NAME);
|
||||
|
||||
DiagnosticFactory0<KtNamedDeclaration> EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE = DiagnosticFactory0.create(WARNING, DECLARATION_NAME);
|
||||
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+1
@@ -339,6 +339,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, "Actual class ''{0}'' has no corresponding members for expected class members:{1}",
|
||||
NAME, adaptGenerics2(IncompatibleExpectedActualClassScopesRenderer.TEXT));
|
||||
MAP.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'");
|
||||
MAP.put(EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, "Expect and corresponding actual are declared in the same module, which will be prohibited in Kotlin 2.0. See https://youtrack.jetbrains.com/issue/KT-55177");
|
||||
|
||||
MAP.put(OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
|
||||
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
|
||||
|
||||
+23
-4
@@ -181,27 +181,46 @@ class ExpectedActualDeclarationChecker(
|
||||
}
|
||||
|
||||
// Here we have exactly one compatible actual and/or some weakly incompatible. In either case, we don't report anything on expect...
|
||||
val actualMembers = actuals.asSequence()
|
||||
.filter { it.key.isCompatibleOrWeakCompatible() }.flatMap { it.value.asSequence() }
|
||||
val actualMembers = actuals.filter { it.key.isCompatibleOrWeakCompatible() }.flatMap { it.value }
|
||||
|
||||
// ...except diagnostics regarding missing actual keyword, because in that case we won't start looking for the actual at all
|
||||
if (checkActualModifier) {
|
||||
actualMembers.forEach { reportMissingActualModifier(it, reportOn = null, trace) }
|
||||
}
|
||||
|
||||
reportExpectAndActualInTheSameModule(reportOn, actualMembers, trace)
|
||||
|
||||
expectActualTracker.reportExpectActual(expected = expectDescriptor, actualMembers = actualMembers)
|
||||
}
|
||||
|
||||
private fun reportMissingActualModifier(actual: MemberDescriptor, reportOn: KtNamedDeclaration?, trace: BindingTrace) {
|
||||
if (actual.isActual) return
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val reportOn = reportOn ?: (actual.source as? KotlinSourceElement)?.psi as? KtNamedDeclaration ?: return
|
||||
val reportOn = reportOn ?: actual.declarationSource ?: return
|
||||
|
||||
if (requireActualModifier(actual)) {
|
||||
trace.report(Errors.ACTUAL_MISSING.on(reportOn))
|
||||
}
|
||||
}
|
||||
|
||||
private val MemberDescriptor.declarationSource: KtNamedDeclaration?
|
||||
get() = (this.source as? KotlinSourceElement)?.psi as? KtNamedDeclaration
|
||||
|
||||
private fun reportExpectAndActualInTheSameModule(
|
||||
expectSource: KtNamedDeclaration,
|
||||
actualMembers: List<MemberDescriptor>,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
if (expectSource.containingKtFile.isCommonSource == true) return
|
||||
val actualMembersWithModifier = actualMembers.filter { it.isActual }
|
||||
if (actualMembersWithModifier.isEmpty()) return
|
||||
trace.report(Errors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE.on(expectSource))
|
||||
for (actual in actualMembersWithModifier) {
|
||||
val actualSource = actual.declarationSource ?: continue
|
||||
trace.report(Errors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE.on(actualSource))
|
||||
}
|
||||
}
|
||||
|
||||
private fun MemberDescriptor.hasNoActualWithDiagnostic(
|
||||
compatibility: Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>
|
||||
): Boolean {
|
||||
@@ -211,7 +230,7 @@ class ExpectedActualDeclarationChecker(
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
|
||||
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: List<MemberDescriptor>) {
|
||||
if (this is ExpectActualTracker.DoNothing) return
|
||||
|
||||
val expectedFile = sourceFile(expected) ?: return
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test
|
||||
|
||||
@Suppress("INLINE_CLASS_DEPRECATED", "EXPERIMENTAL_FEATURE_WARNING")
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test
|
||||
|
||||
@kotlin.jvm.JvmInline
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// SKIP_TXT
|
||||
// Issue: KT-49714
|
||||
|
||||
expect class Counter {
|
||||
operator fun inc(): Counter
|
||||
operator fun dec(): Counter
|
||||
}
|
||||
|
||||
actual typealias Counter = Int
|
||||
@@ -1,11 +1,10 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +MultiPlatformProjects
|
||||
// SKIP_TXT
|
||||
// Issue: KT-49714
|
||||
|
||||
expect class Counter {
|
||||
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class Counter<!> {
|
||||
operator fun inc(): Counter
|
||||
operator fun dec(): Counter
|
||||
}
|
||||
|
||||
actual typealias Counter = Int
|
||||
actual typealias <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>Counter<!> = Int
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// ISSUE: KT-40904, KT-55177
|
||||
|
||||
expect class Foo {
|
||||
fun memberFun()
|
||||
val memberProp: Int
|
||||
}
|
||||
actual class Foo {
|
||||
<!ACTUAL_WITHOUT_EXPECT!>actual fun memberFun() {}<!>
|
||||
<!ACTUAL_WITHOUT_EXPECT!>actual val memberProp: Int = 10<!>
|
||||
}
|
||||
|
||||
expect fun foo()
|
||||
<!ACTUAL_WITHOUT_EXPECT!>actual fun foo() {}<!>
|
||||
|
||||
expect val x: String
|
||||
<!ACTUAL_WITHOUT_EXPECT!>actual val x: String
|
||||
get() = "hello"<!>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// ISSUE: KT-40904, KT-55177
|
||||
|
||||
expect <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class Foo<!> {
|
||||
fun memberFun()
|
||||
val memberProp: Int
|
||||
}
|
||||
actual <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>class Foo<!> {
|
||||
actual fun memberFun() {}
|
||||
actual val memberProp: Int = 10
|
||||
}
|
||||
|
||||
expect fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>foo<!>()
|
||||
actual fun <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>foo<!>() {}
|
||||
|
||||
expect val <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>x<!>: String
|
||||
actual val <!EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE!>x<!>: String
|
||||
get() = "hello"
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package
|
||||
|
||||
public actual val x: kotlin.String
|
||||
public actual fun foo(): kotlin.Unit
|
||||
|
||||
public final actual class Foo {
|
||||
public constructor Foo()
|
||||
public actual final val memberProp: kotlin.Int = 10
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final actual fun memberFun(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
Generated
+6
@@ -21234,6 +21234,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectAndActualInSameModule.kt")
|
||||
public void testExpectAndActualInSameModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multiplatform/expectAndActualInSameModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectDataObject.kt")
|
||||
public void testExpectDataObject() throws Exception {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test.collections.js
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test
|
||||
|
||||
@@ -33,4 +34,4 @@ public expect object BackReferenceHandling {
|
||||
val nonExistentGroup: HandlingOption
|
||||
val nonExistentNamedGroup: HandlingOption
|
||||
val groupZero: HandlingOption
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test.collections.js
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
|
||||
|
||||
package test
|
||||
|
||||
@@ -38,4 +39,4 @@ public actual object BackReferenceHandling {
|
||||
actual val nonExistentGroup: HandlingOption = HandlingOption.MATCH_NOTHING
|
||||
actual val nonExistentNamedGroup: HandlingOption = HandlingOption.THROW
|
||||
actual val groupZero: HandlingOption = HandlingOption.THROW
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user