JS: don't throw AssertionError from RedundantCallElimination

Also mark JS `call` function to avoid removing a custom `call`
This commit is contained in:
Anton Bannykh
2018-08-10 18:12:03 +03:00
parent 0895f72570
commit 4e496cf2b2
7 changed files with 49 additions and 4 deletions
@@ -47,6 +47,8 @@ var JsInvocation.descriptor: CallableDescriptor? by MetadataProperty(default = n
var JsInvocation.psiElement: PsiElement? by MetadataProperty(default = null)
var JsNameRef.isJsCall: Boolean by MetadataProperty(default = false)
var JsNameRef.inlineStrategy: InlineStrategy? by MetadataProperty(default = null)
var JsNameRef.descriptor: CallableDescriptor? by MetadataProperty(default = null)
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
import org.jetbrains.kotlin.js.backend.ast.RecursiveJsVisitor
import org.jetbrains.kotlin.js.inline.util.getCallerQualifier
import org.jetbrains.kotlin.js.backend.ast.metadata.isJsCall
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
// Replaces a.foo.call(a, b) with a.foo(b)
@@ -37,7 +37,11 @@ class RedundantCallElimination(private val root: JsBlock) {
private fun tryEliminate(invocation: JsInvocation) {
if (!isCallInvocation(invocation)) return
val qualifier = getCallerQualifier(invocation) as? JsNameRef ?: return
val call = invocation.qualifier as? JsNameRef ?: return
if (!call.isJsCall) return
val qualifier = call.qualifier as? JsNameRef ?: return
val receiver = qualifier.qualifier as? JsNameRef ?: return
val firstArg = invocation.arguments.firstOrNull() as? JsNameRef ?: return
@@ -70,7 +70,7 @@ fun isCallInvocation(invocation: JsInvocation): Boolean {
if (qualifier.name?.descriptor != null) return false
return qualifier?.ident == Namer.CALL_FUNCTION && arguments.isNotEmpty()
return qualifier?.ident == Namer.CALL_FUNCTION && arguments.isNotEmpty() && qualifier.qualifier != null
}
/**
@@ -3835,6 +3835,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
runTest("js/js.translator/testData/box/inline/extensionWithManyArguments.kt");
}
@TestMetadata("faultyRedundantCallElimination.kt")
public void testFaultyRedundantCallElimination() throws Exception {
runTest("js/js.translator/testData/box/inline/faultyRedundantCallElimination.kt");
}
@TestMetadata("identityEquals.kt")
public void testIdentityEquals() throws Exception {
runTest("js/js.translator/testData/box/inline/identityEquals.kt");
@@ -3835,6 +3835,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
runTest("js/js.translator/testData/box/inline/extensionWithManyArguments.kt");
}
@TestMetadata("faultyRedundantCallElimination.kt")
public void testFaultyRedundantCallElimination() throws Exception {
runTest("js/js.translator/testData/box/inline/faultyRedundantCallElimination.kt");
}
@TestMetadata("identityEquals.kt")
public void testIdentityEquals() throws Exception {
runTest("js/js.translator/testData/box/inline/identityEquals.kt");
@@ -162,7 +162,9 @@ public final class Namer {
@NotNull
public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
return pureFqn(CALL_FUNCTION, functionExpression);
JsNameRef result = pureFqn(CALL_FUNCTION, functionExpression);
MetadataProperties.setJsCall(result, true);
return result;
}
@NotNull
@@ -0,0 +1,27 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1189
// MODULE: lib
// FILE: lib.kt
fun String.call() = this + "O"
inline fun O() = "".call()
object A {
val foo = Foo
}
object Foo {
@JsName("call")
fun call(a: A, k: String) = k
}
inline fun K(a: A) = a.foo.call(a, "K")
// MODULE: main(lib)
// FILE: main.kt
val a = A
fun box() = O() + K(a)