[KMP] Allow matching expect ctorless final classes to objects

both directly and via typealias.

This is a possible fix to KT-59747
This commit is contained in:
marat.akhin
2023-07-20 18:16:06 +02:00
committed by Space Team
parent 6df9ce23f7
commit ae4fab8483
30 changed files with 1273 additions and 1 deletions
@@ -0,0 +1,42 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K2: ANY
// FIR status: expect/actual in the same module
// also used as a workaround for no multi-module support in K1 box tests
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// FILE: actual.kt
actual object TestResult {
fun doTest(): TestResult = this
}
actual fun createTestResult(): TestResult = TestResult
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,48 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K2: ANY
// FIR status: expect/actual in the same module
// also used as a workaround for no multi-module support in K1 box tests
// TARGET_BACKEND: JS, JS_IR, JS_IR_ES6
// WITH_STDLIB
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// FILE: js.kt
import kotlin.js.Promise
class PromiseOfUnit(executor: (resolve: (Unit) -> Unit, reject: (Throwable) -> Unit) -> Unit) : Promise<Unit>(executor)
actual typealias TestResult = PromiseOfUnit
actual fun createTestResult(): TestResult = PromiseOfUnit {
resolve, reject ->
}
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,40 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K2: ANY
// FIR status: expect/actual in the same module
// also used as a workaround for no multi-module support in K1 box tests
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// FILE: actual.kt
actual typealias TestResult = Unit
actual fun createTestResult(): TestResult = TestResult
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,42 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K1: ANY
// MODULE: common
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// MODULE: actual()()(common)
// FILE: actual.kt
actual object TestResult {
fun doTest(): TestResult = this
}
actual fun createTestResult(): TestResult = TestResult
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,48 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K1: ANY
// TARGET_BACKEND: JS, JS_IR, JS_IR_ES6
// WITH_STDLIB
// MODULE: common
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// MODULE: js()()(common)
// FILE: js.kt
import kotlin.js.Promise
class PromiseOfUnit(executor: (resolve: (Unit) -> Unit, reject: (Throwable) -> Unit) -> Unit) : Promise<Unit>(executor)
actual typealias TestResult = PromiseOfUnit
actual fun createTestResult(): TestResult = PromiseOfUnit {
resolve, reject ->
}
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,40 @@
// LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND_K1: ANY
// MODULE: common
// FILE: common.kt
expect class TestResult
expect fun createTestResult(): TestResult
fun commonBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "c01"
if (tr.hashCode() != tr2.hashCode()) return "c02"
if (tr.toString() != tr2.toString()) return "c03"
return "O"
}
// MODULE: actual()()(common)
// FILE: actual.kt
actual typealias TestResult = Unit
actual fun createTestResult(): TestResult = TestResult
fun platformBox(): String {
val tr = createTestResult()
val tr2 = if (true) tr else createTestResult()
if (tr != tr2) return "p01"
if (tr.hashCode() != tr2.hashCode()) return "p02"
if (tr.toString() != tr2.toString()) return "p03"
return "K"
}
fun box() = commonBox() + platformBox()
@@ -0,0 +1,47 @@
// MODULE: m1-common
// FILE: common.kt
expect class E01
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E02()<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class E03<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E04 {
constructor()
}<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E05(e: E01)<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E06 {
constructor(e: E02)
}<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect interface I01<!>
expect class M01 {
fun foo()
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect enum class ENUM01<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect annotation class ANNO01<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual object E01
actual object <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E02<!>
actual object <!ACTUAL_WITHOUT_EXPECT!>E03<!>
actual object <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E04<!>
actual object <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E05<!>
actual object <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E06<!>
actual object <!ACTUAL_WITHOUT_EXPECT!>I01<!>
actual object M01 {
actual fun foo() {}
}
actual object <!ACTUAL_WITHOUT_EXPECT!>ENUM01<!>
actual object <!ACTUAL_WITHOUT_EXPECT!>ANNO01<!>
@@ -0,0 +1,47 @@
// MODULE: m1-common
// FILE: common.kt
expect class E01
expect class E02()
expect open class E03
expect class E04 {
constructor()
}
expect class E05(e: E01)
expect class E06 {
constructor(e: E02)
}
expect interface I01
expect class M01 {
fun foo()
}
expect enum class ENUM01
expect annotation class ANNO01
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
actual object E01
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> E02
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> E03
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> E04
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> E05
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> E06
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> I01
actual object M01 {
actual fun foo() {}
}
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> ENUM01
actual <!ACTUAL_WITHOUT_EXPECT!>object<!> ANNO01
@@ -0,0 +1,49 @@
// MODULE: m1-common
// FILE: common.kt
expect class E01
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E02()<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect open class E03<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E04 {
constructor()
}<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E05(e: E01)<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect class E06 {
constructor(e: E02)
}<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect interface I01<!>
expect class M01 {
fun foo()
}
<!INCOMPATIBLE_MATCHING{JVM}!>expect enum class ENUM01<!>
<!INCOMPATIBLE_MATCHING{JVM}!>expect annotation class ANNO01<!>
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
object ActualObject {
fun foo() {}
}
actual typealias E01 = ActualObject
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E02<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E03<!> = ActualObject
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E04<!> = ActualObject
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E05<!> = ActualObject
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>E06<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>I01<!> = ActualObject
actual typealias M01 = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>ENUM01<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>ANNO01<!> = ActualObject
@@ -0,0 +1,49 @@
// MODULE: m1-common
// FILE: common.kt
expect class E01
expect class E02()
expect open class E03
expect class E04 {
constructor()
}
expect class E05(e: E01)
expect class E06 {
constructor(e: E02)
}
expect interface I01
expect class M01 {
fun foo()
}
expect enum class ENUM01
expect annotation class ANNO01
// MODULE: m2-jvm()()(m1-common)
// FILE: jvm.kt
object ActualObject {
fun foo() {}
}
actual typealias E01 = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E02<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E03<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E04<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E05<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>E06<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>I01<!> = ActualObject
actual typealias M01 = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>ENUM01<!> = ActualObject
actual typealias <!ACTUAL_WITHOUT_EXPECT!>ANNO01<!> = ActualObject