[JS IR] Do not copy prototype references of FO from super class

Reduce bundle size from issue from 4.9M to 3.4M

 - fix KT-41227
 - add simple test
This commit is contained in:
Roman Artemev
2020-10-16 15:17:04 +03:00
parent 99a6bdeec7
commit 4d63ecd83c
5 changed files with 54 additions and 2 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.backend.js.export.isExported
import org.jetbrains.kotlin.ir.backend.js.utils.*
@@ -142,6 +143,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
return this.overriddenSymbols.any { it.owner.overridesExternal() }
}
private fun IrClass.shouldCopyFrom(): Boolean {
return isInterface && !isEffectivelyExternal()
}
private fun generateMemberFunction(declaration: IrSimpleFunction): Pair<JsNameRef, JsFunction?> {
val memberName = context.getNameForMemberFunction(declaration.realOverrideTarget)
val memberRef = JsNameRef(memberName, classPrototypeRef)
@@ -158,10 +163,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
// interface II : I
// II.prototype.foo = I.prototype.foo
if (!irClass.isInterface) {
declaration.realOverrideTarget.let { it ->
declaration.realOverrideTarget.let {
val implClassDeclaration = it.parent as IrClass
if (!implClassDeclaration.defaultType.isAny() && !it.isEffectivelyExternal()) {
if (implClassDeclaration.shouldCopyFrom()) {
val implMethodName = context.getNameForMemberFunction(it)
val implClassName = context.getNameForClass(implClassDeclaration)
@@ -3470,6 +3470,11 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test {
runTest("js/js.translator/testData/box/inheritance/baseClassDefinedAfterDerived.kt");
}
@TestMetadata("childPrototype.kt")
public void testChildPrototype() throws Exception {
runTest("js/js.translator/testData/box/inheritance/childPrototype.kt");
}
@TestMetadata("complexInitializationOrder.kt")
public void testComplexInitializationOrder() throws Exception {
runTest("js/js.translator/testData/box/inheritance/complexInitializationOrder.kt");
@@ -3470,6 +3470,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/inheritance/baseClassDefinedAfterDerived.kt");
}
@TestMetadata("childPrototype.kt")
public void testChildPrototype() throws Exception {
runTest("js/js.translator/testData/box/inheritance/childPrototype.kt");
}
@TestMetadata("complexInitializationOrder.kt")
public void testComplexInitializationOrder() throws Exception {
runTest("js/js.translator/testData/box/inheritance/complexInitializationOrder.kt");
@@ -3485,6 +3485,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/inheritance/baseClassDefinedAfterDerived.kt");
}
@TestMetadata("childPrototype.kt")
public void testChildPrototype() throws Exception {
runTest("js/js.translator/testData/box/inheritance/childPrototype.kt");
}
@TestMetadata("complexInitializationOrder.kt")
public void testComplexInitializationOrder() throws Exception {
runTest("js/js.translator/testData/box/inheritance/complexInitializationOrder.kt");
@@ -0,0 +1,32 @@
// EXPECTED_REACHABLE_NODES: 1251
// KT-41227
var result = ""
open class A {
@JsName("foo")
fun foo() { result += "A" }
@JsName("boo")
open fun boo() { result += "FAIL" }
}
class B : A() {
override fun boo() { result += "B" }
@JsName("bar")
fun bar() { result += "C" }
}
fun box(): String {
val b = B()
b.boo()
b.foo()
b.bar()
if (result != "BAC") return "FAIL: $result"
return "OK"
}
// PROPERTY_WRITE_COUNT: name=foo count=1
// PROPERTY_WRITE_COUNT: name=boo count=2
// PROPERTY_WRITE_COUNT: name=bar count=1