From 27a186126379219bb7e04fffc52044ade7a57a3d Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Wed, 8 Apr 2015 19:24:39 +0300 Subject: [PATCH] JS: lambda constructor cannot have sideEffect --- .../kotlin/js/inline/util/sideEffectUtils.kt | 2 +- .../cases/lambdaWithClosure.kt | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/inlineEvaluationOrder/cases/lambdaWithClosure.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/sideEffectUtils.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/sideEffectUtils.kt index 550d22ee1eb..4bfeeadd175 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/sideEffectUtils.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/sideEffectUtils.kt @@ -31,6 +31,7 @@ public fun JsExpression.canHaveOwnSideEffect(): Boolean = is JsArrayLiteral, is JsNameRef -> false is JsBinaryOperation -> getOperator().isAssignment() + is JsInvocation -> !isFunctionCreatorInvocation(this) else -> true } @@ -43,6 +44,5 @@ public fun JsExpression.shouldHaveOwnAlias(): Boolean = is JsConditional, is JsBinaryOperation, is JsArrayLiteral -> true - is JsInvocation -> !isFunctionCreatorInvocation(this) else -> canHaveOwnSideEffect() } \ No newline at end of file diff --git a/js/js.translator/testData/inlineEvaluationOrder/cases/lambdaWithClosure.kt b/js/js.translator/testData/inlineEvaluationOrder/cases/lambdaWithClosure.kt new file mode 100644 index 00000000000..0a907c8b490 --- /dev/null +++ b/js/js.translator/testData/inlineEvaluationOrder/cases/lambdaWithClosure.kt @@ -0,0 +1,49 @@ +package foo + +/* This tests checks, that lambda fabric invocation is not extracted. + + An example: + fun foo() { + val status = "OK" + run { println(status) } + } + + It's compiled to something like: + function foo() { + var status = "OK"; + run(foo$(status)); + } + + function foo$(status) { + return function() { + console.log(status); + }; + } + + Thus, we need to be sure, that foo$() is not extracted to some temporary var. + */ + +// CHECK_NOT_CALLED: max +// CHECK_NOT_CALLED: box$f +// CHECK_NOT_CALLED: box$f_0 + +inline fun max(getA: ()->Int, b: Int): Int { + val a = getA() + log("max($a, $b)") + + if (a > b) return a + + return b +} + +fun box(): String { + val one = 1 + val two = 2 + val three = 3 + + val test = max({ fizz(one) }, max({ fizz(two) }, buzz(three))) + assertEquals(3, test) + assertEquals("buzz(3);fizz(2);max(2, 3);fizz(1);max(1, 3);", pullLog()) + + return "OK" +} \ No newline at end of file