JS: don't throw AssertionError from RedundantCallElimination
Also mark JS `call` function to avoid removing a custom `call`
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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)
|
||||
Reference in New Issue
Block a user