[K2, MPP] Fix NO_ACTUAL_FOR_EXPECT reporting for all modules including the platform ones

^KT-58483 Fixed
This commit is contained in:
Ivan Kochurkin
2023-06-13 16:46:07 +02:00
committed by Space Team
parent 4f92008f01
commit f4a648aa3e
25 changed files with 141 additions and 61 deletions
@@ -25,6 +25,12 @@ public class FirOldFrontendMPPDiagnosticsWithLightTreeTestGenerated extends Abst
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("checkNoActualForExpectInLastModule.kt")
public void testCheckNoActualForExpectInLastModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/checkNoActualForExpectInLastModule.kt");
}
@Test @Test
@TestMetadata("expectAbstractToString.kt") @TestMetadata("expectAbstractToString.kt")
public void testExpectAbstractToString() throws Exception { public void testExpectAbstractToString() throws Exception {
@@ -25,6 +25,12 @@ public class FirOldFrontendMPPDiagnosticsWithPsiTestGenerated extends AbstractFi
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("checkNoActualForExpectInLastModule.kt")
public void testCheckNoActualForExpectInLastModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/checkNoActualForExpectInLastModule.kt");
}
@Test @Test
@TestMetadata("expectAbstractToString.kt") @TestMetadata("expectAbstractToString.kt")
public void testExpectAbstractToString() throws Exception { public void testExpectAbstractToString() throws Exception {
@@ -62,6 +62,10 @@ internal class ExpectActualCollector(
) { ) {
val linkCollector = ExpectActualLinkCollector(destination, classActualizationInfo, typeSystemContext, diagnosticsReporter) val linkCollector = ExpectActualLinkCollector(destination, classActualizationInfo, typeSystemContext, diagnosticsReporter)
dependentFragments.forEach { linkCollector.visitModuleFragment(it) } dependentFragments.forEach { linkCollector.visitModuleFragment(it) }
// It doesn't make sense to link expects from the last module because actuals always should be located in another module
// Thus relevant actuals are always missing for the last module
// But the collector should be run anyway to detect and report "hanging" expect declarations
linkCollector.visitModuleFragment(mainFragment)
} }
} }
@@ -77,6 +81,8 @@ internal data class ClassActualizationInfo(
} }
} }
private class ActualDeclarationsCollector { private class ActualDeclarationsCollector {
companion object { companion object {
fun collectActualsFromFragments(fragments: List<IrModuleFragment>): ClassActualizationInfo { fun collectActualsFromFragments(fragments: List<IrModuleFragment>): ClassActualizationInfo {
@@ -0,0 +1,4 @@
// ISSUE: KT-58483
// MODULE: jvm
// FILE: jvm.kt
<!NO_ACTUAL_FOR_EXPECT!>expect class A<!>
@@ -0,0 +1,4 @@
// ISSUE: KT-58483
// MODULE: jvm
// FILE: jvm.kt
expect class <!NO_ACTUAL_FOR_EXPECT!>A<!>
@@ -1,14 +1,14 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect enum class En(x: Int) { <!NO_ACTUAL_FOR_EXPECT!>expect enum class En(x: Int) {
E1, E1,
E2(42), E2(42),
; ;
constructor(s: String) constructor(s: String)
} }<!>
expect enum class En2 { <!NO_ACTUAL_FOR_EXPECT!>expect enum class En2 {
E1() E1()
} }<!>
@@ -1,10 +1,10 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect enum class En { <!NO_ACTUAL_FOR_EXPECT!>expect enum class En {
E1, E1,
E2 { E2 {
<!EXPECTED_DECLARATION_WITH_BODY!>fun foo()<!> = "" <!EXPECTED_DECLARATION_WITH_BODY!>fun foo()<!> = ""
}, },
E3 { }; E3 { };
} }<!>
@@ -0,0 +1,22 @@
// MODULE: m1-common
// FILE: common.kt
interface Foo {
fun foo()
}
<!NO_ACTUAL_FOR_EXPECT!>expect class NonAbstractClass : Foo {
<!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> fun bar()
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val baz: Int
<!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> override fun foo()
}<!>
<!NO_ACTUAL_FOR_EXPECT!>expect abstract class AbstractClass : Foo {
abstract fun bar()
abstract val baz: Int
abstract override fun foo()
}<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -1,13 +1,13 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect open class A { <!NO_ACTUAL_FOR_EXPECT!>expect open class A {
constructor(s: String) constructor(s: String)
constructor(n: Number) : this("A") constructor(n: Number) : this("A")
} }<!>
expect class B : A { <!NO_ACTUAL_FOR_EXPECT!>expect class B : A {
constructor(i: Int) constructor(i: Int)
constructor() : super("B") constructor() : super("B")
} }<!>
@@ -1,10 +1,10 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect abstract class BaseA() { <!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseA() {
abstract fun foo() abstract fun foo()
} }<!>
expect open class BaseAImpl() : BaseA <!NO_ACTUAL_FOR_EXPECT!>expect open class BaseAImpl() : BaseA<!>
class DerivedA1 : BaseAImpl() class DerivedA1 : BaseAImpl()
class DerivedA2 : BaseAImpl() { class DerivedA2 : BaseAImpl() {
@@ -13,10 +13,10 @@ class DerivedA2 : BaseAImpl() {
expect interface BaseB { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseB {
fun foo() fun foo()
} }<!>
expect open class BaseBImpl() : BaseB <!NO_ACTUAL_FOR_EXPECT!>expect open class BaseBImpl() : BaseB<!>
class DerivedB1 : BaseBImpl() class DerivedB1 : BaseBImpl()
class DerivedB2 : BaseBImpl() { class DerivedB2 : BaseBImpl() {
@@ -25,10 +25,10 @@ class DerivedB2 : BaseBImpl() {
expect interface BaseC { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseC {
fun foo() fun foo()
} }<!>
expect abstract class BaseCImpl() : BaseC <!NO_ACTUAL_FOR_EXPECT!>expect abstract class BaseCImpl() : BaseC<!>
class DerivedC1 : BaseCImpl() class DerivedC1 : BaseCImpl()
class DerivedC2 : BaseCImpl() { class DerivedC2 : BaseCImpl() {
@@ -37,25 +37,25 @@ class DerivedC2 : BaseCImpl() {
expect interface BaseD { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseD {
fun foo() fun foo()
} }<!>
abstract class BaseDImpl() : BaseD { abstract class BaseDImpl() : BaseD {
fun bar() = super.<!ABSTRACT_SUPER_CALL!>foo<!>() fun bar() = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
} }
expect interface BaseE { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseE {
fun foo() fun foo()
} }<!>
sealed class BaseEImpl() : BaseE { sealed class BaseEImpl() : BaseE {
fun bar() = super.<!ABSTRACT_SUPER_CALL!>foo<!>() fun bar() = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
} }
expect interface BaseF { <!NO_ACTUAL_FOR_EXPECT!>expect interface BaseF {
fun foo() fun foo()
} }<!>
expect class BaseFImpl() : BaseF <!NO_ACTUAL_FOR_EXPECT!>expect class BaseFImpl() : BaseF<!>
@@ -1,7 +1,7 @@
// IGNORE_REVERSED_RESOLVE // IGNORE_REVERSED_RESOLVE
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect class Foo( <!NO_ACTUAL_FOR_EXPECT!>expect class Foo(
val constructorProperty: String, val constructorProperty: String,
constructorParameter: String constructorParameter: String
) { ) {
@@ -24,4 +24,4 @@ expect class Foo(
<!EXPECTED_DECLARATION_WITH_BODY!>fun functionWithBody(x: Int): Int<!> { <!EXPECTED_DECLARATION_WITH_BODY!>fun functionWithBody(x: Int): Int<!> {
return x + 1 return x + 1
} }
} }<!>
@@ -4,6 +4,6 @@
interface A interface A
class B : A class B : A
expect class Foo(b: B) : A by b <!NO_ACTUAL_FOR_EXPECT!>expect class Foo(b: B) : A by b<!>
expect class Bar : A by B() <!NO_ACTUAL_FOR_EXPECT!>expect class Bar : A by B()<!>
@@ -1,7 +1,7 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect class Foo { <!NO_ACTUAL_FOR_EXPECT!>expect class Foo {
val justVal: String val justVal: String
var justVar: String var justVar: String
@@ -25,6 +25,6 @@ expect class Foo {
<!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String <!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String
val delegated: String by <!EXPECTED_DELEGATED_PROPERTY!>Delegate<!> val delegated: String by <!EXPECTED_DELEGATED_PROPERTY!>Delegate<!>
} }<!>
object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" } object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" }
@@ -0,0 +1,12 @@
// MODULE: m1-common
// FILE: common.kt
<!NO_ACTUAL_FOR_EXPECT!>expect class Foo { // also, it's important that Foo doesn't override equals
fun foo()
}<!>
fun check(x1: Foo, x: Any) {
if (x1 == x) {
x.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -1,12 +1,12 @@
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>impl<!> class <!ACTUAL_WITHOUT_EXPECT!>First<!> <!NO_ACTUAL_FOR_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>impl<!> class <!ACTUAL_WITHOUT_EXPECT!>First<!><!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Second <!NO_ACTUAL_FOR_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Second<!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Third<!> <!NO_ACTUAL_FOR_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Third<!><!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class <!ACTUAL_WITHOUT_EXPECT!>Fourth<!> <!NO_ACTUAL_FOR_EXPECT!><!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class <!ACTUAL_WITHOUT_EXPECT!>Fourth<!><!>
<!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Fifth<!> <!DEPRECATED_MODIFIER, INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Fifth<!>
<!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Sixth<!> <!NO_ACTUAL_FOR_EXPECT!><!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class <!ACTUAL_WITHOUT_EXPECT!>Sixth<!><!>
@@ -0,0 +1,7 @@
// MODULE: m1-common
// FILE: common.kt
<!CONFLICTING_OVERLOADS, NO_ACTUAL_FOR_EXPECT!>expect fun foo()<!>
<!CONFLICTING_OVERLOADS, NO_ACTUAL_FOR_EXPECT!>expect fun foo()<!>
<!NO_ACTUAL_FOR_EXPECT!>expect fun foo(x: Int)<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -0,0 +1,8 @@
// MODULE: m1-common
// FILE: common.kt
<!CONFLICTING_OVERLOADS, NO_ACTUAL_FOR_EXPECT!>expect fun foo()<!>
<!NO_ACTUAL_FOR_EXPECT!><!CONFLICTING_OVERLOADS, EXPECTED_DECLARATION_WITH_BODY!>expect fun foo()<!> {}<!>
<!NO_ACTUAL_FOR_EXPECT!><!EXPECTED_DECLARATION_WITH_BODY!>expect fun bar()<!> {}<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -0,0 +1,4 @@
// MODULE: m1-common
// FILE: common.kt
<!NO_ACTUAL_FOR_EXPECT!>expect fun foo()<!>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
@@ -2,35 +2,35 @@
// MODULE: m1-common // MODULE: m1-common
// FILE: common.kt // FILE: common.kt
expect val justVal: String <!NO_ACTUAL_FOR_EXPECT!>expect val justVal: String<!>
expect var justVar: String <!NO_ACTUAL_FOR_EXPECT!>expect var justVar: String<!>
expect val String.extensionVal: Unit <!NO_ACTUAL_FOR_EXPECT!>expect val String.extensionVal: Unit<!>
expect var <T> T.genericExtensionVar: T <!NO_ACTUAL_FOR_EXPECT!>expect var <T> T.genericExtensionVar: T<!>
expect val valWithGet: String <!NO_ACTUAL_FOR_EXPECT!>expect val valWithGet: String
get get<!>
expect var varWithGetSet: String <!NO_ACTUAL_FOR_EXPECT!>expect var varWithGetSet: String
get set get set<!>
expect var varWithPlatformGetSet: String <!NO_ACTUAL_FOR_EXPECT!>expect var varWithPlatformGetSet: String
<!WRONG_MODIFIER_TARGET!>expect<!> get <!WRONG_MODIFIER_TARGET!>expect<!> get
<!WRONG_MODIFIER_TARGET!>expect<!> set <!WRONG_MODIFIER_TARGET!>expect<!> set<!>
expect val backingFieldVal: String = <!EXPECTED_PROPERTY_INITIALIZER!>"no"<!> <!NO_ACTUAL_FOR_EXPECT!>expect val backingFieldVal: String = <!EXPECTED_PROPERTY_INITIALIZER!>"no"<!><!>
expect var backingFieldVar: String = <!EXPECTED_PROPERTY_INITIALIZER!>"no"<!> <!NO_ACTUAL_FOR_EXPECT!>expect var backingFieldVar: String = <!EXPECTED_PROPERTY_INITIALIZER!>"no"<!><!>
expect val customAccessorVal: String <!NO_ACTUAL_FOR_EXPECT!>expect val customAccessorVal: String
get() = "no"<!>
<!NO_ACTUAL_FOR_EXPECT!>expect var customAccessorVar: String
get() = "no" get() = "no"
expect var customAccessorVar: String set(value) {}<!>
get() = "no"
set(value) {}
expect <!CONST_VAL_WITHOUT_INITIALIZER!>const<!> val constVal: Int <!NO_ACTUAL_FOR_EXPECT!>expect <!CONST_VAL_WITHOUT_INITIALIZER!>const<!> val constVal: Int<!>
expect <!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String <!NO_ACTUAL_FOR_EXPECT!>expect <!EXPECTED_LATEINIT_PROPERTY!>lateinit<!> var lateinitVar: String<!>
expect val delegated: String by <!EXPECTED_DELEGATED_PROPERTY!>Delegate<!> <!NO_ACTUAL_FOR_EXPECT!>expect val delegated: String by <!EXPECTED_DELEGATED_PROPERTY!>Delegate<!><!>
object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" } object Delegate { operator fun getValue(x: Any?, y: Any?): String = "" }
fun test(): String { fun test(): String {
@@ -22534,6 +22534,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multiplatform"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true);
} }
@Test
@TestMetadata("checkNoActualForExpectInLastModule.kt")
public void testCheckNoActualForExpectInLastModule() throws Exception {
runTest("compiler/testData/diagnostics/tests/multiplatform/checkNoActualForExpectInLastModule.kt");
}
@Test @Test
@TestMetadata("expectAbstractToString.kt") @TestMetadata("expectAbstractToString.kt")
public void testExpectAbstractToString() throws Exception { public void testExpectAbstractToString() throws Exception {