[JS IR] Export nested objects
Companion objects are exported as ParentClass.Companion. Companion object's members are not exposed to its parent class — one must reference the companion object explicitly if they want to access its members. #KT-43783 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
862f8cdad8
commit
be999564b1
+7
-1
@@ -86,9 +86,15 @@ class ExportModelToJsStatements(
|
||||
)
|
||||
).makeStmt()
|
||||
|
||||
// These are only used when exporting secondary constructors annotated with @JsName
|
||||
val staticFunctions = declaration.members.filter { it is ExportedFunction && it.isStatic }
|
||||
|
||||
val staticsExport = (staticFunctions + declaration.nestedClasses)
|
||||
// Nested objects are exported as static properties
|
||||
val staticProperties = declaration.members.mapNotNull {
|
||||
(it as? ExportedProperty)?.takeIf { it.isStatic }
|
||||
}
|
||||
|
||||
val staticsExport = (staticFunctions + staticProperties + declaration.nestedClasses)
|
||||
.flatMap { generateDeclarationExport(it, newNameSpace) }
|
||||
|
||||
listOf(klassExport) + staticsExport
|
||||
|
||||
Generated
+5
@@ -1627,6 +1627,11 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exportNestedObject.kt")
|
||||
public void testExportNestedObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonIndetifierModuleName.kt")
|
||||
public void testNonIndetifierModuleName() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt");
|
||||
|
||||
+5
@@ -1627,6 +1627,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exportNestedObject.kt")
|
||||
public void testExportNestedObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonIndetifierModuleName.kt")
|
||||
public void testNonIndetifierModuleName() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt");
|
||||
|
||||
+5
@@ -1632,6 +1632,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exportNestedObject.kt")
|
||||
public void testExportNestedObject() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/exportNestedObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonIndetifierModuleName.kt")
|
||||
public void testNonIndetifierModuleName() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt");
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1265
|
||||
// RUN_PLAIN_BOX_FUNCTION
|
||||
// INFER_MAIN_MODULE
|
||||
// SKIP_MINIFICATION
|
||||
// SKIP_DCE_DRIVEN
|
||||
// SKIP_NODE_JS
|
||||
|
||||
// See KT-43783
|
||||
|
||||
// MODULE: nestedObjectExport
|
||||
// FILE: lib.kt
|
||||
|
||||
@JsExport
|
||||
class Abc {
|
||||
companion object AbcCompanion {
|
||||
fun xyz(): String = "Companion object method OK"
|
||||
|
||||
val prop: String
|
||||
get() = "Companion object property OK"
|
||||
}
|
||||
}
|
||||
|
||||
@JsExport
|
||||
class Foo {
|
||||
companion object {
|
||||
fun xyz(): String = "Companion object method OK"
|
||||
|
||||
val prop: String
|
||||
get() = "Companion object property OK"
|
||||
}
|
||||
}
|
||||
|
||||
@JsExport
|
||||
sealed class MyEnum(val name: String) {
|
||||
object A: MyEnum("A")
|
||||
object B: MyEnum("B")
|
||||
object C: MyEnum("C")
|
||||
}
|
||||
|
||||
// FILE: test.js
|
||||
|
||||
function box() {
|
||||
const abcCompanion = nestedObjectExport.Abc.AbcCompanion;
|
||||
|
||||
if (abcCompanion.xyz() != 'Companion object method OK') return 'companion object function failure';
|
||||
if (abcCompanion.prop != 'Companion object property OK') return 'companion object property failure';
|
||||
|
||||
const justCompanion = nestedObjectExport.Foo.Companion;
|
||||
|
||||
if (justCompanion.xyz() != 'Companion object method OK') return 'companion object function failure';
|
||||
if (justCompanion.prop != 'Companion object property OK') return 'companion object property failure';
|
||||
|
||||
if (nestedObjectExport.MyEnum.A.name != 'A') return 'MyEnum.A failure';
|
||||
if (nestedObjectExport.MyEnum.B.name != 'B') return 'MyEnum.B failure';
|
||||
if (nestedObjectExport.MyEnum.C.name != 'C') return 'MyEnum.C failure';
|
||||
|
||||
return 'OK';
|
||||
}
|
||||
@@ -96,8 +96,6 @@ object O {
|
||||
fun takesO(o: O): Int =
|
||||
O.x + O.foo()
|
||||
|
||||
// Test that JsExport with companion object compiles without error.
|
||||
// Usage is not supported yet.
|
||||
class KT_37829 {
|
||||
companion object {
|
||||
val x = 10
|
||||
|
||||
+3
@@ -22,6 +22,7 @@ import _valCustomWithField = JS_TESTS.foo._valCustomWithField;
|
||||
import A4 = JS_TESTS.foo.A4;
|
||||
import O = JS_TESTS.foo.O;
|
||||
import takesO = JS_TESTS.foo.takesO;
|
||||
import KT_37829 = JS_TESTS.foo.KT_37829;
|
||||
|
||||
function assert(condition: boolean) {
|
||||
if (!condition) {
|
||||
@@ -92,5 +93,7 @@ function box(): string {
|
||||
assert(O.foo() === 20);
|
||||
assert(takesO(O) === 30);
|
||||
|
||||
assert(KT_37829.Companion.x == 10);
|
||||
|
||||
return "OK";
|
||||
}
|
||||
Reference in New Issue
Block a user