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
|
// WITH_REFLECT
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
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'
|
// 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.inlineStrategy: InlineStrategy? by MetadataProperty(default = null)
|
||||||
|
|
||||||
|
var JsInvocation.isCallableReference by MetadataProperty(default = false)
|
||||||
|
|
||||||
var JsInvocation.descriptor: CallableDescriptor? by MetadataProperty(default = null)
|
var JsInvocation.descriptor: CallableDescriptor? by MetadataProperty(default = null)
|
||||||
|
|
||||||
var JsInvocation.psiElement: PsiElement? 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 JsObjectLiteral -> expression.propertyInitializers.flatMap { replace(it.labelExpr) + replace(it.valueExpr) }
|
||||||
|
|
||||||
|
is JsFunction -> if (expression.name == null) listOf() else listOf(expression)
|
||||||
|
|
||||||
else -> listOf(expression)
|
else -> listOf(expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.js.inline.context
|
package org.jetbrains.kotlin.js.inline.context
|
||||||
|
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
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.backend.ast.metadata.descriptor
|
||||||
import org.jetbrains.kotlin.js.inline.FunctionReader
|
import org.jetbrains.kotlin.js.inline.FunctionReader
|
||||||
import org.jetbrains.kotlin.js.inline.util.*
|
import org.jetbrains.kotlin.js.inline.util.*
|
||||||
@@ -91,7 +92,7 @@ abstract class FunctionContext(
|
|||||||
val qualifier = callQualifier.transitiveStaticRef
|
val qualifier = callQualifier.transitiveStaticRef
|
||||||
return when (qualifier) {
|
return when (qualifier) {
|
||||||
is JsInvocation -> {
|
is JsInvocation -> {
|
||||||
getSimpleName(qualifier)?.let { simpleName ->
|
tryExtractCallableReference(qualifier) ?: getSimpleName(qualifier)?.let { simpleName ->
|
||||||
lookUpStaticFunction(simpleName)?.let { if (isFunctionCreator(it)) it else null }
|
lookUpStaticFunction(simpleName)?.let { if (isFunctionCreator(it)) it else null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,4 +101,12 @@ abstract class FunctionContext(
|
|||||||
else -> null
|
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")
|
@TestMetadata("simpleNames.kt")
|
||||||
public void testSimpleNames() throws Exception {
|
public void testSimpleNames() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/simpleNames.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/simpleNames.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
@@ -22,6 +22,9 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
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.callTranslator.CallTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
@@ -226,7 +229,10 @@ object CallableReferenceTranslator {
|
|||||||
val nameLiteral = context.program().getStringLiteral(name)
|
val nameLiteral = context.program().getStringLiteral(name)
|
||||||
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
||||||
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
||||||
|
invokeFun.sideEffects = SideEffectKind.PURE
|
||||||
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
||||||
|
invocation.isCallableReference = true
|
||||||
|
invocation.sideEffects = SideEffectKind.PURE
|
||||||
return invocation
|
return invocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import utils.*
|
|||||||
|
|
||||||
// CHECK_CONTAINS_NO_CALLS: test except=imul
|
// 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)
|
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=even
|
||||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test function=filter_azvtw4$
|
// 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)
|
internal fun test(a: List<Int>) = a.filter(::even)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user