From 19438a3a07c38ceeb2b8e2188d12e4bbfc1617dc Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 28 Nov 2017 19:42:33 +0300 Subject: [PATCH] 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). --- .../inline/clean/removeUnusedFunctionDefinitions.kt | 6 +++--- .../jetbrains/kotlin/js/inline/util/collectUtils.kt | 4 ---- .../js/test/semantics/BoxJsTestGenerated.java | 6 ++++++ .../testData/box/incremental/inlineLambda.kt | 13 +++++++++++++ 4 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 js/js.translator/testData/box/incremental/inlineLambda.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedFunctionDefinitions.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedFunctionDefinitions.kt index 13a36601115..ef03d7d77a2 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedFunctionDefinitions.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedFunctionDefinitions.kt @@ -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 = - collectReferencedNames(scope).filter { it.staticRef is JsFunction } - fun collectReferencedNames(scope: JsNode): Set { val references = mutableSetOf() diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 16c71d2dc2c..f3839545a57 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -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"); diff --git a/js/js.translator/testData/box/incremental/inlineLambda.kt b/js/js.translator/testData/box/incremental/inlineLambda.kt new file mode 100644 index 00000000000..49aac002e29 --- /dev/null +++ b/js/js.translator/testData/box/incremental/inlineLambda.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" } \ No newline at end of file