[JS IR] Control an inheritance of non-external entity from external

Add a special annotation @JsExternalInheritorsOnly for marking
 external interfaces and classes. The marked interface or class
 can’t be a parent for non external interfaces, classes or objects.

^KT-57423 Fixed
This commit is contained in:
Alexander Korepanov
2023-03-21 11:45:04 +01:00
committed by Space Team
parent 6e7b078873
commit 4813b659ab
26 changed files with 677 additions and 1 deletions
@@ -0,0 +1,63 @@
// DONT_TARGET_EXACT_BACKEND: JS
// DONT_TARGET_EXACT_BACKEND: WASM
// ES_MODULES
@OptIn(ExperimentalStdlibApi::class)
@JsExternalInheritorsOnly
external interface ExternalInterfaceX {
val x: String
}
external interface ExternalInterfaceXY : ExternalInterfaceX {
val y: String
}
external interface ExternalInterfaceXYZ : ExternalInterfaceXY {
val z: String
}
external class ExternalXYZ() : ExternalInterfaceXYZ {
override val x: String
override val y: String
override val z: String
}
external class ExternalClassNameSpace {
interface NestedInterfaceXYZ : ExternalInterfaceXYZ {
override val x: String
override val y: String
override val z: String
}
}
@JsModule("./jsExternalInheritorsOnly.mjs")
external object Creator: ExternalInterfaceXYZ {
fun createX(): ExternalInterfaceX
fun createXY(): ExternalInterfaceXY
fun createXYZ(): ExternalInterfaceXYZ
fun createClassXYZ(): ExternalXYZ
fun createNestedInterfaceXYZ(): ExternalClassNameSpace.NestedInterfaceXYZ
override val x: String
override val y: String
override val z: String
}
fun checkX(x: ExternalInterfaceX, id: Int) = x.x == "X$id"
fun checkXY(xy: ExternalInterfaceXY, id: Int) = checkX(xy, id) && xy.y == "Y$id"
fun checkXYZ(xyz: ExternalInterfaceXYZ, id: Int) = checkXY(xyz, id) && xyz.z == "Z$id"
fun box(): String {
if (!checkX(Creator.createX(), 1)) return "Fail interface X"
if (!checkXY(Creator.createXY(), 2)) return "Fail interface XY"
if (!checkXYZ(Creator.createXYZ(), 3)) return "Fail interface XYZ"
if (!checkXYZ(Creator.createClassXYZ(), 4)) return "Fail class XYZ"
if (!checkXYZ(Creator.createNestedInterfaceXYZ(), 5)) return "Fail nested interface XYZ"
if (!checkXYZ(Creator, 6)) return "Fail object XYZ"
return "OK"
}
@@ -0,0 +1,21 @@
export default {
createX: function () {
return {x: "X1"};
},
createXY: function () {
return {x: "X2", y: "Y2"};
},
createXYZ: function () {
return {x: "X3", y: "Y3", z: "Z3"};
},
createClassXYZ: function () {
return {x: "X4", y: "Y4", z: "Z4"};
},
createNestedInterfaceXYZ: function () {
return {x: "X5", y: "Y5", z: "Z5"};
},
x: "X6",
y: "Y6",
z: "Z6"
};