[FIR] KT-55570 Fix ACTUAL_WITHOUT_EXPECT reporting for empty classes

- FirExpectActualMatcherTransformer: Instead of returning,
  `transformMemberDeclaration` must assign an empty map to
  `expectForActualData` so that `FirExpectActualDeclarationChecker`
  doesn't assume that the member declaration needs no expect-actual
  checking.

^KT-55570 fixed
This commit is contained in:
Marco Pennekamp
2022-12-19 23:21:26 +01:00
committed by teamcity
parent 7c96124a38
commit 2faa247075
13 changed files with 163 additions and 15 deletions
@@ -21827,6 +21827,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
}
@Test
@TestMetadata("intermediateWithActualAndExpect.kt")
public void testIntermediateWithActualAndExpect() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateWithActualAndExpect.kt");
}
@Test
@TestMetadata("kt-55570.kt")
public void testKt_55570() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/kt-55570.kt");
}
@Test
@TestMetadata("sealedInheritorsInComplexModuleStructure.kt")
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
@@ -21833,6 +21833,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
}
@Test
@TestMetadata("intermediateWithActualAndExpect.kt")
public void testIntermediateWithActualAndExpect() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateWithActualAndExpect.kt");
}
@Test
@TestMetadata("kt-55570.kt")
public void testKt_55570() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/kt-55570.kt");
}
@Test
@TestMetadata("sealedInheritorsInComplexModuleStructure.kt")
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
@@ -21827,6 +21827,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
}
@Test
@TestMetadata("intermediateWithActualAndExpect.kt")
public void testIntermediateWithActualAndExpect() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateWithActualAndExpect.kt");
}
@Test
@TestMetadata("kt-55570.kt")
public void testKt_55570() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/kt-55570.kt");
}
@Test
@TestMetadata("sealedInheritorsInComplexModuleStructure.kt")
public void testSealedInheritorsInComplexModuleStructure() throws Exception {
@@ -79,11 +79,15 @@ open class FirExpectActualMatcherTransformer(
private fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) {
if (!memberDeclaration.isActual) return
val actualSymbol = memberDeclaration.symbol
// Regardless of whether any `expect` symbols are found for `memberDeclaration`, it must be assigned an `expectForActual` map.
// Otherwise, `FirExpectActualDeclarationChecker` will assume that the symbol needs no checking and not report an
// `EXPECT_WITHOUT_ACTUAL` error.
val expectForActualData = FirExpectActualResolver.findExpectForActual(
actualSymbol,
session,
scopeSession
) ?: return
) ?: mapOf()
memberDeclaration.expectForActual = expectForActualData
for ((compatibility, expectSymbols) in expectForActualData) {
if (compatibility.compatible) {
@@ -0,0 +1,15 @@
// FIR_IDENTICAL
// MODULE: common
// TARGET_PLATFORM: Common
expect class A
expect class B
// MODULE: intermediate()()(common)
// TARGET_PLATFORM: Common
actual class B
expect class C
// MODULE: main()()(intermediate)
actual class A
actual class C
@@ -0,0 +1,66 @@
// -- Module: <common> --
package
public final expect class A {
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final expect class B {
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// -- Module: <intermediate> --
package
public final expect class A {
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final actual class B {
public constructor B()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final expect class B {
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final expect class C {
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// -- Module: <main> --
package
public final actual class A {
public constructor A()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final actual class B {
public constructor B()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final actual class C {
public constructor C()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,5 @@
// MODULE: common
// TARGET_PLATFORM: Common
// MODULE: main()()(common)
<!ACTUAL_WITHOUT_EXPECT!>actual class A<!>
@@ -0,0 +1,5 @@
// MODULE: common
// TARGET_PLATFORM: Common
// MODULE: main()()(common)
actual class <!ACTUAL_WITHOUT_EXPECT!>A<!>
@@ -0,0 +1,13 @@
// -- Module: <common> --
package
// -- Module: <main> --
package
public final actual class A {
public constructor A()
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,13 +1,5 @@
// FIR_IDENTICAL
// FIR_IDE_IGNORE
/*
* This test is used for general testing of how compiler diagnostics tests for HMPP projects works
* Js backend is ignored because they use old test infrastructure which doesn't support HMPP
*/
// IGNORE_BACKEND_K2: JVM_IR
// TARGET_BACKEND: JVM
// MODULE: common
// TARGET_PLATFORM: Common
@@ -1,12 +1,12 @@
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>impl<!> class First
<!ACTUAL_WITHOUT_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>impl<!> class First<!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Second
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Third
<!ACTUAL_WITHOUT_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Third<!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Fourth
<!ACTUAL_WITHOUT_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Fourth<!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Fifth
<!ACTUAL_WITHOUT_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Fifth<!>
<!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Sixth
<!ACTUAL_WITHOUT_EXPECT!><!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Sixth<!>
@@ -22,7 +22,7 @@ fun foo() {
// FILE: jvm.kt
class Outer <!ACTUAL_WITHOUT_EXPECT!>actual constructor()<!> {
actual class Nested
<!ACTUAL_WITHOUT_EXPECT!>actual class Nested<!>
<!WRONG_MODIFIER_TARGET!>actual<!> init {}
}
@@ -21833,6 +21833,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform/hmpp"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(fir|ll)\\.kts?$"), true);
}
@Test
@TestMetadata("intermediateWithActualAndExpect.kt")
public void testIntermediateWithActualAndExpect() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/intermediateWithActualAndExpect.kt");
}
@Test
@TestMetadata("kt-55570.kt")
public void testKt_55570() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/hmpp/kt-55570.kt");
}
@Test
@TestMetadata("sealedInheritorsInComplexModuleStructure.kt")
public void testSealedInheritorsInComplexModuleStructure() throws Exception {