Fix temporary variable elimination in JS BE

Don't eliminate temporary variable when between its usage and its
definition there's assignment to a non-local variable.

Fix KT-17540
This commit is contained in:
Alexey Andreev
2017-04-27 19:51:04 +03:00
parent 8d0eb207e3
commit d89ce80d97
6 changed files with 41 additions and 1 deletions
@@ -256,7 +256,7 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
}
private fun handleDefinition(name: JsName, value: JsExpression, node: JsNode) {
val sideEffects = handleExpression(value)
val sideEffects = handleExpression(value) || name !in localVariables
if (shouldConsiderTemporary(name)) {
if (isTrivial(value)) {
statementsToRemove += node
@@ -44,4 +44,6 @@ class TemporaryVariableEliminationTest : BasicOptimizerTest("temporary-variable"
@Test fun assignmentToNonLocal() = box()
@Test fun removeUnusedAndSubstitute() = box()
@Test fun assignmentToOuterVar() = box()
}
@@ -4112,6 +4112,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/inlineEvaluationOrder"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
}
@TestMetadata("alsoWithReassingment.kt")
public void testAlsoWithReassingment() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineEvaluationOrder/alsoWithReassingment.kt");
doTest(fileName);
}
@TestMetadata("argumentOfCall.kt")
public void testArgumentOfCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineEvaluationOrder/argumentOfCall.kt");
@@ -0,0 +1,10 @@
private var _value: String = "OK"
private inline fun String.myAlso(f: (String) -> Unit): String {
f(this)
return this
}
fun overrideValueAndReturnOld(newValue: String) = _value.myAlso { _value = newValue }
fun box() = overrideValueAndReturnOld("fail")
@@ -0,0 +1,11 @@
var value = "OK";
function foo(newValue) {
var $tmp = value;
value = newValue;
return $tmp;
}
function box() {
return foo("fail");
}
@@ -0,0 +1,11 @@
var value = "OK";
function foo(newValue) {
var $tmp = value;
value = newValue;
return $tmp;
}
function box() {
return foo("fail");
}