[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.
|
* 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
|
val obj = expression.symbol.owner
|
||||||
assert(obj.kind == ClassKind.OBJECT)
|
assert(obj.kind == ClassKind.OBJECT)
|
||||||
assert(obj.isEffectivelyExternal()) { "Non external IrGetObjectValue must be lowered" }
|
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)
|
return context.getRefForExternalClass(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -6479,9 +6479,7 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInPropertyAccess() throws Exception {
|
public void testAllFilesPresentInPropertyAccess() throws Exception {
|
||||||
KotlinTestUtils
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"),
|
|
||||||
Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS_IR, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classUsesPackageProperties.kt")
|
@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);
|
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")
|
@TestMetadata("enumEntryInitOrder.kt")
|
||||||
public void testEnumEntryInitOrder() throws Exception {
|
public void testEnumEntryInitOrder() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/regression/enumEntryInitOrder.kt");
|
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 {
|
public void testAllFilesPresentInPropertyAccess() throws Exception {
|
||||||
KotlinTestUtils
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
||||||
.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/propertyAccess"),
|
|
||||||
Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("classUsesPackageProperties.kt")
|
@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);
|
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")
|
@TestMetadata("enumEntryInitOrder.kt")
|
||||||
public void testEnumEntryInitOrder() throws Exception {
|
public void testEnumEntryInitOrder() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/regression/enumEntryInitOrder.kt");
|
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