[JS IR BE] Support companion objects in external interfaces
These objects are referenced but value is not actually used. Replace access to these references with null literals.
This commit is contained in:
committed by
Zalim Bashorov
parent
f4b94ccbc8
commit
3ec13d5bd6
+9
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -95,6 +95,14 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
val obj = expression.symbol.owner
|
||||
assert(obj.kind == ClassKind.OBJECT)
|
||||
assert(obj.isEffectivelyExternal()) { "Non external IrGetObjectValue must be lowered" }
|
||||
|
||||
// External interfaces cannot normally have companion objects.
|
||||
// However, stdlib uses them to simulate string literal unions
|
||||
// TODO: Stop abusing this tech
|
||||
if (obj.isCompanion && obj.parentAsClass.isInterface) {
|
||||
return JsNullLiteral()
|
||||
}
|
||||
|
||||
return context.getRefForExternalClass(obj)
|
||||
}
|
||||
|
||||
|
||||
+6
-3
@@ -6479,9 +6479,7 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPropertyAccess() throws Exception {
|
||||
KotlinTestUtils
|
||||
.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"),
|
||||
Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classUsesPackageProperties.kt")
|
||||
@@ -6816,6 +6814,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/regression"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("companionObjectInExternalInterface.kt")
|
||||
public void testCompanionObjectInExternalInterface() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/companionObjectInExternalInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntryInitOrder.kt")
|
||||
public void testEnumEntryInitOrder() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/enumEntryInitOrder.kt");
|
||||
|
||||
+6
-3
@@ -6504,9 +6504,7 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPropertyAccess() throws Exception {
|
||||
KotlinTestUtils
|
||||
.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"),
|
||||
Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classUsesPackageProperties.kt")
|
||||
@@ -6871,6 +6869,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/regression"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("companionObjectInExternalInterface.kt")
|
||||
public void testCompanionObjectInExternalInterface() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/companionObjectInExternalInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntryInitOrder.kt")
|
||||
public void testEnumEntryInitOrder() throws Exception {
|
||||
runTest("js/js.translator/testData/box/regression/enumEntryInitOrder.kt");
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1303
|
||||
|
||||
// This hack is used in org.w3c.* part of standard library to represent unions of Strings
|
||||
// Test that we are not actually trying to access nonexistent companion object
|
||||
|
||||
@Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE")
|
||||
public external interface I {
|
||||
companion object
|
||||
}
|
||||
public inline val I.Companion.O: I get() = "O".asDynamic().unsafeCast<I>()
|
||||
public inline val I.Companion.K: I get() = "K".asDynamic().unsafeCast<I>()
|
||||
|
||||
fun box(): String {
|
||||
if (I.O != I.O) return "Fail 1"
|
||||
if (I.O == I.K) return "Fail 2"
|
||||
return I.O.unsafeCast<String>() + I.K.unsafeCast<String>()
|
||||
}
|
||||
Reference in New Issue
Block a user