JS: fix inlining of callable references
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -32,6 +32,8 @@ var JsName.descriptor: DeclarationDescriptor? by MetadataProperty(default = null
|
||||
// TODO: move this to module 'js.inliner' and change dependency on 'frontend' to dependency on 'descriptors'
|
||||
var JsInvocation.inlineStrategy: InlineStrategy? by MetadataProperty(default = null)
|
||||
|
||||
var JsInvocation.isCallableReference by MetadataProperty(default = false)
|
||||
|
||||
var JsInvocation.descriptor: CallableDescriptor? by MetadataProperty(default = null)
|
||||
|
||||
var JsInvocation.psiElement: PsiElement? by MetadataProperty(default = null)
|
||||
|
||||
+2
@@ -190,6 +190,8 @@ class RedundantStatementElimination(private val root: JsFunction) {
|
||||
|
||||
is JsObjectLiteral -> expression.propertyInitializers.flatMap { replace(it.labelExpr) + replace(it.valueExpr) }
|
||||
|
||||
is JsFunction -> if (expression.name == null) listOf() else listOf(expression)
|
||||
|
||||
else -> listOf(expression)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.js.inline.context
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.isCallableReference
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
|
||||
import org.jetbrains.kotlin.js.inline.FunctionReader
|
||||
import org.jetbrains.kotlin.js.inline.util.*
|
||||
@@ -91,7 +92,7 @@ abstract class FunctionContext(
|
||||
val qualifier = callQualifier.transitiveStaticRef
|
||||
return when (qualifier) {
|
||||
is JsInvocation -> {
|
||||
getSimpleName(qualifier)?.let { simpleName ->
|
||||
tryExtractCallableReference(qualifier) ?: getSimpleName(qualifier)?.let { simpleName ->
|
||||
lookUpStaticFunction(simpleName)?.let { if (isFunctionCreator(it)) it else null }
|
||||
}
|
||||
}
|
||||
@@ -100,4 +101,12 @@ abstract class FunctionContext(
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryExtractCallableReference(invocation: JsInvocation): JsFunction? {
|
||||
if (invocation.isCallableReference) {
|
||||
val arg = invocation.arguments[1]
|
||||
if (arg is JsFunction) return arg
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -16694,13 +16694,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
@TestMetadata("simpleNames.kt")
|
||||
public void testSimpleNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/simpleNames.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -22,6 +22,9 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.isCallableReference
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
@@ -226,7 +229,10 @@ object CallableReferenceTranslator {
|
||||
val nameLiteral = context.program().getStringLiteral(name)
|
||||
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
||||
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
||||
invokeFun.sideEffects = SideEffectKind.PURE
|
||||
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
||||
invocation.isCallableReference = true
|
||||
invocation.sideEffects = SideEffectKind.PURE
|
||||
return invocation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test except=imul
|
||||
|
||||
internal fun multiplyBy2(x: Int): Int = x * 2
|
||||
internal inline fun multiplyBy2(x: Int): Int = x * 2
|
||||
|
||||
internal fun test(x: Int): Int = apply(x, ::multiplyBy2)
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package foo
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test function=even
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test function=filter_azvtw4$
|
||||
|
||||
internal fun even(x: Int) = x % 2 == 0
|
||||
internal inline fun even(x: Int) = x % 2 == 0
|
||||
|
||||
internal fun test(a: List<Int>) = a.filter(::even)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user