From 989cebe79ec708e589265201b4f205ba54474975 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 24 Aug 2017 16:18:55 +0300 Subject: [PATCH] JS: fix bug in temporary variable eliminator The problem was in considering `a` as trivial in following case: ``` var a = b; ``` However, that's wrong assumption, since `b` can be temporary variable itself which is further substituted by a non-trivial expression. --- .../clean/TemporaryVariableElimination.kt | 2 +- .../js/test/semantics/BoxJsTestGenerated.java | 6 ++++ .../temporaryVarNonTrivial.kt | 31 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/box/inlineEvaluationOrder/temporaryVarNonTrivial.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt index 75ee37ae41f..6e11fb8dc9c 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt @@ -615,7 +615,7 @@ internal class TemporaryVariableElimination(private val function: JsFunction) { is JsNameRef -> { val qualifier = expr.qualifier if (expr.sideEffects == SideEffectKind.PURE && (qualifier == null || isTrivial(qualifier))) { - true + expr.name !in temporary } else { val name = expr.name 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 3883d18650e..a3c11659849 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 @@ -4484,6 +4484,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("temporaryVarNonTrivial.kt") + public void testTemporaryVarNonTrivial() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineEvaluationOrder/temporaryVarNonTrivial.kt"); + doTest(fileName); + } + @TestMetadata("ternaryConditional.kt") public void testTernaryConditional() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineEvaluationOrder/ternaryConditional.kt"); diff --git a/js/js.translator/testData/box/inlineEvaluationOrder/temporaryVarNonTrivial.kt b/js/js.translator/testData/box/inlineEvaluationOrder/temporaryVarNonTrivial.kt new file mode 100644 index 00000000000..6e06fe2cf0c --- /dev/null +++ b/js/js.translator/testData/box/inlineEvaluationOrder/temporaryVarNonTrivial.kt @@ -0,0 +1,31 @@ +// EXPECTED_REACHABLE_NODES: 1002 +var log = "" + +fun bar(): A { + log += "foo;" + return A() +} + +class A { + fun f() { + log += "f;" + } + + fun g() { + log += "g;" + } +} + +inline fun with(x: T, a: T.() -> Unit) = x.a() + +fun box(): String { + with(bar()) { + f() + g() + } + + if (log != "foo;f;g;") return "fail: $log" + + return "OK" +} +