JS: fix inheriting fake overrides in inlined object literals

This commit is contained in:
Anton Bannykh
2018-12-23 22:00:09 +03:00
committed by Anton Bannykh
parent 9716abcc12
commit 2022a9c887
4 changed files with 43 additions and 2 deletions
@@ -3875,6 +3875,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/inline/extensionWithManyArguments.kt");
}
@TestMetadata("fakeOverrideInlining.kt")
public void testFakeOverrideInlining() throws Exception {
runTest("js/js.translator/testData/box/inline/fakeOverrideInlining.kt");
}
@TestMetadata("faultyRedundantCallElimination.kt")
public void testFaultyRedundantCallElimination() throws Exception {
runTest("js/js.translator/testData/box/inline/faultyRedundantCallElimination.kt");
@@ -3875,6 +3875,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/inline/extensionWithManyArguments.kt");
}
@TestMetadata("fakeOverrideInlining.kt")
public void testFakeOverrideInlining() throws Exception {
runTest("js/js.translator/testData/box/inline/fakeOverrideInlining.kt");
}
@TestMetadata("faultyRedundantCallElimination.kt")
public void testFaultyRedundantCallElimination() throws Exception {
runTest("js/js.translator/testData/box/inline/faultyRedundantCallElimination.kt");
@@ -236,6 +236,18 @@ class Merger(
}
}
private fun JsStatement?.isFakeOverrideAssignment(): Boolean {
fun JsExpression?.isMemberReference(): Boolean {
val qualifier = (this as? JsNameRef)?.qualifier as? JsNameRef ?: return false
return qualifier.name == null && qualifier.ident == "prototype"
}
val binOp = (this as? JsExpressionStatement)?.expression as? JsBinaryOperation ?: return false
return binOp.operator == JsBinaryOperator.ASG && binOp.arg1.isMemberReference() && binOp.arg2.isMemberReference()
}
// Adds different boilerplate code (like imports, class prototypes, etc) to resulting program.
fun merge() {
mergeNames()
@@ -246,13 +258,21 @@ class Merger(
addClassPrototypes(this)
// TODO better placing?
importedFunctionWrappers.values.forEach {
this += it.statements
val additionalFakeOverrides = mutableListOf<JsStatement>()
importedFunctionWrappers.values.forEach {block ->
block.statements.forEach { s ->
if (s.isFakeOverrideAssignment()) {
additionalFakeOverrides += s
} else {
this += s
}
}
}
this += declarationBlock.statements
this += exportBlock.statements
addClassPostDeclarations(this)
this += additionalFakeOverrides
this += initializerBlock.statements
this += testsMap.values
mainFn?.second?.let { this += it }
@@ -0,0 +1,11 @@
// EXPECTED_REACHABLE_NODES: 1280
inline fun foo() = (object : II {}).ok()
fun box() = foo()
interface I {
fun ok() = "OK"
}
interface II: I