JS: fix losing lambda in inline function after incremental compilation
See KT-21493 It's hard to maintain staticRef in cached AST. In fact, we don't need it in this optimization. We'll get excessive names in used set, which is ok: non-function names don't matter, they'll be simply ignored. One possible concern: there's more chance to get name same to some function's name and it won't be removed. First, it's not fatal, it won't break the code (but put some excessive code that will likely be removed by DCE). Second, there's same chance of two functions having same names, and we manage to avoid this (otherwise we'll get many problems).
This commit is contained in:
+3
-3
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.isLocal
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
||||
import org.jetbrains.kotlin.js.inline.util.collectFunctionReferencesInside
|
||||
import org.jetbrains.kotlin.js.inline.util.collectReferencedNames
|
||||
|
||||
/**
|
||||
* Removes unused function definitions:
|
||||
@@ -93,13 +93,13 @@ private class UnusedLocalFunctionsCollector(private val functions: Map<JsName, J
|
||||
}
|
||||
|
||||
private fun processLocalFunction(name: JsName, function: JsFunction) {
|
||||
for (referenced in collectFunctionReferencesInside(function)) {
|
||||
for (referenced in collectReferencedNames(function)) {
|
||||
tracker.addRemovableReference(name, referenced)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processNonLocalFunction(function: JsFunction) {
|
||||
for (referenced in collectFunctionReferencesInside(function)) {
|
||||
for (referenced in collectReferencedNames(function)) {
|
||||
tracker.markReachable(referenced)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.js.inline.util
|
||||
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.imported
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||
import org.jetbrains.kotlin.js.inline.util.collectors.InstanceCollector
|
||||
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
|
||||
fun collectFunctionReferencesInside(scope: JsNode): List<JsName> =
|
||||
collectReferencedNames(scope).filter { it.staticRef is JsFunction }
|
||||
|
||||
fun collectReferencedNames(scope: JsNode): Set<JsName> {
|
||||
val references = mutableSetOf<JsName>()
|
||||
|
||||
|
||||
@@ -3803,6 +3803,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambda.kt")
|
||||
public void testInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/incremental/inlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("jsModule.kt")
|
||||
public void testJsModule() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/incremental/jsModule.kt");
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1128
|
||||
// FILE: a.kt
|
||||
inline fun foo(f: () -> String): () -> String {
|
||||
val result = f()
|
||||
return { result }
|
||||
}
|
||||
|
||||
|
||||
// FILE: main.kt
|
||||
// RECOMPILE
|
||||
fun bar(f: () -> String) = foo(f)()
|
||||
|
||||
fun box(): String = bar { "OK" }
|
||||
Reference in New Issue
Block a user