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 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.inlineStrategy: InlineStrategy? by MetadataProperty(default = null)
|
||||||
|
|
||||||
var JsNameRef.descriptor: CallableDescriptor? 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.JsInvocation
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
|
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
|
||||||
import org.jetbrains.kotlin.js.backend.ast.RecursiveJsVisitor
|
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
|
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
|
||||||
|
|
||||||
// Replaces a.foo.call(a, b) with a.foo(b)
|
// 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) {
|
private fun tryEliminate(invocation: JsInvocation) {
|
||||||
if (!isCallInvocation(invocation)) return
|
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 receiver = qualifier.qualifier as? JsNameRef ?: return
|
||||||
val firstArg = invocation.arguments.firstOrNull() 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
|
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");
|
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")
|
@TestMetadata("identityEquals.kt")
|
||||||
public void testIdentityEquals() throws Exception {
|
public void testIdentityEquals() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/inline/identityEquals.kt");
|
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");
|
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")
|
@TestMetadata("identityEquals.kt")
|
||||||
public void testIdentityEquals() throws Exception {
|
public void testIdentityEquals() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/inline/identityEquals.kt");
|
runTest("js/js.translator/testData/box/inline/identityEquals.kt");
|
||||||
|
|||||||
@@ -162,7 +162,9 @@ public final class Namer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
|
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
|
@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